From 348003e4d634922d7a9ec2d6108795bec776ac85 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Sun, 2 Jun 2024 14:33:19 +0800 Subject: [PATCH 1/4] Add ws blink mod that actually works --- ExampleMods/blink_ws.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ExampleMods/blink_ws.js diff --git a/ExampleMods/blink_ws.js b/ExampleMods/blink_ws.js new file mode 100644 index 0000000..1632ade --- /dev/null +++ b/ExampleMods/blink_ws.js @@ -0,0 +1,33 @@ +//Blink hack mod that prototype pollutes WebSocket to implement itself. + +var blinking = false; +var backlog = []; +const originalSend = WebSocket.prototype.send; + +Object.defineProperty(WebSocket.prototype, 'send', { + configurable: true, + enumerable: false, + writable: false, + value: function(data) { + if (blinking) { + backlog.push({data: data, thisArg: this}); + } else { + originalSend.call(this, data); + } + } +}); + + +ModAPI.addEventListener("key", (ev)=>{ + if (ev.key === 48) { + ev.preventDefault = true; + blinking = !blinking; + if (blinking === false) { + for (let i = 0; i < backlog.length; i++) { + const backlogItem = backlog[i]; + originalSend.call(backlogItem.thisArg, backlogItem.data); + } + backlog = []; + } + } +}); \ No newline at end of file From 521bce612a980df02dedbe8751c8e0b353b2cc0a Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Sun, 2 Jun 2024 14:36:08 +0800 Subject: [PATCH 2/4] Add comments --- ExampleMods/blink_ws.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ExampleMods/blink_ws.js b/ExampleMods/blink_ws.js index 1632ade..1263506 100644 --- a/ExampleMods/blink_ws.js +++ b/ExampleMods/blink_ws.js @@ -1,17 +1,24 @@ //Blink hack mod that prototype pollutes WebSocket to implement itself. +//Blinking state var blinking = false; + +//The backlog of packets that need to be sent on disable var backlog = []; + +//Store the original, actual WebSocket send method const originalSend = WebSocket.prototype.send; +//Override WebSocket.send, so when eagler tries to send messages, it runs our code instead Object.defineProperty(WebSocket.prototype, 'send', { configurable: true, enumerable: false, writable: false, value: function(data) { + //If blinking, push data to backlog along with it's websocket instance. if (blinking) { backlog.push({data: data, thisArg: this}); - } else { + } else { //Else send the data as normal originalSend.call(this, data); } } @@ -19,10 +26,11 @@ Object.defineProperty(WebSocket.prototype, 'send', { ModAPI.addEventListener("key", (ev)=>{ - if (ev.key === 48) { + if (ev.key === 48) { //KEY_B ev.preventDefault = true; - blinking = !blinking; - if (blinking === false) { + blinking = !blinking; //Toggle blinking boolean + + if (blinking === false) { //If blink just turned off, send data. for (let i = 0; i < backlog.length; i++) { const backlogItem = backlog[i]; originalSend.call(backlogItem.thisArg, backlogItem.data); From 51112a09ed372f9c18a0393a3d080a47cd0089f4 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Wed, 12 Jun 2024 15:36:57 +0800 Subject: [PATCH 3/4] Add simple noreflect wrapper fn generator --- NoReflect/generate.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NoReflect/generate.js b/NoReflect/generate.js index 355b374..bc955cc 100644 --- a/NoReflect/generate.js +++ b/NoReflect/generate.js @@ -74,10 +74,14 @@ import org.teavm.jso.JSFunctor; //Made by ZXMushroom63 public class PLReflect extends ModData { + @JSBody(params = { "reflectInst" }, script = "reflectInst.getMethodMapFromClass = function(classObj) {var outMethodMap = {}; classObj.methods.forEach(method=>{outMethodMap[method.methodName]=method;}); return outMethodMap;}") + public static native BaseData setMethodMapFn(BaseData reflectInst); + %classdefs% public static PLReflect makeModData() { PLReflect plReflectGlobal = new PLReflect(); + setMethodMapFn(plReflectGlobal); ArrayList reflectProfiles = new ArrayList(); %classdefcalls% From e718d154393b1a201a9dbcdc416aaa54af3402cf Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Wed, 12 Jun 2024 16:01:10 +0800 Subject: [PATCH 4/4] Update tracers.js to use new method maps --- ExampleMods/tracers.js | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/ExampleMods/tracers.js b/ExampleMods/tracers.js index aaf72d2..c055c75 100644 --- a/ExampleMods/tracers.js +++ b/ExampleMods/tracers.js @@ -18,6 +18,15 @@ function initTracers() { WorldRenderer: ModAPI.reflect.getClassByName("WorldRenderer") }; + //Build a method map object, to avoid searching for methods multiple times over. + const methodMaps = {}; + var usedClasses = Object.keys(classes); + usedClasses.forEach((className)=>{ + methodMaps[className] = ModAPI.reflect.getMethodMapFromClass(classes[className]); + }); + + console.log(methodMaps); + //Get the vertex format for 'POSITION' const positionVertexFormat = ModAPI.reflect.getClassByName("VertexFormat").class.$platformClass.$$enumConstants$$().data[5]; @@ -43,41 +52,29 @@ function initTracers() { } - //Utility functions for running methods on classes/instances of classes + //Utility functions for running methods on classes/instances of classes by referencing the created methodMaps object. function glFunction(name, args) { - return classes.GlStateManager.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["GlStateManager"][name].exec(args); } function gpuFunction(name, args) { - return classes.EaglercraftGPU.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["EaglercraftGPU"][name].exec(args); } function entityRendererFunction(name, args) { - return classes.EntityRenderer.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["EntityRenderer"][name].exec(args); } function mathHelperFunction(name, args) { - return classes.MathHelper.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["MathHelper"][name].exec(args); } function tessellatorFunction(name, args) { - return classes.Tessellator.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["Tessellator"][name].exec(args); } function worldRendererFunction(name, args) { - return classes.WorldRenderer.methods.filter((method) => { - return method.methodName === name - })[0].exec(args); + return methodMaps["WorldRenderer"][name].exec(args); }