mirror of
https://github.com/eaglerforge/EaglerForgeInjector
synced 2025-07-23 06:01:38 -09:00
ModAPI.materials and ModAPI.enchantments fixed
This commit is contained in:
parent
0426bfda41
commit
176159bc47
291
index.html
291
index.html
@ -4,96 +4,173 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>EaglerForge Injector</title>
|
<title>EaglerForge Injector</title>
|
||||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
<link
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet">
|
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.github-button-container {
|
.github-button-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.github-button-container a.btn {
|
.github-button-container a.btn {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-color: #ffffff;
|
border-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.github-button-container a.btn:hover {
|
.github-button-container a.btn:hover {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
#info {
|
#info {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
min-width: 50vw;
|
min-width: 50vw;
|
||||||
}
|
}
|
||||||
details {
|
details {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
background-color: rgba(0,0,0,0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
summary {
|
summary {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>EaglerForge Injector</h1>
|
<h1>EaglerForge Injector</h1>
|
||||||
<div class="github-button-container">
|
<div class="github-button-container">
|
||||||
<a href="https://github.com/eaglerforge/EaglerForgeInjector" class="btn btn-default" target="_blank">
|
<a
|
||||||
<i class="fab fa-github"></i> GitHub
|
href="https://github.com/eaglerforge/EaglerForgeInjector"
|
||||||
</a>
|
class="btn btn-default"
|
||||||
</div>
|
target="_blank"
|
||||||
<h6>
|
>
|
||||||
Adds ModAPI with more functionality (adds hooking into functions, exposes
|
<i class="fab fa-github"></i> GitHub
|
||||||
all classes, etc) to unminified unobfuscated EaglercraftX offline downloads (web support coming soon).
|
</a>
|
||||||
</h6>
|
</div>
|
||||||
<br />
|
<h6>
|
||||||
<div class="custom-file mb-3">
|
Adds ModAPI with more functionality (adds hooking into functions,
|
||||||
<input class="custom-file-input" type="file" id="htmlFile" accept=".html,.js" />
|
exposes all classes, etc) to unminified unobfuscated EaglercraftX
|
||||||
<label class="custom-file-label" for="htmlFile">Choose .html file...</label>
|
offline downloads (web support coming soon).
|
||||||
<br /><br />
|
</h6>
|
||||||
<button class="btn btn-primary" id="giveme">Make modded build</button>
|
<br />
|
||||||
</div>
|
<div class="custom-file mb-3">
|
||||||
|
<input
|
||||||
|
class="custom-file-input"
|
||||||
|
type="file"
|
||||||
|
id="htmlFile"
|
||||||
|
accept=".html,.js"
|
||||||
|
/>
|
||||||
|
<label class="custom-file-label" for="htmlFile"
|
||||||
|
>Choose .html file...</label
|
||||||
|
>
|
||||||
|
<br /><br />
|
||||||
|
<button class="btn btn-primary" id="giveme">Make modded build</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br><br><br>
|
<br /><br /><br />
|
||||||
<span>Info:</span>
|
<span>Info:</span>
|
||||||
<div id="#info">
|
<div id="#info">
|
||||||
<details>
|
<details>
|
||||||
<summary>What .html file do I choose?</summary>
|
<summary>What .html file do I choose?</summary>
|
||||||
Once you have a local EaglercraftX workspace setup, in <code>build.gradle</code>, set the <code>obfuscate</code> property to <code>false</code>.
|
Once you have a local EaglercraftX workspace setup, in
|
||||||
Then, run <code>CompileJS.bat</code> (or .sh if on a unix-based os), and then run <code>MakeOfflineDownload.bat</code>. The outputted offline download will have a much larger file size than other offline builds. This is the file you should select.
|
<code>build.gradle</code>, set the <code>obfuscate</code> property to
|
||||||
(it should have a naming convention similar to <code>EaglercraftX_1.8_Offline_en_US.html</code>)
|
<code>false</code>. Then, run <code>CompileJS.bat</code> (or .sh if on
|
||||||
</details>
|
a unix-based os), and then run <code>MakeOfflineDownload.bat</code>.
|
||||||
<details>
|
The outputted offline download will have a much larger file size than
|
||||||
<summary>How does this tool work?</summary>
|
other offline builds. This is the file you should select. (it should
|
||||||
The injector works by analysing your uploaded file for patterns that appear in TeaVM's compiled JavaScript code. Then, it will replace all functions with proxies to the original code, which it moves into
|
have a naming convention similar to
|
||||||
<code>ModAPI.hooks.methods</code>. It does similar things with static properties and constructors, and then hooks into <code>$rt_metadata</code> to access auxilary information.
|
<code>EaglercraftX_1.8_Offline_en_US.html</code>)
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>Where documentation???</summary>
|
<summary>How does this tool work?</summary>
|
||||||
<a href="https://eaglerforge.github.io/EaglerForgeInjector/docs">https://eaglerforge.github.io/EaglerForgeInjector/docs</a>
|
The injector works by analysing your uploaded file for patterns that
|
||||||
</details>
|
appear in TeaVM's compiled JavaScript code. Then, it will replace all
|
||||||
|
functions with proxies to the original code, which it moves into
|
||||||
|
<code>ModAPI.hooks.methods</code>. It does similar things with static
|
||||||
|
properties and constructors, and then hooks into
|
||||||
|
<code>$rt_metadata</code> to access auxilary information.
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Where documentation???</summary>
|
||||||
|
<a href="https://eaglerforge.github.io/EaglerForgeInjector/docs"
|
||||||
|
>https://eaglerforge.github.io/EaglerForgeInjector/docs</a
|
||||||
|
>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="filesaver.min.js"></script>
|
<script src="filesaver.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function entriesToStaticVariableProxy(entries, prefix) {
|
||||||
|
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({${
|
||||||
|
entries
|
||||||
|
.flatMap((x) => {
|
||||||
|
return '"' + x.name + '"';
|
||||||
|
})
|
||||||
|
.join(":null,") + (entries.length > 0 ? ":null" : "")
|
||||||
|
}}, {
|
||||||
|
get: function (a,b,c) {
|
||||||
|
switch (b) {
|
||||||
|
${getComponents}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function (a,b,c) {
|
||||||
|
switch (b) {
|
||||||
|
${setComponents}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});`;
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
var modapi_preinit = `globalThis.ModAPI ||= {};
|
var modapi_preinit = `globalThis.ModAPI ||= {};
|
||||||
ModAPI.hooks ||= {};
|
ModAPI.hooks ||= {};
|
||||||
ModAPI.hooks.freezeCallstack = false;
|
ModAPI.hooks.freezeCallstack = false;
|
||||||
@ -227,7 +304,6 @@ var main;(function(){`
|
|||||||
].flatMap((x) => {
|
].flatMap((x) => {
|
||||||
return x[0];
|
return x[0];
|
||||||
});
|
});
|
||||||
//Todo: add support for static properties on classes with constructors like this: function nmcg_GuiMainMenu() {
|
|
||||||
patchedFile = patchedFile.replaceAll(
|
patchedFile = patchedFile.replaceAll(
|
||||||
/var \S+?_\S+? = \$rt_classWithoutFields\(\S*?\);/gm,
|
/var \S+?_\S+? = \$rt_classWithoutFields\(\S*?\);/gm,
|
||||||
function (match) {
|
function (match) {
|
||||||
@ -250,54 +326,43 @@ var main;(function(){`
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var getComponents = "";
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
getComponents += `
|
|
||||||
case \`${entry.name}\`:
|
|
||||||
return ${entry.variable};
|
|
||||||
break;`;
|
|
||||||
});
|
|
||||||
|
|
||||||
var setComponents = "";
|
var proxy = entriesToStaticVariableProxy(entries, prefix);
|
||||||
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({${
|
|
||||||
entries
|
|
||||||
.flatMap((x) => {
|
|
||||||
return '"' + x.name + '"';
|
|
||||||
})
|
|
||||||
.join(":null,") + (entries.length > 0 ? ":null" : "")
|
|
||||||
}}, {
|
|
||||||
get: function (a,b,c) {
|
|
||||||
switch (b) {
|
|
||||||
${getComponents}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set: function (a,b,c) {
|
|
||||||
switch (b) {
|
|
||||||
${setComponents}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});`;
|
|
||||||
return match + proxy;
|
return match + proxy;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
//Edge cases. sigh
|
||||||
|
//Done: add support for static properties on classes with constructors like this: function nmcg_GuiMainMenu() {
|
||||||
|
patchedFile = patchedFile.replaceAll(
|
||||||
|
/function [a-z]+?_([a-zA-Z\$]+?)\(\) \{/gm,
|
||||||
|
(match) => {
|
||||||
|
var prefix = "var " + match.replace("function ", "").replace("() {", "");
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(prefix);
|
||||||
|
|
||||||
|
var proxy = entriesToStaticVariableProxy(entries, prefix);
|
||||||
|
|
||||||
|
return proxy + "\n" + match;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
patchedFile = patchedFile.replaceAll(
|
patchedFile = patchedFile.replaceAll(
|
||||||
/function \$rt_\S+?\(/gm,
|
/function \$rt_\S+?\(/gm,
|
||||||
(match) => {
|
(match) => {
|
||||||
|
@ -533,8 +533,8 @@ globalThis.modapi_postinit = `(() => {
|
|||||||
|
|
||||||
ModAPI.items = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Items")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.items = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Items")].staticVariables, StaticProps_ProxyConf);
|
||||||
ModAPI.blocks = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Blocks")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.blocks = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Blocks")].staticVariables, StaticProps_ProxyConf);
|
||||||
//ModAPI.materials = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.block.material.Material")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.materials = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.block.material.Material")].staticVariables, StaticProps_ProxyConf);
|
||||||
//ModAPI.enchantments = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.enchantment.Enchantment")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.enchantments = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.enchantment.Enchantment")].staticVariables, StaticProps_ProxyConf);
|
||||||
|
|
||||||
|
|
||||||
const originalOptionsInit = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.gui.GuiOptions", "initGui")];
|
const originalOptionsInit = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.gui.GuiOptions", "initGui")];
|
||||||
|
@ -533,8 +533,8 @@
|
|||||||
|
|
||||||
ModAPI.items = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Items")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.items = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Items")].staticVariables, StaticProps_ProxyConf);
|
||||||
ModAPI.blocks = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Blocks")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.blocks = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.init.Blocks")].staticVariables, StaticProps_ProxyConf);
|
||||||
//ModAPI.materials = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.block.material.Material")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.materials = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.block.material.Material")].staticVariables, StaticProps_ProxyConf);
|
||||||
//ModAPI.enchantments = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.enchantment.Enchantment")].staticVariables, StaticProps_ProxyConf);
|
ModAPI.enchantments = new Proxy(ModAPI.hooks._classMap[ModAPI.util.getCompiledName("net.minecraft.enchantment.Enchantment")].staticVariables, StaticProps_ProxyConf);
|
||||||
|
|
||||||
|
|
||||||
const originalOptionsInit = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.gui.GuiOptions", "initGui")];
|
const originalOptionsInit = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.gui.GuiOptions", "initGui")];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user