add automatic clinit

This commit is contained in:
ZXMushroom63 2024-12-24 20:19:39 +08:00
parent b81edd7de9
commit 55042e7833
6 changed files with 25 additions and 44 deletions

View File

@ -59,8 +59,6 @@ Each `ReflectClass` has the following methods:
- `instanceOf(object: Object)`
- Checks if the `object` is an instance of the class.
- `init()`
- Initializes static variables. Not needed, as static variables already prepare themselves before being accessed, this is mostly used for debugging.
### ReflectMethod Definition

View File

@ -63,9 +63,6 @@
}
ModAPI.reflect.prototypeStack(itemClass, nmi_ItemPistol);
nmi_ItemPistol.prototype.$onItemRightClick = function ($itemstack, $world, $player) {
DamageSourceClass.staticMethods.$callClinit.method();
//Noticed that the gun only worked after an entity in the world takes damage XD
//TeaVM is very optimised. Using $callClinit tells it to hurry up pretty much lol
var cactus = DamageSourceClass.staticVariables.cactus;
var world = ModAPI.util.wrap($world);
var entityplayer = ModAPI.util.wrap($player);

View File

@ -63,9 +63,6 @@
}
ModAPI.reflect.prototypeStack(itemClass, nmi_ItemPistol);
nmi_ItemPistol.prototype.$onItemRightClick = function ($itemstack, $world, $player) {
DamageSourceClass.staticMethods.$callClinit.method();
//Noticed that the gun only worked after an entity in the world takes damage XD
//TeaVM is very optimised. Using $callClinit tells it to hurry up pretty much lol
var cactus = DamageSourceClass.staticVariables.cactus;
var world = ModAPI.util.wrap($world);
var entityplayer = ModAPI.util.wrap($player);

View File

@ -90,9 +90,8 @@
>Choose .html file...</label
>
<br />
<span><label>Minify:&nbsp;</label><input type="checkbox" oninput="globalThis.doShronk = this.checked">&nbsp;&nbsp;&nbsp;
<label>EaglerForge:&nbsp;</label><input checked type="checkbox" oninput="globalThis.doEaglerforge = this.checked">&nbsp;&nbsp;&nbsp;
<label>Optimize π:&nbsp;</label><input checked type="checkbox" oninput="globalThis.optimizePi= this.checked">
<span><label>Minify:&nbsp;</label><input type="checkbox" oninput="globalThis.doShronk = this.checked">
&nbsp;&nbsp;&nbsp;<label>EaglerForge:&nbsp;</label><input checked type="checkbox" oninput="globalThis.doEaglerforge = this.checked">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code id="status">Awaiting input...</code></span>
<br /><br />
<button class="btn btn-primary" id="giveme">Make modded client</button>

View File

@ -1,5 +1,4 @@
globalThis.doEaglerforge = true;
globalThis.optimizePi = true;
function wait(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve(); }, ms);
@ -8,12 +7,19 @@ function wait(ms) {
function _status(x) {
document.querySelector("#status").innerText = x;
}
function entriesToStaticVariableProxy(entries, prefix) {
function entriesToStaticVariableProxy(entries, prefix, clinitList) {
prefix = prefix.replace(
"var ",
""
);
if (entries.length === 0) {
return `ModAPI.hooks._rippedStaticProperties[\`${prefix.replace(
"var ",
""
)}\`]={};`;
return `ModAPI.hooks._rippedStaticProperties[\`${prefix}\`]={};`;
}
if (clinitList.includes(prefix + "_$callClinit")) {
entries.push({
name: "$callClinit",
variable: prefix + "_$callClinit"
});
}
var getComponents = "";
entries.forEach((entry) => {
@ -126,6 +132,10 @@ var main;(function(){`
patchedFile = patchedFile.replaceAll("function TeaVMThread(", "globalThis.ModAPI.hooks.TeaVMThread = TeaVMThread;\nfunction TeaVMThread(");
_status("Getting clinit list...");
var clinitList = [...patchedFile.matchAll(/^[\t ]*function \S+?_\S+?_\$callClinit\(/gm)].map(x=>x[0].replaceAll("function ", "").replaceAll("(", "").trim());
console.log(clinitList);
_status("Extracting constructors and methods...");
await wait(50);
@ -159,28 +169,6 @@ var main;(function(){`
}
);
if(globalThis.optimizePi){
patchedFile = patchedFile.replaceAll(
"3.1415927410125732 / 180.0",
"0.01745"
);
patchedFile = patchedFile.replaceAll(
"180.0 / 3.1415927410125732",
"57.2958"
);
patchedFile = patchedFile.replaceAll(
"3.1415927410125732",
"3.14159"
);
patchedFile = patchedFile.replaceAll(
"0.01745329238474369",
"0.01745"
);
}
const extractInstanceMethodRegex =
/^[\t ]*function \S+?_\S+?_\S+?\((\$this)?/gm; // /^[\t ]*function \S+?_\S+?_\S+?\(\$this/gm
const extractInstanceMethodFullNameRegex = /function (\S*?)\(/gm; // /function (\S*?)\(\$this/gm
@ -189,7 +177,8 @@ var main;(function(){`
(match) => {
if (
match.includes("__init_") ||
match.includes("__clinit_")
match.includes("__clinit_") ||
match.includes("_$callClinit")
) {
return match;
}
@ -236,7 +225,7 @@ var main;(function(){`
}
});
var proxy = entriesToStaticVariableProxy(entries, prefix);
var proxy = entriesToStaticVariableProxy(entries, prefix, clinitList);
return match + proxy;
}
@ -266,7 +255,7 @@ var main;(function(){`
}
});
var proxy = entriesToStaticVariableProxy(entries, prefix);
var proxy = entriesToStaticVariableProxy(entries, prefix, clinitList);
return proxy + "\n" + match;
}

View File

@ -331,8 +331,9 @@ globalThis.modapi_postinit = "(" + (() => {
}
}
});
ModAPI.hooks._classMap[compiledName].init = ModAPI.hooks._classMap[compiledName].staticMethods?.$callClinit?.method || (()=>{});
ModAPI.hooks._classMap[compiledName].staticVariables = makeClinitProxy(ModAPI.hooks._rippedStaticProperties[compiledName] || {}, ModAPI.hooks._classMap[compiledName].init);
ModAPI.hooks._classMap[compiledName].staticVariables = makeClinitProxy(ModAPI.hooks._rippedStaticProperties[compiledName] || {}, (()=>{
(ModAPI.hooks._rippedStaticProperties[compiledName].$callClinit ?? (()=>{}))();
}));
ModAPI.hooks._classMap[compiledName].staticVariableNames = Object.keys(ModAPI.hooks._classMap[compiledName].staticVariables);
});
ModAPI.reflect.classes = Object.values(ModAPI.hooks._classMap);