seppuku/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java

166 lines
6.5 KiB
Java

package me.rigamortis.seppuku.impl.patch;
import me.rigamortis.seppuku.Seppuku;
import me.rigamortis.seppuku.api.event.world.*;
import me.rigamortis.seppuku.api.patch.ClassPatch;
import me.rigamortis.seppuku.api.patch.MethodPatch;
import me.rigamortis.seppuku.impl.management.PatchManager;
import net.minecraft.entity.Entity;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import static org.objectweb.asm.Opcodes.*;
/**
* Author Seth
* 4/6/2019 @ 1:25 PM.
*/
public final class WorldPatch extends ClassPatch {
public WorldPatch() {
super("net.minecraft.world.World", "amu");
}
/**
* This function is used to update light for blocks
* It is VERY unoptimized and in some cases it's
* better off to disable
*
* @param methodNode
* @param env
*/
@MethodPatch(
mcpName = "checkLightFor",
notchName = "c",
mcpDesc = "(Lnet/minecraft/world/EnumSkyBlock;Lnet/minecraft/util/math/BlockPos;)Z",
notchDesc = "(Lana;Let;)Z")
public void checkLightFor(MethodNode methodNode, PatchManager.Environment env) {
//create a list of instructions
final InsnList list = new InsnList();
//call our hook function
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "checkLightForHook", "()Z", false));
//create a label to jump to
final LabelNode jmp = new LabelNode();
//add "if equals" and pass in the label
list.add(new JumpInsnNode(IFEQ, jmp));
//add 0 or false
list.add(new InsnNode(ICONST_0));
//return 0 or false
list.add(new InsnNode(IRETURN));
//add our label
list.add(jmp);
//insert the instructions at the top of the function
methodNode.instructions.insert(list);
}
public static boolean checkLightForHook() {
final EventLightUpdate event = new EventLightUpdate();
Seppuku.INSTANCE.getEventManager().dispatchEvent(event);
return event.isCanceled();
}
/* @MethodPatch(
mcpName = "checkLight",
notchName = "w",
mcpDesc = "(Lnet/minecraft/util/math/BlockPos;)Z",
notchDesc = "(Let;)Z")
public void checkLight(MethodNode methodNode, PatchManager.Environment env) {
final InsnList list = new InsnList();
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "checkLightHook", "()Z", false));
final LabelNode jmp = new LabelNode();
list.add(new JumpInsnNode(IFEQ, jmp));
// by default, this function will return false if the area is not loaded or checked for light
list.add(new InsnNode(ICONST_0));
list.add(new InsnNode(IRETURN));
list.add(jmp);
methodNode.instructions.insert(list);
}
public static boolean checkLightHook() {
final EventLightUpdate event = new EventLightUpdate();
Seppuku.INSTANCE.getEventManager().dispatchEvent(event);
return event.isCanceled();
}*/
@MethodPatch(
mcpName = "getRainStrength",
notchName = "j",
mcpDesc = "(F)F",
notchDesc = "(F)F")
public void getRainStrength(MethodNode methodNode, PatchManager.Environment env) {
final InsnList list = new InsnList();
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "getRainStrengthHook", "()Z", false));
final LabelNode jmp = new LabelNode();
list.add(new JumpInsnNode(IFEQ, jmp));
list.add(new InsnNode(FCONST_0));
list.add(new InsnNode(FRETURN));
list.add(jmp);
methodNode.instructions.insert(list);
}
public static boolean getRainStrengthHook() {
final EventRainStrength event = new EventRainStrength();
Seppuku.INSTANCE.getEventManager().dispatchEvent(event);
return event.isCanceled();
}
@MethodPatch(
mcpName = "onEntityAdded",
notchName = "b",
mcpDesc = "(Lnet/minecraft/entity/Entity;)V",
notchDesc = "(Lvg;)V")
public void onEntityAdded(MethodNode methodNode, PatchManager.Environment env) {
final InsnList list = new InsnList();
list.add(new VarInsnNode(ALOAD, 1));
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onEntityAddedHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/Entity;)Z" : "(Lvg;)Z", false));
final LabelNode jmp = new LabelNode();
list.add(new JumpInsnNode(IFEQ, jmp));
list.add(new InsnNode(RETURN));
list.add(jmp);
methodNode.instructions.insert(list);
}
public static boolean onEntityAddedHook(Entity entity) {
final EventAddEntity eventAddEntity = new EventAddEntity(entity);
Seppuku.INSTANCE.getEventManager().dispatchEvent(eventAddEntity);
return eventAddEntity.isCanceled();
}
@MethodPatch(
mcpName = "onEntityRemoved",
notchName = "c",
mcpDesc = "(Lnet/minecraft/entity/Entity;)V",
notchDesc = "(Lvg;)V")
public void onEntityRemoved(MethodNode methodNode, PatchManager.Environment env) {
final InsnList list = new InsnList();
list.add(new VarInsnNode(ALOAD, 1));
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onEntityRemovedHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/Entity;)V" : "(Lvg;)V", false));
methodNode.instructions.insert(list);
}
public static void onEntityRemovedHook(Entity entity) {
Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventRemoveEntity(entity));
}
@MethodPatch(
mcpName = "spawnParticle",
notchName = "a",
mcpDesc = "(IZDDDDDD[I)V",
notchDesc = "(IZDDDDDD[I)V")
public void spawnParticle(MethodNode methodNode, PatchManager.Environment env) {
final InsnList list = new InsnList();
list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "spawnParticleHook", "()Z", false));
final LabelNode jmp = new LabelNode();
list.add(new JumpInsnNode(IFEQ, jmp));
list.add(new InsnNode(RETURN));
list.add(jmp);
methodNode.instructions.insert(list);
}
public static boolean spawnParticleHook() {
final EventSpawnParticle event = new EventSpawnParticle();
Seppuku.INSTANCE.getEventManager().dispatchEvent(event);
return event.isCanceled();
}
}