diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 1b59b17fa..3b7853f77 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1005,5 +1005,12 @@ opencomputers { # Pass along IDs of items and fluids when converting them to a table # representation for Lua. insertIdsInConverters: false + + # Enable debug card functionality. This may also be of use for custom + # maps, so it is enabled by default. If you run a server where people + # may cheat in items but should not have op/admin-like rights, you may + # want to set this to false. This will *not* remove the card, it will + # just make all functions it provides error out. + enableDebugCard: true } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index c8f09f908..303ba6b80 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -273,6 +273,7 @@ class Settings(config: Config) { val nativeInTmpDir = config.getBoolean("debug.nativeInTmpDir") val periodicallyForceLightUpdate = config.getBoolean("debug.periodicallyForceLightUpdate") val insertIdsInConverters = config.getBoolean("debug.insertIdsInConverters") + val enableDebugCard = config.getBoolean("debug.enableDebugCard") } object Settings { diff --git a/src/main/scala/li/cil/oc/server/component/DebugCard.scala b/src/main/scala/li/cil/oc/server/component/DebugCard.scala index 786ef5499..1a7659506 100644 --- a/src/main/scala/li/cil/oc/server/component/DebugCard.scala +++ b/src/main/scala/li/cil/oc/server/component/DebugCard.scala @@ -1,5 +1,6 @@ package li.cil.oc.server.component +import li.cil.oc.Settings import li.cil.oc.api.Network import li.cil.oc.api.driver.Container import li.cil.oc.api.network.{Arguments, Callback, Context, Visibility} @@ -21,26 +22,47 @@ class DebugCard(owner: Container) extends component.ManagedComponent { // ----------------------------------------------------------------------- // + import li.cil.oc.server.component.DebugCard.checkEnabled + @Callback(doc = """function(value:number):number -- Changes the component network's energy buffer by the specified delta.""") - def changeBuffer(context: Context, args: Arguments): Array[AnyRef] = result(node.changeBuffer(args.checkDouble(0))) + def changeBuffer(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(node.changeBuffer(args.checkDouble(0))) + } @Callback(doc = """function():number -- Get the container's X position in the world.""") - def getX(context: Context, args: Arguments): Array[AnyRef] = result(owner.xPosition) + def getX(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(owner.xPosition) + } @Callback(doc = """function():number -- Get the container's Y position in the world.""") - def getY(context: Context, args: Arguments): Array[AnyRef] = result(owner.yPosition) + def getY(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(owner.yPosition) + } @Callback(doc = """function():number -- Get the container's Z position in the world.""") - def getZ(context: Context, args: Arguments): Array[AnyRef] = result(owner.zPosition) + def getZ(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(owner.zPosition) + } @Callback(doc = """function():userdata -- Get the container's world object.""") - def getWorld(context: Context, args: Arguments): Array[AnyRef] = result(new DebugCard.WorldValue(owner.world)) + def getWorld(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(new DebugCard.WorldValue(owner.world)) + } @Callback(doc = """function(name:string):userdata -- Get the entity of a player.""") - def getPlayer(context: Context, args: Arguments): Array[AnyRef] = result(new DebugCard.PlayerValue(args.checkString(0))) + def getPlayer(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() + result(new DebugCard.PlayerValue(args.checkString(0))) + } } object DebugCard { + def checkEnabled() = if (!Settings.get.enableDebugCard) throw new Exception("debug card functionality is disabled") final private def result(args: Any*): Array[AnyRef] = { def unwrap(arg: Any): AnyRef = arg match { @@ -56,15 +78,21 @@ object DebugCard { // ----------------------------------------------------------------------- // def withPlayer(f: (EntityPlayerMP) => Array[AnyRef]) = { + checkEnabled() MinecraftServer.getServer.getConfigurationManager.getPlayerForUsername(name) match { case player: EntityPlayerMP => f(player) - case _ => Array(Unit, "player is offline") + case _ => result(Unit, "player is offline") } } + @Callback(doc = """function():userdata -- Get the container's world object.""") + def getWorld(context: Context, args: Arguments): Array[AnyRef] = { + withPlayer(player => result(new DebugCard.WorldValue(player.getEntityWorld))) + } + @Callback(doc = """function():string -- Get the player's game type.""") def getGameType(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => Array(player.theItemInWorldManager.getGameType.getName)) + withPlayer(player => result(player.theItemInWorldManager.getGameType.getName)) @Callback(doc = """function(gametype:string) -- Set the player's game type (survival, creative, adventure).""") def setGameType(context: Context, args: Arguments): Array[AnyRef] = @@ -75,7 +103,7 @@ object DebugCard { @Callback(doc = """function():number, number, number -- Get the player's position.""") def getPosition(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => Array(double2Double(player.posX), double2Double(player.posY), double2Double(player.posZ))) + withPlayer(player => result(player.posX, player.posY, player.posZ)) @Callback(doc = """function(x:number, y:number, z:number) -- Set the player's position.""") def setPosition(context: Context, args: Arguments): Array[AnyRef] = @@ -86,11 +114,11 @@ object DebugCard { @Callback(doc = """function():number -- Get the player's health.""") def getHealth(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => Array(float2Float(player.getHealth))) + withPlayer(player => result(player.getHealth)) @Callback(doc = """function():number -- Get the player's max health.""") def getMaxHealth(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => Array(float2Float(player.getMaxHealth))) + withPlayer(player => result(player.getMaxHealth)) @Callback(doc = """function(health:number) -- Set the player's health.""") def setHealth(context: Context, args: Arguments): Array[AnyRef] = @@ -118,53 +146,71 @@ object DebugCard { // ----------------------------------------------------------------------- // @Callback(doc = """function():number -- Gets the numeric id of the current dimension.""") - def getDimensionId(context: Context, args: Arguments): Array[AnyRef] = + def getDimensionId(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.provider.dimensionId) + } @Callback(doc = """function():string -- Gets the name of the current dimension.""") - def getDimensionName(context: Context, args: Arguments): Array[AnyRef] = + def getDimensionName(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.provider.getDimensionName) + } @Callback(doc = """function():number -- Gets the seed of the world.""") - def getSeed(context: Context, args: Arguments): Array[AnyRef] = + def getSeed(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getSeed) + } @Callback(doc = """function():boolean -- Returns whether it is currently raining.""") - def isRaining(context: Context, args: Arguments): Array[AnyRef] = + def isRaining(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.isRaining) + } @Callback(doc = """function(value:boolean) -- Sets whether it is currently raining.""") def setRaining(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() world.getWorldInfo.setRaining(args.checkBoolean(0)) null } @Callback(doc = """function():boolean -- Returns whether it is currently thundering.""") - def isThundering(context: Context, args: Arguments): Array[AnyRef] = + def isThundering(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.isThundering) + } @Callback(doc = """function(value:boolean) -- Sets whether it is currently thundering.""") def setThundering(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() world.getWorldInfo.setThundering(args.checkBoolean(0)) null } @Callback(doc = """function():number -- Get the current world time.""") - def getTime(context: Context, args: Arguments): Array[AnyRef] = + def getTime(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getWorldTime) + } @Callback(doc = """function(value:number) -- Set the current world time.""") def setTime(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() world.setWorldTime(args.checkDouble(0).toLong) null } @Callback(doc = """function():number, number, number -- Get the current spawn point coordinates.""") - def getSpawnPoint(context: Context, args: Arguments): Array[AnyRef] = + def getSpawnPoint(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getWorldInfo.getSpawnX, world.getWorldInfo.getSpawnY, world.getWorldInfo.getSpawnZ) + } @Callback(doc = """function(x:number, y:number, z:number) -- Set the spawn point coordinates.""") def setSpawnPoint(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() world.getWorldInfo.setSpawnPosition(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) null } @@ -172,39 +218,56 @@ object DebugCard { // ----------------------------------------------------------------------- // @Callback(doc = """function(x:number, y:number, z:number):number -- Get the ID of the block at the specified coordinates.""") - def getBlockId(context: Context, args: Arguments): Array[AnyRef] = + def getBlockId(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getBlockId(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Get the metadata of the block at the specified coordinates.""") - def getMetadata(context: Context, args: Arguments): Array[AnyRef] = + def getMetadata(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getBlockMetadata(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Check whether the block at the specified coordinates is loaded.""") - def isLoaded(context: Context, args: Arguments): Array[AnyRef] = + def isLoaded(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.blockExists(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Check whether the block at the specified coordinates has a tile entity.""") - def hasTileEntity(context: Context, args: Arguments): Array[AnyRef] = + def hasTileEntity(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.blockHasTileEntity(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Get the light opacity of the block at the specified coordinates.""") - def getLightOpacity(context: Context, args: Arguments): Array[AnyRef] = + def getLightOpacity(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getBlockLightOpacity(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Get the light value (emission) of the block at the specified coordinates.""") - def getLightValue(context: Context, args: Arguments): Array[AnyRef] = + def getLightValue(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.getBlockLightValue(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number):number -- Get whether the block at the specified coordinates is directly under the sky.""") - def canSeeSky(context: Context, args: Arguments): Array[AnyRef] = + def canSeeSky(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.canBlockSeeTheSky(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + } @Callback(doc = """function(x:number, y:number, z:number, id:number, meta:number):number -- Set the block at the specified coordinates.""") - def setBlock(context: Context, args: Arguments): Array[AnyRef] = + def setBlock(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() result(world.setBlock(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2), args.checkInteger(3), args.checkInteger(4), 3)) + } @Callback(doc = """function(x1:number, y1:number, z1:number, x2:number, y2:number, z2:number, id:number, meta:number):number -- Set all blocks in the area defined by the two corner points (x1, y1, z1) and (x2, y2, z2).""") def setBlocks(context: Context, args: Arguments): Array[AnyRef] = { + checkEnabled() val (xMin, yMin, zMin) = (args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) val (xMax, yMax, zMax) = (args.checkInteger(3), args.checkInteger(4), args.checkInteger(5)) val (blockId, metadata) = (args.checkInteger(6), args.checkInteger(7))