mirror of
https://github.com/eaglerforge/EaglerForgeInjector
synced 2025-07-26 15:29:26 -09:00
commit
485da5863c
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Eagler Forge
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -9,3 +9,5 @@ EaglerForge Injector is a tool that uses regular expressions to attach itself to
|
|||||||
[Modding tutorials](tutorials/index.md)
|
[Modding tutorials](tutorials/index.md)
|
||||||
|
|
||||||
[Modding API documentation](apidoc/index.md)
|
[Modding API documentation](apidoc/index.md)
|
||||||
|
|
||||||
|
[Compiling the client for EaglerForgeInjector](compiling_client.md)
|
90
docs/tutorials/disable_all_particles.md
Normal file
90
docs/tutorials/disable_all_particles.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
## Disable All Particles
|
||||||
|
Particles in minecraft are really laggy, and there's a large chance you may want to disable them to boost your FPS when breaking blocks.
|
||||||
|
|
||||||
|
Let's look through the Eaglercraft 1.8 source code to find where particles are rendered. We can do this with a global search for `particle`. You'll find a lot of hits in the `EffectRenderer` class in the `net.minecraft.client.particle` package. We methods we'll want to patch are:
|
||||||
|
- `renderParticles`
|
||||||
|
- `addEffect`
|
||||||
|
- `addBlockDestroyEffects`
|
||||||
|
- `hasParticlesInAlphaLayer`
|
||||||
|
|
||||||
|
For the first 3 methods, you can see that they are defined something like:
|
||||||
|
```java
|
||||||
|
public void renderParticles() {
|
||||||
|
// render particles code.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The `void` in `public void` means that it does not expect a return value.
|
||||||
|
Using [`ModAPI.util.getMethodFromPackage`](../apidoc/utils.md) we can find the compiled method name, and look for it in [`ModAPI.hooks.methods`](../apidoc/hooks.md#property-modapihooksmethods).
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function NoParticles() {
|
||||||
|
//Basic, boilerplate code
|
||||||
|
ModAPI.meta.title("No Particles");
|
||||||
|
ModAPI.meta.description("Disables all particles in game");
|
||||||
|
ModAPI.meta.credits("By <developer name>");
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "renderParticles")
|
||||||
|
] = function () {}; //Override renderParticles in EffectRenderer to an empty function that does nothing.
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
We can also do this for `addEffect` and `addBlockDestroyEffects`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function NoParticles() {
|
||||||
|
//Basic, boilerplate code
|
||||||
|
ModAPI.meta.title("No Particles");
|
||||||
|
ModAPI.meta.description("Disables all particles in game");
|
||||||
|
ModAPI.meta.credits("By <developer name>");
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "renderParticles")
|
||||||
|
] = function () {}; //Override renderParticles in EffectRenderer with an empty function that does nothing.
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addEffect")
|
||||||
|
] = function () {}; //Override addEffect in EffectRenderer with an empty function that does nothing.
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addBlockDestroyEffects")
|
||||||
|
] = function () {}; //Override addBlockDestroyEffects in EffectRenderer with an empty function that does nothing.
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
For `hasParticlesInAlphaLayer`, it doesn't use `void`, but instead a `boolean`.
|
||||||
|
```java
|
||||||
|
public boolean hasParticlesInAlphaLayer() {
|
||||||
|
// hasParticlesInAlphaLayer code.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
When TeaVM translates booleans, it converts booleans to integers:
|
||||||
|
- `false` turns into `0`
|
||||||
|
- `true` turns into `1`
|
||||||
|
|
||||||
|
So when we override `hasParticlesInAlphaLayer`, we'll need to return a `0` or a `1`. Since we want the game to thing that there aren't any particles in the alpha layer, we'll return `0` (false).
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function NoParticles() {
|
||||||
|
//Basic, boilerplate code
|
||||||
|
ModAPI.meta.title("No Particles");
|
||||||
|
ModAPI.meta.description("Disables all particles in game");
|
||||||
|
ModAPI.meta.credits("By <developer name>");
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "renderParticles")
|
||||||
|
] = function () {}; //Override renderParticles in EffectRenderer with an empty function that does nothing.
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addEffect")
|
||||||
|
] = function () {}; //Override addEffect in EffectRenderer with an empty function that does nothing.
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addBlockDestroyEffects")
|
||||||
|
] = function () {}; //Override addBlockDestroyEffects in EffectRenderer with an empty function that does nothing.
|
||||||
|
|
||||||
|
ModAPI.hooks.methods[
|
||||||
|
ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "hasParticlesInAlphaLayer")
|
||||||
|
] = function () {return 0}; //Override hasParticlesInAlphaLayer in EffectRenderer with a function that returns 0.
|
||||||
|
})();
|
||||||
|
```
|
71
docs/tutorials/hat.md
Normal file
71
docs/tutorials/hat.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
## /hat with ModAPI
|
||||||
|
/hat is a common server-side plugin that lets you put any block/item on your head. This tutorial will explain how to register a server-side command, construct a packet, and send it to a player.
|
||||||
|
[`S09PacketHeldItemChange` constructors]()
|
||||||
|
|
||||||
|
|
||||||
|
As always, start with the basic boilerplate IIFE with credits:
|
||||||
|
```javascript
|
||||||
|
(function HatMod() {
|
||||||
|
ModAPI.meta.title("Hat Mod");
|
||||||
|
ModAPI.meta.description("Use /hat to put anything on your head.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
In order to add a server side command, we need to:
|
||||||
|
- Write a function to run on the server.
|
||||||
|
- In this function, we'll add a listener to the [`processcommand` event](../apidoc/events.md#server-side-events)
|
||||||
|
- We'll check if the command is `/hat`
|
||||||
|
- If it is, we'll swap their head and current hand inventory slots, and send a network packet.
|
||||||
|
- Finally, the function from step 1 is thrown into [`ModAPI.dedicatedServer.appendCode`](../apidoc/dedicatedserver.md)
|
||||||
|
|
||||||
|
Here's the completed code:
|
||||||
|
```javascript
|
||||||
|
(function HatMod() {
|
||||||
|
ModAPI.meta.title("Hat Mod");
|
||||||
|
ModAPI.meta.description("Use /hat to put anything on your head.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
|
||||||
|
ModAPI.dedicatedServer.appendCode(function serverSideCode() {
|
||||||
|
// Find the constructor for the held item change packet that has only one argument.
|
||||||
|
// This will be used to notify the client that their hotbar has been updated.
|
||||||
|
// Reference: https://nurmarvin.github.io/Minecraft-1.8-JavaDocs/net/minecraft/network/play/server/S09PacketHeldItemChange.html
|
||||||
|
var S09PacketHeldItemChange_Constructor = ModAPI.reflect.getClassByName("S09PacketHeldItemChange").constructors.find(x => x.length === 1);
|
||||||
|
|
||||||
|
//Add an event listener for when a command is processed on the server.
|
||||||
|
ModAPI.addEventListener("processcommand", (event) => {
|
||||||
|
// If the command starts with /hat
|
||||||
|
if (event.command.toLowerCase().startsWith("/hat")) {
|
||||||
|
// Exit if the sender isn't a player
|
||||||
|
if (
|
||||||
|
!ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP").instanceOf(
|
||||||
|
event.sender.getRef()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the current held item
|
||||||
|
var heldItem = event.sender.inventory.getCurrentItem();
|
||||||
|
|
||||||
|
// Get the contents of the helmet slot
|
||||||
|
var armorItem = event.sender.inventory.armorInventory[3];
|
||||||
|
|
||||||
|
// Get the inventory index of the current held item
|
||||||
|
var hotbarIdx = event.sender.inventory.currentItem;
|
||||||
|
|
||||||
|
// Set the helmet slot to heldItem.getRef() (raw java object) if heldItem exists, otherwise set it to null
|
||||||
|
event.sender.inventory.armorInventory[3] = heldItem ? heldItem.getRef() : null;
|
||||||
|
|
||||||
|
// Set the hotbar slot to the original value of the helmet slot if it has a value, otherwise set it to null
|
||||||
|
event.sender.inventory.mainInventory[hotbarIdx] = armorItem ? armorItem.getRef() : null;
|
||||||
|
|
||||||
|
// Make a packet to notify the client that the selected hotbar slot has been updated.
|
||||||
|
event.sender.playerNetServerHandler.sendPacket(makePacketItemChange(hotbarIdx));
|
||||||
|
|
||||||
|
// Prevent the 'unknown command' error
|
||||||
|
event.preventDefault = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
```
|
@ -11,23 +11,23 @@ Prerequisites:
|
|||||||
Tutorials:
|
Tutorials:
|
||||||
- [Step Hack](step.md)
|
- [Step Hack](step.md)
|
||||||
- [Spider Hack](spider.md)
|
- [Spider Hack](spider.md)
|
||||||
- [VClip Exploit](comingsoon)
|
- [VClip Exploit](vclip.md)
|
||||||
|
|
||||||
### Intermediate
|
### Intermediate
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
- Basic knowledge of JavaScript
|
- Intermediate knowledge of JavaScript (functions, arrays, promises, callbacks, keys and values in objects)
|
||||||
- A good code editor (recommended: https://vscode.dev)
|
- A good code editor (recommended: https://vscode.dev)
|
||||||
- A copy of the eaglercraft workspace (optional, get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)
|
- A copy of the eaglercraft workspace (optional, get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)
|
||||||
|
|
||||||
Tutorials:
|
Tutorials:
|
||||||
- [Disable All Particles](comingsoon)
|
- [Disable All Particles](disable_all_particles.md)
|
||||||
- [/hat mod](comingsoon)
|
- [Slippery Mod](slippery.md)
|
||||||
|
- [/hat mod](hat.md)
|
||||||
- [/spawnxp command](comingsoon)
|
- [/spawnxp command](comingsoon)
|
||||||
- [Slippery Mod](comingsoon)
|
|
||||||
|
|
||||||
### Advanced
|
### Advanced
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
- Basic knowledge of JavaScript
|
- Advanced knowledge of JavaScript (prototypes)
|
||||||
- A good code editor (recommended: https://vscode.dev)
|
- A good code editor (recommended: https://vscode.dev)
|
||||||
- A copy of the eaglercraft workspace (get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)
|
- A copy of the eaglercraft workspace (get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)
|
||||||
- Your EaglerForgeInjector processed.html opened in an editor (optional)
|
- Your EaglerForgeInjector processed.html opened in an editor (optional)
|
||||||
|
108
docs/tutorials/slippery.md
Normal file
108
docs/tutorials/slippery.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
## Slippery Mod with ModAPI
|
||||||
|
In this tutorial you will learn how to modify properties of blocks, and run the code that does this on both the dedicated server and the client.
|
||||||
|
|
||||||
|
We'll begin with the basic boilerplate mod code:
|
||||||
|
```javascript
|
||||||
|
(function SlipperyMod() {
|
||||||
|
ModAPI.meta.title("Slippery Mod");
|
||||||
|
ModAPI.meta.description("Makes everything turn into ice.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
|
||||||
|
//New code will go here!
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's write the client side part of the code first.
|
||||||
|
- We'll get the keys for the ModAPI.blocks object (ids of each block) using [`Object.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
|
||||||
|
- Then, we'll loop over those keys, and modify their respective block to be as slippery as ice.
|
||||||
|
```javascript
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
|
||||||
|
blockKeys.forEach(key => { //for each key (block id)
|
||||||
|
//make sure the block has a slipperiness property
|
||||||
|
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98; //Set the slipperiness value of the block at that key to 0.98
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Your code should now look like this:
|
||||||
|
```javascript
|
||||||
|
(function SlipperyMod() {
|
||||||
|
ModAPI.meta.title("Slippery Mod");
|
||||||
|
ModAPI.meta.description("Makes everything turn into ice.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
blockKeys.forEach(key => {
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
Your code should now look like this:
|
||||||
|
```javascript
|
||||||
|
(function SlipperyMod() {
|
||||||
|
ModAPI.meta.title("Slippery Mod");
|
||||||
|
ModAPI.meta.description("Makes everything turn into ice.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
blockKeys.forEach(key => {
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//dedicated server code will be added here
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
Currently this only runs on the client meaning in singleplayer, when you throw an item or punch a sheep, it still won't slide. Only you will.
|
||||||
|
|
||||||
|
We'll have to duplicate the code to run on the server using [`ModAPI.dedicatedServer`](../apidoc/dedicatedserver.md).
|
||||||
|
We also have to run the code after the `serverstart` event, as on the server, `ModAPI.blocks` is only created when it is needed.
|
||||||
|
```javascript
|
||||||
|
ModAPI.dedicatedServer.appendCode(function () {
|
||||||
|
//Code in here cannot reference outside variables.
|
||||||
|
ModAPI.addEventListener("serverstart", function () {
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
blockKeys.forEach(key => {
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
let's add this to the final mod, and we'll be finished!
|
||||||
|
```javascript
|
||||||
|
(function SlipperyMod() {
|
||||||
|
ModAPI.meta.title("Slippery Mod");
|
||||||
|
ModAPI.meta.description("Makes everything turn into ice.");
|
||||||
|
ModAPI.meta.credits("By <author_name>");
|
||||||
|
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
blockKeys.forEach(key => {
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ModAPI.dedicatedServer.appendCode(function () {
|
||||||
|
//Code in here cannot reference outside variables.
|
||||||
|
ModAPI.addEventListener("serverstart", function () {
|
||||||
|
var blockKeys = Object.keys(ModAPI.blocks);
|
||||||
|
blockKeys.forEach(key => {
|
||||||
|
if(ModAPI.blocks[key]?.slipperiness) {
|
||||||
|
ModAPI.blocks[key].slipperiness = 0.98;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
```
|
82
docs/tutorials/vclip.md
Normal file
82
docs/tutorials/vclip.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
## VClip Exploit with ModAPI
|
||||||
|
Most minecraft servers have an exploit where you can trick the server into clipping you up to 10 blocks up or down through ceilings or floors.
|
||||||
|
|
||||||
|
### Part 1: Setup
|
||||||
|
|
||||||
|
Make a new file in your editor, and call it something like `vclip.js`
|
||||||
|
First, let's setup a basic [IIFE (immediately invoked function expression)](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) around our mod code. This ensures that we don't leak variables that can interfere wiht other mods.\
|
||||||
|
Example of the issue: if mod A and mod B both use `var myVariable = 0`, the value for myVariable will get overwritten.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function VClipExploit() {
|
||||||
|
//Future code here
|
||||||
|
})(); //We define a function, called VClipExploit, which we wrap in parantheses () and immediately execute.
|
||||||
|
```
|
||||||
|
This allows us to use variables without worrying about mod compatibility, as variables are scoped to the function.
|
||||||
|
|
||||||
|
\
|
||||||
|
Then, we'll add some basic [metadata](../apidoc/meta.md) for the mod loader (note that this is optional, but makes the mod look a lot better in the GUI once the game is loaded.)\
|
||||||
|
We'll also require the player, so the `ModAPI.player` global is generated.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function VClipExploit() {
|
||||||
|
ModAPI.meta.title("VClip Exploit");
|
||||||
|
ModAPI.meta.description("todo: add description.");
|
||||||
|
ModAPI.meta.credits("By author_name");
|
||||||
|
|
||||||
|
ModAPI.require("player");
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Part 2: VClip Exploit
|
||||||
|
Our VClip exploit will be triggered by a client-side command, `.vclip <amount>`.
|
||||||
|
Let's start off with the vclip command by adding an event listener to when the player sends a chat message:
|
||||||
|
```javascript
|
||||||
|
(function VClipExploit() {
|
||||||
|
ModAPI.meta.title("VClip Exploit");
|
||||||
|
ModAPI.meta.description("todo: add description.");
|
||||||
|
ModAPI.meta.credits("By author_name");
|
||||||
|
|
||||||
|
ModAPI.require("player");
|
||||||
|
|
||||||
|
ModAPI.addEventListener("sendchatmessage", (ev) => {
|
||||||
|
// handler code here
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
In this event handler, we can get the content of the message by using `event.message`, process it, and check whether it is using the `.vclip` command. We can do this by casting the string to lowercase, using [`string.toLowerCase()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase), checking if the result of that is a call to the `.vclip` command using [`string.startsWith()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith).
|
||||||
|
|
||||||
|
If it is a call to the VClip command, we can use [`string.split(" ")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) to get all the arguments, find the vclip amount, and change the player's position.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function VClipExploit() {
|
||||||
|
ModAPI.meta.title("VClip Exploit");
|
||||||
|
ModAPI.meta.description("todo: add description.");
|
||||||
|
ModAPI.meta.credits("By author_name");
|
||||||
|
|
||||||
|
ModAPI.require("player");
|
||||||
|
|
||||||
|
ModAPI.addEventListener("sendchatmessage", (ev) => {
|
||||||
|
var string = ev.message.toLowerCase(); //Get the lower case version of the command
|
||||||
|
if (string.startsWith(".vclip")) { //does the chat message start with .vclip?
|
||||||
|
ev.preventDefault = true; //we don't want this being sent into chat as a message
|
||||||
|
var yOffset = 1; //The offset on the y axis
|
||||||
|
var args = string.split(" ");
|
||||||
|
if (args[1]) { //If the second argument to .vclip exists (the vclip <amount>)
|
||||||
|
yOffset = parseFloat(args[1]) || 0; //Convert the second argument into a number. We use || to replace NaN (invalid numbers) with 0. Then, store it into the y offset.
|
||||||
|
} //This allows you to just type .vclip to clip upwards 1 block.
|
||||||
|
|
||||||
|
ModAPI.player.setPosition( //This function sets the players position to an XYZ coordinate
|
||||||
|
ModAPI.player.posX,
|
||||||
|
ModAPI.player.posY + yOffset, //All XYZ elements are the same, except we add the yOffset variable to the y axis.
|
||||||
|
ModAPI.player.posZ
|
||||||
|
);
|
||||||
|
|
||||||
|
//Finally, log the amount we've VClipped into the chat.
|
||||||
|
ModAPI.displayToChat("[VClip] VClipped " + yOffset + " blocks.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
```
|
@ -9,9 +9,6 @@ ModAPI.dedicatedServer.appendCode(function () {
|
|||||||
// This will be used to notify the client that their hotbar has been updated.
|
// This will be used to notify the client that their hotbar has been updated.
|
||||||
var makePacketItemChange = ModAPI.reflect.getClassByName("S09PacketHeldItemChange").constructors.find(x => x.length === 1);
|
var makePacketItemChange = ModAPI.reflect.getClassByName("S09PacketHeldItemChange").constructors.find(x => x.length === 1);
|
||||||
|
|
||||||
// Find the method for sending packets.
|
|
||||||
var sendPacket = ModAPI.reflect.getClassByName("NetHandlerPlayServer").methods.sendPacket.method;
|
|
||||||
|
|
||||||
// When the server is processing a command
|
// When the server is processing a command
|
||||||
ModAPI.addEventListener("processcommand", (event) => {
|
ModAPI.addEventListener("processcommand", (event) => {
|
||||||
// If the command starts with /hat
|
// If the command starts with /hat
|
||||||
@ -35,7 +32,7 @@ ModAPI.dedicatedServer.appendCode(function () {
|
|||||||
event.sender.inventory.mainInventory[hotbarIdx] = armorItem ? armorItem.getRef() : null;
|
event.sender.inventory.mainInventory[hotbarIdx] = armorItem ? armorItem.getRef() : null;
|
||||||
|
|
||||||
// Use the sendPacket method to send a item change packet to the client.
|
// Use the sendPacket method to send a item change packet to the client.
|
||||||
sendPacket(event.sender.playerNetServerHandler.getRef(), makePacketItemChange(hotbarIdx));
|
event.sender.playerNetServerHandler.sendPacket(makePacketItemChange(hotbarIdx));
|
||||||
|
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "renderParticles")] = ()=>{};
|
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "renderParticles")] = ()=>{};
|
||||||
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "hasParticlesInAlphaLayer")] = ()=>{return 0};
|
|
||||||
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addEffect")] = ()=>{};
|
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addEffect")] = ()=>{};
|
||||||
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addBlockDestroyEffects")] = ()=>{};
|
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "addBlockDestroyEffects")] = ()=>{};
|
||||||
|
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.client.particle.EffectRenderer", "hasParticlesInAlphaLayer")] = ()=>{return 0};
|
@ -9,7 +9,6 @@ ModAPI.dedicatedServer.appendCode(()=>{ //Add version of the code to the dedicat
|
|||||||
blockKeys.forEach(key=>{ //Loop through all the identifiers
|
blockKeys.forEach(key=>{ //Loop through all the identifiers
|
||||||
if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
|
if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
|
||||||
ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
|
ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
|
||||||
ModAPI.blocks[key].reload();// load the value
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -18,6 +17,5 @@ var blockKeys = Object.keys(ModAPI.blocks); //Get keys (identifiers) of all the
|
|||||||
blockKeys.forEach(key=>{ //Loop through all the identifiers
|
blockKeys.forEach(key=>{ //Loop through all the identifiers
|
||||||
if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
|
if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
|
||||||
ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
|
ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
|
||||||
ModAPI.blocks[key].reload();// load the value
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user