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
import cpw.mods.fml.common.ObfuscationReflectionHelper
import java.util.logging.Level
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.{OpenComputers, Settings}
import net.minecraft.block.{BlockPistonBase, BlockFluid, Block}
import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.{EnumStatus, EntityPlayer}
@ -13,6 +15,7 @@ import net.minecraft.server.MinecraftServer
import net.minecraft.util._
import net.minecraft.world.World
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.world.BlockEvent
import net.minecraftforge.event.{Event, ForgeEventFactory}
@ -30,7 +33,10 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
setSize(1, 1)
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
@ -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 = {
callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled || event.useBlock == Event.Result.DENY) {
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side))) {
return ActivationType.None
}
@ -138,8 +143,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
def useEquippedItem(duration: Double) = {
callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_AIR, 0, 0, 0, -1)
if (!event.isCanceled && event.useItem != Event.Result.DENY) {
if (!shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_AIR, 0, 0, 0, -1))) {
tryUseItem(getCurrentEquippedItem, duration)
}
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 = {
callUsingItemInSlot(slot, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled || event.useBlock == Event.Result.DENY || event.useItem == Event.Result.DENY) {
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side))) {
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 = {
callUsingItemInSlot(0, stack => {
val event = ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled || event.useBlock == Event.Result.DENY || event.useItem == Event.Result.DENY) {
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, x, y, z, side))) {
return 0
}
@ -291,6 +293,20 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
override def dropPlayerItemWithRandomChoice(stack: ItemStack, inPlace: Boolean) =
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) = {
val itemsBefore = adjacentItems
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}
object Mods {
val BattleGear2 = new Mod("battlegear2")
val BuildCraftPower = new Mod("BuildCraftAPI|power")
val ComputerCraft = new Mod("ComputerCraft@[1.6,1.50)")
val ForgeMultipart = new Mod("ForgeMultipart")