2024-05-21 06:07:24 -05:00
|
|
|
const templateClassdef = `
|
|
|
|
//CLASSDEF FOR %classname%
|
|
|
|
BaseData reflect_%classname% = new ModData();
|
|
|
|
|
|
|
|
ArrayList<BaseData> reflect_%classname%_constructors = new ArrayList<BaseData>();
|
|
|
|
%constructordefs%
|
2024-05-24 03:39:34 -05:00
|
|
|
BaseData[] reflect_%classname%_constructors_arr = new BaseData[reflect_%classname%_constructors.size()];
|
2024-05-21 06:07:24 -05:00
|
|
|
for (int i = 0; i < reflect_%classname%_constructors_arr.length; i++) {
|
|
|
|
reflect_%classname%_constructors_arr[i] = reflect_%classname%_constructors.get(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
ArrayList<BaseData> reflect_%classname%_methods = new ArrayList<BaseData>();
|
|
|
|
%methoddefs%
|
2024-05-24 03:39:34 -05:00
|
|
|
BaseData[] reflect_%classname%_methods_arr = new BaseData[reflect_%classname%_methods.size()];
|
2024-05-21 06:07:24 -05:00
|
|
|
for (int i = 0; i < reflect_%classname%_methods_arr.length; i++) {
|
|
|
|
reflect_%classname%_methods_arr[i] = reflect_%classname%_methods.get(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
reflect_%classname%.set("constructors", reflect_%classname%_constructors_arr);
|
|
|
|
reflect_%classname%.set("methods", reflect_%classname%_methods_arr);
|
|
|
|
reflect_%classname%.set("className", "%classname%");
|
2024-05-27 03:02:40 -05:00
|
|
|
reflect_%classname%.set("classId", "%classid%");
|
2024-05-22 04:22:08 -05:00
|
|
|
reflect_%classname%.set("class", %classname%.class);
|
2024-05-21 06:07:24 -05:00
|
|
|
reflectProfiles.add(reflect_%classname%);
|
|
|
|
|
|
|
|
`;
|
|
|
|
//IXCVVIX
|
|
|
|
//CXVIIVX
|
|
|
|
//MVVMCXI
|
|
|
|
const templateConstructor = `
|
|
|
|
BaseData reflect_%classname%_constructor_%constructorname%_%idx% = new ModData();
|
|
|
|
reflect_%classname%_constructor_%constructorname%_%idx%.set("returnType", %returntype%);
|
|
|
|
reflect_%classname%_constructor_%constructorname%_%idx%.set("argnames", %argkeys%);
|
|
|
|
reflect_%classname%_constructor_%constructorname%_%idx%.set("argtypes", %argvalues%);
|
2024-05-24 03:39:34 -05:00
|
|
|
reflect_%classname%_constructor_%constructorname%_%idx%.%constructorimpl%
|
2024-05-21 06:07:24 -05:00
|
|
|
reflect_%classname%_constructors.add(reflect_%classname%_constructor_%constructorname%_%idx%);
|
|
|
|
|
|
|
|
`;
|
|
|
|
const templateMethod = `
|
|
|
|
BaseData reflect_%classname%_method_%methodname%_%idx% = new ModData();
|
2024-05-21 19:04:52 -05:00
|
|
|
reflect_%classname%_method_%methodname%_%idx%.set("methodName", "%methodname%");
|
2024-05-21 06:07:24 -05:00
|
|
|
reflect_%classname%_method_%methodname%_%idx%.set("returnType", %returntype%);
|
|
|
|
reflect_%classname%_method_%methodname%_%idx%.set("static", %static%);
|
|
|
|
reflect_%classname%_method_%methodname%_%idx%.set("argnames", %argkeys%);
|
|
|
|
reflect_%classname%_method_%methodname%_%idx%.set("argtypes", %argvalues%);
|
|
|
|
reflect_%classname%_method_%methodname%_%idx%.%methodimpl%
|
|
|
|
reflect_%classname%_methods.add(reflect_%classname%_method_%methodname%_%idx%);
|
|
|
|
|
|
|
|
`;
|
|
|
|
const templateManager = `
|
|
|
|
import net.eaglerforge.api.*;
|
|
|
|
import java.util.ArrayList;
|
2024-05-24 03:39:34 -05:00
|
|
|
import java.lang.Exception;
|
2024-05-27 03:02:40 -05:00
|
|
|
import org.teavm.jso.JSBody;
|
|
|
|
import org.teavm.jso.JSObject;
|
|
|
|
import org.teavm.jso.JSFunctor;
|
2024-05-24 03:39:34 -05:00
|
|
|
|
|
|
|
//AUTOGENERATED BY NOREFLECT
|
|
|
|
//Made by ZXMushroom63
|
|
|
|
|
2024-05-27 03:02:40 -05:00
|
|
|
public class PLReflect extends ModData {
|
|
|
|
public static PLReflect makeModData() {
|
|
|
|
PLReflect plReflectGlobal = new PLReflect();
|
2024-05-21 06:07:24 -05:00
|
|
|
ArrayList<BaseData> reflectProfiles = new ArrayList<BaseData>();
|
|
|
|
%classdefs%
|
|
|
|
BaseData[] reflectProfilesArr = new BaseData[reflectProfiles.size()];
|
|
|
|
for (int i = 0; i < reflectProfilesArr.length; i++) {
|
|
|
|
reflectProfilesArr[i] = reflectProfiles.get(i);
|
|
|
|
}
|
|
|
|
plReflectGlobal.set("classes", reflectProfilesArr);
|
2024-05-27 03:02:40 -05:00
|
|
|
|
|
|
|
plReflectGlobal.setCallbackClassFinder("getClassByName", (String className)->{
|
|
|
|
for (int i = 0; i < reflectProfilesArr.length; i++) {
|
|
|
|
if (reflectProfilesArr[i].getString("className").equals(className)) {
|
|
|
|
return reflectProfilesArr[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
|
|
|
|
plReflectGlobal.setCallbackClassFinder("getClassById", (String classId)->{
|
|
|
|
for (int i = 0; i < reflectProfilesArr.length; i++) {
|
|
|
|
if (reflectProfilesArr[i].getString("classId").equals(classId)) {
|
|
|
|
return reflectProfilesArr[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
return plReflectGlobal;
|
|
|
|
}
|
|
|
|
}`;
|
|
|
|
function wait(d) {
|
|
|
|
return new Promise((res, rej)=>{
|
|
|
|
setTimeout(()=>{res()}, d*1000);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function logClear() {
|
|
|
|
document.querySelector("#logs").innerText = "";
|
|
|
|
}
|
|
|
|
function logTxt(txt) {
|
|
|
|
if (document.querySelector("#logs").innerText === "") {
|
|
|
|
document.querySelector("#logs").innerText += txt;
|
|
|
|
} else {
|
|
|
|
document.querySelector("#logs").innerText += "\n" + txt;
|
|
|
|
}
|
|
|
|
document.querySelector("#logs").scrollTop = document.querySelector("#logs").scrollHeight;
|
|
|
|
}
|
2024-05-27 03:02:40 -05:00
|
|
|
function process(file, reader, classDataDump, className, classId) {
|
2024-05-21 06:07:24 -05:00
|
|
|
return new Promise((res, rej)=>{
|
|
|
|
reader.addEventListener("load", ()=>{
|
|
|
|
var output = reader.result;
|
|
|
|
classDataDump[className] = (reconJ(output, className));
|
2024-05-27 03:02:40 -05:00
|
|
|
classDataDump[className].classId = classId;
|
2024-05-21 06:07:24 -05:00
|
|
|
res(output);
|
|
|
|
});
|
|
|
|
reader.readAsText(file);
|
|
|
|
});
|
|
|
|
}
|
2024-05-22 04:15:24 -05:00
|
|
|
function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) {
|
2024-05-21 06:07:24 -05:00
|
|
|
var manager = managerTemplate;
|
|
|
|
var filePath = config.managerFile.replaceAll(".", "/") + ".java";
|
|
|
|
|
|
|
|
for (let i = 0; i < config.targetFiles.length; i++) {
|
2024-05-21 19:04:52 -05:00
|
|
|
manager = `import ${config.targetFiles[i]}` + ";\n" + manager;
|
2024-05-21 06:07:24 -05:00
|
|
|
}
|
2024-05-22 04:15:24 -05:00
|
|
|
var imports = [];
|
2024-05-21 06:07:24 -05:00
|
|
|
|
|
|
|
var classText = "";
|
|
|
|
var classes = Object.keys(dataDump);
|
|
|
|
for (let i = 0; i < classes.length; i++) {
|
|
|
|
const className = classes[i];
|
2024-05-22 04:15:24 -05:00
|
|
|
imports = [...new Set(imports.concat(dataDump[className].usedClasses))];
|
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
var tmpClassText = templateClassdef;
|
|
|
|
tmpClassText = tmpClassText.replaceAll("%classname%", className);
|
2024-05-27 03:02:40 -05:00
|
|
|
tmpClassText = tmpClassText.replaceAll("%classid%", dataDump[className].classId);
|
2024-05-21 06:07:24 -05:00
|
|
|
|
|
|
|
var constructorText = "";
|
|
|
|
for (let i = 0; i < dataDump[className].constructors.length; i++) {
|
|
|
|
const constructor = dataDump[className].constructors[i];
|
|
|
|
var tmpConstructorText = templateConstructor;
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%classname%", className);
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%idx%", constructor.idx);
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%constructorname%", constructor.name);
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%returntype%", "\""+className+"\"");
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%argkeys%", `new String[]{${(()=>{
|
|
|
|
var txt = "";
|
|
|
|
var argumentKeys = Object.keys(constructor.arguments);
|
|
|
|
for (let i = 0; i < argumentKeys.length; i++) {
|
|
|
|
const k = argumentKeys[i];
|
|
|
|
txt += `"${k}"`;
|
|
|
|
if (i !== argumentKeys.length - 1) {
|
|
|
|
txt += ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return txt;
|
|
|
|
})()}}`);
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%argvalues%", `new String[]{${(()=>{
|
|
|
|
var txt = "";
|
|
|
|
var argumentKeys = Object.keys(constructor.arguments);
|
|
|
|
for (let i = 0; i < argumentKeys.length; i++) {
|
|
|
|
const k = argumentKeys[i];
|
|
|
|
txt += `"${constructor.arguments[k]}"`;
|
|
|
|
if (i !== argumentKeys.length - 1) {
|
|
|
|
txt += ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return txt;
|
|
|
|
})()}}`);
|
|
|
|
tmpConstructorText = tmpConstructorText.replaceAll("%constructorimpl%", constructor.impl);
|
|
|
|
constructorText += tmpConstructorText;
|
|
|
|
}
|
|
|
|
tmpClassText = tmpClassText.replaceAll("%constructordefs%", constructorText);
|
|
|
|
|
2024-05-21 19:04:52 -05:00
|
|
|
|
|
|
|
var methodText = "";
|
|
|
|
for (let i = 0; i < dataDump[className].methods.length; i++) {
|
|
|
|
const method = dataDump[className].methods[i];
|
|
|
|
var tmpMethodText = templateMethod;
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%classname%", className);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%idx%", method.idx);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%static%", method.isStatic);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%methodname%", method.name);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%returntype%", "\""+className+"\"");
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%argkeys%", `new String[]{${(()=>{
|
|
|
|
var txt = "";
|
|
|
|
var argumentKeys = Object.keys(method.arguments);
|
|
|
|
for (let i = 0; i < argumentKeys.length; i++) {
|
|
|
|
const k = argumentKeys[i];
|
|
|
|
txt += `"${k}"`;
|
|
|
|
if (i !== argumentKeys.length - 1) {
|
|
|
|
txt += ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return txt;
|
|
|
|
})()}}`);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%argvalues%", `new String[]{${(()=>{
|
|
|
|
var txt = "";
|
|
|
|
var argumentKeys = Object.keys(method.arguments);
|
|
|
|
for (let i = 0; i < argumentKeys.length; i++) {
|
|
|
|
const k = argumentKeys[i];
|
|
|
|
txt += `"${method.arguments[k]}"`;
|
|
|
|
if (i !== argumentKeys.length - 1) {
|
|
|
|
txt += ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return txt;
|
|
|
|
})()}}`);
|
|
|
|
tmpMethodText = tmpMethodText.replaceAll("%methodimpl%", method.impl);
|
|
|
|
methodText += tmpMethodText;
|
|
|
|
}
|
2024-05-22 04:15:24 -05:00
|
|
|
|
2024-05-21 19:04:52 -05:00
|
|
|
tmpClassText = tmpClassText.replaceAll("%methoddefs%", methodText);
|
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
classText += tmpClassText;
|
|
|
|
}
|
2024-05-22 04:15:24 -05:00
|
|
|
for (let i = 0; i < config.imports.length; i++) {
|
|
|
|
manager = `import ${config.imports[i]}` + ";\n" + manager;
|
|
|
|
logTxt(`Force imported classid: ${config.imports[i]}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.attemptAutoImport) {
|
|
|
|
for (let i = 0; i < imports.length; i++) {
|
|
|
|
if (classIdMap.has(imports[i])) {
|
|
|
|
manager = `import ${classIdMap.get(imports[i])}` + ";\n" + manager;
|
|
|
|
logTxt(`Imported classid: ${classIdMap.get(imports[i])}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
manager = `package ${config.managerFile.match(/(.*)(?=\.[^.]*$)/g)[0]}` + ";\n" + manager;
|
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
manager = manager.replaceAll("%classdefs%", classText);
|
|
|
|
|
|
|
|
zip.file(filePath, manager);
|
|
|
|
}
|
|
|
|
async function generate(fileList) {
|
2024-05-22 04:15:24 -05:00
|
|
|
var classToLocationMap = new Map();
|
2024-05-21 06:07:24 -05:00
|
|
|
var cfg;
|
|
|
|
var output = new JSZip();
|
|
|
|
var classDataDump = {};
|
|
|
|
logClear();
|
2024-05-22 04:15:24 -05:00
|
|
|
logTxt("[INIT] Build @ "+(new Date()));
|
2024-05-21 06:07:24 -05:00
|
|
|
if (!fileList || fileList.length === 0) {
|
|
|
|
logTxt("[ERROR] Filelist is empty.")
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
cfg = JSON.parse(document.querySelector("#config").value.trim());
|
|
|
|
} catch (e) {
|
|
|
|
logTxt("[ERROR] Invalid config.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!cfg.targetFiles) {
|
|
|
|
logTxt("[ERROR] Invalid config.");
|
|
|
|
}
|
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
|
|
const file = fileList[i];
|
|
|
|
if (file.webkitRelativePath.endsWith(".java")) {
|
|
|
|
var classId = file.webkitRelativePath.replaceAll("java/", "").replaceAll(".java", "").replaceAll("/", ".");
|
|
|
|
var className = classId.split(".")[classId.split(".").length - 1];
|
2024-05-22 04:15:24 -05:00
|
|
|
classToLocationMap.set(className, classId);
|
2024-05-21 06:07:24 -05:00
|
|
|
if (cfg.targetFiles.includes(classId)) {
|
|
|
|
logTxt("Found "+classId+" ["+file.name+"], processing...");
|
2024-05-27 03:02:40 -05:00
|
|
|
var javaFileContent = await process(file, new FileReader(), classDataDump, className, classId);
|
2024-05-22 04:15:24 -05:00
|
|
|
if (cfg.includeReadFiles) {
|
|
|
|
output.file(file.webkitRelativePath.replaceAll("java/", ""), javaFileContent);
|
|
|
|
}
|
2024-05-21 06:07:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-24 03:39:34 -05:00
|
|
|
console.log(classDataDump);
|
2024-05-22 04:15:24 -05:00
|
|
|
logTxt(`Creating manager file...`);
|
|
|
|
createManagerFile(templateManager, cfg, output, classDataDump, classToLocationMap);
|
|
|
|
|
|
|
|
logTxt(`Writing log.txt...`);
|
2024-05-21 06:07:24 -05:00
|
|
|
output.file("log.txt", document.querySelector("#logs").innerText);
|
2024-05-22 04:15:24 -05:00
|
|
|
|
2024-05-21 06:07:24 -05:00
|
|
|
output.generateAsync({type:"blob"}).then(function(content) {
|
|
|
|
saveAs(content, "patch.zip");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
window.addEventListener("load", ()=>{
|
|
|
|
document.querySelector('#generate').addEventListener("click", ()=>{
|
|
|
|
generate(document.querySelector('#data').files);
|
|
|
|
});
|
|
|
|
logClear();
|
2024-05-22 04:34:59 -05:00
|
|
|
logTxt("//Upload the ./src/main/java folder and press generate to begin hook generation");
|
2024-05-21 06:07:24 -05:00
|
|
|
});
|