working around BattleGear 2's access transformer screwing with the EntityPlayer class in a way that breaks robots

This commit is contained in:
Florian Nücke 2014-03-30 17:54:51 +02:00
parent e03d7ce2ff
commit 0adfbe42c6
2 changed files with 27 additions and 10 deletions

View File

@ -1,8 +1,10 @@
package li.cil.oc.server.component.robot package li.cil.oc.server.component.robot
import cpw.mods.fml.common.ObfuscationReflectionHelper
import java.util.logging.Level
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.Settings
import li.cil.oc.util.mods.{Mods, UniversalElectricity, TinkersConstruct, PortalGun} import li.cil.oc.util.mods.{Mods, UniversalElectricity, TinkersConstruct, PortalGun}
import li.cil.oc.{OpenComputers, Settings}
import net.minecraft.block.{BlockPistonBase, BlockFluid, Block} import net.minecraft.block.{BlockPistonBase, BlockFluid, Block}
import net.minecraft.entity.item.EntityItem import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.{EnumStatus, EntityPlayer} import net.minecraft.entity.player.{EnumStatus, EntityPlayer}
@ -13,6 +15,7 @@ import net.minecraft.server.MinecraftServer
import net.minecraft.util._ import net.minecraft.util._
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.{MinecraftForge, ForgeHooks, ForgeDirection} import net.minecraftforge.common.{MinecraftForge, ForgeHooks, ForgeDirection}
import net.minecraftforge.event.entity.player.PlayerInteractEvent
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.event.world.BlockEvent
import net.minecraftforge.event.{Event, ForgeEventFactory} import net.minecraftforge.event.{Event, ForgeEventFactory}
@ -30,7 +33,10 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
setSize(1, 1) setSize(1, 1)
val robotInventory = new Inventory(this) val robotInventory = new Inventory(this)
inventory = robotInventory if (Mods.BattleGear2.isAvailable) {
ObfuscationReflectionHelper.setPrivateValue(classOf[EntityPlayer], this, robotInventory, "inventory", "field_71071_by")
}
else inventory = robotInventory
var facing, side = ForgeDirection.UNKNOWN var facing, side = ForgeDirection.UNKNOWN
@ -106,8 +112,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = { def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = {
callUsingItemInSlot(0, stack => { callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side) if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side))) {
if (event.isCanceled || event.useBlock == Event.Result.DENY) {
return ActivationType.None return ActivationType.None
} }
@ -138,8 +143,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
def useEquippedItem(duration: Double) = { def useEquippedItem(duration: Double) = {
callUsingItemInSlot(0, stack => { callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_AIR, 0, 0, 0, -1) if (!shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_AIR, 0, 0, 0, -1))) {
if (!event.isCanceled && event.useItem != Event.Result.DENY) {
tryUseItem(getCurrentEquippedItem, duration) tryUseItem(getCurrentEquippedItem, duration)
} }
else false else false
@ -181,8 +185,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
def placeBlock(slot: Int, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { def placeBlock(slot: Int, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
callUsingItemInSlot(slot, stack => { callUsingItemInSlot(slot, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side) if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side))) {
if (event.isCanceled || event.useBlock == Event.Result.DENY || event.useItem == Event.Result.DENY) {
return false return false
} }
@ -192,8 +195,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
def clickBlock(x: Int, y: Int, z: Int, side: Int): Double = { def clickBlock(x: Int, y: Int, z: Int, side: Int): Double = {
callUsingItemInSlot(0, stack => { callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, x, y, z, side) if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, x, y, z, side))) {
if (event.isCanceled || event.useBlock == Event.Result.DENY || event.useItem == Event.Result.DENY) {
return 0 return 0
} }
@ -291,6 +293,20 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
override def dropPlayerItemWithRandomChoice(stack: ItemStack, inPlace: Boolean) = override def dropPlayerItemWithRandomChoice(stack: ItemStack, inPlace: Boolean) =
robot.spawnStackInWorld(stack, if (inPlace) ForgeDirection.UNKNOWN else facing) robot.spawnStackInWorld(stack, if (inPlace) ForgeDirection.UNKNOWN else facing)
private def shouldCancel(f: () => PlayerInteractEvent) = {
try {
val event = f()
event.isCanceled || event.useBlock == Event.Result.DENY || event.useItem == Event.Result.DENY
}
catch {
case t: Throwable =>
if (!t.getStackTrace.exists(_.getClassName.startsWith("mods.battlegear2."))) {
OpenComputers.log.log(Level.WARNING, "Some event handler screwed up!", t)
}
false
}
}
private def callUsingItemInSlot[T](slot: Int, f: (ItemStack) => T, repair: Boolean = true) = { private def callUsingItemInSlot[T](slot: Int, f: (ItemStack) => T, repair: Boolean = true) = {
val itemsBefore = adjacentItems val itemsBefore = adjacentItems
val stack = inventory.getStackInSlot(slot) val stack = inventory.getStackInSlot(slot)

View File

@ -4,6 +4,7 @@ import cpw.mods.fml.common.versioning.VersionParser
import cpw.mods.fml.common.{ModAPIManager, Loader} import cpw.mods.fml.common.{ModAPIManager, Loader}
object Mods { object Mods {
val BattleGear2 = new Mod("battlegear2")
val BuildCraftPower = new Mod("BuildCraftAPI|power") val BuildCraftPower = new Mod("BuildCraftAPI|power")
val ComputerCraft = new Mod("ComputerCraft@[1.6,1.50)") val ComputerCraft = new Mod("ComputerCraft@[1.6,1.50)")
val ForgeMultipart = new Mod("ForgeMultipart") val ForgeMultipart = new Mod("ForgeMultipart")