From 2c34bca1c1f186d4906d2ddd65a2c62f99bfed2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 2 Nov 2014 14:29:59 +0100 Subject: [PATCH] Added permission check when changing sign value, closes #636. Tested with Cauldron and WorldGuard. --- .../oc/integration/vanilla/DriverSign.java | 28 +++++++++++++++++++ .../cil/oc/server/component/UpgradeSign.scala | 12 +++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/integration/vanilla/DriverSign.java b/src/main/scala/li/cil/oc/integration/vanilla/DriverSign.java index d9332da4f..18a871c7a 100644 --- a/src/main/scala/li/cil/oc/integration/vanilla/DriverSign.java +++ b/src/main/scala/li/cil/oc/integration/vanilla/DriverSign.java @@ -1,5 +1,7 @@ package li.cil.oc.integration.vanilla; +import cpw.mods.fml.common.eventhandler.Event; +import li.cil.oc.Settings; import li.cil.oc.api.driver.EnvironmentAware; import li.cil.oc.api.driver.NamedBlock; import li.cil.oc.api.machine.Arguments; @@ -8,10 +10,15 @@ import li.cil.oc.api.machine.Context; import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.api.prefab.DriverTileEntity; import li.cil.oc.integration.ManagedTileEntityEnvironment; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntitySign; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.FakePlayerFactory; +import net.minecraftforge.event.world.BlockEvent; public final class DriverSign extends DriverTileEntity implements EnvironmentAware { @Override @@ -53,6 +60,10 @@ public final class DriverSign extends DriverTileEntity implements EnvironmentAwa @Callback(doc = "function(value:string):string -- Set the multi-line text the sign should display. This is clamped as necessary.") public Object[] setValue(final Context context, final Arguments args) { + if (!canChangeSign(null, tileEntity)) { + return new Object[]{null, "not allowed"}; + } + final String value = args.checkString(0); final String[] lines = value.split("\n"); for (int i = 0; i < 4; ++i) { @@ -82,4 +93,21 @@ public final class DriverSign extends DriverTileEntity implements EnvironmentAwa return value.toString(); } } + + public static boolean canChangeSign(EntityPlayer player, final TileEntitySign tileEntity) { + if (player == null) { + player = FakePlayerFactory.get((WorldServer) tileEntity.getWorldObj(), Settings.get().fakePlayerProfile()); + } + if (!tileEntity.getWorldObj().canMineBlock(player, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord)) { + return false; + } + + final BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, tileEntity.getWorldObj(), tileEntity.getBlockType(), tileEntity.getBlockMetadata(), player); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled() || event.getResult() == Event.Result.DENY) { + return false; + } + + return true; + } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala b/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala index ae37df98f..42a6d4e2b 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala @@ -2,12 +2,14 @@ package li.cil.oc.server.component import li.cil.oc.api.Network import li.cil.oc.api.driver.EnvironmentHost +import li.cil.oc.api.internal.Robot +import li.cil.oc.api.internal.Rotatable import li.cil.oc.api.machine.Arguments import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.api.prefab -import li.cil.oc.api.internal.Rotatable +import li.cil.oc.integration.vanilla.DriverSign import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ import net.minecraft.tileentity.TileEntitySign @@ -33,6 +35,14 @@ class UpgradeSign(val host: EnvironmentHost with Rotatable) extends prefab.Manag val text = args.checkString(0).lines.padTo(4, "").map(line => if (line.length > 15) line.substring(0, 15) else line) findSign match { case Some(sign) => + val player = host match { + case robot: Robot => Option(robot.player) + case _ => None + } + if (!DriverSign.canChangeSign(player.orNull, sign)) { + return result(Unit, "not allowed") + } + text.copyToArray(sign.signText) host.world.markBlockForUpdate(sign.xCoord, sign.yCoord, sign.zCoord) result(sign.signText.mkString("\n"))