Hook directly into Inventory#add using coremod

Fixes #43
This commit is contained in:
DBotThePony 2022-10-01 19:43:22 +07:00
parent acf568d6cc
commit d31b692f94
Signed by: DBot
GPG Key ID: DCC23B5715498507
6 changed files with 646 additions and 26 deletions

View File

@ -7,6 +7,12 @@ charset = utf-8
indent_style = tab
end_of_line = crlf
[*.js]
insert_final_newline = true
charset = utf-8
indent_style = tab
end_of_line = crlf
[*.java]
insert_final_newline = true
charset = utf-8
@ -18,3 +24,10 @@ insert_final_newline = false
charset = utf-8
indent_style = space
indent_size = 2
[*.toml]
insert_final_newline = false
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf

2
.gitattributes vendored
View File

@ -6,3 +6,5 @@ src/generated/**/*.json text eol=lf
*.kt text eol=crlf
*.json text eol=crlf
*.js text eol=crlf
*.toml text eol=lf

View File

@ -124,7 +124,6 @@ public final class OverdriveThatMatters {
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerChangeDimensionEvent);
EVENT_BUS.addListener(EventPriority.LOWEST, MatteryPlayerCapability.Companion::onPlayerDeath);
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerCloneEvent);
EVENT_BUS.addListener(EventPriority.LOW, MatteryPlayerCapability.Companion::onPickupEvent);
EVENT_BUS.addListener(EventPriority.HIGHEST, MatteryPlayerCapability.Companion::onLivingDrops);
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::canEntitySpawn);

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.capability
import it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap
import net.minecraft.ChatFormatting
import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag
@ -16,6 +15,7 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.MobSpawnType
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.monster.Phantom
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse
@ -57,6 +57,35 @@ import kotlin.collections.ArrayDeque
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
/**
* this method is hooked through coremod transformer
*/
fun inventoryAddItemHook(inventory: Inventory, item: ItemStack) {
if (item.isEmpty) {
return
}
val it = inventory.player.matteryPlayer ?: return
if (!it.hasExoSuit) {
return
}
val leftover = it.exoSuitContainer.addItem(item, false)
item.count = leftover.count
}
/**
* this method is hooked through coremod transformer
*/
fun inventoryAddDamagedItemHook(determinedSlot: Int, inventory: Inventory, item: ItemStack) {
if (determinedSlot > 0) {
return
}
inventoryAddItemHook(inventory, item)
}
@Suppress("unused")
class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerializable<CompoundTag> {
private inner class PlayerMatteryContainer(size: Int) : MatteryContainer(size) {
@ -820,32 +849,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
const val SLEEP_TICKS_LIMIT = 80
private val itemPickupTicks = WeakHashMap<Player, WeakHashMap<ItemEntity, MutableInt>>()
private val LOGGER = LogManager.getLogger()
fun onPickupEvent(event: EntityItemPickupEvent) {
if (event.item.owner != null && event.item.owner != event.entity.uuid && event.item.age < 200 || event.item.item.isEmpty) {
return
}
val it = event.entity.matteryPlayer ?: return
if (!it.hasExoSuit) {
return
}
val ticks = itemPickupTicks.computeIfAbsent(event.entity) { WeakHashMap() }.computeIfAbsent(event.item) { MutableInt() }
ticks.increment()
if (ticks.value < 10) {
return
}
val leftover = it.exoSuitContainer.addItem(event.item.item, false)
event.item.item.count = leftover.count
}
fun canEntitySpawn(event: LivingSpawnEvent.CheckSpawn) {
if (event.spawnReason == MobSpawnType.NATURAL && event.entity is Phantom) {
for (ply in event.entity.level.players()) {

View File

@ -0,0 +1,3 @@
{
"code_injector": "coremods/code_injector.js"
}

View File

@ -0,0 +1,598 @@
var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI')
var AbstractInsnNode = Java.type('org.objectweb.asm.tree.AbstractInsnNode')
var Opcodes = Java.type('org.objectweb.asm.Opcodes')
var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode')
var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode')
var opcodesRemapped = {
'aaload': 50,
'aastore': 83,
'aconst_null': 1,
'aload': 25,
'aload_0': 42,
'aload_1': 43,
'aload_2': 44,
'aload_3': 45,
'anewarray': 189,
'areturn': 176,
'arraylength': 190,
'astore': 58,
'astore_0': 75,
'astore_1': 76,
'astore_2': 77,
'astore_3': 78,
'athrow': 191,
'baload': 51,
'bastore': 84,
'bipush': 16,
'breakpoint': 202,
'caload': 52,
'castore': 85,
'checkcast': 192,
'd2f': 144,
'd2i': 142,
'd2l': 143,
'dadd': 99,
'daload': 49,
'dastore': 82,
'dcmpg': 152,
'dcmpl': 151,
'dconst_0': 14,
'dconst_1': 15,
'ddiv': 111,
'dload': 24,
'dload_0': 38,
'dload_1': 39,
'dload_2': 40,
'dload_3': 41,
'dmul': 107,
'dneg': 119,
'drem': 115,
'dreturn': 175,
'dstore': 57,
'dstore_0': 71,
'dstore_1': 72,
'dstore_2': 73,
'dstore_3': 74,
'dsub': 103,
'dup': 89,
'dup_x1': 90,
'dup_x2': 91,
'dup2': 92,
'dup2_x1': 93,
'dup2_x2': 94,
'f2d': 141,
'f2i': 139,
'f2l': 140,
'fadd': 98,
'faload': 48,
'fastore': 81,
'fcmpg': 150,
'fcmpl': 149,
'fconst_0': 11,
'fconst_1': 12,
'fconst_2': 13,
'fdiv': 110,
'fload': 23,
'fload_0': 34,
'fload_1': 35,
'fload_2': 36,
'fload_3': 37,
'fmul': 106,
'fneg': 118,
'frem': 114,
'freturn': 174,
'fstore': 56,
'fstore_0': 67,
'fstore_1': 68,
'fstore_2': 69,
'fstore_3': 70,
'fsub': 102,
'getfield': 180,
'getstatic': 178,
'goto': 167,
'goto_w': 200,
'i2b': 145,
'i2c': 146,
'i2d': 135,
'i2f': 134,
'i2l': 133,
'i2s': 147,
'iadd': 96,
'iaload': 46,
'iand': 126,
'iastore': 79,
'iconst_0': 3,
'iconst_1': 4,
'iconst_2': 5,
'iconst_3': 6,
'iconst_4': 7,
'iconst_5': 8,
'iconst_m1': 2,
'idiv': 108,
'if_acmpeq': 165,
'if_acmpne': 166,
'if_icmpeq': 159,
'if_icmpge': 162,
'if_icmpgt': 163,
'if_icmple': 164,
'if_icmplt': 161,
'if_icmpne': 160,
'ifeq': 153,
'ifge': 156,
'ifgt': 157,
'ifle': 158,
'iflt': 155,
'ifne': 154,
'ifnonnull': 199,
'ifnull': 198,
'iinc': 132,
'iload': 21,
'iload_0': 26,
'iload_1': 27,
'iload_2': 28,
'iload_3': 29,
'impdep1': 254,
'impdep2': 255,
'imul': 104,
'ineg': 116,
'instanceof': 193,
'invokedynamic': 186,
'invokeinterface': 185,
'invokespecial': 183,
'invokestatic': 184,
'invokevirtual': 182,
'ior': 128,
'irem': 112,
'ireturn': 172,
'ishl': 120,
'ishr': 122,
'istore': 54,
'istore_0': 59,
'istore_1': 60,
'istore_2': 61,
'istore_3': 62,
'isub': 100,
'iushr': 124,
'ixor': 130,
'jsr': 168,
'jsr_w': 201,
'l2d': 138,
'l2f': 137,
'l2i': 136,
'ladd': 97,
'laload': 47,
'land': 127,
'lastore': 80,
'lcmp': 148,
'lconst_0': 9,
'lconst_1': 10,
'ldc': 18,
'ldc_w': 19,
'ldc2_w': 20,
'ldiv': 109,
'lload': 22,
'lload_0': 30,
'lload_1': 31,
'lload_2': 32,
'lload_3': 33,
'lmul': 105,
'lneg': 117,
'lookupswitch': 171,
'lor': 129,
'lrem': 113,
'lreturn': 173,
'lshl': 121,
'lshr': 123,
'lstore': 55,
'lstore_0': 63,
'lstore_1': 64,
'lstore_2': 65,
'lstore_3': 66,
'lsub': 101,
'lushr': 125,
'lxor': 131,
'monitorenter': 194,
'monitorexit': 195,
'multianewarray': 197,
'new': 187,
'newarray': 188,
'nop': 0,
'pop': 87,
'pop2': 88,
'putfield': 181,
'putstatic': 179,
'ret': 169,
'return': 177,
'saload': 53,
'sastore': 86,
'sipush': 17,
'swap': 95,
'tableswitch': 170,
'wide': 196
}
var opcodes = []
opcodes[opcodesRemapped.aaload] = 'aaload'
opcodes[opcodesRemapped.aastore] = 'aastore'
opcodes[opcodesRemapped.aconst_null] = 'aconst_null'
opcodes[opcodesRemapped.aload] = 'aload'
opcodes[opcodesRemapped.aload_0] = 'aload_0'
opcodes[opcodesRemapped.aload_1] = 'aload_1'
opcodes[opcodesRemapped.aload_2] = 'aload_2'
opcodes[opcodesRemapped.aload_3] = 'aload_3'
opcodes[opcodesRemapped.anewarray] = 'anewarray'
opcodes[opcodesRemapped.areturn] = 'areturn'
opcodes[opcodesRemapped.arraylength] = 'arraylength'
opcodes[opcodesRemapped.astore] = 'astore'
opcodes[opcodesRemapped.astore_0] = 'astore_0'
opcodes[opcodesRemapped.astore_1] = 'astore_1'
opcodes[opcodesRemapped.astore_2] = 'astore_2'
opcodes[opcodesRemapped.astore_3] = 'astore_3'
opcodes[opcodesRemapped.athrow] = 'athrow'
opcodes[opcodesRemapped.baload] = 'baload'
opcodes[opcodesRemapped.bastore] = 'bastore'
opcodes[opcodesRemapped.bipush] = 'bipush'
opcodes[opcodesRemapped.breakpoint] = 'breakpoint'
opcodes[opcodesRemapped.caload] = 'caload'
opcodes[opcodesRemapped.castore] = 'castore'
opcodes[opcodesRemapped.checkcast] = 'checkcast'
opcodes[opcodesRemapped.d2f] = 'd2f'
opcodes[opcodesRemapped.d2i] = 'd2i'
opcodes[opcodesRemapped.d2l] = 'd2l'
opcodes[opcodesRemapped.dadd] = 'dadd'
opcodes[opcodesRemapped.daload] = 'daload'
opcodes[opcodesRemapped.dastore] = 'dastore'
opcodes[opcodesRemapped.dcmpg] = 'dcmpg'
opcodes[opcodesRemapped.dcmpl] = 'dcmpl'
opcodes[opcodesRemapped.dconst_0] = 'dconst_0'
opcodes[opcodesRemapped.dconst_1] = 'dconst_1'
opcodes[opcodesRemapped.ddiv] = 'ddiv'
opcodes[opcodesRemapped.dload] = 'dload'
opcodes[opcodesRemapped.dload_0] = 'dload_0'
opcodes[opcodesRemapped.dload_1] = 'dload_1'
opcodes[opcodesRemapped.dload_2] = 'dload_2'
opcodes[opcodesRemapped.dload_3] = 'dload_3'
opcodes[opcodesRemapped.dmul] = 'dmul'
opcodes[opcodesRemapped.dneg] = 'dneg'
opcodes[opcodesRemapped.drem] = 'drem'
opcodes[opcodesRemapped.dreturn] = 'dreturn'
opcodes[opcodesRemapped.dstore] = 'dstore'
opcodes[opcodesRemapped.dstore_0] = 'dstore_0'
opcodes[opcodesRemapped.dstore_1] = 'dstore_1'
opcodes[opcodesRemapped.dstore_2] = 'dstore_2'
opcodes[opcodesRemapped.dstore_3] = 'dstore_3'
opcodes[opcodesRemapped.dsub] = 'dsub'
opcodes[opcodesRemapped.dup] = 'dup'
opcodes[opcodesRemapped.dup_x1] = 'dup_x1'
opcodes[opcodesRemapped.dup_x2] = 'dup_x2'
opcodes[opcodesRemapped.dup2] = 'dup2'
opcodes[opcodesRemapped.dup2_x1] = 'dup2_x1'
opcodes[opcodesRemapped.dup2_x2] = 'dup2_x2'
opcodes[opcodesRemapped.f2d] = 'f2d'
opcodes[opcodesRemapped.f2i] = 'f2i'
opcodes[opcodesRemapped.f2l] = 'f2l'
opcodes[opcodesRemapped.fadd] = 'fadd'
opcodes[opcodesRemapped.faload] = 'faload'
opcodes[opcodesRemapped.fastore] = 'fastore'
opcodes[opcodesRemapped.fcmpg] = 'fcmpg'
opcodes[opcodesRemapped.fcmpl] = 'fcmpl'
opcodes[opcodesRemapped.fconst_0] = 'fconst_0'
opcodes[opcodesRemapped.fconst_1] = 'fconst_1'
opcodes[opcodesRemapped.fconst_2] = 'fconst_2'
opcodes[opcodesRemapped.fdiv] = 'fdiv'
opcodes[opcodesRemapped.fload] = 'fload'
opcodes[opcodesRemapped.fload_0] = 'fload_0'
opcodes[opcodesRemapped.fload_1] = 'fload_1'
opcodes[opcodesRemapped.fload_2] = 'fload_2'
opcodes[opcodesRemapped.fload_3] = 'fload_3'
opcodes[opcodesRemapped.fmul] = 'fmul'
opcodes[opcodesRemapped.fneg] = 'fneg'
opcodes[opcodesRemapped.frem] = 'frem'
opcodes[opcodesRemapped.freturn] = 'freturn'
opcodes[opcodesRemapped.fstore] = 'fstore'
opcodes[opcodesRemapped.fstore_0] = 'fstore_0'
opcodes[opcodesRemapped.fstore_1] = 'fstore_1'
opcodes[opcodesRemapped.fstore_2] = 'fstore_2'
opcodes[opcodesRemapped.fstore_3] = 'fstore_3'
opcodes[opcodesRemapped.fsub] = 'fsub'
opcodes[opcodesRemapped.getfield] = 'getfield'
opcodes[opcodesRemapped.getstatic] = 'getstatic'
opcodes[opcodesRemapped.goto] = 'goto'
opcodes[opcodesRemapped.goto_w] = 'goto_w'
opcodes[opcodesRemapped.i2b] = 'i2b'
opcodes[opcodesRemapped.i2c] = 'i2c'
opcodes[opcodesRemapped.i2d] = 'i2d'
opcodes[opcodesRemapped.i2f] = 'i2f'
opcodes[opcodesRemapped.i2l] = 'i2l'
opcodes[opcodesRemapped.i2s] = 'i2s'
opcodes[opcodesRemapped.iadd] = 'iadd'
opcodes[opcodesRemapped.iaload] = 'iaload'
opcodes[opcodesRemapped.iand] = 'iand'
opcodes[opcodesRemapped.iastore] = 'iastore'
opcodes[opcodesRemapped.iconst_0] = 'iconst_0'
opcodes[opcodesRemapped.iconst_1] = 'iconst_1'
opcodes[opcodesRemapped.iconst_2] = 'iconst_2'
opcodes[opcodesRemapped.iconst_3] = 'iconst_3'
opcodes[opcodesRemapped.iconst_4] = 'iconst_4'
opcodes[opcodesRemapped.iconst_5] = 'iconst_5'
opcodes[opcodesRemapped.iconst_m1] = 'iconst_m1'
opcodes[opcodesRemapped.idiv] = 'idiv'
opcodes[opcodesRemapped.if_acmpeq] = 'if_acmpeq'
opcodes[opcodesRemapped.if_acmpne] = 'if_acmpne'
opcodes[opcodesRemapped.if_icmpeq] = 'if_icmpeq'
opcodes[opcodesRemapped.if_icmpge] = 'if_icmpge'
opcodes[opcodesRemapped.if_icmpgt] = 'if_icmpgt'
opcodes[opcodesRemapped.if_icmple] = 'if_icmple'
opcodes[opcodesRemapped.if_icmplt] = 'if_icmplt'
opcodes[opcodesRemapped.if_icmpne] = 'if_icmpne'
opcodes[opcodesRemapped.ifeq] = 'ifeq'
opcodes[opcodesRemapped.ifge] = 'ifge'
opcodes[opcodesRemapped.ifgt] = 'ifgt'
opcodes[opcodesRemapped.ifle] = 'ifle'
opcodes[opcodesRemapped.iflt] = 'iflt'
opcodes[opcodesRemapped.ifne] = 'ifne'
opcodes[opcodesRemapped.ifnonnull] = 'ifnonnull'
opcodes[opcodesRemapped.ifnull] = 'ifnull'
opcodes[opcodesRemapped.iinc] = 'iinc'
opcodes[opcodesRemapped.iload] = 'iload'
opcodes[opcodesRemapped.iload_0] = 'iload_0'
opcodes[opcodesRemapped.iload_1] = 'iload_1'
opcodes[opcodesRemapped.iload_2] = 'iload_2'
opcodes[opcodesRemapped.iload_3] = 'iload_3'
opcodes[opcodesRemapped.impdep1] = 'impdep1'
opcodes[opcodesRemapped.impdep2] = 'impdep2'
opcodes[opcodesRemapped.imul] = 'imul'
opcodes[opcodesRemapped.ineg] = 'ineg'
opcodes[opcodesRemapped.instanceof] = 'instanceof'
opcodes[opcodesRemapped.invokedynamic] = 'invokedynamic'
opcodes[opcodesRemapped.invokeinterface] = 'invokeinterface'
opcodes[opcodesRemapped.invokespecial] = 'invokespecial'
opcodes[opcodesRemapped.invokestatic] = 'invokestatic'
opcodes[opcodesRemapped.invokevirtual] = 'invokevirtual'
opcodes[opcodesRemapped.ior] = 'ior'
opcodes[opcodesRemapped.irem] = 'irem'
opcodes[opcodesRemapped.ireturn] = 'ireturn'
opcodes[opcodesRemapped.ishl] = 'ishl'
opcodes[opcodesRemapped.ishr] = 'ishr'
opcodes[opcodesRemapped.istore] = 'istore'
opcodes[opcodesRemapped.istore_0] = 'istore_0'
opcodes[opcodesRemapped.istore_1] = 'istore_1'
opcodes[opcodesRemapped.istore_2] = 'istore_2'
opcodes[opcodesRemapped.istore_3] = 'istore_3'
opcodes[opcodesRemapped.isub] = 'isub'
opcodes[opcodesRemapped.iushr] = 'iushr'
opcodes[opcodesRemapped.ixor] = 'ixor'
opcodes[opcodesRemapped.jsr] = 'jsr'
opcodes[opcodesRemapped.jsr_w] = 'jsr_w'
opcodes[opcodesRemapped.l2d] = 'l2d'
opcodes[opcodesRemapped.l2f] = 'l2f'
opcodes[opcodesRemapped.l2i] = 'l2i'
opcodes[opcodesRemapped.ladd] = 'ladd'
opcodes[opcodesRemapped.laload] = 'laload'
opcodes[opcodesRemapped.land] = 'land'
opcodes[opcodesRemapped.lastore] = 'lastore'
opcodes[opcodesRemapped.lcmp] = 'lcmp'
opcodes[opcodesRemapped.lconst_0] = 'lconst_0'
opcodes[opcodesRemapped.lconst_1] = 'lconst_1'
opcodes[opcodesRemapped.ldc] = 'ldc'
opcodes[opcodesRemapped.ldc_w] = 'ldc_w'
opcodes[opcodesRemapped.ldc2_w] = 'ldc2_w'
opcodes[opcodesRemapped.ldiv] = 'ldiv'
opcodes[opcodesRemapped.lload] = 'lload'
opcodes[opcodesRemapped.lload_0] = 'lload_0'
opcodes[opcodesRemapped.lload_1] = 'lload_1'
opcodes[opcodesRemapped.lload_2] = 'lload_2'
opcodes[opcodesRemapped.lload_3] = 'lload_3'
opcodes[opcodesRemapped.lmul] = 'lmul'
opcodes[opcodesRemapped.lneg] = 'lneg'
opcodes[opcodesRemapped.lookupswitch] = 'lookupswitch'
opcodes[opcodesRemapped.lor] = 'lor'
opcodes[opcodesRemapped.lrem] = 'lrem'
opcodes[opcodesRemapped.lreturn] = 'lreturn'
opcodes[opcodesRemapped.lshl] = 'lshl'
opcodes[opcodesRemapped.lshr] = 'lshr'
opcodes[opcodesRemapped.lstore] = 'lstore'
opcodes[opcodesRemapped.lstore_0] = 'lstore_0'
opcodes[opcodesRemapped.lstore_1] = 'lstore_1'
opcodes[opcodesRemapped.lstore_2] = 'lstore_2'
opcodes[opcodesRemapped.lstore_3] = 'lstore_3'
opcodes[opcodesRemapped.lsub] = 'lsub'
opcodes[opcodesRemapped.lushr] = 'lushr'
opcodes[opcodesRemapped.lxor] = 'lxor'
opcodes[opcodesRemapped.monitorenter] = 'monitorenter'
opcodes[opcodesRemapped.monitorexit] = 'monitorexit'
opcodes[opcodesRemapped.multianewarray] = 'multianewarray'
opcodes[opcodesRemapped.new] = 'new'
opcodes[opcodesRemapped.newarray] = 'newarray'
opcodes[opcodesRemapped.nop] = 'nop'
opcodes[opcodesRemapped.pop] = 'pop'
opcodes[opcodesRemapped.pop2] = 'pop2'
opcodes[opcodesRemapped.putfield] = 'putfield'
opcodes[opcodesRemapped.putstatic] = 'putstatic'
opcodes[opcodesRemapped.ret] = 'ret'
opcodes[opcodesRemapped.return] = 'return'
opcodes[opcodesRemapped.saload] = 'saload'
opcodes[opcodesRemapped.sastore] = 'sastore'
opcodes[opcodesRemapped.sipush] = 'sipush'
opcodes[opcodesRemapped.swap] = 'swap'
opcodes[opcodesRemapped.tableswitch] = 'tableswitch'
opcodes[opcodesRemapped.wide] = 'wide'
function includes(array, value) {
var i
for (i = 0; i < array.length; i++) {
if (array[i] == value) {
return true
}
}
return false
}
function test(instructionList, instructions, offset) {
var i
var offset = offset
for (i = 0; i < instructionList.length && instructions.size() > offset; i++) {
var instruction = instructions.get(offset)
// no opcode
if (instruction.getOpcode() == -1) {
i--
offset++
continue
}
if (instructionList[i] == instruction.getOpcode()) {
offset++
} else {
// print("Not matched at " + i + " offset " + offset + " because it has op code of " + opcodes[instruction.getOpcode()] + " when expected " + opcodes[instructionList[i]])
return -1
}
}
// print("exiting with " + i + " when expecting " + instructionList.length)
return i == instructionList.length ? offset : -1
}
function injectInventoryInsertHook(
instructions,
determinedOffset,
hookName,
hookDesc,
pre
) {
var last = instructions.get(determinedOffset)
// print('Patching Inventory#add at instruction ' + determinedOffset + ' to add ' + hookName + hookDesc)
// loading this (Inventory) to stack
if (pre != undefined) {
instructions.insert(last, pre)
last = pre
}
var next = new VarInsnNode(opcodesRemapped.aload, 0)
instructions.insert(last, next)
last = next
// loading itemstack to stack
next = new VarInsnNode(opcodesRemapped.aload, 2)
instructions.insert(last, next)
last = next
// dispatching hook method
next = new MethodInsnNode(
opcodesRemapped.invokestatic,
'ru/dbotthepony/mc/otm/capability/MatteryPlayerCapabilityKt',
hookName,
hookDesc,
false
)
instructions.insert(last, next)
}
function initializeCoreMod() {
return {
'Inventory#add patch': {
'target': {
'type': 'METHOD',
'class': 'net.minecraft.world.entity.player.Inventory',
'methodName': ASMAPI.mapMethod('m_36040_'), // add
'methodDesc': '(ILnet/minecraft/world/item/ItemStack;)Z'
},
'transformer': function(node) {
// If item is not "damaged":
// 113: invokevirtual #144 // Method addResource:(ILnet/minecraft/world/item/ItemStack;)I
// 116: invokevirtual #158 // Method net/minecraft/world/item/ItemStack.setCount:(I)V
// 119: aload_2
// 120: invokevirtual #57 // Method net/minecraft/world/item/ItemStack.isEmpty:()Z
// 123: ifne 134
// 126: aload_2
// 127: invokevirtual #68 // Method net/minecraft/world/item/ItemStack.getCount:()I
// 130: iload_3
// 131: if_icmplt 87
// <-- our target
// 134: aload_2
// 135: invokevirtual #68 // Method net/minecraft/world/item/ItemStack.getCount:()I
// 138: iload_3
// 139: if_icmpne 162
// 142: aload_0
// If item returned that it is damaged:
// 10: invokevirtual #97 // Method net/minecraft/world/item/ItemStack.isDamaged:()Z
// 13: ifeq 87
// 16: iload_1
// 17: iconst_m1
// 18: if_icmpne 26
// 21: aload_0
// 22: invokevirtual #86 // Method getFreeSlot:()I
// 25: istore_1
// <-- our target
// 26: iload_1
// 27: iflt 65
// 30: aload_0
// 31: getfield #19 // Field items:Lnet/minecraft/core/NonNullList;
// 34: iload_1
// 35: aload_2
var i
// patch "not damaged"
for (i = 0; i < node.instructions.size(); i++) {
var determinedOffset = test([
opcodesRemapped.invokevirtual,
opcodesRemapped.invokevirtual,
opcodesRemapped.aload,
opcodesRemapped.invokevirtual,
opcodesRemapped.ifne,
opcodesRemapped.aload,
opcodesRemapped.invokevirtual,
opcodesRemapped.iload,
opcodesRemapped.if_icmplt,
], node.instructions, i)
if (determinedOffset != -1) {
injectInventoryInsertHook(node.instructions, determinedOffset,
'inventoryAddItemHook',
'(Lnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/item/ItemStack;)V')
break
}
}
// patch "damaged"
for (i = 0; i < node.instructions.size(); i++) {
var determinedOffset = test([
opcodesRemapped.invokevirtual,
opcodesRemapped.ifeq,
opcodesRemapped.iload,
opcodesRemapped.iconst_m1,
opcodesRemapped.if_icmpne,
opcodesRemapped.aload,
opcodesRemapped.invokevirtual,
opcodesRemapped.istore,
], node.instructions, i)
if (determinedOffset != -1) {
injectInventoryInsertHook(node.instructions, determinedOffset,
'inventoryAddDamagedItemHook',
'(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/item/ItemStack;)V',
new VarInsnNode(opcodesRemapped.iload, 1))
break
}
}
return node
}
}
}
}