Add support for static properties

This commit is contained in:
ZXMushroom63 2024-08-24 23:07:32 +08:00
parent 574b478976
commit db6e60a196
3 changed files with 172 additions and 39 deletions

View File

@ -0,0 +1,5 @@
//Very much WIP, still firguring out how to poke the dedicated server.
(()=>{
//PluginAPI.javaClient.$timer.$timerSpeed = 4;
ModAPI.dedicatedServer.appendCode(`console.log(ModAPI.hooks._rippedStaticProperties[ModAPI.util.getCompiledNameFromPackage("net.lax1dude.eaglercraft.v1_8.sp.server.EaglerIntegratedServerWorker")].currentProcess)`);
})();

View File

@ -26,7 +26,7 @@
<h1>EaglerForge Injector</h1> <h1>EaglerForge Injector</h1>
<h4> <h4>
Adds ModAPI with more functionality (adds hooking into functions, exposes Adds ModAPI with more functionality (adds hooking into functions, exposes
all classes, etc) to unminified unobfuscated EaglercraftX and Eaglercraft all classes, etc) to unminified unobfuscated EaglercraftX
builds. builds.
</h4> </h4>
<br /> <br />
@ -203,6 +203,8 @@ ModAPI.hooks._rippedConstructors ||= {};
ModAPI.hooks.methods ||= {}; ModAPI.hooks.methods ||= {};
ModAPI.hooks._rippedMethodTypeMap ||= {}; ModAPI.hooks._rippedMethodTypeMap ||= {};
ModAPI.hooks._postInit ||= ()=>{}; ModAPI.hooks._postInit ||= ()=>{};
ModAPI.hooks._rippedStaticProperties ||= {};
ModAPI.hooks._rippedStaticIndexer ||= {};
`; `;
document.querySelector("#giveme").addEventListener("click", () => { document.querySelector("#giveme").addEventListener("click", () => {
if ( if (
@ -245,7 +247,9 @@ var main;(function(){`
patchedFile = patchedFile.replace( patchedFile = patchedFile.replace(
` id="game_frame">`, ` id="game_frame">`,
` id="game_frame">\<script id="modapi_postinit"\>${globalThis.modapi_postinit}\<\/script\>` ` id="game_frame">
\<script id="modapi_postinit"\>${globalThis.modapi_postinit}\<\/script\>
\<script id="modapi_postinit_data"\>globalThis.modapi_postinit = \`${globalThis.modapi_postinit}\`;\<\/script\>`
); );
const extractConstructorRegex = const extractConstructorRegex =
@ -272,8 +276,7 @@ var main;(function(){`
if ( if (
match.includes("__init_") || match.includes("__init_") ||
match.includes("__clinit_") || match.includes("__clinit_") ||
match.includes("_$callClinit") || match.includes("_$callClinit")
match.match(/_\S+?\$\S+?_/gm)
) { ) {
return match; return match;
} }
@ -294,6 +297,53 @@ var main;(function(){`
return match; return match;
} }
); );
var staticVariables = [...patchedFile.matchAll(/var \S+?_\S+?_\S+? = null;/gm)].flatMap(x => {return x[0]});
patchedFile = patchedFile.replaceAll(/var \S+?_\S+? = \$rt_classWithoutFields\(\);/gm, function (match) {
var prefix = match.replace(" = $rt_classWithoutFields();", "");
var entries = [];
staticVariables.forEach(entry => {
if (entry.startsWith(prefix)) {
var variableName = entry.replace("var ", "").replace(" = null;", "");
var segments = variableName.split("_");
segments.splice(0, 2);
var name = segments.join("_");
entries.push({
"name": name,
"variable": variableName,
});
}
});
var getComponents = "";
entries.forEach(entry => {
getComponents+= `
case \`${entry.name}\`:
return ${entry.variable};
break;`
});
var setComponents = "";
entries.forEach(entry => {
setComponents+= `
case \`${entry.name}\`:
${entry.variable} = c;
break;`;
});
var proxy = `
ModAPI.hooks._rippedStaticIndexer[\`${prefix.replace("var ", "")}\`] = [${entries.flatMap((x)=>{return "\"" + x.name + "\""}).join(",")}];
ModAPI.hooks._rippedStaticProperties[\`${prefix.replace("var ", "")}\`] = new Proxy({}, {
get: function (a,b,c) {
switch (b) {
${getComponents}
}
},
set: function (a,b,c) {
switch (b) {
${setComponents}
}
}
});`;
return match + proxy;
});
patchedFile = patchedFile.replaceAll(/main\(\);\s*?}/gm, (match) => { patchedFile = patchedFile.replaceAll(/main\(\);\s*?}/gm, (match) => {
return match.replace("main();", "main();ModAPI.hooks._postInit();"); return match.replace("main();", "main();ModAPI.hooks._postInit();");
}); });
@ -306,10 +356,42 @@ var main;(function(){`
<script> <script>
globalThis.modapi_postinit = `(() => { globalThis.modapi_postinit = `(() => {
//EaglerForge post initialization code. //EaglerForge post initialization code.
//This script cannot contain backticks, escape characters, or backslashes in order to inject into the dedicated server code.
ModAPI.hooks._classMap = {}; ModAPI.hooks._classMap = {};
globalThis.PluginAPI ||= ModAPI; globalThis.PluginAPI ||= ModAPI;
ModAPI.mcinstance ||= {}; ModAPI.mcinstance ||= {};
ModAPI.javaClient ||= {}; ModAPI.javaClient ||= {};
ModAPI.dedicatedServer ||= {};
ModAPI.dedicatedServer._data ||= [];
ModAPI.dedicatedServer.appendCode = function (code) {
ModAPI.dedicatedServer._data.push(code);
}
ModAPI.util ||= {};
ModAPI.util.getMethodFromPackage = function (classId, methodName) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
name += "_" + methodName;
return name;
}
ModAPI.util.getCompiledNameFromPackage = function (classId) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
return name;
}
ModAPI.version = "v2.0"; ModAPI.version = "v2.0";
ModAPI.flavour = "injector"; ModAPI.flavour = "injector";
ModAPI.credits = ["ZXMushroom63", "radmanplays", "OtterCodes101", "TheIdiotPlays"]; ModAPI.credits = ["ZXMushroom63", "radmanplays", "OtterCodes101", "TheIdiotPlays"];
@ -318,11 +400,14 @@ var main;(function(){`
ModAPI.hooks._rippedData.forEach(block => { ModAPI.hooks._rippedData.forEach(block => {
block.forEach(item => { block.forEach(item => {
if (typeof item === "function") { if (typeof item === "function") {
var compiledName = item.name;
if (!item.$meta || typeof item.$meta.name !== "string") { if (!item.$meta || typeof item.$meta.name !== "string") {
return; return;
} }
var classId = item.$meta.name; var classId = item.$meta.name;
var compiledName = ModAPI.util.getCompiledNameFromPackage(classId);
if (!ModAPI.hooks._classMap[classId]) { if (!ModAPI.hooks._classMap[classId]) {
ModAPI.hooks._classMap[classId] = { ModAPI.hooks._classMap[classId] = {
"name": classId.split(".")[classId.split(".").length - 1], "name": classId.split(".")[classId.split(".").length - 1],
@ -331,6 +416,8 @@ var main;(function(){`
"constructors": [], "constructors": [],
"methods": {}, "methods": {},
"staticMethods": {}, "staticMethods": {},
"staticVariables": {},
"staticVariableNames": [],
"class": item, "class": item,
"compiledName": compiledName "compiledName": compiledName
} }
@ -338,6 +425,8 @@ var main;(function(){`
if (typeof item.$meta.superclass === "function" && item.$meta.superclass.$meta) { if (typeof item.$meta.superclass === "function" && item.$meta.superclass.$meta) {
ModAPI.hooks._classMap[classId].superclass = item.$meta.superclass.$meta.name; ModAPI.hooks._classMap[classId].superclass = item.$meta.superclass.$meta.name;
} }
ModAPI.hooks._classMap[classId].staticVariableNames = ModAPI.hooks._rippedStaticIndexer[compiledName];
ModAPI.hooks._classMap[classId].staticVariables = ModAPI.hooks._rippedStaticProperties[compiledName];
if (item["$$constructor$$"]) { if (item["$$constructor$$"]) {
//Class does not have any hand written constructors //Class does not have any hand written constructors
//Eg: class MyClass {} //Eg: class MyClass {}
@ -443,6 +532,9 @@ var main;(function(){`
return true; return true;
}, },
}; };
ModAPI.util.TeaVM_to_BaseData_ProxyConf = TeaVM_to_BaseData_ProxyConf;
ModAPI.util.TeaVMArray_To_Recursive_BaseData_ProxyConf = TeaVMArray_To_Recursive_BaseData_ProxyConf;
ModAPI.util.TeaVM_to_Recursive_BaseData_ProxyConf = TeaVM_to_Recursive_BaseData_ProxyConf;
ModAPI.required = new Set(); ModAPI.required = new Set();
ModAPI.events = {}; ModAPI.events = {};
ModAPI.events.types = ["event"]; ModAPI.events.types = ["event"];
@ -517,21 +609,6 @@ var main;(function(){`
}); });
}; };
ModAPI.events.newEvent("update"); ModAPI.events.newEvent("update");
ModAPI.util ||= {};
ModAPI.util.TeaVM_to_BaseData_ProxyConf = TeaVM_to_BaseData_ProxyConf;
ModAPI.util.getMethodFromPackage = function (classId, methodName) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
name += "_" + methodName;
return name;
}
ModAPI.require = function (module) { ModAPI.require = function (module) {
ModAPI.required.add(module); ModAPI.required.add(module);
}; };
@ -588,7 +665,22 @@ var main;(function(){`
ModAPI.settings = new Proxy(ModAPI.mcinstance.$gameSettings, TeaVM_to_Recursive_BaseData_ProxyConf); ModAPI.settings = new Proxy(ModAPI.mcinstance.$gameSettings, TeaVM_to_Recursive_BaseData_ProxyConf);
return x; return x;
}; };
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "loadIntegratedServerSourceInline");
//Integrated server setup has a randomised suffix on the end
integratedServerStartup = ModAPI.hooks._rippedMethodKeys.filter(key => {return key.startsWith(integratedServerStartup); })[0];
const integratedServerStartupMethod = ModAPI.hooks.methods[integratedServerStartup];
ModAPI.hooks.methods[integratedServerStartup] = function (worker, bootstrap) {
var x = integratedServerStartupMethod.apply(this, [worker, bootstrap + ";" + globalThis.modapi_postinit + ";" + ModAPI.dedicatedServer._data.join(";")]);
return x;
};
})();`; })();`;
</script> </script>
<script>
globalThis.modapi_guikit = ``;
</script>
</body> </body>
</html> </html>

View File

@ -1,9 +1,41 @@
(() => { (() => {
//EaglerForge post initialization code. //EaglerForge post initialization code.
//This script cannot contain backticks, escape characters, or backslashes in order to inject into the dedicated server code.
ModAPI.hooks._classMap = {}; ModAPI.hooks._classMap = {};
globalThis.PluginAPI ||= ModAPI; globalThis.PluginAPI ||= ModAPI;
ModAPI.mcinstance ||= {}; ModAPI.mcinstance ||= {};
ModAPI.javaClient ||= {}; ModAPI.javaClient ||= {};
ModAPI.dedicatedServer ||= {};
ModAPI.dedicatedServer._data ||= [];
ModAPI.dedicatedServer.appendCode = function (code) {
ModAPI.dedicatedServer._data.push(code);
}
ModAPI.util ||= {};
ModAPI.util.getMethodFromPackage = function (classId, methodName) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
name += "_" + methodName;
return name;
}
ModAPI.util.getCompiledNameFromPackage = function (classId) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
return name;
}
ModAPI.version = "v2.0"; ModAPI.version = "v2.0";
ModAPI.flavour = "injector"; ModAPI.flavour = "injector";
ModAPI.credits = ["ZXMushroom63", "radmanplays", "OtterCodes101", "TheIdiotPlays"]; ModAPI.credits = ["ZXMushroom63", "radmanplays", "OtterCodes101", "TheIdiotPlays"];
@ -12,11 +44,14 @@
ModAPI.hooks._rippedData.forEach(block => { ModAPI.hooks._rippedData.forEach(block => {
block.forEach(item => { block.forEach(item => {
if (typeof item === "function") { if (typeof item === "function") {
var compiledName = item.name;
if (!item.$meta || typeof item.$meta.name !== "string") { if (!item.$meta || typeof item.$meta.name !== "string") {
return; return;
} }
var classId = item.$meta.name; var classId = item.$meta.name;
var compiledName = ModAPI.util.getCompiledNameFromPackage(classId);
if (!ModAPI.hooks._classMap[classId]) { if (!ModAPI.hooks._classMap[classId]) {
ModAPI.hooks._classMap[classId] = { ModAPI.hooks._classMap[classId] = {
"name": classId.split(".")[classId.split(".").length - 1], "name": classId.split(".")[classId.split(".").length - 1],
@ -25,6 +60,8 @@
"constructors": [], "constructors": [],
"methods": {}, "methods": {},
"staticMethods": {}, "staticMethods": {},
"staticVariables": {},
"staticVariableNames": [],
"class": item, "class": item,
"compiledName": compiledName "compiledName": compiledName
} }
@ -32,6 +69,8 @@
if (typeof item.$meta.superclass === "function" && item.$meta.superclass.$meta) { if (typeof item.$meta.superclass === "function" && item.$meta.superclass.$meta) {
ModAPI.hooks._classMap[classId].superclass = item.$meta.superclass.$meta.name; ModAPI.hooks._classMap[classId].superclass = item.$meta.superclass.$meta.name;
} }
ModAPI.hooks._classMap[classId].staticVariableNames = ModAPI.hooks._rippedStaticIndexer[compiledName];
ModAPI.hooks._classMap[classId].staticVariables = ModAPI.hooks._rippedStaticProperties[compiledName];
if (item["$$constructor$$"]) { if (item["$$constructor$$"]) {
//Class does not have any hand written constructors //Class does not have any hand written constructors
//Eg: class MyClass {} //Eg: class MyClass {}
@ -137,6 +176,9 @@
return true; return true;
}, },
}; };
ModAPI.util.TeaVM_to_BaseData_ProxyConf = TeaVM_to_BaseData_ProxyConf;
ModAPI.util.TeaVMArray_To_Recursive_BaseData_ProxyConf = TeaVMArray_To_Recursive_BaseData_ProxyConf;
ModAPI.util.TeaVM_to_Recursive_BaseData_ProxyConf = TeaVM_to_Recursive_BaseData_ProxyConf;
ModAPI.required = new Set(); ModAPI.required = new Set();
ModAPI.events = {}; ModAPI.events = {};
ModAPI.events.types = ["event"]; ModAPI.events.types = ["event"];
@ -211,21 +253,6 @@
}); });
}; };
ModAPI.events.newEvent("update"); ModAPI.events.newEvent("update");
ModAPI.util ||= {};
ModAPI.util.TeaVM_to_BaseData_ProxyConf = TeaVM_to_BaseData_ProxyConf;
ModAPI.util.getMethodFromPackage = function (classId, methodName) {
var name = "";
var classStuff = classId.split(".");
classStuff.forEach((component, i) => {
if (i === classStuff.length - 1) {
name += "_" + component;
} else {
name += component[0].toLowerCase();
}
});
name += "_" + methodName;
return name;
}
ModAPI.require = function (module) { ModAPI.require = function (module) {
ModAPI.required.add(module); ModAPI.required.add(module);
}; };
@ -282,4 +309,13 @@
ModAPI.settings = new Proxy(ModAPI.mcinstance.$gameSettings, TeaVM_to_Recursive_BaseData_ProxyConf); ModAPI.settings = new Proxy(ModAPI.mcinstance.$gameSettings, TeaVM_to_Recursive_BaseData_ProxyConf);
return x; return x;
}; };
var integratedServerStartup = ModAPI.util.getMethodFromPackage("net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer", "loadIntegratedServerSourceInline");
//Integrated server setup has a randomised suffix on the end
integratedServerStartup = ModAPI.hooks._rippedMethodKeys.filter(key => {return key.startsWith(integratedServerStartup); })[0];
const integratedServerStartupMethod = ModAPI.hooks.methods[integratedServerStartup];
ModAPI.hooks.methods[integratedServerStartup] = function (worker, bootstrap) {
var x = integratedServerStartupMethod.apply(this, [worker, bootstrap + ";" + globalThis.modapi_postinit + ";" + ModAPI.dedicatedServer._data.join(";")]);
return x;
};
})(); })();