0
0
mirror of https://github.com/marcrobledo/savegame-editors.git synced 2025-04-24 16:35:10 +00:00

* switch to service worker in all editors

* added MK7 editor
* fixed KI:Uprising weapon saving
* BOTW:
    * added Wii U/Switch mode transfer
    * fixed scrolling topbar
    * added compatibility with Kiosk version
    * master editor: revamp and faster
savegame-editor.js has been updated with fixes and performance improvements, also using now fetch to retrieve example files
This commit is contained in:
Marc Robledo 2019-04-16 11:21:05 +02:00
parent 76589c1e52
commit 1e66904112
58 changed files with 1222 additions and 660 deletions

View File

@ -6,6 +6,7 @@ It can edit a few bits in the following games:
* Hyrule Warriors (Wii U)
* Kid Icarus: Uprising (3DS)
* Final Fantasy Explorers (3DS)
* Mario Kart 7 (3DS)
* Team Kirby Clash Deluxe (3DS)
* Kirby's Blowout Blast (3DS)
* Picross 3D Round 2 (3DS)

View File

@ -1,25 +1,30 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
mod by marcrobledo, original from: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
*/
const PRECACHE_ID='v20180710';
const PRECACHE_FILES=[
'index.html','./',
'final-fantasy-explorers.js',
'database.js',
'icons.png',
'favicon.png',
'../savegame-editor.js'
const PRECACHE = 'precache-editor-ffexplorers-v2';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'database.js',
'favicon.png',
'final-fantasy-explorers.js',
'icons.png',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install',event=>{event.waitUntil(caches.open(PRECACHE_ID).then(cache=>cache.addAll(PRECACHE_FILES)).then(self.skipWaiting()))});self.addEventListener('activate',event=>{const currentCaches=[PRECACHE_ID,'runtime'];event.waitUntil(caches.keys().then(cacheNames=>{return cacheNames.filter(cacheName=>!currentCaches.includes(cacheName));}).then(cachesToDelete=>{return Promise.all(cachesToDelete.map(cacheToDelete=>{return caches.delete(cacheToDelete);}))}).then(()=>self.clients.claim()))});self.addEventListener('fetch',event=>{if(event.request.url.startsWith(self.location.origin))event.respondWith(caches.match(event.request).then(cachedResponse=>{if(cachedResponse)return cachedResponse;return caches.open('runtime').then(cache=>{return fetch(event.request).then(response=>{return cache.put(event.request,response.clone()).then(()=>{return response})})})}))})
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -17,7 +17,7 @@ SavegameEditor={
/* check if savegame is valid */
checkValidSavegame:function(){
return (tempFile.fileSize==201816)
return (tempFile.fileSize===201816)
},
@ -36,8 +36,8 @@ SavegameEditor={
tempFile.littleEndian=true;
tempFile.fileName='game0';
setValue('gil', tempFile.readThreeBytes(this.Offsets.GIL), 0, 9999999);
setValue('cp', tempFile.readThreeBytes(this.Offsets.CP), 0, 9999999);
setValue('gil', tempFile.readU24(this.Offsets.GIL), 0, 9999999);
setValue('cp', tempFile.readU24(this.Offsets.CP), 0, 9999999);
readInventoryFromTable('material', MATERIALS, this.Offsets.MATERIALS);
readInventoryFromTable('atmalith', ATMALITHS, this.Offsets.ATMALITHS);
@ -47,9 +47,8 @@ SavegameEditor={
/* save function */
save:function(){
tempFile.writeThreeBytes(this.Offsets.GIL, getValue('gil'));
tempFile.writeThreeBytes(this.Offsets.CP, getValue('cp'));
tempFile.writeU24(this.Offsets.GIL, getValue('gil'));
tempFile.writeU24(this.Offsets.CP, getValue('cp'));
writeToInventory('material', MATERIALS, this.Offsets.MATERIALS);
writeToInventory('atmalith', ATMALITHS, this.Offsets.ATMALITHS);
@ -58,22 +57,16 @@ SavegameEditor={
}
/* Implement 3-byte reader/writer in MarcBinFile */
MarcBinFile.prototype.readThreeBytes=function(offset){return (this.readByte(offset+2) << 16)+(this.readByte(offset+1) << 8)+(this.readByte(offset+0))}
MarcBinFile.prototype.writeThreeBytes=function(offset,val){this.writeBytes(offset, [(val & 0x0000ff) >> 0, (val & 0x00ff00) >> 8, (val & 0xff0000) >> 16])}
function readInventoryFromTable(container, table, offset){
for(var i=0; i<table.length; i++){
setValue(container+table[i][0], tempFile.readByte(offset+table[i][0]));
setValue(container+table[i][0], tempFile.readU8(offset+table[i][0]));
checkQuantity(getField(container+table[i][0]));
}
}
function writeToInventory(container, table, offset){
for(var i=0; i<table.length; i++){
tempFile.writeByte(offset+table[i][0], getValue(container+table[i][0]))
tempFile.writeU8(offset+table[i][0], getValue(container+table[i][0]))
}
}
function createInventoryTable(container, table){
@ -114,19 +107,4 @@ function Weapon(offset){
this.mRecovery=tempFile.readShort(offset+12);
this.trait=tempFile.readInt(offset+14);
this.traitValue=tempFile.readInt(offset+18);
}*/
window.addEventListener('load',function(){
/* service worker */
if(location.protocol==='http:')
location.href=window.location.href.replace('http:','https:');
if('serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
}*/

View File

@ -11,6 +11,16 @@
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./final-fantasy-explorers.js"></script>
<script type="text/javascript" src="./database.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
<style type="text/css"><!--
.fficon{
display:inline-block;

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-hwarriors-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'hyrule-warriors.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,86 +0,0 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<head>
<title>Savegame Editor &ndash; Hyrule Warriors</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
<meta name="description" content="A savegame editor for Hyrule Warriors. It can edit values for your apple and materials."/>
<meta name="keywords" content="html5, savegame, save, editor, hack, exploit, wii u, hyrule warriors, materials, experience, weapons"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="shortcut icon" href="../savegame-editor.png"/>
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./hyrule-warriors.js"></script>
</head>
<body>
<!-- HEADER -->
<div id="header">
<div id="header-top">
<div class="row wrapper padding-vertical">
<h1 class="six columns text-left"><img src="../favicon.png" /> Savegame Editor <small>for Hyrule Warriors</small></h1>
<div class="six columns text-right header-buttons">
by <a href="/" class="author">Marc Robledo</a>
<a href="https://github.com/marcrobledo/savegame-editors/tree/master/hyrule-warriors" target="_blank" class="button"><span class="sprite github"></span> See on GitHub</a>
<a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow" class="donate button"><span class="sprite heart"></span> Donate</a>
</div>
</div>
</div>
<div id="toolbar" class="hidden padding-vertical">
<div class="row wrapper">
<div class="twelve columns text-center">
<button class="button with-icon icon3" onclick="closeFileConfirm()">Close file</button>
<button class="button colored blue with-icon icon9" onclick="saveChanges()">Save changes</button>
</div>
</div>
</div>
</div>
<!-- THE EDITOR -->
<div id="the-editor" class="wrapper hidden">
<!-- MATERIALS -->
<h3 class="border-red">Materials</h3>
<div class="row" id="row-materials">
<div class="three columns"><label for="number-rupees">Rupees</label></div>
<div class="one columns"><input id="number-rupees" type="text" /></div>
</div>
<div class="text-center">
<button class="button" id="button-discover-materials" onclick="SavegameEditor.discoverMaterials()">Discover all materials</button>
</div>
<!-- CHARACTERS -->
<h3 class="border-green">Characters</h3>
<div class="row" id="row-characters">
<div class="three columns">&nbsp;</div>
<div class="three columns">Damage</div>
<div class="three columns">Level</div>
<div class="three columns">Experience</div>
</div>
<!-- MAPS -->
<h3 class="border-orange">Maps</h3>
<label for="select-map">Map</label> <span id="container-select-map"></span>
<hr/>
<div id="maps"></div>
<!-- WEAPONS -->
<h3 class="border-red">Weapons</h3>
<label for="select-weapon">Weapon slot</label>
<span id="container-select-weapon"></span>
<span class="bg-light-gray round" style="padding: 3px 12px">Approximate power: <span id="span-weapon-power"></span></span>
<hr/>
<div class="row">
<div class="three columns">Weapon type</div><div class="three columns" id="container-weapon-type"></div>
<div class="three columns">Weapon ID</div><div class="three columns" id="container-weapon-id"></div>
<div class="three columns">Base Power</div><div class="three columns" id="container-weapon-base-power"></div>
<div class="three columns">Stars</div><div class="three columns" id="container-weapon-stars"></div>
</div>
<hr/>
<div id="weapons-skills-container"></div>
</div>
</body>
</html>

View File

@ -479,7 +479,7 @@ SavegameEditor={
discoverMaterials:function(){
hide('button-discover-materials');
for(var i=0; i<this.Constants.MATERIALS_DISCOVERED_ALL.length; i++){
tempFile.writeByte(this.Constants.MATERIALS_DISCOVERED+i, this.Constants.MATERIALS_DISCOVERED_ALL[i]);
tempFile.writeU8(this.Constants.MATERIALS_DISCOVERED+i, this.Constants.MATERIALS_DISCOVERED_ALL[i]);
}
MarcDialogs.alert('All materials are now discovered (won\'t appear as ??? in-game)');
},
@ -490,26 +490,26 @@ SavegameEditor={
currentWeapon=i;
var offset=this._getWeaponOffset();
setValue('weapon-type', tempFile.readByte(offset+0x00));
setValue('weapon-id', tempFile.readInt(offset+0x04));
setValue('weapon-base-power', tempFile.readShort(offset+0x08));
setValue('weapon-stars', tempFile.readShort(offset+0x0a));
setValue('weapon-type', tempFile.readU8(offset+0x00));
setValue('weapon-id', tempFile.readU32(offset+0x04));
setValue('weapon-base-power', tempFile.readU16(offset+0x08));
setValue('weapon-stars', tempFile.readU16(offset+0x0a));
for(var i=0; i<8; i++){
setValue('weapon-skill'+i, tempFile.readInt(offset+0x0c+0x04*i));
setValue('weapon-koskill'+i, tempFile.readInt(offset+0x2c+0x04*i));
setValue('weapon-skill'+i, tempFile.readU32(offset+0x0c+0x04*i));
setValue('weapon-koskill'+i, tempFile.readU32(offset+0x2c+0x04*i));
}
SavegameEditor._calculateWeaponPower();
},
_writeWeapon:function(){
var offset=SavegameEditor._getWeaponOffset();
tempFile.writeByte(offset+0x00, getValue('weapon-type'));
tempFile.writeInt(offset+0x04, getValue('weapon-id'));
tempFile.writeShort(offset+0x08, getValue('weapon-base-power'));
tempFile.writeShort(offset+0x0a, getValue('weapon-stars'));
tempFile.writeU8(offset+0x00, getValue('weapon-type'));
tempFile.writeU32(offset+0x04, getValue('weapon-id'));
tempFile.writeU16(offset+0x08, getValue('weapon-base-power'));
tempFile.writeU16(offset+0x0a, getValue('weapon-stars'));
for(var i=0; i<8; i++){
tempFile.writeInt(offset+0x0c+0x04*i, getValue('weapon-skill'+i));
tempFile.writeInt(offset+0x2c+0x04*i, getValue('weapon-koskill'+i));
tempFile.writeU32(offset+0x0c+0x04*i, getValue('weapon-skill'+i));
tempFile.writeU32(offset+0x2c+0x04*i, getValue('weapon-koskill'+i));
}
SavegameEditor._calculateWeaponPower();
@ -559,10 +559,10 @@ SavegameEditor={
/* MATERIALS */
setValue('rupees', tempFile.readInt(this.Constants.RUPEES_OFFSET), 0, 9999999);
setValue('rupees', tempFile.readU32(this.Constants.RUPEES_OFFSET), 0, 9999999);
for(var i=0; i<this.Constants.MATERIALS.length; i++){
get('row-materials').appendChild(col(3, label('number-material'+i, this.Constants.MATERIALS[i])));
get('row-materials').appendChild(col(1, inputNumber('material'+i, 0, 999, tempFile.readShort(this.Constants.MATERIALS_OFFSET+i*2))));
get('row-materials').appendChild(col(1, inputNumber('material'+i, 0, 999, tempFile.readU16(this.Constants.MATERIALS_OFFSET+i*2))));
}
@ -572,7 +572,7 @@ SavegameEditor={
for(var j=0; j<names.length; j++){
var offset=this.Constants.CHARACTER_PACKS[i].Offset+j*this.Constants.CHARACTER_SIZE;
var level=tempFile.readByte(offset+this.Constants.CHARACTER_LEVEL_OFFSET);
var level=tempFile.readU8(offset+this.Constants.CHARACTER_LEVEL_OFFSET);
if(level==0xf00){
this.Constants.CHARACTER_PACKS[i].Names[j]=null; //set this character to null, so it won't be updated on saving
}else if(names[j]){
@ -580,13 +580,13 @@ SavegameEditor={
col(3, span(names[j]))
);
get('row-characters').appendChild(
col(3, inputNumber('characters'+i+'_damage'+j, 0, 99999999, tempFile.readShort(offset)))
col(3, inputNumber('characters'+i+'_damage'+j, 0, 99999999, tempFile.readU16(offset)))
);
get('row-characters').appendChild(
col(3, inputNumber('characters'+i+'_level'+j, 1, 255, level+1))
);
get('row-characters').appendChild(
col(3, inputNumber('characters'+i+'_exp'+j, 0, 12842457, tempFile.readInt(offset+this.Constants.CHARACTER_EXP_OFFSET)))
col(3, inputNumber('characters'+i+'_exp'+j, 0, 12842457, tempFile.readU32(offset+this.Constants.CHARACTER_EXP_OFFSET)))
);
var regexName=new RegExp(' \\('+names[j]+' - ');
@ -616,7 +616,7 @@ SavegameEditor={
for(var j=0; j<map.Items.length; j++){
if(map.Items[j]){
mapDiv.appendChild(col(4, label('number-map'+i+'-item'+j, map.Items[j])));
mapDiv.appendChild(col(2, inputNumber('map'+i+'-item'+j, 0, 5, tempFile.readByte(map.Offset+j))));
mapDiv.appendChild(col(2, inputNumber('map'+i+'-item'+j, 0, 5, tempFile.readU8(map.Offset+j))));
}
}
}
@ -658,9 +658,9 @@ SavegameEditor={
/* save function */
save:function(){
/* MATERIALS */
tempFile.writeInt(this.Constants.RUPEES_OFFSET, getValue('rupees'));
tempFile.writeU32(this.Constants.RUPEES_OFFSET, getValue('rupees'));
for(var i=0; i<this.Constants.MATERIALS.length; i++){
tempFile.writeShort(this.Constants.MATERIALS_OFFSET+i*2, getValue('material'+i));
tempFile.writeU16(this.Constants.MATERIALS_OFFSET+i*2, getValue('material'+i));
}
@ -671,9 +671,9 @@ SavegameEditor={
if(names[j]){
var offset=this.Constants.CHARACTER_PACKS[i].Offset+j*this.Constants.CHARACTER_SIZE;
tempFile.writeShort(offset, getValue('characters'+i+'_damage'+j));
tempFile.writeByte(offset+this.Constants.CHARACTER_LEVEL_OFFSET, getValue('characters'+i+'_level'+j)-1);
tempFile.writeInt(offset+this.Constants.CHARACTER_EXP_OFFSET, getValue('characters'+i+'_exp'+j));
tempFile.writeU16(offset, getValue('characters'+i+'_damage'+j));
tempFile.writeU8(offset+this.Constants.CHARACTER_LEVEL_OFFSET, getValue('characters'+i+'_level'+j)-1);
tempFile.writeU32(offset+this.Constants.CHARACTER_EXP_OFFSET, getValue('characters'+i+'_exp'+j));
}
}
}
@ -686,7 +686,7 @@ SavegameEditor={
for(var j=0; j<map.Items.length; j++){
if(map.Items[j]){
tempFile.writeByte(map.Offset+j, getValue('map'+i+'-item'+j));
tempFile.writeU8(map.Offset+j, getValue('map'+i+'-item'+j));
}
}
}

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Hyrule Warriors</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./hyrule-warriors.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
@ -73,7 +83,7 @@
<div class="container">
<label for="select-weapon">Weapon slot</label>
<span id="container-select-weapon"></span>
<span class="bg-light-gray round" style="padding: 3px 12px">Approximate power: <span id="span-weapon-power"></span></span>
<span class="bg-dark-gray round" style="padding: 3px 12px">Approximate power: <span id="span-weapon-power"></span></span>
<hr/>
<div class="row">
<div class="three columns">Weapon type</div><div class="three columns" id="container-weapon-type"></div>

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
hyrule-warriors.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -99,13 +99,13 @@ h6 a:hover{
<a class="four columns game" href="kirbys-blowout-blast/"><img src="thumb.png" id="thumb-kirbys-blowout-blast" /><div>Kirby's Blowout Blast</div></a>
<a class="four columns game" href="picross-3d-round-2/"><img src="thumb.png" id="thumb-picross-3d-round-2" /><div>Picross 3D: Round 2</div></a>
<a class="four columns game" href="pokemon-picross/"><img src="thumb.png" id="thumb-pokemon-picross" /><div>Pokémon Picross</div></a>
<a class="four columns game" href="final-fantasy-explorers/"><img src="thumb.png" id="thumb-final-fantasy-explorers" /><div>Final Fantasy Explorers <b>NEW!</b></div></a>
<a class="four columns game" href="final-fantasy-explorers/"><img src="thumb.png" id="thumb-final-fantasy-explorers" /><div>Final Fantasy Explorers</div></a>
</div>
<div class="row">
<a class="four columns game" href="zelda-botw-master/"><img src="thumb.png" id="thumb-zelda-botw-master" /><div>The legend of Zelda: Breath of the wild (Master editor)</div></a>
<a class="four columns game" href="rhythm-paradise-megamix/"><img src="thumb.png" id="thumb-rhythm-paradise-megamix" /><div>Rhythm Paradise Megamix</div></a>
<a class="four columns game" href="streetpass-mii-plaza/"><img src="thumb.png" id="thumb-streetpass-mii-plaza" /><div>StreetPass Mii Plaza</div></a>
<div class="four columns game"></div>
<a class="four columns game" href="mario-kart-7/"><img src="thumb.png" id="thumb-mario-kart-7" /><div>Mario Kart 7 <b>NEW!</b></div></a>
</div>
<hr/>

View File

@ -0,0 +1,29 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-kiuprising-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'kid-icarus-uprising.js',
'icons.png',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Kid Icarus: Uprising</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./kid-icarus-uprising.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
@ -91,7 +101,7 @@
<div class="six columns"><label for="select-weapon-modifier5">Modifier 6</label></div>
<div class="six columns" id="container-weapon-modifier5"></div>
</div>
Approximate value: <span id="weapon-value"></span>
<span class="bg-dark-gray round" style="padding: 3px 12px">Approximate value: <span id="weapon-value"></span></span>
</div>
</div>

View File

@ -1,6 +1,6 @@
/*
Kid Icarus: Uprising for HTML5 Save Editor v20170706
by Marc Robledo 2016-2017
Kid Icarus: Uprising for HTML5 Save Editor v20190411
by Marc Robledo 2016-2019
*/
var currentWeapon=0
@ -564,7 +564,7 @@ SavegameEditor={
_checkIfMissingAnyUnreleasedTrophy:function(){
var missing=false;
for(var i=404; i<412 && !missing; i++){
if(tempFile.readByte(this.Offsets.TROPHIES+i)==0){
if(tempFile.readU8(this.Offsets.TROPHIES+i)==0){
missing=true;
}
}
@ -581,14 +581,14 @@ SavegameEditor={
currentWeapon=i;
var offset=this._getWeaponOffset();
var weaponType=(tempFile.readByte(offset+0x05)<<16)+(tempFile.readByte(offset+0x06)<<8)+tempFile.readByte(offset+0x07);
var weaponType=(tempFile.readU8(offset+0x05)<<16)+(tempFile.readU8(offset+0x06)<<8)+tempFile.readU8(offset+0x07);
get('weapon-unknown').innerHTML='0x'+weaponType.toString(16);
get('weapon-unknown').value=weaponType;
get('select-weapon-type').value=weaponType;
var starsRanged=tempFile.readShort(offset+0x08);
var starsMelee=tempFile.readShort(offset+0x0a);
var starsRanged=tempFile.readU16(offset+0x08);
var starsMelee=tempFile.readU16(offset+0x0a);
if((starsRanged>=0x11 && starsRanged<=0x16) && starsMelee==0x00){ /* unknown fix for some weapons? */
starsMelee=starsRanged;
starsRanged=0;
@ -600,7 +600,7 @@ SavegameEditor={
get('select-weapon-stars-melee').value=starsMelee;
for(var i=0; i<6; i++){
get('select-weapon-modifier'+i).value=tempFile.readShort(offset+0x14+i*2);
get('select-weapon-modifier'+i).value=tempFile.readU16(offset+0x14+i*2);
}
this._calculateWeaponValue();
@ -609,15 +609,15 @@ SavegameEditor={
var offset=SavegameEditor._getWeaponOffset();
var weaponType=parseInt(getValue('weapon-type'));
tempFile.writeInt(offset+0x05, (weaponType & 0xff0000) >> 16);
tempFile.writeInt(offset+0x06, (weaponType & 0x00ff00) >> 8);
tempFile.writeInt(offset+0x07, (weaponType & 0x0000ff) >> 0);
tempFile.writeU8(offset+0x05, (weaponType & 0xff0000) >> 16);
tempFile.writeU8(offset+0x06, (weaponType & 0x00ff00) >> 8);
tempFile.writeU8(offset+0x07, (weaponType & 0x0000ff) >> 0);
tempFile.writeShort(offset+0x08, getValue('weapon-stars-ranged'));
tempFile.writeShort(offset+0x0a, getValue('weapon-stars-melee'));
tempFile.writeU16(offset+0x08, getValue('weapon-stars-ranged'));
tempFile.writeU16(offset+0x0a, getValue('weapon-stars-melee'));
for(var i=0; i<6; i++)
tempFile.writeShort(offset+0x14+i*2, getValue('weapon-modifier'+i));
tempFile.writeU16(offset+0x14+i*2, getValue('weapon-modifier'+i));
SavegameEditor._calculateWeaponValue();
},
@ -632,7 +632,7 @@ SavegameEditor={
//val=parseInt(val);
val=Math.ceil(val);
if(val<351){
get('weapon-value').style.color='initial';
get('weapon-value').style.color='default';
get('weapon-value').innerHTML=val;
}else{
get('weapon-value').style.color='red';
@ -658,9 +658,9 @@ SavegameEditor={
load:function(){
tempFile.littleEndian=true;
setValue('hearts', tempFile.readInt(this.Offsets.CURRENT_HEARTS));
setValue('hearts-for-palutena', tempFile.readInt(this.Offsets.HEARTS_OFFERED_TO_PALUTENA));
setValue('hearts-for-viridi', tempFile.readInt(this.Offsets.HEARTS_OFFERED_TO_VIRIDI));
setValue('hearts', tempFile.readU32(this.Offsets.CURRENT_HEARTS));
setValue('hearts-for-palutena', tempFile.readU32(this.Offsets.HEARTS_OFFERED_TO_PALUTENA));
setValue('hearts-for-viridi', tempFile.readU32(this.Offsets.HEARTS_OFFERED_TO_VIRIDI));
if(!this._checkIfMissingAnyUnreleasedTrophy())
this._disableUnlockUnreleasedTrophiesButton();
@ -669,11 +669,11 @@ SavegameEditor={
for(var i=0; i<this.Constants.STATS.length; i++){
var val,input;
if(i==24 || i==25){
val=tempFile.readFloat32(this.Offsets.STATS+i*4);
val=tempFile.readF32(this.Offsets.STATS+i*4);
//console.log((this.Offsets.STATS+i*4).toString(16));
input=inputFloat('stat'+i, 0.0, 9.0, val);
}else{
val=tempFile.readInt(this.Offsets.STATS+i*4);
val=tempFile.readU32(this.Offsets.STATS+i*4);
input=inputNumber('stat'+i, 0, 0xffffffff, val);
}
@ -712,7 +712,7 @@ SavegameEditor={
for(var i=0; i<this.Constants.NUM_WEAPONS; i++){
currentWeapon=i;
var offset=this._getWeaponOffset();
if((tempFile.readByte(offset+0x05)<<16)+(tempFile.readByte(offset+0x06)<<8)+tempFile.readByte(offset+0x07)!==0x000000)
if((tempFile.readU8(offset+0x05)<<16)+(tempFile.readU8(offset+0x06)<<8)+tempFile.readU8(offset+0x07)!==0x000000)
validWeapons.push(i);
}
@ -752,16 +752,16 @@ SavegameEditor={
/* save function */
save:function(){
tempFile.writeInt(this.Offsets.CURRENT_HEARTS, getValue('hearts'));
tempFile.writeInt(this.Offsets.HEARTS_OFFERED_TO_PALUTENA, getValue('hearts-for-palutena'));
tempFile.writeInt(this.Offsets.HEARTS_OFFERED_TO_VIRIDI, getValue('hearts-for-viridi'));
tempFile.writeU32(this.Offsets.CURRENT_HEARTS, getValue('hearts'));
tempFile.writeU32(this.Offsets.HEARTS_OFFERED_TO_PALUTENA, getValue('hearts-for-palutena'));
tempFile.writeU32(this.Offsets.HEARTS_OFFERED_TO_VIRIDI, getValue('hearts-for-viridi'));
/* STATS */
for(var i=0; i<this.Constants.STATS.length; i++){
if(i==24 || i==25){
tempFile.writeFloat32(this.Offsets.STATS+i*4, getValue('stat'+i));
tempFile.writeF32(this.Offsets.STATS+i*4, getValue('stat'+i));
}else{
tempFile.writeInt(this.Offsets.STATS+i*4, getValue('stat'+i));
tempFile.writeU32(this.Offsets.STATS+i*4, getValue('stat'+i));
}
}
}

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
kid-icarus-uprising.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-kirbyblow-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'kirbys-blowout-blast.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Kirby's Blowout Blast</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./kirbys-blowout-blast.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -11,8 +11,8 @@ SavegameEditor={
unlockAmiiboPuzzles:function(){
for(var i=0; i<5; i++)
tempFile.writeByte(this.StatuesOffset+i*2, 0x01);
tempFile.writeByte(this.StatuesOffset+1, 0x01);
tempFile.writeU8(this.StatuesOffset+i*2, 0x01);
tempFile.writeU8(this.StatuesOffset+1, 0x01);
setValue('amiibocount', 5);
},
@ -27,7 +27,7 @@ SavegameEditor={
var unlockedStatues=0;
for(var i=0; i<5; i++){
if(tempFile.readByte(this.StatuesOffset+i*2))
if(tempFile.readU8(this.StatuesOffset+i*2))
unlockedStatues++;
}
setValue('amiibocount', unlockedStatues);

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-11
#CACHE:
index.html
favicon.png
kirbys-blowout-blast.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-mk7-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'mario-kart-7.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

BIN
mario-kart-7/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

105
mario-kart-7/index.html Normal file
View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<title>Savegame Editor &ndash; Mario Kart 7</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
<meta name="description" content="A savegame editor for Mario Kart 7. It can edit your coin count and unlock tracks and car parts with a single click!"/>
<meta name="keywords" content="html5, savegame, save, editor, hack, exploit, 3ds, mario, kart, 7, coin, unlock, tracks, karts, cars, parts, tire, tires, glider, gliders"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="shortcut icon" href="favicon.png"/>
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./mario-kart-7.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
<!-- HEADER -->
<div id="header">
<div id="header-top">
<div class="row wrapper">
<h1 class="six columns text-left"><img src="favicon.png" /> Savegame Editor <small>for Mario Kart 7</small></h1>
<div class="six columns header-buttons text-right">
by <a href="/">Marc Robledo</a>
<i class="icon github"></i> <a href="https://github.com/marcrobledo/savegame-editors/tree/master/mario-kart-7" target="_blank">See on GitHub</a>
<i class="icon heart"></i> <a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow">Donate</a>
</div>
</div>
<div class="hidden row wrapper" id="toolbar">
<div class="twelve columns text-center">
<button class="close" onclick="closeFile()"><i class="icon close"></i> Close file</button>
<button class="colored" onclick="saveChanges()"><i class="icon accept"></i> Save changes</button>
</div>
</div>
</div>
</div>
<!-- THE EDITOR -->
<div id="the-editor" class="wrapper hidden">
<!-- PROFILE -->
<h3 class="orange">Profile</h3>
<div class="container">
<div class="row">
<div class="nine columns"><label for="input-name">Name</label></div>
<div class="three columns"><input id="input-name" type="text" class="fw" maxlength="10"/></div>
</div>
<div class="row">
<div class="nine columns"><label for="input-coins">Coins</label></div>
<div class="three columns"><input id="input-coins" type="text" class="fw" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="input-streetpass">Streetpass</label></div>
<div class="three columns"><input id="input-streetpass" type="text" class="fw" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="input-wins">Wins</label></div>
<div class="three columns"><input id="input-wins" type="text" class="fw" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="input-loses">Loses</label></div>
<div class="three columns"><input id="input-loses" type="text" class="fw" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="input-vrpoints">VR Points</label></div>
<div class="three columns"><input id="input-vrpoints" type="text" class="fw" /></div>
</div>
</div>
<!-- PROFILE -->
<h3 class="green">Unlocks</h3>
<div class="container">
<div class="row">
<div class="ten columns"><label for="checkbox-unlock-cups">Unlock all cups</label></div>
<div class="two columns text-right"><input id="checkbox-unlock-cups" type="checkbox" class="fw" /></div>
</div>
<div class="row">
<div class="ten columns"><label for="checkbox-unlock-characters">Unlock all characters</label></div>
<div class="two columns text-right"><input id="checkbox-unlock-characters" type="checkbox" class="fw" /></div>
</div>
<div class="row">
<div class="ten columns"><label for="checkbox-unlock-karts">Unlock all karts</label></div>
<div class="two columns text-right"><input id="checkbox-unlock-karts" type="checkbox" class="fw" /></div>
</div>
<div class="row">
<div class="ten columns"><label for="checkbox-unlock-tires">Unlock all tires</label></div>
<div class="two columns text-right"><input id="checkbox-unlock-tires" type="checkbox" class="fw" /></div>
</div>
<div class="row">
<div class="ten columns"><label for="checkbox-unlock-gliders">Unlock all gliders</label></div>
<div class="two columns text-right"><input id="checkbox-unlock-gliders" type="checkbox" class="fw" /></div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,126 @@
/*
Mario Kart 7 for HTML5 Save Editor v20190410
by Marc Robledo 2019
*/
SavegameEditor={
Name:'Mario Kart 7',
Filename:'system0.dat',
Offsets:{
NAME:0x22,
COINS:0x4c28,
STREETPASS:0x4e24,
WINS:0x4e34,
LOSES:0x4e38,
VR_POINTS:0x4e3c,
UNLOCKED_CUPS:0x4e3f,
UNLOCKED_CHARACTERS:0x4e42,
UNLOCKED_KARTS:0x4e48,
UNLOCKED_TIRES:0x4e4c,
UNLOCKED_GLIDERS:0x4e50
},
Unlocks:{
ALL_CUPS:[0x3f],
ALL_CHARACTERS:[0xff,0x01,0xff,0x01],
ALL_KARTS:[0xff,0x3f],
ALL_TIRES:[0x7f],
ALL_GLIDERS:[0x3f]
},
/* CRC32 - from Alex - https://stackoverflow.com/a/18639999 */
CRC32_TABLE:(function(){
var c,crcTable=[];
for(var n=0;n<256;n++){
c=n;
for(var k=0;k<8;k++)
c=((c&1)?(0xedb88320^(c>>>1)):(c>>>1));
crcTable[n]=c;
}
return crcTable;
}()),
crc32:function(file, len){
var data=file.readBytes(0, len);
var crc=0^(-1);
for(var i=0;i<len;i++){
crc=(crc>>>8)^this.CRC32_TABLE[(crc^data[i])&0xff];
}
return ((crc^(-1))>>>0);
},
/* compare byte arrays */
compareUnlockArrays(id){
var idUpper=id.toUpperCase();
var bytes=tempFile.readBytes(this.Offsets['UNLOCKED_'+idUpper], this.Unlocks['ALL_'+idUpper].length);
var compare=true;
for(var i=0; i<bytes.length && compare; i++){
if(bytes[i]!==this.Unlocks['ALL_'+idUpper][i])
compare=false;
}
getField('unlock-'+id).checked=compare;
},
/* unlock */
unlock(id){
var idUpper=id.toUpperCase();
if(getField('unlock-'+id).checked)
tempFile.writeBytes(this.Offsets['UNLOCKED_'+idUpper], this.Unlocks['ALL_'+idUpper]);
},
/* check if savegame is valid */
checkValidSavegame:function(){
return (tempFile.fileSize===20692)
},
/* preload function */
preload:function(){
setNumericRange('coins', 0, 99999);
setNumericRange('streetpass', 0, 99999);
setNumericRange('wins', 0, 99999);
setNumericRange('loses', 0, 99999);
setNumericRange('vrpoints', 0, 99999);
},
/* load function */
load:function(){
tempFile.littleEndian=true;
setValue('name', tempFile.readU16String(this.Offsets.NAME, 10));
setValue('coins', tempFile.readU24(this.Offsets.COINS));
setValue('streetpass', tempFile.readU24(this.Offsets.STREETPASS));
setValue('wins', tempFile.readU16(this.Offsets.WINS));
setValue('loses', tempFile.readU16(this.Offsets.LOSES));
setValue('vrpoints', tempFile.readU16(this.Offsets.VR_POINTS));
this.compareUnlockArrays('cups');
this.compareUnlockArrays('characters');
this.compareUnlockArrays('karts');
this.compareUnlockArrays('tires');
this.compareUnlockArrays('gliders');
},
/* save function */
save:function(){
tempFile.writeU16String(this.Offsets.NAME, 10, getValue('name'));
tempFile.writeU24(this.Offsets.COINS, getValue('coins'));
tempFile.writeU24(this.Offsets.STREETPASS, getValue('streetpass'));
tempFile.writeU16(this.Offsets.WINS, getValue('wins'));
tempFile.writeU16(this.Offsets.LOSES, getValue('loses'));
tempFile.writeU16(this.Offsets.VR_POINTS, getValue('vrpoints'));
this.unlock('cups');
this.unlock('characters');
this.unlock('karts');
this.unlock('tires');
this.unlock('gliders');
tempFile.writeU32(20688, this.crc32(tempFile, 20692-4));
}
}

BIN
mario-kart-7/system0.dat Normal file

Binary file not shown.

BIN
mario-kart-7/thumb.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-picross3d2-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'picross-3d-round-2.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Picross 3D: Round 2</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./picross-3d-round-2.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -12,9 +12,9 @@ SavegameEditor={
unlockAmiiboPuzzles:function(){
for(var i=0; i<9; i++){
var offset=this.AmiiboOffset+i*16;
var b=tempFile.readByte(offset);
var b=tempFile.readU8(offset);
if(!(b & 0x09)){
tempFile.writeByte(offset, b+0x09);
tempFile.writeU8(offset, b+0x09);
}
}
setValue('amiibocount', 9);
@ -31,7 +31,7 @@ SavegameEditor={
var unlockedAmiibos=0;
for(var i=0; i<9; i++){
if(tempFile.readByte(this.AmiiboOffset+i*16) & 0x09){
if(tempFile.readU8(this.AmiiboOffset+i*16) & 0x09){
unlockedAmiibos++;
}
}

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
picross-3d-round-2.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-pokemonpicross-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'pokemon-picross.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Pokémon Picross</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./pokemon-picross.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -16,7 +16,7 @@ SavegameEditor={
/* check if savegame is valid */
checkValidSavegame:function(){
return (tempFile.fileSize==14920)
return (tempFile.fileSize===14920)
},
/* preload function */
@ -29,16 +29,16 @@ SavegameEditor={
load:function(){
tempFile.fileName='all.dat';
setValue('picrites', tempFile.readShort(this.Offsets.PICRITES));
setValue('boughtpicrites', tempFile.readShort(this.Offsets.BOUGHTPICRITES));
setValue('picrites', tempFile.readU16(this.Offsets.PICRITES));
setValue('boughtpicrites', tempFile.readU16(this.Offsets.BOUGHTPICRITES));
},
/* save function */
save:function(){
tempFile.writeShort(this.Offsets.PICRITES, getValue('picrites'));
tempFile.writeU16(this.Offsets.PICRITES, getValue('picrites'));
var boughtPicrites=getValue('boughtpicrites');
tempFile.writeShort(this.Offsets.BOUGHTPICRITES, boughtPicrites);
var unlockedShopByte=tempFile.readByte(this.Offsets.UNLOCKEDSHOPFLAG) & ~0x01;
tempFile.writeByte(this.Offsets.UNLOCKEDSHOPFLAG, unlockedShopByte+(boughtPicrites>=5000)?0x01:0x00);
tempFile.writeU16(this.Offsets.BOUGHTPICRITES, boughtPicrites);
var unlockedShopByte=tempFile.readU8(this.Offsets.UNLOCKEDSHOPFLAG) & ~0x01;
tempFile.writeU8(this.Offsets.UNLOCKEDSHOPFLAG, unlockedShopByte+(boughtPicrites>=5000)?0x01:0x00);
}
}

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
pokemon-picross.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-pokemonshuffle-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'pokemon-shuffle.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Pokémon Shuffle</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./pokemon-shuffle.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -54,11 +54,11 @@ SavegameEditor={
_readBytes(address, numBytes){
var num;
if(numBytes==4){
num=tempFile.readInt(address);
num=tempFile.readU32(address);
}else if(numBytes==2){
num=tempFile.readShort(address);
num=tempFile.readU16(address);
}else{
num=tempFile.readByte(address);
num=tempFile.readU8(address);
}
return num;
},
@ -76,11 +76,11 @@ SavegameEditor={
var newValue=(originalBytes & inverseMask) + (parseInt(newValInput) << v.BITOFFSET) >>> 0;
if(v.NBYTES==4){
tempFile.writeInt(v.ADDRESS+addOffset, newValue);
tempFile.writeU32(v.ADDRESS+addOffset, newValue);
}else if(v.NBYTES==2){
tempFile.writeShort(v.ADDRESS+addOffset, newValue);
tempFile.writeU16(v.ADDRESS+addOffset, newValue);
}else{
tempFile.writeByte(v.ADDRESS+addOffset, newValue);
tempFile.writeU8(v.ADDRESS+addOffset, newValue);
}
},

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
pokemon-shuffle.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-rhythmheavenmix-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'rhythm-paradise-megamix.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Rhythm Paradise/Heaven Megamix</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./rhythm-paradise-megamix.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -35,20 +35,20 @@ SavegameEditor={
tempFile.littleEndian=true;
tempFile.fileName='savedataArc.txt';
setValue('coins', tempFile.readShort(this.Offsets.COINS), 0, 9999);
setValue('flowballs', tempFile.readShort(this.Offsets.FLOWBALLS), 0, 255);
setValue('onions1', tempFile.readByte(this.Offsets.ONIONS1), 0, 255);
setValue('onions2', tempFile.readByte(this.Offsets.ONIONS2), 0, 255);
setValue('onions3', tempFile.readByte(this.Offsets.ONIONS3), 0, 255);
setValue('coins', tempFile.readU16(this.Offsets.COINS), 0, 9999);
setValue('flowballs', tempFile.readU16(this.Offsets.FLOWBALLS), 0, 255);
setValue('onions1', tempFile.readU8(this.Offsets.ONIONS1), 0, 255);
setValue('onions2', tempFile.readU8(this.Offsets.ONIONS2), 0, 255);
setValue('onions3', tempFile.readU8(this.Offsets.ONIONS3), 0, 255);
},
/* save function */
save:function(){
tempFile.writeShort(this.Offsets.COINS, getValue('coins'));
tempFile.writeShort(this.Offsets.FLOWBALLS, getValue('flowballs'));
tempFile.writeByte(this.Offsets.ONIONS1, getValue('onions1'));
tempFile.writeByte(this.Offsets.ONIONS2, getValue('onions2'));
tempFile.writeByte(this.Offsets.ONIONS3, getValue('onions3'));
tempFile.writeU16(this.Offsets.COINS, getValue('coins'));
tempFile.writeU16(this.Offsets.FLOWBALLS, getValue('flowballs'));
tempFile.writeU8(this.Offsets.ONIONS1, getValue('onions1'));
tempFile.writeU8(this.Offsets.ONIONS2, getValue('onions2'));
tempFile.writeU8(this.Offsets.ONIONS3, getValue('onions3'));
}
}

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
rhythm-paradise-megamix.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -1,20 +1,37 @@
/*
savegame-editor.js v20180408
savegame-editor.js v20190411
A library that lets you create easily a savegame editor. Made with vanilla JS.
by Marc Robledo 2016-2018
by Marc Robledo 2016-2019
http://www.marcrobledo.com/license
*/
/* LIBRARIES */
/* MarcBinFile.js v2016 */
function MarcBinFile(a,b){if("function"!=typeof window.FileReader)throw console.error("MarcBinFile.js: Browser doesn't support FileReader."),"Invalid browser";if("object"==typeof a&&a.name&&a.size)this.file=a,this.fileName=this.file.name,this.fileSize=this.file.size,this.fileType=a.type;else if("object"==typeof a&&a.files){if(1!=a.files.length){for(var c=[],d=a.files.length,e=function(){d--,0==d&&b&&b.call()},f=0;f<a.files.length;f++)c.push(new MarcBinFile(a.files[f],e));return c}this.file=a.files[0],this.fileName=this.file.name,this.fileSize=this.file.size,this.fileType=this.file.type}else{if("number"!=typeof a)throw console.error("MarcBinFile.js: Invalid type of file."),"Invalid file.";this.file=!1,this.fileName="newfile.hex",this.fileSize=a,this.fileType="application/octet-stream"}this.littleEndian=function(){var a=new ArrayBuffer(2);return new DataView(a).setInt16(0,256,!0),256===new Int16Array(a)[0]}(),this.file?(this.fileReader=new FileReader,this.fileReader.addEventListener("load",function(){this.dataView=new DataView(this.result)},!1),b&&this.fileReader.addEventListener("load",b,!1),this.fileReader.readAsArrayBuffer(this.file)):(this.fileReader=new ArrayBuffer(this.fileSize),this.fileReader.dataView=new DataView(this.fileReader),b&&b.call())}MarcBinFile.prototype.isReady=function(){return 2==this.fileReader.readyState},MarcBinFile.prototype.save=function(){var a;try{a=new Blob([this.fileReader.dataView],{type:this.fileType});}catch(e){if(e.name==="InvalidStateError"){var bb=new MSBlobBuilder();bb.append(this.fileReader.dataView.buffer);a=bb.getBlob('application/octet-stream')}}saveAs(a,this.fileName)},MarcBinFile.prototype.readByte=function(a){return this.fileReader.dataView.getUint8(a)},MarcBinFile.prototype.readByteSigned=function(a){return this.fileReader.dataView.getInt8(a)},MarcBinFile.prototype.readBytes=function(a,b){for(var c=new Array(b),d=0;d<b;d++)c[d]=this.readByte(a+d);return c},MarcBinFile.prototype.readShort=function(a){return this.fileReader.dataView.getUint16(a,this.littleEndian)},MarcBinFile.prototype.readShortSigned=function(a){return this.fileReader.dataView.getInt16(a,this.littleEndian)},MarcBinFile.prototype.readInt=function(a){return this.fileReader.dataView.getUint32(a,this.littleEndian)},MarcBinFile.prototype.readIntSigned=function(a){return this.fileReader.dataView.getInt32(a,this.littleEndian)},MarcBinFile.prototype.readFloat32=function(a){return this.fileReader.dataView.getFloat32(a,this.littleEndian)},MarcBinFile.prototype.readFloat64=function(a){return this.fileReader.dataView.getFloat64(a,this.littleEndian)},MarcBinFile.prototype.readString=function(a,b){for(var c=this.readBytes(a,b),d="",e=0;e<b&&c[e]>0;e++)d+=String.fromCharCode(c[e]);return d},MarcBinFile.prototype.writeByte=function(a,b){this.fileReader.dataView.setUint8(a,b,this.littleEndian)},MarcBinFile.prototype.writeByteSigned=function(a,b){this.fileReader.dataView.setInt8(a,b,this.littleEndian)},MarcBinFile.prototype.writeBytes=function(a,b){for(var c=0;c<b.length;c++)this.writeByte(a+c,b[c])},MarcBinFile.prototype.writeShort=function(a,b){this.fileReader.dataView.setUint16(a,b,this.littleEndian)},MarcBinFile.prototype.writeShortSigned=function(a,b){this.fileReader.dataView.setInt16(a,b,this.littleEndian)},MarcBinFile.prototype.writeInt=function(a,b){this.fileReader.dataView.setUint32(a,b,this.littleEndian)},MarcBinFile.prototype.writeIntSigned=function(a,b){this.fileReader.dataView.setInt32(a,b,this.littleEndian)},MarcBinFile.prototype.writeFloat32=function(a,b){this.fileReader.dataView.setFloat32(a,b,this.littleEndian)},MarcBinFile.prototype.writeFloat64=function(a,b){this.fileReader.dataView.setFloat64(a,b,this.littleEndian)},MarcBinFile.prototype.writeString=function(a,b,c){for(var d=0;d<c;d++)this.writeByte(a+d,0);for(var d=0;d<b.length&&d<c;d++)this.writeByte(a+d,b.charCodeAt(d))};
/* MODDED VERSION OF MarcFile.js v20181020 - Marc Robledo 2014-2018 - http://www.marcrobledo.com/license */
function MarcFile(a,b){"object"==typeof a&&a.files&&(a=a.files[0]);var c=!1;if("object"==typeof a&&a.name&&a.size){if("function"!=typeof window.FileReader)throw new Error("Incompatible Browser");c=!0,this.fileName=a.name,this.fileType=a.type,this.fileSize=a.size}else if("number"==typeof a)this.fileName="file.bin",this.fileType="application/octet-stream",this.fileSize=a;else throw new Error("Invalid source");if(this.littleEndian=!1,c)this._fileReader=new FileReader,this._fileReader.marcFile=this,this._fileReader.addEventListener("load",function(){this.marcFile._u8array=new Uint8Array(this.result),this.marcFile._dataView=new DataView(this.result),b&&b.call()},!1),this._fileReader.readAsArrayBuffer(a);else if(0<a){var d=new ArrayBuffer(a);this._u8array=new Uint8Array(d),this._dataView=new DataView(d),b&&b.call()}}MarcFile.prototype.IS_MACHINE_LITTLE_ENDIAN=function(){var a=new ArrayBuffer(2);return new DataView(a).setInt16(0,256,!0),256===new Int16Array(a)[0]}(),MarcFile.prototype.save=function(){var a;try{a=new Blob([this._u8array],{type:this.fileType})}catch(c){if(window.BlobBuilder=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,"InvalidStateError"===c.name&&window.BlobBuilder){var b=new BlobBuilder;b.append(this._u8array.buffer),a=b.getBlob(this.fileType)}else{throw new Error("Incompatible Browser")}}saveAs(a,this.fileName)},MarcFile.prototype.readU8=function(a){return this._u8array[a]},MarcFile.prototype.readU16=function(a){return this.littleEndian?this._u8array[a]+(this._u8array[a+1]<<8)>>>0:(this._u8array[a]<<8)+this._u8array[a+1]>>>0},MarcFile.prototype.readU24=function(a){return this.littleEndian?this._u8array[a]+(this._u8array[a+1]<<8)+(this._u8array[a+2]<<16)>>>0:(this._u8array[a]<<16)+(this._u8array[a+1]<<8)+this._u8array[a+2]>>>0},MarcFile.prototype.readU32=function(a){return this.littleEndian?this._u8array[a]+(this._u8array[a+1]<<8)+(this._u8array[a+2]<<16)+(this._u8array[a+3]<<24)>>>0:(this._u8array[a]<<24)+(this._u8array[a+1]<<16)+(this._u8array[a+2]<<8)+this._u8array[a+3]>>>0},MarcFile.prototype.readS8=function(a){return this._dataView.getInt8(a,this.littleEndian)},MarcFile.prototype.readS16=function(a){return this._dataView.getInt16(a,this.littleEndian)},MarcFile.prototype.readS32=function(a){return this._dataView.getInt32(a,this.littleEndian)},MarcFile.prototype.readF32=function(a){return this._dataView.getFloat32(a,this.littleEndian)},MarcFile.prototype.readF64=function(a){return this._dataView.getFloat64(a,this.littleEndian)},MarcFile.prototype.readBytes=function(a,b){for(var c=Array(b),d=0;d<b;d++)c[d]=this._u8array[a+d];return c},MarcFile.prototype.readString=function(a,b){for(var c="",d=0;d<b&&a+d<this.fileSize&&0<this._u8array[a+d];d++)c+=String.fromCharCode(this._u8array[a+d]);return c},MarcFile.prototype.writeU8=function(a,b){this._u8array[a]=b},MarcFile.prototype.writeU16=function(a,b){this.littleEndian?(this._u8array[a]=255&b,this._u8array[a+1]=b>>8):(this._u8array[a]=b>>8,this._u8array[a+1]=255&b)},MarcFile.prototype.writeU24=function(a,b){this.littleEndian?(this._u8array[a]=255&b,this._u8array[a+1]=(65280&b)>>8,this._u8array[a+2]=(16711680&b)>>16):(this._u8array[a]=(16711680&b)>>16,this._u8array[a+1]=(65280&b)>>8,this._u8array[a+2]=255&b)},MarcFile.prototype.writeU32=function(a,b){this.littleEndian?(this._u8array[a]=255&b,this._u8array[a+1]=(65280&b)>>8,this._u8array[a+2]=(16711680&b)>>16,this._u8array[a+3]=(4278190080&b)>>24):(this._u8array[a]=(4278190080&b)>>24,this._u8array[a+1]=(16711680&b)>>16,this._u8array[a+2]=(65280&b)>>8,this._u8array[a+3]=255&b)},MarcFile.prototype.writeS8=function(a,b){this._dataView.setInt8(a,b,this.littleEndian)},MarcFile.prototype.writeS16=function(a,b){this._dataView.setInt16(a,b,this.littleEndian)},MarcFile.prototype.writeS32=function(a,b){this._dataView.setInt32(a,b,this.littleEndian)},MarcFile.prototype.writeF32=function(a,b){this._dataView.setFloat32(a,b,this.littleEndian)},MarcFile.prototype.writeF64=function(a,b){this._dataView.setFloat64(a,b,this.littleEndian)},MarcFile.prototype.writeBytes=function(b,c){for(var a=0;a<c.length;a++)this._u8array[b+a]=c[a]},MarcFile.prototype.writeString=function(a,b,c){c=c||b.length;for(var d=0;d<b.length&&d<c;d++)this._u8array[a+d]=b.charCodeAt(d);for(;d<c;d++)this._u8array[a+d]=0};
/* implement U16 string in MarcFile (PROVISIONAL!) */
MarcFile.prototype.readU16String=function(pos,maxLength){
var cs=new Array(maxLength);
var str='';
for(var i=0;i<maxLength && this.readU16(pos+i*2)!=0;i++)
str+=String.fromCharCode(this.readU16(pos+i*2));
//cs[i]=this.readU16(pos+i*2);
return str
}
MarcFile.prototype.writeU16String=function(pos,maxLength,str){
for(var i=0;i<str.length && i<maxLength-1;i++)
this.writeU16(pos+i*2,str.charCodeAt(i));
for(;i<maxLength;i++)
this.writeU16(pos+i*2,0)
}
/* FileSaver.js by eligrey - https://github.com/eligrey/FileSaver.js */
var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}
var saveAs=saveAs||function(c){"use strict";if(!(void 0===c||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var t=c.document,f=function(){return c.URL||c.webkitURL||c},s=t.createElementNS("http://www.w3.org/1999/xhtml","a"),d="download"in s,u=/constructor/i.test(c.HTMLElement)||c.safari,l=/CriOS\/[\d]+/.test(navigator.userAgent),p=c.setImmediate||c.setTimeout,v=function(t){p(function(){throw t},0)},w=function(t){setTimeout(function(){"string"==typeof t?f().revokeObjectURL(t):t.remove()},4e4)},m=function(t){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob([String.fromCharCode(65279),t],{type:t.type}):t},r=function(t,n,e){e||(t=m(t));var r,o=this,a="application/octet-stream"===t.type,i=function(){!function(t,e,n){for(var r=(e=[].concat(e)).length;r--;){var o=t["on"+e[r]];if("function"==typeof o)try{o.call(t,n||t)}catch(t){v(t)}}}(o,"writestart progress write writeend".split(" "))};if(o.readyState=o.INIT,d)return r=f().createObjectURL(t),void p(function(){var t,e;s.href=r,s.download=n,t=s,e=new MouseEvent("click"),t.dispatchEvent(e),i(),w(r),o.readyState=o.DONE},0);!function(){if((l||a&&u)&&c.FileReader){var e=new FileReader;return e.onloadend=function(){var t=l?e.result:e.result.replace(/^data:[^;]*;/,"data:attachment/file;");c.open(t,"_blank")||(c.location.href=t),t=void 0,o.readyState=o.DONE,i()},e.readAsDataURL(t),o.readyState=o.INIT}r||(r=f().createObjectURL(t)),a?c.location.href=r:c.open(r,"_blank")||(c.location.href=r);o.readyState=o.DONE,i(),w(r)}()},e=r.prototype;return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(t,e,n){return e=e||t.name||"download",n||(t=m(t)),navigator.msSaveOrOpenBlob(t,e)}:(e.abort=function(){},e.readyState=e.INIT=0,e.WRITING=1,e.DONE=2,e.error=e.onwritestart=e.onprogress=e.onwrite=e.onabort=e.onerror=e.onwriteend=null,function(t,e,n){return new r(t,e||t.name||"download",n)})}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);
/* MarcDialogs.js v2016 */
MarcDialogs=function(){function e(e,t,n){a?e.attachEvent("on"+t,n):e.addEventListener(t,n,!1)}function t(){s&&(o?history.go(-1):(c.className="dialog-overlay",s.className=s.className.replace(/ active/g,""),s=null))}function n(e){for(var t=0;t<s.dialogElements.length;t++){var n=s.dialogElements[t];if("INPUT"===n.nodeName&&"hidden"!==n.type||"INPUT"!==n.nodeName)return n.focus(),!0}return!1}function l(){s&&(s.style.marginLeft="-"+s.offsetWidth/2+"px",s.style.marginTop="-"+s.offsetHeight/2-30+"px")}var a=/MSIE 8/.test(navigator.userAgent),o=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i)&&"function"==typeof history.pushState,i=["Cancel","Accept"],s=null,c=document.createElement("div");c.className="dialog-overlay",c.style.position="fixed",c.style.top="0",c.style.left="0",c.style.width="100%",c.style.height="100%",c.style.zIndex=8e3,e(c,"click",t),e(window,"load",function(){document.body.appendChild(c),o&&history.replaceState({myDialog:!1},null,null)}),e(window,"resize",l),o&&e(window,"popstate",function(e){e.state.myDialog?(s=e.state.myDialog,MarcDialogs.open(e.state.myDialog)):e.state.myDialog===!1&&s&&(c.className="dialog-overlay",s.className=s.className.replace(/ active/g,""),s=null)}),e(document,"keydown",function(e){s&&(27==e.keyCode?(e.preventDefault?e.preventDefault():e.returnValue=!1,t()):9==e.keyCode&&s.dialogElements[s.dialogElements.length-1]==document.activeElement&&(e.preventDefault?e.preventDefault():e.returnValue=!1,n()))});var d=null,u=null,m=null;return{open:function(e){s&&(s.className=s.className.replace(/ active/g,"")),o&&(s?history.replaceState({myDialog:e},null,null):(console.log("a"),history.pushState({myDialog:e},null,null))),c.className="dialog-overlay active",s="string"==typeof e?document.getElementById("dialog-"+e):e,s.className+=" active",s.style.position="fixed",s.style.top="50%",s.style.left="50%",s.style.zIndex=8001,s.dialogElements||(s.dialogElements=s.querySelectorAll("input,textarea,select")),n(),l(s),l(s)},close:t,alert:function(t){if(!d){d=document.createElement("div"),d.id="dialog-quick-alert",d.className="dialog",d.msg=document.createElement("div"),d.msg.style.textAlign="center",d.appendChild(d.msg),d.buttons=document.createElement("div"),d.buttons.className="buttons";var n=document.createElement("button");n.innerHTML=i[1],e(n,"click",this.close),d.buttons.appendChild(n),d.appendChild(d.buttons),document.body.appendChild(d)}d.msg.innerHTML=t,MarcDialogs.open("quick-alert")},confirm:function(t,n){if(!u){u=document.createElement("div"),u.id="dialog-quick-confirm",u.className="dialog",u.msg=document.createElement("div"),u.msg.style.textAlign="center",u.appendChild(u.msg),u.buttons=document.createElement("div"),u.buttons.className="buttons";var l=document.createElement("button");l.className="button colored blue with-icon icon9",l.innerHTML=i[1],e(l,"click",function(){m()}),u.buttons.appendChild(l);var a=document.createElement("button");a.className="button with-icon icon3",a.innerHTML=i[0],e(a,"click",this.close),u.buttons.appendChild(a),u.appendChild(u.buttons),document.body.appendChild(u)}m=n,u.msg.innerHTML=t,MarcDialogs.open("quick-confirm")}}}();
/* mCreate v20170315 */
function mCreate(a,b){var c=document.createElement(a);if("object"==typeof b)for(var d in b)b.hasOwnProperty(d)&&("html"===d?c.innerHTML=b[d]:"class"===d?c.className=b[d]:d.startsWith("style")||d.startsWith("css")?c.style[d.replace(/^(style|css)(:- )?/,"")]=b[d]:c[d]=b[d]);return c};
/* MarcDragAndDrop.js v20170421 - Marc Robledo 2014-2017 - http://www.marcrobledo.com/license */
MarcDragAndDrop=(function(){
function addEvent(e,t,f){if(/MSIE 8/.test(navigator.userAgent))e.attachEvent('on'+t,f);else e.addEventListener(t,f,false)}
@ -92,21 +109,6 @@ MarcDragAndDrop=(function(){
/* implement U16 string in MarcBinFile (PROVISIONAL!) */
MarcBinFile.prototype.readU16String=function(pos,maxLength){
var cs=new Array(maxLength);
var str='';
for(var i=0;i<maxLength && this.readShort(pos+i*2)!=0;i++)
str+=String.fromCharCode(this.readShort(pos+i*2));
//cs[i]=this.readShort(pos+i*2);
return str
}
MarcBinFile.prototype.writeU16String=function(pos,maxLength,str){
for(var i=0;i<str.length && i<maxLength-1;i++)
this.writeShort(pos+i*2,str.charCodeAt(i));
for(;i<maxLength;i++)
this.writeShort(pos+i*2,0)
}
/* savegame load/save */
@ -128,7 +130,7 @@ function _tempFileLoadFunction(){
}
function loadSavegameFromInput(input){
tempFile=new MarcBinFile(input.files[0], _tempFileLoadFunction);
tempFile=new MarcFile(input.files[0], _tempFileLoadFunction);
}
function saveChanges(){
@ -185,11 +187,49 @@ window.addEventListener('load', function(){
loadSavegameFromInput(this);
}, false);
var demoMessage=document.createElement('a');
var demoMessage=document.createElement('button');
demoMessage.id='demo';
demoMessage.href=SavegameEditor.Filename;
demoMessage.download=SavegameEditor.Filename;
demoMessage.innerHTML='Do you want to try it out? <u>Download an example savegame</u>';
demoMessage.innerHTML='Do you want to try it out? <u>Try an example savegame</u>';
demoMessage.addEventListener('click', function(){
if(typeof window.fetch==='function'){
fetch(SavegameEditor.Filename)
.then(res => res.arrayBuffer()) // Gets the response and returns it as a blob
.then(ab => {
tempFile=new MarcFile(ab.byteLength);
tempFile.fileName=SavegameEditor.Filename;
tempFile._u8array=new Uint8Array(ab);
tempFile._dataView=new DataView(ab);
_tempFileLoadFunction();
})
.catch(function(){
alert('Unexpected error: can\'t download example savegame');
});
}else{
var oReq=new XMLHttpRequest();
oReq.open('GET', SavegameEditor.Filename, true);
oReq.responseType='arraybuffer';
oReq.onload=function(oEvent){
if(this.status===200) {
var ab=oReq.response; //Note: not oReq.responseText
tempFile=new MarcFile(ab.byteLength);
tempFile.fileName=SavegameEditor.Filename;
tempFile._u8array=new Uint8Array(ab);
tempFile._dataView=new DataView(ab);
_tempFileLoadFunction();
}else{
alert('Unexpected error: can\'t download example savegame');
}
};
oReq.onerror=function(oEvent){
alert('Unexpected error: can\'t download example savegame');
};
oReq.send(null);
}
}, false);
dragZone.appendChild(dragMessage);
dragZone.appendChild(inputFile);
@ -199,7 +239,7 @@ window.addEventListener('load', function(){
MarcDragAndDrop.add('dragzone', function(droppedFiles){
tempFile=new MarcBinFile(droppedFiles[0], _tempFileLoadFunction);
tempFile=new MarcFile(droppedFiles[0], _tempFileLoadFunction);
});
@ -271,7 +311,7 @@ function fixNumericFieldValue(field){
if(isNaN(val) || val<field.minValue){
val=field.minValue || 0;
val=field.minValue;
}else if(val > field.maxValue){
val=field.maxValue;
}

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-streetpassplaza-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'streetpass-mii-plaza.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; StreetPass Mii Plaza</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./streetpass-mii-plaza.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
@ -48,15 +58,6 @@
<div class="eight columns"><label for="number-fantastic">Fantastic ratings</label></div>
<div class="four columns"><input id="number-fantastic" type="text" class="fw" /></div>
<div class="eight columns"><label for="button-unlockmap">Unlock maps</label></div>
<div class="four columns"><button id="button-unlockmap" onclick="SavegameEditor._unlockMap()">Unlock</button></div>
<div class="eight columns"><label for="button-unlockbirthdays">Unlock birthdays</label></div>
<div class="four columns"><button id="button-unlockbirthdays" onclick="SavegameEditor._unlockBirthdays()">Unlock</button></div>
<div class="eight columns"><label for="button-unlockaccomplishments">Unlock accomplishments</label></div>
<div class="four columns"><button id="button-unlockaccomplishments" onclick="SavegameEditor._unlockAccomplishments()">Unlock</button></div>
</div>
</div>

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
streetpass-mii-plaza.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,28 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PRECACHE = 'precache-editor-teamkirbyclashdx-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'favicon.png',
'team-kirby-clash-dx.js',
'../savegame-editor.js',
'../savegame-editor.css'
];
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html manifest="savegame-editor.appcache">
<html>
<head>
<title>Savegame Editor &ndash; Team Kirby Clash Deluxe</title>
<meta http-equiv="content-Type" content="text/html; charset=UTF-8"/>
@ -10,6 +10,16 @@
<link type="text/css" rel="stylesheet" href="../savegame-editor.css" media="all"/>
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./team-kirby-clash-dx.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>

View File

@ -1,12 +0,0 @@
CACHE MANIFEST
# last update 2017-07-06
#CACHE:
index.html
favicon.png
team-kirby-clash-dx.js
../savegame-editor.css
../savegame-editor.js
# force these files to be loaded in network
NETWORK:
*

View File

@ -49,34 +49,34 @@ SavegameEditor={
/* load data */
setValue('name', tempFile.readU16String(this.Offsets.PROFILE_NAME, 16));
setValue('time', tempFile.readInt(this.Offsets.PROFILE_PLAYED_TIME));
setValue('missions', tempFile.readInt(this.Offsets.PROFILE_COMPLETED_MISSIONS));
setValue('encounters', tempFile.readInt(this.Offsets.PROFILE_MULTIPLAYER_ENCOUNTERS));
setValue('multiplayerbattles', tempFile.readInt(this.Offsets.PROFILE_MULTIPLAYER_BATTLES));
setValue('time', tempFile.readU32(this.Offsets.PROFILE_PLAYED_TIME));
setValue('missions', tempFile.readU32(this.Offsets.PROFILE_COMPLETED_MISSIONS));
setValue('encounters', tempFile.readU32(this.Offsets.PROFILE_MULTIPLAYER_ENCOUNTERS));
setValue('multiplayerbattles', tempFile.readU32(this.Offsets.PROFILE_MULTIPLAYER_BATTLES));
setValue('applegems', tempFile.readShort(this.Offsets.APPLE_GEMS));
setValue('boughtapplegems', tempFile.readShort(this.Offsets.BOUGHT_APPLE_GEMS));
setValue('applegems', tempFile.readU16(this.Offsets.APPLE_GEMS));
setValue('boughtapplegems', tempFile.readU16(this.Offsets.BOUGHT_APPLE_GEMS));
setValue('shards-red', tempFile.readShort(this.Offsets.SHARDS_RED));
setValue('shards-blue', tempFile.readShort(this.Offsets.SHARDS_BLUE));
setValue('shards-yellow', tempFile.readShort(this.Offsets.SHARDS_YELLOW));
setValue('shards-rare', tempFile.readShort(this.Offsets.SHARDS_RARE));
setValue('shards-red', tempFile.readU16(this.Offsets.SHARDS_RED));
setValue('shards-blue', tempFile.readU16(this.Offsets.SHARDS_BLUE));
setValue('shards-yellow', tempFile.readU16(this.Offsets.SHARDS_YELLOW));
setValue('shards-rare', tempFile.readU16(this.Offsets.SHARDS_RARE));
},
/* save function */
save:function(){
tempFile.writeU16String(this.Offsets.PROFILE_NAME, 16, getValue('name'));
tempFile.writeInt(this.Offsets.PROFILE_PLAYED_TIME, getValue('time'));
tempFile.writeInt(this.Offsets.PROFILE_COMPLETED_MISSIONS, getValue('missions'));
tempFile.writeInt(this.Offsets.PROFILE_MULTIPLAYER_ENCOUNTERS, getValue('encounters'));
tempFile.writeInt(this.Offsets.PROFILE_MULTIPLAYER_BATTLES, getValue('multiplayerbattles'));
tempFile.writeU32(this.Offsets.PROFILE_PLAYED_TIME, getValue('time'));
tempFile.writeU32(this.Offsets.PROFILE_COMPLETED_MISSIONS, getValue('missions'));
tempFile.writeU32(this.Offsets.PROFILE_MULTIPLAYER_ENCOUNTERS, getValue('encounters'));
tempFile.writeU32(this.Offsets.PROFILE_MULTIPLAYER_BATTLES, getValue('multiplayerbattles'));
tempFile.writeShort(this.Offsets.APPLE_GEMS, getValue('applegems'));
tempFile.writeShort(this.Offsets.BOUGHT_APPLE_GEMS, getValue('boughtapplegems'));
tempFile.writeU16(this.Offsets.APPLE_GEMS, getValue('applegems'));
tempFile.writeU16(this.Offsets.BOUGHT_APPLE_GEMS, getValue('boughtapplegems'));
tempFile.writeShort(this.Offsets.SHARDS_RED, getValue('shards-red'));
tempFile.writeShort(this.Offsets.SHARDS_BLUE, getValue('shards-blue'));
tempFile.writeShort(this.Offsets.SHARDS_YELLOW, getValue('shards-yellow'));
tempFile.writeShort(this.Offsets.SHARDS_RARE, getValue('shards-rare'));
tempFile.writeU16(this.Offsets.SHARDS_RED, getValue('shards-red'));
tempFile.writeU16(this.Offsets.SHARDS_BLUE, getValue('shards-blue'));
tempFile.writeU16(this.Offsets.SHARDS_YELLOW, getValue('shards-yellow'));
tempFile.writeU16(this.Offsets.SHARDS_RARE, getValue('shards-rare'));
}
}

View File

@ -1,25 +1,29 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
mod by marcrobledo, original from: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
*/
const PRECACHE_ID='v20180520';
const PRECACHE_FILES=[
'index.html','./',
'zelda-botw-master.css',
'zelda-botw-master.js',
'hashes.js',
'favicon.png',
'../savegame-editor.js'
const PRECACHE = 'precache-editor-zeldabotwmaster-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'zelda-botw-master.css',
'zelda-botw-master.js',
'hashes.js',
'favicon.png',
'../savegame-editor.js'
];
self.addEventListener('install',event=>{event.waitUntil(caches.open(PRECACHE_ID).then(cache=>cache.addAll(PRECACHE_FILES)).then(self.skipWaiting()))});self.addEventListener('activate',event=>{const currentCaches=[PRECACHE_ID,'runtime'];event.waitUntil(caches.keys().then(cacheNames=>{return cacheNames.filter(cacheName=>!currentCaches.includes(cacheName));}).then(cachesToDelete=>{return Promise.all(cachesToDelete.map(cacheToDelete=>{return caches.delete(cacheToDelete);}))}).then(()=>self.clients.claim()))});self.addEventListener('fetch',event=>{if(event.request.url.startsWith(self.location.origin))event.respondWith(caches.match(event.request).then(cachedResponse=>{if(cachedResponse)return cachedResponse;return caches.open('runtime').then(cache=>{return fetch(event.request).then(response=>{return cache.put(event.request,response.clone()).then(()=>{return response})})})}))})
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

Binary file not shown.

View File

@ -11,6 +11,16 @@
<script type="text/javascript" src="../savegame-editor.js"></script>
<script type="text/javascript" src="./zelda-botw-master.js"></script>
<script type="text/javascript" src="./hashes.js"></script>
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
@ -30,7 +40,18 @@
<div id="toolbar" class="hidden padding-vertical">
<div class="row wrapper">
<div class="twelve columns text-center">
<span id="span-version"></span> | <button class="button with-icon icon3" onclick="closeFile()">Close file</button>
<span class="clickable" onclick="SavegameEditor.changeEndianess()" id="span-version"></span> |
<label for="select-filters">Filter: </label>
<select id="select-filters" onchange="SavegameEditor.showHashes(parseInt(this.value), 0)">
<option value="-1">- All -</option>
</select>
<label for="select-page">Page: </label>
<button id="page-prev" onclick="if(document.getElementById('select-page').selectedIndex>0)SavegameEditor.showHashes(parseInt(document.getElementById('select-filters').value), parseInt(document.getElementById('select-page').value)-1)">&laquo;</button>
<select id="select-page" onchange="SavegameEditor.showHashes(parseInt(document.getElementById('select-filters').value), parseInt(this.value))"></select>
<button id="page-next" onclick="if(document.getElementById('select-page').selectedIndex<document.getElementById('select-page').children.length-1)SavegameEditor.showHashes(parseInt(document.getElementById('select-filters').value), parseInt(document.getElementById('select-page').value)+1)">&raquo;</button> |
<button class="button with-icon icon3" onclick="closeFile()">Close file</button>
<button class="button colored blue with-icon icon9" onclick="saveChanges()">Save changes</button>
</div>
</div>

View File

@ -178,7 +178,9 @@ button.with-icon.file-load:before{background-position:-32px -48px;width:20px;hei
#toolbar{
padding:8px
}
#span-version:hover{text-decoration:underline}
#toolbar select{width:initial !important}
#page-prev,#page-next{min-width:initial !important}
#header h1{display:none}
#header h1 img{vertical-align:middle}
@ -234,7 +236,6 @@ h3{
}
table{width:100%}
tbody tr:nth-child(even){background-color:#f2f2f2}
th{background-color:#d4d4d4}
@ -466,14 +467,15 @@ button.no-text.with-icon:before{margin-right:0px}
}
#demo{
text-decoration:none;
background-color:#5271e7;
color:black;
padding:4px 16px;
border-radius:3px;
clear:both
clear:both;
position:relative;
top:80px;
}
#demo:hover{
background-color:#8a9eea;
background-color:#bbb;
color:#000
}
#warning{

View File

@ -1,13 +1,13 @@
/*
The legend of Zelda: Breath of the wild - Master editor v20180520
by Marc Robledo 2017-2018
The legend of Zelda: Breath of the wild - Master editor v20190416
by Marc Robledo 2017-2019
*/
var currentEditingItem=0;
SavegameEditor={
Name:'The legend of Zelda: Breath of the wild (Master editor)',
Filename:'game_data.sav',
Version:20180520,
Version:20190416,
/* Constants */
@ -15,11 +15,25 @@ SavegameEditor={
STRING_SIZE:0x20,
STRING64_SIZE:0x80,
/* v1.0 v1.1 v1.2 v1.3 v1.3.3 v1.4 v1.5 */
FILESIZE: [896976, 897160, 897112, 907824, 1020648, 1027208, 1027208],
HEADER: [0x24e2, 0x24ee, 0x2588, 0x29c0, 0x3ef8, 0x471a, 0x471b],
VERSION: ['v1.0', 'v1.1', 'v1.2', 'v1.3', 'v1.3.3','v1.4', 'v1.5']
/* v1.0 v1.1 v1.2 v1.3 kiosk v1.3.3 v1.4/v1.5 */
FILESIZE: [896976, 897160, 897112, 907824, 916576, 1020648, 1027208],
HEADER: [0x24e2, 0x24ee, 0x2588, 0x29c0, 0x2f8e, 0x3ef8, 0x471a],
VERSION: ['v1.0', 'v1.1', 'v1.2', 'v1.3', 'Kiosk', 'v1.3.3','v1.4/v1.5'],
},
HashFilters:[
['Amiibo', /WolfLink_|Amiibo/],
['Display flag names', /_DispNameFlag$/],
['DLC1', /100enemy/],
['DLC2', /Motorcycle/],
['Horses', /Horse_/],
['Defeated enemies', /Defeat_Enemy_|Defeated.+Num/],
['Items', /Porch|Cook/],
['Get flags', /IsGet_/],
['Korok', /HiddenKorok|OldKorok_/],
['Visited locations', /^Location_/],
['Compendium', /AlbumPicture|PictureBook/]
],
Hashes:[],
@ -27,14 +41,15 @@ SavegameEditor={
/* private functions */
_toHexInt:function(i){var s=i.toString(16);while(s.length<8)s='0'+s;return '0x'+s},
_writeBoolean:function(offset,val,arrayPos){if(arrayPos)tempFile.writeInt(offset+8*arrayPos,val?1:0);else tempFile.writeInt(offset,val?1:0)},
_writeValue:function(offset,val,arrayPos){if(arrayPos)tempFile.writeInt(offset+8*arrayPos,val);else tempFile.writeInt(offset,val)},
_writeBoolean:function(offset,val,arrayPos){if(arrayPos)tempFile.writeU32(offset+8*arrayPos,val?1:0);else tempFile.writeU32(offset,val?1:0)},
_writeValue:function(offset,val,arrayPos){if(arrayPos)tempFile.writeU32(offset+8*arrayPos,val);else tempFile.writeU32(offset,val)},
_writeFloat32:function(offset,val,arrayPos){if(arrayPos)tempFile.writeF32(offset+8*arrayPos,val);else tempFile.writeF32(offset,val)},
_writeString:function(offset,str){
for(var i=0; i<8; i++){
tempFile.writeBytes(offset,[0,0,0,0]);
var fourBytes=str.substr(i*4, 4);
for(j=0; j<fourBytes.length; j++){
tempFile.writeByte(offset+j, fourBytes.charCodeAt(j));
tempFile.writeU8(offset+j, fourBytes.charCodeAt(j));
}
offset+=8;
}
@ -44,7 +59,7 @@ SavegameEditor={
tempFile.writeBytes(offset,[0,0,0,0]);
var fourBytes=str.substr(i*4, 4);
for(j=0; j<fourBytes.length; j++){
tempFile.writeByte(offset+j, fourBytes.charCodeAt(j));
tempFile.writeU8(offset+j, fourBytes.charCodeAt(j));
}
offset+=8;
}
@ -68,18 +83,33 @@ SavegameEditor={
},
changeEndianess:function(){
var tempFileByteSwapped=new MarcFile(tempFile.fileSize);
tempFileByteSwapped.fileType=tempFile.fileType;
tempFileByteSwapped.fileName=tempFile.fileName;
tempFileByteSwapped.littleEndian=!tempFile.littleEndian;
for(var i=0; i<tempFile.fileSize; i+=4){
tempFileByteSwapped.writeU32(i, tempFile.readU32(i));
}
tempFile=tempFileByteSwapped;
this.checkValidSavegame();
},
/* check if savegame is valid */
_checkValidSavegameByConsole:function(switchMode){
var CONSOLE=switchMode?'Switch':'Wii U';
tempFile.littleEndian=switchMode;
for(var i=0; i<this.Constants.FILESIZE.length; i++){
var versionHash=tempFile.readInt(0);
var versionHash=tempFile.readU32(0);
if(versionHash===0x2a46) //v1.3.0 switch?
versionHash=0x29c0;
if(versionHash===0x3ef9) //v1.3.3 switch?
else if(versionHash===0x3ef9) //v1.3.3 switch?
versionHash=0x3ef8;
else if(versionHash===0x471b) //v1.5 is the same as 1.4
versionHash=0x471a;
if(tempFile.fileSize===this.Constants.FILESIZE[i] && versionHash===this.Constants.HEADER[i] && tempFile.readInt(4)===0xffffffff){
if(tempFile.fileSize===this.Constants.FILESIZE[i] && versionHash===this.Constants.HEADER[i] && tempFile.readU32(4)===0xffffffff){
setValue('version', this.Constants.VERSION[i]+' ('+CONSOLE+')');
return true;
}
@ -93,48 +123,76 @@ SavegameEditor={
preload:function(){
for(var i=0; i<this.HashFilters.length; i++){
var option=document.createElement('option');
option.value=i;
option.innerHTML=this.HashFilters[i][0];
document.getElementById('select-filters').appendChild(option);
}
},
/* load function */
load:function(){
tempFile.fileName='game_data.sav';
showHashes:function(regexFilter, page){
var findHashesIn;
empty('table');
this.Hashes=[];
//var textarea=document.createElement('textarea');
//document.body.appendChild(textarea);
if(regexFilter===-1){
findHashesIn=HASHES;
}else if(regexFilter>-1){
findHashesIn={};
for(var hash in HASHES){
if(this.HashFilters[regexFilter][1].test(HASHES[hash][1])){
findHashesIn[hash]=true;
}
}
}
var previousHashValue=0;
for(var i=0x0c; i<tempFile.fileSize-4; i+=8){
var hashValue=tempFile.readInt(i);
var hashValue=tempFile.readU32(i);
if(hashValue===previousHashValue)
continue;
previousHashValue=hashValue;
if(HASHES[hashValue]){
if(findHashesIn[hashValue]){
this.Hashes.push({
type:HASHES[hashValue][0],
id:HASHES[hashValue][1],
offset:i
});
}else{
}else if(regexFilter===-1){
this.Hashes.push({
id:'* '+this._toHexInt(hashValue)
});
}
previousHashValue=hashValue;
/*if(/ \(NEW!\)/.test(hashId)){
textarea.value+=this._toHexInt(hashValue)+',\"'+hashId+'\",//'+hashType+'\n';
}*/
}
this.Hashes.sort(function(a,b){
if(a.id<b.id)return -1;
if(a.id>b.id)return 1;
return 0;
if(a.id<b.id)return -1;
if(a.id>b.id)return 1;
return 0;
});
empty('table');
var placeholder=document.createElement('div');
var HASHES_PER_PAGE=100;
var nPages=parseInt(this.Hashes.length/HASHES_PER_PAGE);
if(this.Hashes.length%HASHES_PER_PAGE!==0){
nPages++;
}
empty('select-page');
for(var i=0; i<nPages; i++){
var option=document.createElement('option');
option.value=i;
option.innerHTML=i+1;
document.getElementById('select-page').appendChild(option);
}
document.getElementById('select-page').selectedIndex=page;
this.Hashes=this.Hashes.splice(page*HASHES_PER_PAGE, HASHES_PER_PAGE);
var placeholder=document.createElement('tbody');
for(var i=0; i<this.Hashes.length; i++){
var hash=this.Hashes[i];
@ -145,6 +203,14 @@ SavegameEditor={
}
}
get('table').appendChild(placeholder);
},
/* load function */
load:function(){
tempFile.fileName='game_data.sav';
this.showHashes(-1, 0);
document.getElementById('select-filters').value=-1;
},
/* save function */
@ -156,6 +222,7 @@ function addEditorRow(container, left, right){
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.children[1].className='text-right';
if(right){
tr.children[0].appendChild(label(right.id, left));
tr.children[1].appendChild(right);
@ -169,14 +236,31 @@ function createHashInput(container, hashId, type, offset){
var c=checkbox(hashId);
c.offset=offset+4;
c.addEventListener('change', setBoolean);
if(tempFile.readInt(offset+4))
if(tempFile.readU32(offset+4))
c.checked=true;
addEditorRow(container, hashId, c);
}else if(type===S32){
var inp=inputNumber(hashId, 0, 0xffffffff, tempFile.readInt(offset+4));
var inp=inputNumber(hashId, 0, 0xffffffff, tempFile.readU32(offset+4));
inp.offset=offset+4;
inp.addEventListener('change', setS32);
addEditorRow(container, hashId, inp);
}else if(type===F32){
var inp=inputNumber(hashId, 0, 0xffffffff, tempFile.readF32(offset+4));
inp.offset=offset+4;
inp.addEventListener('change', setF32);
addEditorRow(container, hashId, inp);
}else if(type===VECTOR2F){
createHashInput(container, hashId+'[0]', F32, offset);
createHashInput(container, hashId+'[1]', F32, offset+8);
}else if(type===VECTOR3F){
createHashInput(container, hashId+'[0]', F32, offset);
createHashInput(container, hashId+'[1]', F32, offset+8);
createHashInput(container, hashId+'[2]', F32, offset+16);
}else if(type===VECTOR4F){
createHashInput(container, hashId+'[0]', F32, offset);
createHashInput(container, hashId+'[1]', F32, offset+8);
createHashInput(container, hashId+'[2]', F32, offset+16);
createHashInput(container, hashId+'[3]', F32, offset+24);
}else if(type===STRING){
var inp=input(hashId, SavegameEditor._readString(offset+4));
inp.offset=offset+4;
@ -190,31 +274,58 @@ function createHashInput(container, hashId, type, offset){
inp.addEventListener('change', setString64);
addEditorRow(container, hashId, inp);
}else if(type===BOOL_ARRAY){
var hash=tempFile.readInt(offset);
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', BOOL, offset+i*8);
i++;
nextHash=tempFile.readInt(offset+i*8);
nextHash=tempFile.readU32(offset+i*8);
}
}else if(type===S32_ARRAY){
var hash=tempFile.readInt(offset);
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', S32, offset+i*8);
i++;
nextHash=tempFile.readInt(offset+i*8);
nextHash=tempFile.readU32(offset+i*8);
}
}else if(type===F32_ARRAY){
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', F32, offset+i*8);
i++;
nextHash=tempFile.readU32(offset+i*8);
}
}else if(type===VECTOR2F_ARRAY){
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', VECTOR2F, offset+i*16);
i++;
nextHash=tempFile.readU32(offset+i*16);
}
}else if(type===VECTOR3F_ARRAY){
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', VECTOR3F, offset+i*24);
i++;
nextHash=tempFile.readU32(offset+i*24);
}
}else if(type===STRING64_ARRAY){
var hash=tempFile.readInt(offset);
var hash=tempFile.readU32(offset);
var nextHash=hash;
var i=0;
while(nextHash===hash){
createHashInput(container, hashId+'['+i+']', STRING64, offset+i*128);
i++;
nextHash=tempFile.readInt(offset+i*128);
nextHash=tempFile.readU32(offset+i*128);
}
}else{
addEditorRow(container, hashId+' ('+DATA_TYPES[type]+')');
@ -223,6 +334,26 @@ function createHashInput(container, hashId, type, offset){
function setBoolean(){
SavegameEditor._writeBoolean(this.offset, this.checked, 0);
}
function setS32(){
SavegameEditor._writeValue(this.offset, this.value, 0);
}
function setF32(){
SavegameEditor._writeFloat32(this.offset, this.value, 0);
}
function setString(){
SavegameEditor._writeString(this.offset, this.value);
}
function setString64(){
SavegameEditor._writeString64(this.offset, this.value);
}
function onScroll(){
var h=document.getElementById('header-top').getBoundingClientRect().height;
if(window.scrollY>h){
@ -233,30 +364,4 @@ function onScroll(){
document.getElementById('header').style.top='0px';
}
}
window.addEventListener('load',function(){
/* service worker */
if(location.protocol==='http:')
location.href=window.location.href.replace('http:','https:');
if('serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
window.addEventListener('scroll',onScroll,false);
}, false);
function setBoolean(){
SavegameEditor._writeBoolean(this.offset, this.checked, 0);
}
function setS32(){
SavegameEditor._writeValue(this.offset, this.value, 0);
}
function setString(){
SavegameEditor._writeString(this.offset, this.value);
}
function setString64(){
SavegameEditor._writeString64(this.offset, this.value);
}
window.addEventListener('scroll', onScroll, false);

View File

@ -1,31 +1,35 @@
/*
original: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
mod by marcrobledo, original from: https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js
*/
const PRECACHE_ID='v20190128';
const PRECACHE_FILES=[
'index.html','./',
'zelda-botw.css',
'zelda-botw.js',
'zelda-botw.data.js',
'zelda-botw.icons.js',
'zelda-botw.locations.js',
'favicon.png',
'assets/_blank.png',
'assets/logo.png',
'assets/bg_black.jpg',
'assets/bg_white.jpg',
'../savegame-editor.js'
const PRECACHE = 'precache-editor-zeldabotw-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = [
'index.html','./',
'zelda-botw.css',
'zelda-botw.js',
'zelda-botw.data.js',
'zelda-botw.icons.js',
'zelda-botw.locations.js',
'favicon.png',
'assets/_blank.png',
'assets/logo.png',
'assets/bg_black.jpg',
'assets/bg_white.jpg',
'../savegame-editor.js'
];
self.addEventListener('install',event=>{event.waitUntil(caches.open(PRECACHE_ID).then(cache=>cache.addAll(PRECACHE_FILES)).then(self.skipWaiting()))});self.addEventListener('activate',event=>{const currentCaches=[PRECACHE_ID,'runtime'];event.waitUntil(caches.keys().then(cacheNames=>{return cacheNames.filter(cacheName=>!currentCaches.includes(cacheName));}).then(cachesToDelete=>{return Promise.all(cachesToDelete.map(cacheToDelete=>{return caches.delete(cacheToDelete);}))}).then(()=>self.clients.claim()))});self.addEventListener('fetch',event=>{if(event.request.url.startsWith(self.location.origin))event.respondWith(caches.match(event.request).then(cachedResponse=>{if(cachedResponse)return cachedResponse;return caches.open('runtime').then(cache=>{return fetch(event.request).then(response=>{return cache.put(event.request,response.clone()).then(()=>{return response})})})}))})
self.addEventListener('install', event => {event.waitUntil(caches.open(PRECACHE).then(cache => cache.addAll(PRECACHE_URLS)).then(self.skipWaiting()));});self.addEventListener('activate', event => {const currentCaches = [PRECACHE, RUNTIME];event.waitUntil(caches.keys().then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));}).then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);}));}).then(() => self.clients.claim()));});self.addEventListener('fetch', event => {if (event.request.url.startsWith(self.location.origin)) {event.respondWith(caches.match(event.request).then(cachedResponse => {if (cachedResponse) {return cachedResponse;}return caches.open(RUNTIME).then(cache => {return fetch(event.request).then(response => {return cache.put(event.request, response.clone()).then(() => {return response;});});});}));}});

View File

@ -14,6 +14,16 @@
<script type="text/javascript" src="./zelda-botw.locations.js"></script>
<script type="text/javascript" src="./zelda-botw.icons.js"></script>
<!-- <script type="text/javascript" src="./zelda-botw.hashes.js"></script> -->
<script type="text/javascript"><!--
/* service worker */
var FORCE_HTTPS=true;
window.addEventListener('load',function(){
if(location.protocol==='http:' && FORCE_HTTPS)
location.href=window.location.href.replace('http:','https:');
else if(location.protocol==='https:' && 'serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
}, false);
--></script>
</head>
<body>
@ -33,7 +43,7 @@
<div id="toolbar" class="hidden padding-vertical">
<div class="row wrapper">
<div class="twelve columns text-center">
<span id="span-version"></span> | <button class="with-icon icon1" onclick="SavegameEditor.addItem()">Add item</button>
<span class="clickable" onclick="SavegameEditor.changeEndianess()" id="span-version"></span> | <button class="with-icon icon1" onclick="SavegameEditor.addItem()">Add item</button>
| <button class="button with-icon icon3" onclick="closeFile()">Close file</button>
<button class="button colored blue with-icon icon9" onclick="saveChanges()">Save changes</button>
</div>

View File

@ -174,7 +174,7 @@ button.with-icon.file-load:before{background-position:-32px -48px;width:20px;hei
#toolbar{
padding:8px
}
#span-version:hover{text-decoration:underline}
#header h1{display:none}
#header h1 img{vertical-align:middle}
@ -462,14 +462,15 @@ button.no-text.with-icon:before{margin-right:0px}
}
#demo{
text-decoration:none;
background-color:#5271e7;
color:black;
padding:4px 16px;
border-radius:3px;
clear:both
clear:both;
position:relative;
top:80px;
}
#demo:hover{
background-color:#8a9eea;
background-color:#bbb;
color:#000
}
#warning{

View File

@ -1,5 +1,5 @@
/*
The legend of Zelda: Breath of the wild v20190128
The legend of Zelda: Breath of the wild v20190415
by Marc Robledo 2017-2019
*/
var currentEditingItem=0;
@ -14,10 +14,10 @@ SavegameEditor={
MAX_ITEMS:410,
STRING_SIZE:0x80,
/* v1.0 v1.1 v1.2 v1.3 v1.3.3 v1.4 v1.5 */
FILESIZE: [896976, 897160, 897112, 907824, 1020648, 1027208, 1027208],
HEADER: [0x24e2, 0x24ee, 0x2588, 0x29c0, 0x3ef8, 0x471a, 0x471b],
VERSION: ['v1.0', 'v1.1', 'v1.2', 'v1.3', 'v1.3.3','v1.4', 'v1.5'],
/* v1.0 v1.1 v1.2 v1.3 kiosk v1.3.3 v1.4/v1.5 */
FILESIZE: [896976, 897160, 897112, 907824, 916576, 1020648, 1027208],
HEADER: [0x24e2, 0x24ee, 0x2588, 0x29c0, 0x2f8e, 0x3ef8, 0x471a],
VERSION: ['v1.0', 'v1.1', 'v1.2', 'v1.3', 'Kiosk', 'v1.3.3','v1.4/v1.5'],
MAP_ICONS: 0x9383490e,
MAP_POS: 0xea9def3f,
@ -26,58 +26,58 @@ SavegameEditor={
/* Offsets */
OffsetsAll:{
/* hash v1.0 v1.1 v1.2 v1.3 v1.3.3 v1.4 v1.5 */
RUPEES: [0x23149bf8, 0x00e0a0, 0x00e110, 0x00e110, 0x00e678, 0x00e730, 0x00eaf8, 0x00eaf8],
MONS: [0xce7afed3, 0x0bc480, 0x0bc558, 0x0bc538, 0x0be728, 0x0d6ac8, 0x0d7fa8, 0x0d7fa8],
MAX_HEARTS: [0x2906f327, 0x00fd28, 0x00fdb8, 0x00fdb8, 0x010438, 0x010508, 0x010970, 0x010970],
MAX_STAMINA: [0x3adff047, 0x043208, 0x0432c0, 0x0432c0, 0x043c98, 0x04fdb0, 0x0503c8, 0x0503c8],
ITEMS: [0x5f283289, 0x052828, 0x0528d8, 0x0528c0, 0x053890, 0x05fa48, 0x060408, 0x060408],
ITEMS_QUANTITY: [0x6a09fc59, 0x063340, 0x0633f0, 0x0633d8, 0x064550, 0x070730, 0x0711c8, 0x0711c8],
/* hash v1.0 v1.1 v1.2 v1.3 kiosk v1.3.3 v1.4/v1.5 */
RUPEES: [0x23149bf8, 0x00e0a0, 0x00e110, 0x00e110, 0x00e678, 0x00f5a8, 0x00e730, 0x00eaf8],
MONS: [0xce7afed3, 0x0bc480, 0x0bc558, 0x0bc538, 0x0be728, 0x0c0498, 0x0d6ac8, 0x0d7fa8],
MAX_HEARTS: [0x2906f327, 0x00fd28, 0x00fdb8, 0x00fdb8, 0x010438, 0x011420, 0x010508, 0x010970],
MAX_STAMINA: [0x3adff047, 0x043208, 0x0432c0, 0x0432c0, 0x043c98, 0x044da8, 0x04fdb0, 0x0503c8],
ITEMS: [0x5f283289, 0x052828, 0x0528d8, 0x0528c0, 0x053890, 0x054c78, 0x05fa48, 0x060408],
ITEMS_QUANTITY: [0x6a09fc59, 0x063340, 0x0633f0, 0x0633d8, 0x064550, 0x0659d0, 0x070730, 0x0711c8],
FLAGS_WEAPON: [0x57ee221d, 0x050328, 0x0503d8, 0x0503c0, 0x051270, 0x05d420, 0x05dd20, 0x05dd20],
FLAGSV_WEAPON: [0xa6d926bc, 0x0a9ca8, 0x0a9d78, 0x0a9d58, 0x0ab8d0, 0x0c3bd8, 0x0c4c68, 0x0c4c68],
FLAGS_BOW: [0x0cbf052a, 0x0045f0, 0x0045f8, 0x0045f8, 0x0047e8, 0x004828, 0x004990, 0x004990],
FLAGSV_BOW: [0x1e3fd294, 0x00a8e0, 0x00a940, 0x00a940, 0x00ae08, 0x00ae90, 0x00b1e0, 0x00b1e0],
FLAGS_SHIELD: [0xc5238d2b, 0x0b5810, 0x0b58e8, 0x0b58c8, 0x0b7910, 0x0cfc70, 0x0d1038, 0x0d1038],
FLAGSV_SHIELD: [0x69f17e8a, 0x063218, 0x0632c8, 0x0632b0, 0x064420, 0x070600, 0x071098, 0x071098],
FLAGS_WEAPON: [0x57ee221d, 0x050328, 0x0503d8, 0x0503c0, 0x051270, 0x0525f0, 0x05d420, 0x05dd20],
FLAGSV_WEAPON: [0xa6d926bc, 0x0a9ca8, 0x0a9d78, 0x0a9d58, 0x0ab8d0, 0x0ad2e8, 0x0c3bd8, 0x0c4c68],
FLAGS_BOW: [0x0cbf052a, 0x0045f0, 0x0045f8, 0x0045f8, 0x0047e8, 0x004950, 0x004828, 0x004990],
FLAGSV_BOW: [0x1e3fd294, 0x00a8e0, 0x00a940, 0x00a940, 0x00ae08, 0x00bcd0, 0x00ae90, 0x00b1e0],
FLAGS_SHIELD: [0xc5238d2b, 0x0b5810, 0x0b58e8, 0x0b58c8, 0x0b7910, 0x0b95b0, 0x0cfc70, 0x0d1038],
FLAGSV_SHIELD: [0x69f17e8a, 0x063218, 0x0632c8, 0x0632b0, 0x064420, 0x0658a0, 0x070600, 0x071098],
HORSE_SADDLES: [0x333aa6e5, 0x03d0e8, 0x03d190, 0x03d190, 0x03d9d8, 0x049ab8, 0x04a008, 0x04a008],
HORSE_REINS: [0x6150c6be, 0x060508, 0x0605b8, 0x0605a0, 0x0615d0, 0x06d7a0, 0x06e190, 0x06e190],
HORSE_NAMES: [0x7b74e117, 0x070320, 0x0703c0, 0x0703a8, 0x071820, 0x07da30, 0x07e640, 0x07e640],
HORSE_MANES: [0x9c6cfd3f, 0x0a6478, 0x0a6538, 0x0a6520, 0x0a7f18, 0x0c01c0, 0x0c1168, 0x0c1168],
HORSE_TYPES: [0xc247b696, 0x0b46f8, 0x0b47d8, 0x0b47b8, 0x0b6780, 0x0cead8, 0x0cfe40, 0x0cfe40],
HORSE_BONDS: [0xe1a0ca54, 0x0c3670, 0x0c3738, 0x0c3710, 0x0c5bb0, 0x0de2a0, 0x0df960, 0x0df960], /* max=0x3f80 */
HORSE_POSITION: [0x982ba201, 0x07aed0, 0x07af90, 0x07af78, 0x07c8f8, 0x088b78, 0x089a80, 0x089a80],
HORSE_SADDLES: [0x333aa6e5, 0x03d0e8, 0x03d190, 0x03d190, 0x03d9d8, 0x03ea60, 0x049ab8, 0x04a008],
HORSE_REINS: [0x6150c6be, 0x060508, 0x0605b8, 0x0605a0, 0x0615d0, 0x0629d8, 0x06d7a0, 0x06e190],
HORSE_NAMES: [0x7b74e117, 0x070320, 0x0703c0, 0x0703a8, 0x071820, 0x072e10, 0x07da30, 0x07e640],
HORSE_MANES: [0x9c6cfd3f, 0x0a6478, 0x0a6538, 0x0a6520, 0x0a7f18, 0x0a9828, 0x0c01c0, 0x0c1168],
HORSE_TYPES: [0xc247b696, 0x0b46f8, 0x0b47d8, 0x0b47b8, 0x0b6780, 0x0b83f0, 0x0cead8, 0x0cfe40],
HORSE_BONDS: [0xe1a0ca54, 0x0c3670, 0x0c3738, 0x0c3710, 0x0c5bb0, 0x0c7a70, 0x0de2a0, 0x0df960], /* max=0x3f80 */
HORSE_POSITION: [0x982ba201, 0x07aed0, 0x07af90, 0x07af78, 0x07c8f8, 0x07e178, 0x088b78, 0x089a80],
KOROK_SEED_COUNTER: [0x8a94e07a, 0x076148, 0x0761f8, 0x0761e0, 0x0778f8, 0x083b60, 0x084908, 0x084908],
DEFEATED_HINOX_COUNTER: [0x54679940, 0x04d2b8, 0x04d368, 0x04d358, 0x04e158, 0x05a2f0, 0x05ab78, 0x05ab78],
DEFEATED_TALUS_COUNTER: [0x698266be, 0x063010, 0x0630c0, 0x0630a8, 0x064218, 0x0703f0, 0x070e88, 0x070e88],
DEFEATED_MOLDUGA_COUNTER:[0x441b7231, 0x0466d0, 0x046788, 0x046780, 0x0472a8, 0x0533e8, 0x053b00, 0x053b00],
KOROK_SEED_COUNTER: [0x8a94e07a, 0x076148, 0x0761f8, 0x0761e0, 0x0778f8, 0x079040, 0x083b60, 0x084908],
DEFEATED_HINOX_COUNTER: [0x54679940, 0x04d2b8, 0x04d368, 0x04d358, 0x04e158, 0x04f488, 0x05a2f0, 0x05ab78],
DEFEATED_TALUS_COUNTER: [0x698266be, 0x063010, 0x0630c0, 0x0630a8, 0x064218, 0x065690, 0x0703f0, 0x070e88],
DEFEATED_MOLDUGA_COUNTER:[0x441b7231, 0x0466d0, 0x046788, 0x046780, 0x0472a8, 0x048480, 0x0533e8, 0x053b00],
PLAYTIME: [0x73c29681, 0x067888, 0x067920, 0x067908, 0x068c40, 0x074e40, 0x075998, 0x075998],
PLAYTIME: [0x73c29681, 0x067888, 0x067920, 0x067908, 0x068c40, 0x06a170, 0x074e40, 0x075998],
RELIC_GERUDO: [0x97f925c3, 0x07adc0, 0x07ae80, 0x07ae68, 0x07c7e0, 0x088a60, 0x089968, 0x089968],
RELIC_GORON: [0xf1cf4807, 0x0cb3c0, 0x0cb488, 0x0cb460, 0x0cdbf8, 0x0e6340, 0x0e7ba0, 0x0e7ba0],
RELIC_RITO: [0xfda0cde4, 0x0da0d8, 0x0da190, 0x0da160, 0x0dcac0, 0x0f8370, 0x0f9cc8, 0x0f9cc8],
RELIC_GERUDO: [0x97f925c3, 0x07adc0, 0x07ae80, 0x07ae68, 0x07c7e0, 0x07e060, 0x088a60, 0x089968],
RELIC_GORON: [0xf1cf4807, 0x0cb3c0, 0x0cb488, 0x0cb460, 0x0cdbf8, 0x0cfbf0, 0x0e6340, 0x0e7ba0],
RELIC_RITO: [0xfda0cde4, 0x0da0d8, 0x0da190, 0x0da160, 0x0dcac0, 0x0decc8, 0x0f8370, 0x0f9cc8],
MOTORCYCLE: [0xc9328299, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d2660, 0x0d2660], /* IsGet_Obj_Motorcycle */
MOTORCYCLE: [0xc9328299, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d2660], /* IsGet_Obj_Motorcycle */
PLAYER_POSITION: [0xa40ba103, 0x0a8cd8, 0x0a8da8, 0x0a8d90, 0x0aa8a8, 0x0c2b98, 0x0c3bf0, 0x0c3bf0],
MAP: [0x0bee9e46, 0x004128, 0x004130, 0x004130, 0x004310, 0x004348, 0x0044a0, 0x0044a0],
MAPTYPE: [0xd913b769, 0x0c0588, 0x0c0658, 0x0c0630, 0x0c29b0, 0x0db080, 0x0dc658, 0x0dc658]
PLAYER_POSITION: [0xa40ba103, 0x0a8cd8, 0x0a8da8, 0x0a8d90, 0x0aa8a8, 0x0ac278, 0x0c2b98, 0x0c3bf0],
MAP: [0x0bee9e46, 0x004128, 0x004130, 0x004130, 0x004310, 0x004448, 0x004348, 0x0044a0],
MAPTYPE: [0xd913b769, 0x0c0588, 0x0c0658, 0x0c0630, 0x0c29b0, 0x0c47e8, 0x0db080, 0x0dc658]
},
/* private functions */
_toHexInt:function(i){var s=i.toString(16);while(s.length<8)s='0'+s;return '0x'+s},
_writeBoolean:function(offset,val,arrayPos){if(arrayPos)tempFile.writeInt(offset+8*i,val?1:0);else tempFile.writeInt(offset,val?1:0)},
_writeValue:function(offset,val,arrayPos){if(arrayPos)tempFile.writeInt(offset+8*i,val);else tempFile.writeInt(offset,val)},
_writeBoolean:function(offset,val,arrayPos){if(arrayPos)tempFile.writeU32(offset+8*i,val?1:0);else tempFile.writeU32(offset,val?1:0)},
_writeValue:function(offset,val,arrayPos){if(arrayPos)tempFile.writeU32(offset+8*i,val);else tempFile.writeU32(offset,val)},
_writeString:function(offset,str){
for(var i=0; i<16; i++){
tempFile.writeBytes(offset,[0,0,0,0]);
var fourBytes=str.substr(i*4, 4);
for(j=0; j<fourBytes.length; j++){
tempFile.writeByte(offset+j, fourBytes.charCodeAt(j));
tempFile.writeU8(offset+j, fourBytes.charCodeAt(j));
}
offset+=8;
}
@ -87,7 +87,7 @@ SavegameEditor={
tempFile.writeBytes(offset,[0,0,0,0]);
var fourBytes=str.substr(i*4, 4);
for(j=0; j<fourBytes.length; j++){
tempFile.writeByte(offset+j, fourBytes.charCodeAt(j));
tempFile.writeU8(offset+j, fourBytes.charCodeAt(j));
}
offset+=8;
}
@ -95,14 +95,14 @@ SavegameEditor={
_searchHash:function(hash){
for(var i=0x0c; i<tempFile.fileSize; i+=8)
if(hash===tempFile.readInt(i))
if(hash===tempFile.readU32(i))
return i;
return false;
},
_readFromHash:function(hash){
var offset=this._searchHash(hash);
if(typeof offset === 'number')
return tempFile.readInt(offset+4);
return tempFile.readU32(offset+4);
return false;
},
_writeValueAtHash:function(hash,val){
@ -113,7 +113,7 @@ SavegameEditor={
_getOffsets:function(v){
this.Offsets={};
if(v<this.OffsetsAll.RUPEES.length){
if(v<this.OffsetsAll.RUPEES.length-1){
for(prop in this.OffsetsAll){
this.Offsets[prop]=this.OffsetsAll[prop][v+1];
}
@ -189,7 +189,7 @@ SavegameEditor={
},
_createItemRow:function(i,itemCat){
var itemNameId=this._loadItemName(i);
var itemVal=itemCat===false?1:tempFile.readInt(this._getItemQuantityOffset(i));
var itemVal=itemCat===false?1:tempFile.readU32(this._getItemQuantityOffset(i));
var img=new Image();
img.id='icon'+i;
@ -295,8 +295,8 @@ SavegameEditor={
},
editModifier2:function(type,i,modifier,val){
tempFile.writeInt(this._getModifierOffset1(type)+i*0x08, modifier);
tempFile.writeInt(this._getModifierOffset2(type)+i*0x08, val);
tempFile.writeU32(this._getModifierOffset1(type)+i*0x08, modifier);
tempFile.writeU32(this._getModifierOffset2(type)+i*0x08, val);
},
editHorse:function(i){
@ -343,18 +343,32 @@ SavegameEditor={
},
changeEndianess:function(){
var tempFileByteSwapped=new MarcFile(tempFile.fileSize);
tempFileByteSwapped.fileType=tempFile.fileType;
tempFileByteSwapped.fileName=tempFile.fileName;
tempFileByteSwapped.littleEndian=!tempFile.littleEndian;
for(var i=0; i<tempFile.fileSize; i+=4){
tempFileByteSwapped.writeU32(i, tempFile.readU32(i));
}
tempFile=tempFileByteSwapped;
this.checkValidSavegame();
},
/* check if savegame is valid */
_checkValidSavegameByConsole:function(switchMode){
var CONSOLE=switchMode?'Switch':'Wii U';
tempFile.littleEndian=switchMode;
for(var i=0; i<this.Constants.FILESIZE.length; i++){
var versionHash=tempFile.readInt(0);
var versionHash=tempFile.readU32(0);
if(versionHash===0x2a46) //v1.3.0 switch?
versionHash=0x29c0;
if(versionHash===0x3ef9) //v1.3.3 switch?
else if(versionHash===0x3ef9) //v1.3.3 switch?
versionHash=0x3ef8;
else if(versionHash===0x471b) //v1.5 is the same as 1.4
versionHash=0x471a;
if(tempFile.fileSize===this.Constants.FILESIZE[i] && versionHash===this.Constants.HEADER[i] && tempFile.readInt(4)===0xffffffff){
if(tempFile.fileSize===this.Constants.FILESIZE[i] && versionHash===this.Constants.HEADER[i] && tempFile.readU32(4)===0xffffffff){
this._getOffsets(i);
setValue('version', this.Constants.VERSION[i]+' ('+CONSOLE+')');
return true;
@ -467,24 +481,24 @@ SavegameEditor={
/* prepare editor */
setValue('rupees', tempFile.readInt(this.Offsets.RUPEES));
setValue('mons', tempFile.readInt(this.Offsets.MONS));
setValue('max-hearts', tempFile.readInt(this.Offsets.MAX_HEARTS));
setValue('max-stamina', tempFile.readInt(this.Offsets.MAX_STAMINA));
setValue('rupees', tempFile.readU32(this.Offsets.RUPEES));
setValue('mons', tempFile.readU32(this.Offsets.MONS));
setValue('max-hearts', tempFile.readU32(this.Offsets.MAX_HEARTS));
setValue('max-stamina', tempFile.readU32(this.Offsets.MAX_STAMINA));
setValue('relic-gerudo', tempFile.readInt(this.Offsets.RELIC_GERUDO));
setValue('relic-goron', tempFile.readInt(this.Offsets.RELIC_GORON));
setValue('relic-rito', tempFile.readInt(this.Offsets.RELIC_RITO));
setValue('relic-gerudo', tempFile.readU32(this.Offsets.RELIC_GERUDO));
setValue('relic-goron', tempFile.readU32(this.Offsets.RELIC_GORON));
setValue('relic-rito', tempFile.readU32(this.Offsets.RELIC_RITO));
setValue('koroks', tempFile.readInt(this.Offsets.KOROK_SEED_COUNTER));
setValue('defeated-hinox', tempFile.readInt(this.Offsets.DEFEATED_HINOX_COUNTER));
setValue('defeated-talus', tempFile.readInt(this.Offsets.DEFEATED_TALUS_COUNTER));
setValue('defeated-molduga', tempFile.readInt(this.Offsets.DEFEATED_MOLDUGA_COUNTER));
setValue('playtime',this._timeToString(tempFile.readInt(this.Offsets.PLAYTIME)));
setValue('koroks', tempFile.readU32(this.Offsets.KOROK_SEED_COUNTER));
setValue('defeated-hinox', tempFile.readU32(this.Offsets.DEFEATED_HINOX_COUNTER));
setValue('defeated-talus', tempFile.readU32(this.Offsets.DEFEATED_TALUS_COUNTER));
setValue('defeated-molduga', tempFile.readU32(this.Offsets.DEFEATED_MOLDUGA_COUNTER));
setValue('playtime',this._timeToString(tempFile.readU32(this.Offsets.PLAYTIME)));
/* motorcycle */
document.getElementById('checkbox-motorcycle').checked=!!tempFile.readInt(this.Offsets.MOTORCYCLE);
document.getElementById('checkbox-motorcycle').checked=!!tempFile.readU32(this.Offsets.MOTORCYCLE);
if(this.Offsets.MOTORCYCLE){
document.getElementById('row-motorcycle').style.display='flex';
}else{
@ -493,9 +507,9 @@ SavegameEditor={
/* coordinates */
setValue('pos-x', tempFile.readFloat32(this.Offsets.PLAYER_POSITION));
setValue('pos-y', tempFile.readFloat32(this.Offsets.PLAYER_POSITION+8));
setValue('pos-z', tempFile.readFloat32(this.Offsets.PLAYER_POSITION+16));
setValue('pos-x', tempFile.readF32(this.Offsets.PLAYER_POSITION));
setValue('pos-y', tempFile.readF32(this.Offsets.PLAYER_POSITION+8));
setValue('pos-z', tempFile.readF32(this.Offsets.PLAYER_POSITION+16));
var map=this._readStringShort(this.Offsets.MAP);
var mapType=this._readStringShort(this.Offsets.MAPTYPE);
@ -506,9 +520,9 @@ SavegameEditor={
setValue('pos-map',map)
setValue('pos-maptype',mapType)
setValue('pos-x-horse', tempFile.readFloat32(this.Offsets.HORSE_POSITION));
setValue('pos-y-horse', tempFile.readFloat32(this.Offsets.HORSE_POSITION+8));
setValue('pos-z-horse', tempFile.readFloat32(this.Offsets.HORSE_POSITION+16));
setValue('pos-x-horse', tempFile.readF32(this.Offsets.HORSE_POSITION));
setValue('pos-y-horse', tempFile.readF32(this.Offsets.HORSE_POSITION+8));
setValue('pos-z-horse', tempFile.readF32(this.Offsets.HORSE_POSITION+16));
/* map pins */
@ -565,13 +579,13 @@ SavegameEditor={
for(var j=0; j<3; j++){
var modifierColumn=modifierColumns[j];
for(var i=0; i<modifiersArray[j]; i++){
var modifier=tempFile.readInt(this.Offsets['FLAGS_'+modifierColumn.toUpperCase()]+i*8);
var modifier=tempFile.readU32(this.Offsets['FLAGS_'+modifierColumn.toUpperCase()]+i*8);
var modifierSelect=select('modifier-'+modifierColumn+'s-'+i, BOTW_Data.MODIFIERS.concat({value:modifier,name:this._toHexInt(modifier)}));
modifierSelect.value=modifier;
var additional=document.getElementById('container-'+modifierColumn+'s').children[i].children[2];
additional.appendChild(modifierSelect);
additional.appendChild(inputNumber('modifier-'+modifierColumn+'s-value-'+i, 0, 0xffffffff, tempFile.readInt(this.Offsets['FLAGSV_'+modifierColumn.toUpperCase()]+i*8)));
additional.appendChild(inputNumber('modifier-'+modifierColumn+'s-value-'+i, 0, 0xffffffff, tempFile.readU32(this.Offsets['FLAGSV_'+modifierColumn.toUpperCase()]+i*8)));
}
}
},
@ -579,61 +593,61 @@ SavegameEditor={
/* save function */
save:function(){
/* STATS */
tempFile.writeInt(this.Offsets.RUPEES, getValue('rupees'));
tempFile.writeInt(this.Offsets.MONS, getValue('mons'));
tempFile.writeInt(this.Offsets.MAX_HEARTS, getValue('max-hearts'));
tempFile.writeInt(this.Offsets.MAX_STAMINA, getValue('max-stamina'));
tempFile.writeU32(this.Offsets.RUPEES, getValue('rupees'));
tempFile.writeU32(this.Offsets.MONS, getValue('mons'));
tempFile.writeU32(this.Offsets.MAX_HEARTS, getValue('max-hearts'));
tempFile.writeU32(this.Offsets.MAX_STAMINA, getValue('max-stamina'));
tempFile.writeInt(this.Offsets.RELIC_GERUDO, getValue('relic-gerudo'));
tempFile.writeInt(this.Offsets.RELIC_GORON, getValue('relic-goron'));
tempFile.writeInt(this.Offsets.RELIC_RITO, getValue('relic-rito'));
tempFile.writeU32(this.Offsets.RELIC_GERUDO, getValue('relic-gerudo'));
tempFile.writeU32(this.Offsets.RELIC_GORON, getValue('relic-goron'));
tempFile.writeU32(this.Offsets.RELIC_RITO, getValue('relic-rito'));
tempFile.writeInt(this.Offsets.KOROK_SEED_COUNTER, getValue('koroks'));
tempFile.writeInt(this.Offsets.DEFEATED_HINOX_COUNTER, getValue('defeated-hinox'));
tempFile.writeInt(this.Offsets.DEFEATED_TALUS_COUNTER, getValue('defeated-talus'));
tempFile.writeInt(this.Offsets.DEFEATED_MOLDUGA_COUNTER, getValue('defeated-molduga'));
tempFile.writeU32(this.Offsets.KOROK_SEED_COUNTER, getValue('koroks'));
tempFile.writeU32(this.Offsets.DEFEATED_HINOX_COUNTER, getValue('defeated-hinox'));
tempFile.writeU32(this.Offsets.DEFEATED_TALUS_COUNTER, getValue('defeated-talus'));
tempFile.writeU32(this.Offsets.DEFEATED_MOLDUGA_COUNTER, getValue('defeated-molduga'));
/* MOTORCYCLE */
if(this.Offsets.MOTORCYCLE){
tempFile.writeInt(this.Offsets.MOTORCYCLE, getField('checkbox-motorcycle').checked?1:0);
tempFile.writeU32(this.Offsets.MOTORCYCLE, getField('checkbox-motorcycle').checked?1:0);
}
/* COORDINATES */
tempFile.writeFloat32(this.Offsets.PLAYER_POSITION, getValue('pos-x'));
tempFile.writeFloat32(this.Offsets.PLAYER_POSITION+8, getValue('pos-y'));
tempFile.writeFloat32(this.Offsets.PLAYER_POSITION+16, getValue('pos-z'));
tempFile.writeF32(this.Offsets.PLAYER_POSITION, getValue('pos-x'));
tempFile.writeF32(this.Offsets.PLAYER_POSITION+8, getValue('pos-y'));
tempFile.writeF32(this.Offsets.PLAYER_POSITION+16, getValue('pos-z'));
this._writeStringShort(this.Offsets.MAP, getValue('pos-map'))
this._writeStringShort(this.Offsets.MAPTYPE, getValue('pos-maptype'))
tempFile.writeFloat32(this.Offsets.HORSE_POSITION, getValue('pos-x-horse'));
tempFile.writeFloat32(this.Offsets.HORSE_POSITION+8, getValue('pos-y-horse'));
tempFile.writeFloat32(this.Offsets.HORSE_POSITION+16, getValue('pos-z-horse'));
tempFile.writeF32(this.Offsets.HORSE_POSITION, getValue('pos-x-horse'));
tempFile.writeF32(this.Offsets.HORSE_POSITION+8, getValue('pos-y-horse'));
tempFile.writeF32(this.Offsets.HORSE_POSITION+16, getValue('pos-z-horse'));
/* ITEMS */
for(var i=0; i<this.Constants.MAX_ITEMS; i++){
if(document.getElementById('number-item'+i) || document.getElementById('select-item'+i))
tempFile.writeInt(this._getItemQuantityOffset(i), getValue('item'+i));
tempFile.writeU32(this._getItemQuantityOffset(i), getValue('item'+i));
else
break;
}
/* modifiers */
for(var i=0; document.getElementById('select-modifier-weapons-'+i); i++){
tempFile.writeInt(this.Offsets.FLAGS_WEAPON+i*8, getValue('modifier-weapons-'+i));
tempFile.writeInt(this.Offsets.FLAGSV_WEAPON+i*8, getValue('modifier-weapons-value-'+i));
tempFile.writeU32(this.Offsets.FLAGS_WEAPON+i*8, getValue('modifier-weapons-'+i));
tempFile.writeU32(this.Offsets.FLAGSV_WEAPON+i*8, getValue('modifier-weapons-value-'+i));
}
for(var i=0; document.getElementById('select-modifier-bows-'+i); i++){
tempFile.writeInt(this.Offsets.FLAGS_BOW+i*8, getValue('modifier-bows-'+i));
tempFile.writeInt(this.Offsets.FLAGSV_BOW+i*8, getValue('modifier-bows-value-'+i));
tempFile.writeU32(this.Offsets.FLAGS_BOW+i*8, getValue('modifier-bows-'+i));
tempFile.writeU32(this.Offsets.FLAGSV_BOW+i*8, getValue('modifier-bows-value-'+i));
}
for(var i=0; document.getElementById('select-modifier-shields-'+i); i++){
tempFile.writeInt(this.Offsets.FLAGS_SHIELD+i*8, getValue('modifier-shields-'+i));
tempFile.writeInt(this.Offsets.FLAGSV_SHIELD+i*8, getValue('modifier-shields-value-'+i));
tempFile.writeU32(this.Offsets.FLAGS_SHIELD+i*8, getValue('modifier-shields-'+i));
tempFile.writeU32(this.Offsets.FLAGSV_SHIELD+i*8, getValue('modifier-shields-value-'+i));
}
}
}
@ -660,8 +674,8 @@ function setBooleans(hashTable, counterElement){
var counter=0;
for(var i=0;i<hashTable.length; i++){
var offset=SavegameEditor._searchHash(hashTable[i]);
if(offset && !tempFile.readInt(offset+4)){
tempFile.writeInt(offset+4, 1);
if(offset && !tempFile.readU32(offset+4)){
tempFile.writeU32(offset+4, 1);
counter++;
}
}
@ -674,7 +688,7 @@ function setBooleans(hashTable, counterElement){
function unlockKoroks(){
var unlockedKoroks=setBooleans(BOTW_Data.KOROKS,'koroks');
var offset=SavegameEditor._searchHash(0x64622a86); //HiddenKorok_Complete
tempFile.writeInt(offset+4, 1);
tempFile.writeU32(offset+4, 1);
//search korok seeds in inventory
for(var i=0; i<SavegameEditor.Constants.MAX_ITEMS; i++){
@ -707,9 +721,9 @@ function setCompendiumToStock(){
for(var i=0; i<BOTW_Data.PICTURE_BOOK_SIZE.length; i++){
var offset=SavegameEditor._searchHash(BOTW_Data.PICTURE_BOOK_SIZE[i]);
if(typeof offset === 'number'){
var val=tempFile.readInt(offset+4);
var val=tempFile.readU32(offset+4);
if(val && val!==0xffffffff){
tempFile.writeInt(offset+4, 0xffffffff);
tempFile.writeU32(offset+4, 0xffffffff);
setToStock++;
}
}
@ -799,7 +813,7 @@ function clearMapPins(){
iterateMapPins(function(val,offset){
if (val != 0xffffffff){
count++;
tempFile.writeInt(offset, 0xffffffff)
tempFile.writeU32(offset, 0xffffffff)
}
return true;
})
@ -811,7 +825,7 @@ function clearMapPins(){
i++;
if (val != expect){
count2++
tempFile.writeFloat32(offset, expect)
tempFile.writeF32(offset, expect)
}
return true
})
@ -827,8 +841,8 @@ function iterateMapPins(f){
var offset = SavegameEditor._searchHash(SavegameEditor.Constants.MAP_ICONS)
for (var i = 0;; i++){
var base = offset + (8 * i)
var hdr = tempFile.readInt(base)
var val = tempFile.readInt(base + 4)
var hdr = tempFile.readU32(base)
var val = tempFile.readU32(base + 4)
if (hdr != SavegameEditor.Constants.MAP_ICONS){
break
}
@ -841,8 +855,8 @@ function iterateMapPinLocations(f){
offset = SavegameEditor._searchHash(SavegameEditor.Constants.MAP_POS)
for (var i = 0;; i++){
var base = offset + (8 * i)
var hdr = tempFile.readInt(base)
var val = tempFile.readFloat32(base + 4)
var hdr = tempFile.readU32(base)
var val = tempFile.readF32(base + 4)
if (hdr != SavegameEditor.Constants.MAP_POS){
break
}
@ -860,9 +874,9 @@ function dist(px,py,pz,l){
function addToMap(data, icon){
var px=tempFile.readFloat32(SavegameEditor.Offsets.PLAYER_POSITION);
var py=tempFile.readFloat32(SavegameEditor.Offsets.PLAYER_POSITION+8);
var pz=tempFile.readFloat32(SavegameEditor.Offsets.PLAYER_POSITION+16);
var px=tempFile.readF32(SavegameEditor.Offsets.PLAYER_POSITION);
var py=tempFile.readF32(SavegameEditor.Offsets.PLAYER_POSITION+8);
var pz=tempFile.readF32(SavegameEditor.Offsets.PLAYER_POSITION+16);
var points = [];
for (var i = 0; i<data.length; i++){
@ -882,7 +896,7 @@ function addToMap(data, icon){
var pt = points[i]
var hash = pt.H;
var offset=SavegameEditor._searchHash(hash);
if(offset && !tempFile.readInt(offset + 4)){
if(offset && !tempFile.readU32(offset + 4)){
addMapPin(icon, pt.L)
count++;
mapPinCount++;
@ -896,7 +910,7 @@ function addMapPin(icon, location){
// add pin to next availible location.
iterateMapPins(function(val,offset){
if (val == 0xffffffff){
tempFile.writeInt(offset, icon)
tempFile.writeU32(offset, icon)
return false
}
return true;
@ -911,9 +925,9 @@ function addMapPin(icon, location){
i++
if (val == -100000){
added = true;
tempFile.writeFloat32(offset,location[0])
tempFile.writeFloat32(offset+8,location[1])
tempFile.writeFloat32(offset+16,location[2])
tempFile.writeF32(offset,location[0])
tempFile.writeF32(offset+8,location[1])
tempFile.writeF32(offset+16,location[2])
return false;
}
return true;
@ -960,16 +974,7 @@ function onScroll(){
document.getElementById('header').style.top='0px';
}
}
window.addEventListener('load',function(){
/* service worker */
if(location.protocol==='http:')
location.href=window.location.href.replace('http:','https:');
if('serviceWorker' in navigator)
navigator.serviceWorker.register('_cache_service_worker.js');
window.addEventListener('scroll',onScroll,false);
}, false);
window.addEventListener('scroll', onScroll, false);
if(typeof String.endsWith==='undefined'){
String.prototype.endsWith=function(search){