|
|
|
@@ -32,35 +32,38 @@ h1{font-size:20px;color:#fff;margin:0}
|
|
|
|
<button class="btn btn-download" onclick="applyUpdate()" id="btnApply" disabled>下载更新</button>
|
|
|
|
<button class="btn btn-download" onclick="applyUpdate()" id="btnApply" disabled>下载更新</button>
|
|
|
|
<div class="log" id="log"></div>
|
|
|
|
<div class="log" id="log"></div>
|
|
|
|
<script>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
var channel='stable';
|
|
|
|
var dlUrl='',dlVer='',dlSha='';
|
|
|
|
var dlUrl='',dlVer='',dlSha='';
|
|
|
|
var BASE='https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota';
|
|
|
|
var BASE='https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota';
|
|
|
|
|
|
|
|
|
|
|
|
function selectCh(el,ch){
|
|
|
|
function selectCh(el,ch){
|
|
|
|
document.querySelectorAll('.chip').forEach(function(c){c.className='chip chip-off'});
|
|
|
|
document.querySelectorAll('.chip').forEach(function(c){c.className='chip chip-off'});
|
|
|
|
el.className='chip chip-on';
|
|
|
|
el.className='chip chip-on';
|
|
|
|
|
|
|
|
channel=ch;
|
|
|
|
log('channel: '+ch)
|
|
|
|
log('channel: '+ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function log(m){document.getElementById('log').innerText+=m+'\n'}
|
|
|
|
function log(m){document.getElementById('log').innerText+=m+'\n'}
|
|
|
|
function checkUpdate(){
|
|
|
|
function checkUpdate(){
|
|
|
|
fetch(BASE+'/version.txt?t='+Date.now(),{cache:'no-store'})
|
|
|
|
var manFile='/manifest-'+channel+'.json';
|
|
|
|
.then(r=>{if(!r.ok)throw Error('HTTP '+r.status);return r.text()})
|
|
|
|
log('checking '+manFile+' ...');
|
|
|
|
.then(function(t){t=t.trim();log('remote: '+t);
|
|
|
|
fetch(BASE+manFile+'?t='+Date.now(),{cache:'no-store'})
|
|
|
|
var parts=t.split('|');var remoteVer=parts[0];dlUrl=parts[1]||'';dlSha=parts[2]||'';
|
|
|
|
.then(function(r){if(!r.ok)throw Error('HTTP '+r.status);return r.json()})
|
|
|
|
if(!dlUrl)dlUrl=BASE+'/h5/index-v'+remoteVer.replace('0.1.0-dav-android-','')+'.html';
|
|
|
|
.then(function(j){log('remote: '+j.h5_version);
|
|
|
|
if(remoteVer!=='0.1.0-dav-android-6'){dlVer=remoteVer;
|
|
|
|
dlUrl=j.h5_url;dlSha=j.h5_sha256||'';
|
|
|
|
|
|
|
|
if(!dlUrl){log('ERR: no h5_url');return}
|
|
|
|
|
|
|
|
if(j.h5_version!=='0.1.0-dav-android-6'){dlVer=j.h5_version;
|
|
|
|
log('*** NEW VERSION ***');document.getElementById('btnApply').disabled=false}
|
|
|
|
log('*** NEW VERSION ***');document.getElementById('btnApply').disabled=false}
|
|
|
|
else log('up to date')})
|
|
|
|
else log('up to date')})
|
|
|
|
.catch(function(e){log('ERR: '+e.message)})
|
|
|
|
.catch(function(e){log('ERR: '+e.message)})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function applyUpdate(){
|
|
|
|
function applyUpdate(){
|
|
|
|
fetch(dlUrl+'?t='+Date.now(),{cache:'no-store'})
|
|
|
|
fetch(dlUrl+'?t='+Date.now(),{cache:'no-store'})
|
|
|
|
.then(r=>{if(!r.ok)throw Error('HTTP '+r.status);return r.arrayBuffer()})
|
|
|
|
.then(function(r){if(!r.ok)throw Error('HTTP '+r.status);return r.text()})
|
|
|
|
.then(function(buf){
|
|
|
|
.then(function(t){
|
|
|
|
return crypto.subtle.digest('SHA-256',buf).then(function(hash){
|
|
|
|
if(!dlSha){log('ERR: SHA256 required');return}
|
|
|
|
var hex=Array.from(new Uint8Array(hash)).map(function(b){return b.toString(16).padStart(2,'0')}).join('');
|
|
|
|
var h=Android.sha256(t);
|
|
|
|
if(dlSha&&hex!==dlSha){log('SHA256 MISMATCH!');return}
|
|
|
|
if(h!==dlSha){log('SHA256 MISMATCH!');return}
|
|
|
|
Android.saveCache(new TextDecoder().decode(buf));log('OK! restart app to apply')
|
|
|
|
Android.saveCache(t);log('OK! restart app to apply')
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.catch(function(e){log('ERR: '+e.message)})
|
|
|
|
.catch(function(e){log('ERR: '+e.message)})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|