From b9b9ad2594fb320d8b73e07030bc21a0395b7c2a Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Fri, 31 May 2024 21:22:26 +0800 Subject: [PATCH] Fix various bugs, add loads of NoReflect classes, tracer hack mod --- ExampleMods/tracers.js | 214 +++++++++++++++++++++++++++++++++++++++++ NoReflect/generate.js | 100 +++++++++++-------- NoReflect/index.html | 91 +++++++++++++++++- NoReflect/javaRecon.js | 19 +++- 4 files changed, 378 insertions(+), 46 deletions(-) create mode 100644 ExampleMods/tracers.js diff --git a/ExampleMods/tracers.js b/ExampleMods/tracers.js new file mode 100644 index 0000000..aaf72d2 --- /dev/null +++ b/ExampleMods/tracers.js @@ -0,0 +1,214 @@ +//Tracer hack w/ NoReflect +ModAPI.require("player"); + +//init function +function initTracers() { + //Get necessary classes and store them + const classes = { + EntityPlayerSP: ModAPI.reflect.getClassByName("EntityPlayerSP"), + EntityPlayer: ModAPI.reflect.getClassByName("EntityPlayer"), + EntityItem: ModAPI.reflect.getClassByName("EntityItem"), + EntityAnimal: ModAPI.reflect.getClassByName("EntityAnimal"), + EntityMob: ModAPI.reflect.getClassByName("EntityMob"), + GlStateManager: ModAPI.reflect.getClassByName("GlStateManager"), + EaglercraftGPU: ModAPI.reflect.getClassByName("EaglercraftGPU"), + MathHelper: ModAPI.reflect.getClassByName("MathHelper"), + EntityRenderer: ModAPI.reflect.getClassByName("EntityRenderer"), + Tessellator: ModAPI.reflect.getClassByName("Tessellator"), + WorldRenderer: ModAPI.reflect.getClassByName("WorldRenderer") + }; + + //Get the vertex format for 'POSITION' + const positionVertexFormat = ModAPI.reflect.getClassByName("VertexFormat").class.$platformClass.$$enumConstants$$().data[5]; + + //Utility functions for type checking + function isEntityPlayerSP(obj) { + return classes.EntityPlayerSP.isObjInstanceOf({ obj: obj }); + } + + function isEntityPlayer(obj) { + return classes.EntityPlayer.isObjInstanceOf({ obj: obj }); + } + + function isEntityItem(obj) { + return classes.EntityItem.isObjInstanceOf({ obj: obj }); + } + + function isEntityAnimal(obj) { + return classes.EntityAnimal.isObjInstanceOf({ obj: obj }); + } + + function isEntityMob(obj) { + return classes.EntityMob.isObjInstanceOf({ obj: obj }); + } + + + //Utility functions for running methods on classes/instances of classes + function glFunction(name, args) { + return classes.GlStateManager.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + function gpuFunction(name, args) { + return classes.EaglercraftGPU.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + function entityRendererFunction(name, args) { + return classes.EntityRenderer.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + function mathHelperFunction(name, args) { + return classes.MathHelper.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + function tessellatorFunction(name, args) { + return classes.Tessellator.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + function worldRendererFunction(name, args) { + return classes.WorldRenderer.methods.filter((method) => { + return method.methodName === name + })[0].exec(args); + } + + + //Function to get the player's look vector (position right in front of their nose) + function getClientLookVec() { + var f = mathHelperFunction("cos", {value: -ModAPI.player.rotationYaw * 0.017453292 - Math.PI}); + var f1 = mathHelperFunction("sin", {parFloat1: -ModAPI.player.rotationYaw * 0.017453292 - Math.PI}); + var f2 = -mathHelperFunction("cos", {value: -ModAPI.player.rotationPitch * 0.017453292}); + var f3 = mathHelperFunction("sin", {parFloat1: -ModAPI.player.rotationPitch * 0.017453292}); + return [f1 * f2, f3 + ModAPI.player.getEyeHeight(), f * f2]; + } + + //Function to draw a line between two poitns + function drawLine(start, end) { + //Get the tessellator by running Tessellator.getInstance() + var tessellator = tessellatorFunction("getInstance", {}); + + //Get the WorldRenderer instance by running tessellator.getWorldRenderer() + var worldrenderer = tessellatorFunction("getWorldRenderer", { + _self: tessellator + }); + + //Run worldrenderer.begin(3, positionVertexFormat) to start building the lines + worldRendererFunction("begin", { + _self: worldrenderer, + parInt1: 3, + parVertexFormat: positionVertexFormat + }); + + //Add the start position and end the vertex immediately. + worldRendererFunction("endVertex", { + _self: worldRendererFunction("pos", { + _self: worldrenderer, + parDouble1: start[0], + parDouble2: start[1], + parDouble3: start[2] + }) + }); + + //Add the start position and end the vertex immediately. + worldRendererFunction("endVertex", { + _self: worldRendererFunction("pos", { + _self: worldrenderer, + parDouble1: end[0], + parDouble2: end[1], + parDouble3: end[2] + }) + }); + + //Draw to screen + tessellatorFunction("draw", { + _self: tessellator + }); + } + + //Every time a frame is rendered + ModAPI.addEventListener("render", (event) => { + //Check if both the player and the world instance exist + if (ModAPI.player && ModAPI.mcinstance.$theWorld) { + //Store world and render manager + const world = ModAPI.mcinstance.$theWorld; + const renderManager = ModAPI.mcinstance.$renderManager; + + //Loop through loaded entities + for (let i = 0; i < world.$loadedEntityList.$array1.data.length; i++) { + const entity = world.$loadedEntityList.$array1.data[i]; + + //Checks to avoid tracing to self and invalid entities + if (!entity || isEntityPlayerSP(entity)) { + continue; + } + if (!(isEntityAnimal(entity) || isEntityItem(entity) || isEntityMob(entity) || isEntityPlayer(entity))) { + continue; + } + + //Temporarily disable view bobbing + var bobbing = ModAPI.mcinstance.$gameSettings.$viewBobbing; + ModAPI.mcinstance.$gameSettings.$viewBobbing = 0; + + //Update camera transform to remove view bobbing + entityRendererFunction("setupCameraTransform", { + partialTicks: event.partialTicks, + pass: 0 + }); + + //WebGL commands to disable depth-test & depth-write, as well as selecting a blend function and line width. + glFunction("blendFunc", { srcFactor: 770, dstFactor: 771 }); + glFunction("enableBlend", {}); + gpuFunction("glLineWidth", { f: 3.0 }); + glFunction("disableTexture2D", {}); + glFunction("disableDepth", {}); + glFunction("depthMask", { flagIn: false }); + + //Choose tracer color based on entity type. + if (isEntityPlayer(entity)) { + glFunction("color", { colorRed: 1, colorGreen: 0, colorBlue: 0, colorAlpha: 0.5 }); + } else if (isEntityAnimal(entity)) { + glFunction("color", { colorRed: 0, colorGreen: 0, colorBlue: 1, colorAlpha: 0.5 }); + } else if (isEntityMob(entity)) { + glFunction("color", { colorRed: 1, colorGreen: 1, colorBlue: 0, colorAlpha: 0.5 }); + } else if (isEntityItem(entity)) { + glFunction("color", { colorRed: 0, colorGreen: 1, colorBlue: 1, colorAlpha: 0.5 }); + } + + //Start is equal to the client look vector + var start = getClientLookVec(); + + //End is equal to the center of the entities' bounding box minus the render position. + var end = [ + ((entity.$boundingBox.$minX0 + entity.$boundingBox.$maxX0) / 2) - 0.05 - renderManager.$renderPosX, + ((entity.$boundingBox.$minY0 + entity.$boundingBox.$maxY0) / 2) - 0.05 - renderManager.$renderPosY, + ((entity.$boundingBox.$minZ0 + entity.$boundingBox.$maxZ0) / 2) - 0.05 - renderManager.$renderPosZ + ]; + + //Draw the line + drawLine(start, end); + + //Restore the gl state + glFunction("enableTexture2D", {}); + glFunction("depthMask", { flagIn: true }); + glFunction("enableDepth", {}); + glFunction("disableBlend", {}); + + //Restore view bobbing + ModAPI.mcinstance.$gameSettings.$viewBobbing = bobbing; + entityRendererFunction("setupCameraTransform", { + partialTicks: event.partialTicks, + pass: 0 + }); + } + } + }); +} +initTracers(); \ No newline at end of file diff --git a/NoReflect/generate.js b/NoReflect/generate.js index ca9b076..355b374 100644 --- a/NoReflect/generate.js +++ b/NoReflect/generate.js @@ -1,52 +1,60 @@ const templateClassdef = ` -//CLASSDEF FOR %classname% -BaseData reflect_%classname% = new ModData(); + //classdef for %classname% + public static void reflect_%classname%_generator(ArrayList reflectProfiles) { + BaseData reflect_%classname% = new ModData(); -ArrayList reflect_%classname%_constructors = new ArrayList(); -%constructordefs% -BaseData[] reflect_%classname%_constructors_arr = new BaseData[reflect_%classname%_constructors.size()]; -for (int i = 0; i < reflect_%classname%_constructors_arr.length; i++) { - reflect_%classname%_constructors_arr[i] = reflect_%classname%_constructors.get(i); -} + ArrayList reflect_%classname%_constructors = new ArrayList(); + %constructordefs% + BaseData[] reflect_%classname%_constructors_arr = new BaseData[reflect_%classname%_constructors.size()]; + for (int i = 0; i < reflect_%classname%_constructors_arr.length; i++) { + reflect_%classname%_constructors_arr[i] = reflect_%classname%_constructors.get(i); + } -ArrayList reflect_%classname%_methods = new ArrayList(); -%methoddefs% -BaseData[] reflect_%classname%_methods_arr = new BaseData[reflect_%classname%_methods.size()]; -for (int i = 0; i < reflect_%classname%_methods_arr.length; i++) { - reflect_%classname%_methods_arr[i] = reflect_%classname%_methods.get(i); -} + ArrayList reflect_%classname%_methods = new ArrayList(); + %methoddefs% + BaseData[] reflect_%classname%_methods_arr = new BaseData[reflect_%classname%_methods.size()]; + 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%"); -reflect_%classname%.set("classId", "%classid%"); -reflect_%classname%.set("class", %classname%.class); -reflectProfiles.add(reflect_%classname%); + reflect_%classname%.set("constructors", reflect_%classname%_constructors_arr); + reflect_%classname%.set("methods", reflect_%classname%_methods_arr); + reflect_%classname%.set("className", "%classname%"); + reflect_%classname%.set("classId", "%classid%"); + reflect_%classname%.set("class", %classname%.class); + reflect_%classname%.setCallbackBooleanWithDataArg("isObjInstanceOf", (args)->{ + return args.getReflective("obj") instanceof %classname%; + }); + 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%); -reflect_%classname%_constructor_%constructorname%_%idx%.%constructorimpl% -reflect_%classname%_constructors.add(reflect_%classname%_constructor_%constructorname%_%idx%); + 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%); + reflect_%classname%_constructor_%constructorname%_%idx%.%constructorimpl% + reflect_%classname%_constructors.add(reflect_%classname%_constructor_%constructorname%_%idx%); `; const templateMethod = ` -BaseData reflect_%classname%_method_%methodname%_%idx% = new ModData(); -reflect_%classname%_method_%methodname%_%idx%.set("methodName", "%methodname%"); -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%); + BaseData reflect_%classname%_method_%methodname%_%idx% = new ModData(); + reflect_%classname%_method_%methodname%_%idx%.set("methodName", "%methodname%"); + 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 classDefCallTemplate = ` PLReflect.reflect_%classname%_generator(reflectProfiles); +`; const templateManager = ` import net.eaglerforge.api.*; import java.util.ArrayList; @@ -55,14 +63,24 @@ import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; import org.teavm.jso.JSFunctor; -//AUTOGENERATED BY NOREFLECT +// _ _ ___ __ _ _ +// | \\| |___| _ \\___ / _| |___ __| |_ +// | .\` / _ \\ / -_) _| / -_) _| _| +// |_|\\_\\___/_|_\\___|_| |_\\___\\__|\\__| +// _________________________________ + + +//AutoGenerated by NoReflect //Made by ZXMushroom63 public class PLReflect extends ModData { + %classdefs% + public static PLReflect makeModData() { PLReflect plReflectGlobal = new PLReflect(); ArrayList reflectProfiles = new ArrayList(); - %classdefs% + +%classdefcalls% BaseData[] reflectProfilesArr = new BaseData[reflectProfiles.size()]; for (int i = 0; i < reflectProfilesArr.length; i++) { reflectProfilesArr[i] = reflectProfiles.get(i); @@ -127,6 +145,7 @@ function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) { var imports = []; var classText = ""; + var classCallText = ""; var classes = Object.keys(dataDump); for (let i = 0; i < classes.length; i++) { const className = classes[i]; @@ -182,7 +201,7 @@ function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) { 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("%returntype%", "\""+method.returnType+"\""); tmpMethodText = tmpMethodText.replaceAll("%argkeys%", `new String[]{${(()=>{ var txt = ""; var argumentKeys = Object.keys(method.arguments); @@ -214,6 +233,7 @@ function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) { tmpClassText = tmpClassText.replaceAll("%methoddefs%", methodText); classText += tmpClassText; + classCallText += classDefCallTemplate.replaceAll("%classname%", className); } for (let i = 0; i < config.imports.length; i++) { manager = `import ${config.imports[i]}` + ";\n" + manager; @@ -232,6 +252,7 @@ function createManagerFile(managerTemplate, config, zip, dataDump, classIdMap) { manager = `package ${config.managerFile.match(/(.*)(?=\.[^.]*$)/g)[0]}` + ";\n" + manager; manager = manager.replaceAll("%classdefs%", classText); + manager = manager.replaceAll("%classdefcalls%", classCallText); zip.file(filePath, manager); } @@ -247,7 +268,10 @@ async function generate(fileList) { return; } try { - cfg = JSON.parse(document.querySelector("#config").value.trim()); + var cfgString = document.querySelector("#config").value.trim(); + cfgString = cfgString.replace(/\/\/.*$/gm, ''); + cfgString = cfgString.replace(/\/\*[\s\S]*?\*\//gm, ''); + cfg = JSON.parse(cfgString); } catch (e) { logTxt("[ERROR] Invalid config."); return; diff --git a/NoReflect/index.html b/NoReflect/index.html index 9d04370..12c34a6 100644 --- a/NoReflect/index.html +++ b/NoReflect/index.html @@ -97,16 +97,97 @@