patches
This commit is contained in:
66
index.html
66
index.html
@ -15,17 +15,71 @@
|
||||
<input type="file" id="sifgamefile">
|
||||
<br><br>
|
||||
Server URL: <input id="serverurl" type="text" value="http://localhost:51376" autocomplete="off"><br><br>
|
||||
<input type="radio" id="apk" name="format" value="apk" checked><label for="apk">Android</label>
|
||||
<input type="radio" id="ipa" name="format" value="ipa"><label for="ipa">iOS</label>
|
||||
<input type="radio" id="apk" name="format" value="apk" onchange="clickstuff(event)" checked><label for="apk">Android</label>
|
||||
<input type="radio" id="ipa" name="format" value="ipa" onchange="clickstuff(event)"><label for="ipa">iOS</label>
|
||||
<div id="patches">
|
||||
<div id="patches-android"></div>
|
||||
<div id="patches-ios"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<br><br><br>
|
||||
<button onclick="load(event)">Patch</button>
|
||||
<script>
|
||||
function load(e) {
|
||||
e.target.remove()
|
||||
console.log("load");
|
||||
init_honoka(document.getElementById("sifgamefile").files[0], document.getElementById("apk").checked, document.getElementById("serverurl").value);
|
||||
function clickstuff(e) {
|
||||
if (document.getElementById("apk").checked) {
|
||||
document.getElementById("patches-android").style.display = "";
|
||||
document.getElementById("patches-ios").style.display = "none";
|
||||
} else {
|
||||
document.getElementById("patches-android").style.display = "none";
|
||||
document.getElementById("patches-ios").style.display = "";
|
||||
}
|
||||
}
|
||||
let patches;
|
||||
function load(e) {
|
||||
let android = document.getElementById("apk").checked;
|
||||
e.target.remove();
|
||||
console.log("Patch start");
|
||||
for (let i=0; i<patches.length; i++) {
|
||||
let patch = patches[i];
|
||||
if (android) {
|
||||
patches[i].checked = patch.android ? document.getElementById(patch.id + "-android").checked : false;
|
||||
} else {
|
||||
patches[i].checked = patch.ios ? document.getElementById(patch.id + "-ios").checked : false;
|
||||
}
|
||||
}
|
||||
init_honoka(document.getElementById("sifgamefile").files[0], android, document.getElementById("serverurl").value, patches);
|
||||
}
|
||||
(async () => {
|
||||
patches = JSON.parse(await (await fetch("patches.json")).text());
|
||||
patches.forEach(patch => {
|
||||
let input = document.createElement("input");
|
||||
input.type = "checkbox";
|
||||
input.checked = patch.checked;
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.innerText = patch.description;
|
||||
|
||||
if (patch.android) {
|
||||
let id = patch.id + "-android";
|
||||
input.id = id;
|
||||
input.value = id;
|
||||
label.for = id;
|
||||
document.getElementById("patches-android").appendChild(document.createElement("br"));
|
||||
document.getElementById("patches-android").appendChild(input);
|
||||
document.getElementById("patches-android").appendChild(label);
|
||||
}
|
||||
if (patch.ios) {
|
||||
let id = patch.id + "-ios";
|
||||
input.id = id;
|
||||
input.value = id;
|
||||
label.for = id;
|
||||
document.getElementById("patches-ios").appendChild(document.createElement("br"));
|
||||
document.getElementById("patches-ios").appendChild(input);
|
||||
document.getElementById("patches-ios").appendChild(label);
|
||||
}
|
||||
})
|
||||
})();
|
||||
addEventListener("DOMContentLoaded", clickstuff);
|
||||
</script>
|
||||
<p id="status"></p>
|
||||
</body>
|
||||
|
196
loader.js
196
loader.js
@ -1,95 +1,131 @@
|
||||
function update_status(status) {
|
||||
console.log(status);
|
||||
document.getElementById("status").innerText = status;
|
||||
}
|
||||
|
||||
function init_honoka(file, android, newDomain) {
|
||||
async function onloaded() {
|
||||
if (newDomain.endsWith("/")) newDomain = newDomain.slice(0, -1);
|
||||
if (!file) {
|
||||
console.log("downloading");
|
||||
update_status("Downloading...");
|
||||
if (android) {
|
||||
file = await (await fetch("https://ethanthesleepy.one/public/lovelive/lovelive-community.apk")).blob();
|
||||
} else {
|
||||
file = await (await fetch("https://ethanthesleepy.one/public/lovelive/lovelive-community.ipa")).blob();
|
||||
async function patch(file, android, newDomain, patches) {
|
||||
if (newDomain.endsWith("/")) newDomain = newDomain.slice(0, -1);
|
||||
|
||||
if (!file) {
|
||||
console.log("downloading");
|
||||
update_status("Downloading...");
|
||||
file = await (await fetch("https://ethanthesleepy.one/public/lovelive/lovelive-community." + (android ? "apk" : "ipa"))).blob();
|
||||
console.log("downloaded");
|
||||
}
|
||||
console.log("loaded");
|
||||
update_status("Opening file");
|
||||
const zip = new JSZip();
|
||||
await zip.loadAsync(file);
|
||||
update_status("Getting current config");
|
||||
|
||||
let basePath = android ? "" : "Payload/LoveLive.app/ProjectResources/";
|
||||
let server_file;
|
||||
if (android) {
|
||||
let server_info = await zip.file("assets/AppAssets.zip").async("arraybuffer");
|
||||
const zip2 = new JSZip();
|
||||
await zip2.loadAsync(server_info);
|
||||
server_file = await zip2.file("config/server_info.json").async("arraybuffer");
|
||||
} else {
|
||||
server_file = await zip.file("Payload/LoveLive.app/ProjectResources/config/server_info.json").async("arraybuffer");
|
||||
}
|
||||
|
||||
let postPatches = [];
|
||||
for (let i=0; i<patches.length; i++) {
|
||||
let patch = patches[i];
|
||||
if (!patch.checked) continue;
|
||||
for (let j=0; j<patch.files.length; j++) {
|
||||
let file = patch.files[j];
|
||||
if (android && file.outpath.startsWith("assets/")) {
|
||||
postPatches.push(file);
|
||||
continue;
|
||||
}
|
||||
console.log("downloaded");
|
||||
}
|
||||
console.log("loaded");
|
||||
update_status("Opening file");
|
||||
const zip = new JSZip();
|
||||
await zip.loadAsync(file);
|
||||
update_status("Getting current config");
|
||||
let server_file;
|
||||
if (android) {
|
||||
let server_info = await zip.file("assets/AppAssets.zip").async("arraybuffer");
|
||||
const zip2 = new JSZip();
|
||||
await zip2.loadAsync(server_info);
|
||||
server_file = await zip2.file("config/server_info.json").async("arraybuffer");
|
||||
} else {
|
||||
server_file = await zip.file("Payload/LoveLive.app/ProjectResources/config/server_info.json").async("arraybuffer");
|
||||
}
|
||||
//console.log(server_file);
|
||||
FS.writeFile("/server_info.json", new Uint8Array(server_file));
|
||||
update_status("Decrypting");
|
||||
Module.callMain(["server_info.json"]);
|
||||
update_status("Patching domain");
|
||||
const data = FS.readFile("/server_info.json", {encoding: 'utf8'});
|
||||
const currentData = JSON.parse(data);
|
||||
const currentDomain = currentData.domain;
|
||||
const newData = data.split(currentDomain).join(newDomain);
|
||||
FS.writeFile("/server_info.json", newData);
|
||||
update_status("Encrypting");
|
||||
Module.callMain(["-e", "-j", "server_info.json"]);
|
||||
const new_server_info = FS.readFile("/server_info.json");
|
||||
let type;
|
||||
let ext;
|
||||
update_status("Applying changes");
|
||||
if (android) {
|
||||
let server_info = await zip.file("assets/AppAssets.zip").async("arraybuffer");
|
||||
const zip2 = new JSZip();
|
||||
await zip2.loadAsync(server_info);
|
||||
zip2.file("config/server_info.json", new_server_info);
|
||||
const appAssets = await zip2.generateAsync({type: "uint8array"});
|
||||
zip.file("assets/AppAssets.zip", appAssets);
|
||||
zip.file("assets/version", "MD5 (AppAssets.zip) = " + CryptoJS.MD5(appAssets).toString());
|
||||
type = "application/vnd.android.package-archive";
|
||||
ext = "apk";
|
||||
} else {
|
||||
zip.file("Payload/LoveLive.app/ProjectResources/config/server_info.json", new_server_info);
|
||||
type = "application/octet-stream";
|
||||
ext = "ipa";
|
||||
}
|
||||
let finalized = await zip.generateAsync({type: "uint8array"});
|
||||
update_status("Finalizing");
|
||||
const downloadUrl = URL.createObjectURL(new Blob([finalized], {type: type}));
|
||||
const b = document.createElement("a");
|
||||
b.href = URL.createObjectURL(new Blob([new_server_info], {type: "application/json"}))
|
||||
b.innerText = "Download patched server_info.json";
|
||||
b.download = "server_info.json";
|
||||
document.body.appendChild(b);
|
||||
|
||||
document.body.appendChild(document.createElement("br"));
|
||||
document.body.appendChild(document.createElement("br"));
|
||||
|
||||
const a = document.createElement("a");
|
||||
a.href = downloadUrl;
|
||||
a.innerText = "Download";
|
||||
a.download = "lovelive."+ext;
|
||||
document.body.appendChild(a);
|
||||
update_status("Done!");
|
||||
if (android) {
|
||||
const p = document.createElement("p");
|
||||
p.innerHTML = "Package is not signed. Using <a href=\"https://github.com/patrickfav/uber-apk-signer/releases\">uber-apk-signer</a>, sign it with the command `java -jar uber-apk-signer-<version>.jar lovelive.apk`.";
|
||||
document.body.appendChild(p);
|
||||
console.log("Downloading patch", file.path);
|
||||
let res = await fetch(file.path);
|
||||
if (!res.ok) {
|
||||
console.warn("Error downloading patch");
|
||||
continue;
|
||||
}
|
||||
zip.file(basePath + file.outpath, await res.blob());
|
||||
}
|
||||
}
|
||||
|
||||
//console.log(server_file);
|
||||
FS.writeFile("/server_info.json", new Uint8Array(server_file));
|
||||
update_status("Decrypting");
|
||||
Module.callMain(["server_info.json"]);
|
||||
update_status("Patching domain");
|
||||
const data = FS.readFile("/server_info.json", {encoding: 'utf8'});
|
||||
const currentData = JSON.parse(data);
|
||||
const currentDomain = currentData.domain;
|
||||
const newData = data.split(currentDomain).join(newDomain);
|
||||
FS.writeFile("/server_info.json", newData);
|
||||
update_status("Encrypting");
|
||||
Module.callMain(["-e", "-j", "server_info.json"]);
|
||||
const new_server_info = FS.readFile("/server_info.json");
|
||||
|
||||
let type;
|
||||
let ext;
|
||||
update_status("Applying changes");
|
||||
if (android) {
|
||||
let server_info = await zip.file("assets/AppAssets.zip").async("arraybuffer");
|
||||
const zip2 = new JSZip();
|
||||
await zip2.loadAsync(server_info);
|
||||
zip2.file("config/server_info.json", new_server_info);
|
||||
|
||||
for (let i=0; i<postPatches.length; i++) {
|
||||
let file = postPatches[i];
|
||||
console.log("Downloading patch", file.path);
|
||||
let res = await fetch(file.path);
|
||||
if (!res.ok) {
|
||||
console.warn("Error downloading patch");
|
||||
continue;
|
||||
}
|
||||
zip2.file(basePath + file.outpath, await res.blob());
|
||||
}
|
||||
|
||||
const appAssets = await zip2.generateAsync({type: "uint8array"});
|
||||
zip.file("assets/AppAssets.zip", appAssets);
|
||||
zip.file("assets/version", "MD5 (AppAssets.zip) = " + CryptoJS.MD5(appAssets).toString());
|
||||
type = "application/vnd.android.package-archive";
|
||||
ext = "apk";
|
||||
} else {
|
||||
zip.file("Payload/LoveLive.app/ProjectResources/config/server_info.json", new_server_info);
|
||||
type = "application/octet-stream";
|
||||
ext = "ipa";
|
||||
}
|
||||
let finalized = await zip.generateAsync({type: "uint8array"});
|
||||
update_status("Finalizing");
|
||||
const downloadUrl = URL.createObjectURL(new Blob([finalized], {type: type}));
|
||||
const b = document.createElement("a");
|
||||
b.href = URL.createObjectURL(new Blob([new_server_info], {type: "application/json"}))
|
||||
b.innerText = "Download patched server_info.json (you probably dont need this)";
|
||||
b.download = "server_info.json";
|
||||
document.body.appendChild(b);
|
||||
|
||||
document.body.appendChild(document.createElement("br"));
|
||||
document.body.appendChild(document.createElement("br"));
|
||||
|
||||
const a = document.createElement("a");
|
||||
a.href = downloadUrl;
|
||||
a.innerText = "Download";
|
||||
a.download = "lovelive-patched."+ext;
|
||||
document.body.appendChild(a);
|
||||
update_status("Done!");
|
||||
if (android) {
|
||||
const p = document.createElement("p");
|
||||
p.innerHTML = "Package is not signed. Using <a href=\"https://github.com/patrickfav/uber-apk-signer/releases\">uber-apk-signer</a>, sign it with the command `java -jar uber-apk-signer-<version>.jar -a lovelive.apk`.";
|
||||
document.body.appendChild(p);
|
||||
}
|
||||
}
|
||||
|
||||
function init_honoka(file, android, newDomain, patches) {
|
||||
window.Module = {
|
||||
noInitialRun: true,
|
||||
onRuntimeInitialized: async function() {
|
||||
try {
|
||||
await onloaded();
|
||||
await patch(file, android, newDomain, patches);
|
||||
} catch(e) {
|
||||
console.warn(e);
|
||||
document.getElementById("status").innerText = "It didnt work. Are your files/options invalid?";
|
||||
}
|
||||
},
|
||||
|
49
patches.json
Normal file
49
patches.json
Normal file
@ -0,0 +1,49 @@
|
||||
[
|
||||
{
|
||||
"id": "english",
|
||||
"description": "Force the language to english",
|
||||
"android": false,
|
||||
"ios": true,
|
||||
"checked": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "patches/english/language.lua",
|
||||
"outpath": "common/language.lua"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "enable_serial_code",
|
||||
"description": "Enable serial code in settings menu",
|
||||
"android": false,
|
||||
"ios": true,
|
||||
"checked": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "patches/serial_code/model.lua",
|
||||
"outpath": "m_menu/model.lua"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "restore_title_screen_song",
|
||||
"description": "Enable the title screen music",
|
||||
"android": false,
|
||||
"ios": true,
|
||||
"checked": true,
|
||||
"files": [
|
||||
{
|
||||
"path": "patches/restore_title_screen_song/assets/sound/login/startup_aq_1.mp3",
|
||||
"outpath": "assets/sound/login/startup_aq_1.mp3"
|
||||
},
|
||||
{
|
||||
"path": "patches/restore_title_screen_song/assets/sound/login/startup_mu_1.mp3",
|
||||
"outpath": "assets/sound/login/startup_mu_1.mp3"
|
||||
},
|
||||
{
|
||||
"path": "patches/restore_title_screen_song/m_login/start.lua",
|
||||
"outpath": "m_login/start.lua"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
BIN
patches/english/language.lua
Normal file
BIN
patches/english/language.lua
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
patches/restore_title_screen_song/m_login/start.lua
Normal file
BIN
patches/restore_title_screen_song/m_login/start.lua
Normal file
Binary file not shown.
BIN
patches/serial_code/model.lua
Normal file
BIN
patches/serial_code/model.lua
Normal file
Binary file not shown.
Reference in New Issue
Block a user