NoReflect: Static functions, autoimports, sparse inclusion

This commit is contained in:
ZXMushroom63 2024-05-22 17:15:24 +08:00
parent b4da547505
commit 9576c62734
3 changed files with 76 additions and 18 deletions

View File

@ -82,26 +82,26 @@ function process(file, reader, classDataDump, className) {
reader.addEventListener("load", ()=>{ reader.addEventListener("load", ()=>{
var output = reader.result; var output = reader.result;
classDataDump[className] = (reconJ(output, className)); classDataDump[className] = (reconJ(output, className));
console.log(classDataDump[className].usedClasses);
res(output); res(output);
}); });
reader.readAsText(file); reader.readAsText(file);
}); });
} }
function createManagerFile(managerTemplate, config, zip, dataDump) { function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) {
var manager = managerTemplate; var manager = managerTemplate;
var filePath = config.managerFile.replaceAll(".", "/") + ".java"; var filePath = config.managerFile.replaceAll(".", "/") + ".java";
for (let i = 0; i < config.targetFiles.length; i++) { for (let i = 0; i < config.targetFiles.length; i++) {
manager = `import ${config.targetFiles[i]}` + ";\n" + manager; manager = `import ${config.targetFiles[i]}` + ";\n" + manager;
} }
manager = `package ${config.managerFile.match(/(.*)(?=\.[^.]*$)/g)[0]}` + ";\n" + manager; var imports = [];
var classText = ""; var classText = "";
var classes = Object.keys(dataDump); var classes = Object.keys(dataDump);
for (let i = 0; i < classes.length; i++) { for (let i = 0; i < classes.length; i++) {
const className = classes[i]; const className = classes[i];
imports = [...new Set(imports.concat(dataDump[className].usedClasses))];
var tmpClassText = templateClassdef; var tmpClassText = templateClassdef;
tmpClassText = tmpClassText.replaceAll("%classname%", className); tmpClassText = tmpClassText.replaceAll("%classname%", className);
@ -179,21 +179,39 @@ function createManagerFile(managerTemplate, config, zip, dataDump) {
tmpMethodText = tmpMethodText.replaceAll("%methodimpl%", method.impl); tmpMethodText = tmpMethodText.replaceAll("%methodimpl%", method.impl);
methodText += tmpMethodText; methodText += tmpMethodText;
} }
tmpClassText = tmpClassText.replaceAll("%methoddefs%", methodText); tmpClassText = tmpClassText.replaceAll("%methoddefs%", methodText);
classText += tmpClassText; classText += tmpClassText;
} }
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;
manager = manager.replaceAll("%classdefs%", classText); manager = manager.replaceAll("%classdefs%", classText);
zip.file(filePath, manager); zip.file(filePath, manager);
} }
async function generate(fileList) { async function generate(fileList) {
var classToLocationMap = new Map();
var cfg; var cfg;
var output = new JSZip(); var output = new JSZip();
const reader = new FileReader(); const reader = new FileReader();
var classDataDump = {}; var classDataDump = {};
logClear(); logClear();
logTxt("[LOG] Build @ "+(new Date())); logTxt("[INIT] Build @ "+(new Date()));
if (!fileList || fileList.length === 0) { if (!fileList || fileList.length === 0) {
logTxt("[ERROR] Filelist is empty.") logTxt("[ERROR] Filelist is empty.")
return; return;
@ -212,14 +230,22 @@ async function generate(fileList) {
if (file.webkitRelativePath.endsWith(".java")) { if (file.webkitRelativePath.endsWith(".java")) {
var classId = file.webkitRelativePath.replaceAll("java/", "").replaceAll(".java", "").replaceAll("/", "."); var classId = file.webkitRelativePath.replaceAll("java/", "").replaceAll(".java", "").replaceAll("/", ".");
var className = classId.split(".")[classId.split(".").length - 1]; var className = classId.split(".")[classId.split(".").length - 1];
classToLocationMap.set(className, classId);
if (cfg.targetFiles.includes(classId)) { if (cfg.targetFiles.includes(classId)) {
logTxt("Found "+classId+" ["+file.name+"], processing..."); logTxt("Found "+classId+" ["+file.name+"], processing...");
output.file(file.webkitRelativePath.replaceAll("java/", ""), await process(file, reader, classDataDump, className)); var javaFileContent = await process(file, reader, classDataDump, className);
if (cfg.includeReadFiles) {
output.file(file.webkitRelativePath.replaceAll("java/", ""), javaFileContent);
}
} }
} }
} }
logTxt(`Creating manager file...`);
createManagerFile(templateManager, cfg, output, classDataDump, classToLocationMap);
logTxt(`Writing log.txt...`);
output.file("log.txt", document.querySelector("#logs").innerText); output.file("log.txt", document.querySelector("#logs").innerText);
createManagerFile(templateManager, cfg, output, classDataDump);
output.generateAsync({type:"blob"}).then(function(content) { output.generateAsync({type:"blob"}).then(function(content) {
saveAs(content, "patch.zip"); saveAs(content, "patch.zip");
}); });

View File

@ -21,6 +21,7 @@
text-shadow: 0px 0px 3px; text-shadow: 0px 0px 3px;
min-height: 10rem; min-height: 10rem;
min-width: 50rem; min-width: 50rem;
font-size: 0.8rem;
} }
textarea:focus { textarea:focus {
outline: 0; outline: 0;
@ -56,22 +57,52 @@
color: orange; color: orange;
text-shadow: 0px 0px 2px; text-shadow: 0px 0px 2px;
} }
.crt::after {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(18, 16, 16, 0.1);
opacity: 0;
z-index: 2;
pointer-events: none;
}
.crt::before {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
z-index: 2;
background-size: 100% 2px, 3px 100%;
pointer-events: none;
}
</style> </style>
<script src="FileSaver.js"></script> <script src="FileSaver.js"></script>
<script src="jszip.min.js"></script> <script src="jszip.min.js"></script>
<script src="javaRecon.js"></script> <script src="javaRecon.js"></script>
<script src="generate.js"></script> <script src="generate.js"></script>
</head> </head>
<body> <body class="crt">
<h1>> NoReflect Generator WebUI</h1> <h1>> NoReflect Generator WebUI</h1>
<br> <br>
<span>Config</span> <span>Config</span>
<br> <br>
<textarea id="config"> <textarea id="config" spellcheck="false">
{ {
"targetFiles": ["net.minecraft.item.ItemStack"], "targetFiles": ["net.minecraft.item.ItemStack", "net.minecraft.client.Minecraft"],
"managerFile": "net.eaglerforge.reflect.PLReflect" "imports": ["java.lang.String"],
} "managerFile": "net.eaglerforge.reflect.PLReflect",
"includeReadFiles": false,
"attemptAutoImport": true
}
</textarea> </textarea>
<br><br> <br><br>
<input id="data" type="file" webkitdirectory> <input id="data" type="file" webkitdirectory>

View File

@ -103,22 +103,22 @@ function reconJ(java, className) {
argStr += ", " argStr += ", "
} }
} }
let prefix = isStatic ? className : `((${className}) params.get("_self"))`;
let impl; let impl;
if (returnType === "void") { if (returnType === "void") {
impl = `setCallbackVoidWithArgs("${methodName}", (BaseData params) -> { impl = `setCallbackVoidWithArgs("${methodName}", (BaseData params) -> {
((${className}) params.get("_self")).${methodName}(${argStr}); ${prefix}.${methodName}(${argStr});
}); });
`; `;
} else if (callbackStatementsTypes.includes(returnType)) { } else if (callbackStatementsTypes.includes(returnType)) {
impl = `${callbackStatements[returnType]}("${methodName}", (BaseData params) -> { impl = `${callbackStatements[returnType]}("${methodName}", (BaseData params) -> {
return (${returnType}) ((${className}) params.get("_self")).${methodName}(${argStr}); return (${returnType}) ${prefix}.${methodName}(${argStr});
}); });
`; `;
} else { } else {
usedClasses.push(returnType); usedClasses.push(returnType);
impl = `setCallbackReflectiveWithArgs("${methodName}", (BaseData params) -> { impl = `setCallbackReflectiveWithArgs("${methodName}", (BaseData params) -> {
return (${returnType}) ((${className}) params.get("_self")).${methodName}(${argStr}); return (${returnType}) ${prefix}.${methodName}(${argStr});
}); });
`; `;
} }
@ -129,7 +129,8 @@ function reconJ(java, className) {
returnType: returnType, returnType: returnType,
isStatic: isStatic, isStatic: isStatic,
arguments: arguments, arguments: arguments,
impl: impl impl: impl,
idx: methods.indexOf(method)
}; };
}); });
return { return {