mirror of
https://github.com/eaglerforge/EaglerForgeInjector
synced 2025-07-23 14:11:16 -09:00
Fix more stack implosion occurences
This commit is contained in:
parent
03f62846cc
commit
195a50315c
@ -4,7 +4,7 @@ The EaglerForge ModAPI is housed in a global JavaScript object stored on `global
|
||||
The global object has the following properties:
|
||||
- `ModAPI.player: EntityPlayerSP`
|
||||
- Only accessible after `ModAPI.require("player")` is called, this is the local player entity. It is regenerated every time the `update` event is called.
|
||||
- `ModAPI.world: WorldClient`
|
||||
- `ModAPI.world: WorldClient`
|
||||
- Only accessible after `ModAPI.require("world")` is called, this is the client-side world. It is regenerated every time the `update` event is called.
|
||||
- `ModAPI.network: NetHandlerPlayClient`
|
||||
- Only accessible after `ModAPI.require("network")` is called, this is the client's networking handler. It is regenerated every time the `update` event is called.
|
||||
|
@ -24,11 +24,16 @@ Methods:
|
||||
- Alias: `ModAPI.util.ustr()`
|
||||
- Alias: `ModAPI.util.unstring()`
|
||||
- Alias: `ModAPI.util.jclStrToJsStr()`
|
||||
- `ModAPI.util.getMethodFromPackage(classId: String, methodName: String)`
|
||||
- `ModAPI.util.getMethodFromPackage(classId: String, methodName: String) : String`
|
||||
- Takes a class id (eg: `net.minecraft.client.Minecraft`) and a method name (eg: `middleClickMouse`) and returns its key in `ModAPI.hooks.methods`.
|
||||
- `ModAPI.util.stringToUint16Array(string: String) : Uint16Array`
|
||||
- Encodes a string into a uint16array.
|
||||
- `ModAPI.util.setStringContent(jclString: java.lang.String, contents: String) : void`
|
||||
- Writes a new javascript string into the contents of a java string.
|
||||
- `ModAPI.util.getMethodFromPackage(classId: String, methodName: String)`
|
||||
- Takes a class id (eg: `net.minecraft.client.Minecraft`) and a method name (eg: `middleClickMouse`) and returns its key in `ModAPI.hooks.methods`.
|
||||
- `ModAPI.util.getMethodFromPackage(classId: String, methodName: String) : String`
|
||||
- Takes a class id (eg: `net.minecraft.client.Minecraft`) and a method name (eg: `middleClickMouse`) and returns its key in `ModAPI.hooks.methods`.
|
||||
- `ModAPI.util.hashCode(string: String) : String`
|
||||
- Returns the hash of a string.
|
||||
- `ModAPI.util.isCritical() : boolean`
|
||||
- Checks wether the thread is in a critical state.
|
||||
- When patching methods, it is good practice to allow the method to resume as usual if this is `true`, to avoid stack implosions. (yes, those are real)
|
@ -11,4 +11,7 @@ When I was trying to hook into the server-side processing of chat messages, I fo
|
||||
Incorrectly patching methods with ModAPI.hooks (such as returning `false` instead of `0`, or a javascript string without using `ModAPI.str()`) will effectively cause the memory stack to implode, along with all crash handlers. I came across this when I was using the `processcommand` event with preventDefault set to true. I didn't return any value when patching methods for the event being `preventDefault`ed, when the output expected was a java boolean (`0`/`1`). This would cause the dedicated server to freeze/lock up, without triggering any form of crash.
|
||||
|
||||
Update 13/09/2024:
|
||||
Any form of incorrect data type, even passing the wrong values, can cause this sort of hang. I encountered this when trying to set a block in the world to any form of wood or leaf block, without adding iproperties to the tree type.
|
||||
Any form of incorrect data type, even passing the wrong values, can cause this sort of hang. I encountered this when trying to set a block in the world to any form of wood or leaf block, without adding iproperties to the tree type.
|
||||
|
||||
Update 13/09/2024:
|
||||
Calling methods while the TeaVM thread is in a critical transition state (see `ModAPI.util.isCritical()`) will shift the call stack, cause methods to access the incorrect values at runtime, and also cause the stack to implode. Gotta love TeaVM.
|
@ -8,8 +8,16 @@ ModAPI.dedicatedServer.appendCode(function () {
|
||||
var rayTraceMethod = worldMethodMap[Object.keys(worldMethodMap).filter(key => {
|
||||
return key.startsWith("rayTraceBlocks") && worldMethodMap[key].method.length === 4;
|
||||
})].method;
|
||||
var blockPosConstructor = ModAPI.reflect.getClassById("net.minecraft.util.BlockPos").constructors.find((x) => { return x.length === 3 });
|
||||
var blockTypesList = Object.keys(ModAPI.blocks);
|
||||
var blockTypesList = [];
|
||||
ModAPI.addEventListener("serverstart", () => {
|
||||
blockTypesList = Object.keys(ModAPI.blocks).filter(key => {
|
||||
var blockType = ModAPI.blocks[key];
|
||||
if (!blockType) {
|
||||
return false;
|
||||
}
|
||||
return blockType.fullBlock && !blockType.needsRandomTick;
|
||||
});
|
||||
});
|
||||
function getPlayerEntitiesAndTheirWorld() {
|
||||
var out = [];
|
||||
ModAPI.server.worldServers.forEach(x => {
|
||||
@ -31,11 +39,12 @@ ModAPI.dedicatedServer.appendCode(function () {
|
||||
ModAPI.addEventListener("processcommand", (event) => {
|
||||
if (event.command.toLowerCase().startsWith("/blocklook")) {
|
||||
active = !active;
|
||||
console.log(blockTypesList);
|
||||
var playerEntities = getPlayerEntitiesAndTheirWorld();
|
||||
playerEntities.forEach(pair => {
|
||||
pair.player.addChatMessage(
|
||||
ModAPI.reflect.getClassById("net.minecraft.util.ChatComponentText").constructors[0](ModAPI.util.str(
|
||||
"[BlockLook] Toggled to " + (active ? "on" : off)
|
||||
"[BlockLook] Toggled to " + (active ? "on" : "off")
|
||||
))
|
||||
)
|
||||
});
|
||||
@ -45,7 +54,7 @@ ModAPI.dedicatedServer.appendCode(function () {
|
||||
var t = 0;
|
||||
ModAPI.addEventListener("tick", () => {
|
||||
t++;
|
||||
if (t > 20) {
|
||||
if (t > 5) {
|
||||
t = 0;
|
||||
} else {
|
||||
return;
|
||||
@ -53,6 +62,9 @@ ModAPI.dedicatedServer.appendCode(function () {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
if (blockTypesList.length < 1) {
|
||||
return;
|
||||
}
|
||||
var playerEntities = getPlayerEntitiesAndTheirWorld();
|
||||
playerEntities.forEach(pair => {
|
||||
var start = pair.player.getPositionEyes(1).getRef();
|
||||
@ -63,21 +75,22 @@ ModAPI.dedicatedServer.appendCode(function () {
|
||||
lookVector.addVector(start.$xCoord, start.$yCoord, start.$zCoord);
|
||||
var hitResult = rayTraceMethod(pair.world.getRef(), start, lookVector.getRef(), 0);
|
||||
if (hitResult) {
|
||||
console.log(hitResult);
|
||||
if (ModAPI.util.unstr(hitResult.$typeOfHit.$name5) !== "BLOCK") {
|
||||
return console.log("Non block collision detected.")
|
||||
}
|
||||
var blockPos = hitResult.$blockPos;
|
||||
if (!pair.world.isBlockLoaded(blockPos)) {
|
||||
console.log("[BlockLook] Block is not loaded!");
|
||||
return console.log("[BlockLook] Block is not loaded!");
|
||||
}
|
||||
var blockType = blockTypesList[Math.floor(Math.random() * blockTypesList.length)];
|
||||
blockType = ModAPI.blocks[blockType];
|
||||
if (!blockType.fullBlock) {
|
||||
if (!blockType.fullBlock || blockType.needsRandomTick) {
|
||||
return;
|
||||
}
|
||||
console.log("[BlockLook] " + ModAPI.util.unstr(blockType.unlocalizedName.getRef()));
|
||||
var block = blockType.getDefaultState();
|
||||
pair.world.setBlockState(blockPos, block.getRef(), 2);
|
||||
pair.world.notifyNeighborsRespectDebug(blockPos, block.getRef());
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
@ -509,6 +509,12 @@ globalThis.modapi_postinit = `(() => {
|
||||
return Math.floor(Math.abs(hash)) + "";
|
||||
};
|
||||
|
||||
//Check whether the thread is in a critical transition state (resuming or suspending)
|
||||
//Calling functions in a critical state will cause stack implosions.
|
||||
ModAPI.util.isCritical = function isCritical() {
|
||||
return ModAPI.hooks._teavm.$rt_suspending() || ModAPI.hooks._teavm.$rt_resuming();
|
||||
}
|
||||
|
||||
ModAPI.clickMouse = function () {
|
||||
ModAPI.hooks.methods["nmc_Minecraft_clickMouse"](ModAPI.javaClient);
|
||||
}
|
||||
@ -573,6 +579,9 @@ globalThis.modapi_postinit = `(() => {
|
||||
const serverTickMethodName = ModAPI.util.getMethodFromPackage("net.minecraft.server.MinecraftServer", "tick");
|
||||
const serverTickMethod = ModAPI.hooks.methods[serverTickMethodName];
|
||||
ModAPI.hooks.methods[serverTickMethodName] = function ($this) {
|
||||
if (ModAPI.util.isCritical()) {
|
||||
return serverTickMethod.apply(this, [$this]);
|
||||
}
|
||||
var data = { preventDefault: false }
|
||||
ModAPI.events.callEvent("tick", data);
|
||||
if (data.preventDefault) {
|
||||
|
@ -509,6 +509,12 @@
|
||||
return Math.floor(Math.abs(hash)) + "";
|
||||
};
|
||||
|
||||
//Check whether the thread is in a critical transition state (resuming or suspending)
|
||||
//Calling functions in a critical state will cause stack implosions.
|
||||
ModAPI.util.isCritical = function isCritical() {
|
||||
return ModAPI.hooks._teavm.$rt_suspending() || ModAPI.hooks._teavm.$rt_resuming();
|
||||
}
|
||||
|
||||
ModAPI.clickMouse = function () {
|
||||
ModAPI.hooks.methods["nmc_Minecraft_clickMouse"](ModAPI.javaClient);
|
||||
}
|
||||
@ -573,6 +579,9 @@
|
||||
const serverTickMethodName = ModAPI.util.getMethodFromPackage("net.minecraft.server.MinecraftServer", "tick");
|
||||
const serverTickMethod = ModAPI.hooks.methods[serverTickMethodName];
|
||||
ModAPI.hooks.methods[serverTickMethodName] = function ($this) {
|
||||
if (ModAPI.util.isCritical()) {
|
||||
return serverTickMethod.apply(this, [$this]);
|
||||
}
|
||||
var data = { preventDefault: false }
|
||||
ModAPI.events.callEvent("tick", data);
|
||||
if (data.preventDefault) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user