Quick Nav


Back To Top

Introduction

DragonAPI includes a command intended for debugging where more specialized debuggers do not exist, designed to be able to inspect or modify anything about the game state at will. It works similarly to a REPL (Read-Evaluate-Print-Loop) console, allowing the user to invoke or access any arbitrary class, object, or member thereof, allowing for the ability to - for example - see entity AI targets, query or edit data registries, check the return value of functions, and edit objects' properties.

Because this command can be used to execute nearly arbitrary code, it is very dangerous if misused - either from ill intent or incompetence - and so it does not use the usual "admin or not" check most commands have. Instead, you need to explicitly and individually whitelist each user you want to have the power to run the command, by UUID, in the relevant string-list entry in the DragonAPI config file.

Usage

All invocations of this command are done in the form of /bytecodeexec [opcode] <arguments> for standard instructions and /bytecodeexec [action] <arguments> for special actions.

The command operates like the JVM itself, ie on an operand stack, with various "instructions" (here called "opcodes") being able to view, consume, or place objects on the stack. For those with experience with Java ASM, it is modelled after this system, and an understanding of ASM should make using the command fairly intuitive. This command also requires knowing the code of the relevant classes (vanilla, Forge, and mod) to be used effectively, as you will otherwise not know what properties to look for or how to properly manipulate them.

All object references work like Java, ie they are copy by reference unless they are primitives, and as such modifications are reflected back into the ingame objects. Internally, the command works via reflection, not bytecode, and so is subject to the usual rules of reflection, with the exception of accessibility modifiers, which are ignored.

Class References and Arguments

Many opcodes take special strings as arguments, which are not parsed as literal strings. These are either class references or method parameter lists.

Class References

For opcodes which take a class as an argument, the class is specified using a "class reference" string, which can be in one of two forms. The first form is simply the fully qualified class name, eg net.minecraft.world.biome.BiomeGenBase or Reika.ChromatiCraft.TileEntity.AOE.Effect.TileEntityAccelerator. The second form, generally more convenient - and in some cases required due to command character limit counts - is as a shorthand form, referenced as simply the class's simple name preceded with '#', eg #BiomeGenBase and #TileEntityAccelerator for the two examples above. Note that aside from some common presets, classes' shortcuts must be defined explicitly, using the define special action (details below).

The following classes come with preset shortcuts:
Full Class Name Shortcut
java.lang.String String
java.lang.Object Object
java.lang.Enum Enum
java.util.ArrayList ArrayList
java.util.HashMap HashMap
java.lang. Class Class
java.lang.reflect.Field Field
java.lang.reflect.Method Method
java.lang.reflect.Array Array
java.util.Arrays Arrays
java.lang.Math Math
net.minecraft.world.World World
net.minecraft.entity.Entity Entity
net.minecraft.entity.EntityLivingBase EntityLivingBase
net.minecraft.entity.player.EntityPlayer EntityPlayer
net.minecraft.entity.player.EntityPlayerMP EntityPlayerMP
net.minecraft.tileentity.TileEntity TileEntity
net.minecraft.block.Block Block
net.minecraft.item.Item Item
net.minecraft.init.Blocks Blocks
net.minecraft.init.Items Items
net.minecraft.item.ItemStack ItemStack
net.minecraft.world.biome.BiomeGenBase Biome
net.minecraft.world.biome.BiomeGenBase BiomeGenBase
net.minecraft.server.MinecraftServer Server
net.minecraft.server.MinecraftServer MinecraftServer
net.minecraft.world.gen.ChunkProviderServer ChunkProviderServer
net.minecraft.world.gen.ChunkProviderGenerate ChunkProviderGenerate
net.minecraftforge.common.DimensionManager DimensionManager
cpw.mods.fml.common.FMLCommonHandler FML
net.minecraftforge.common.MinecraftForge Forge
net.minecraftforge.common.util.ForgeDirection ForgeDirection
cpw.mods.fml.common.Loader Loader
net.minecraftforge.fluids.Fluid Fluid
net.minecraftforge.fluids.FluidStack FluidStack
net.minecraftforge.fluids.FluidRegistry FluidRegistry
cpw.mods.fml.common.registry.GameRegistry GameRegistry
net.minecraftforge.oredict.OreDictionary OreDictionary
Reika.DragonAPI.Libraries.Java.ReikaASMHelper ASMHelper
Reika.DragonAPI.Libraries.Java.ReikaReflectionHelper ReflectionHelper
Reika.DragonAPI.Libraries.Java.ReikaJavaLibrary JavaLibrary
Reika.DragonAPI.Libraries.Java.ReikaStringParser StringParser
Reika.DragonAPI.Libraries.Java.ReikaArrayHelper ArrayHelper
Reika.DragonAPI.Libraries.MathSci.ReikaMathLibrary MathLibrary
Reika.DragonAPI.Libraries.MathSci.ReikaPhysicsHelper PhysicsHelper
Reika.DragonAPI.Libraries.World.ReikaWorldHelper WorldHelper
Reika.DragonAPI.Libraries.World.ReikaBiomeHelper BiomeHelper
Reika.DragonAPI.Libraries.World.ReikaBlockHelper BlockHelper
Reika.DragonAPI.Libraries.Registry.ReikaItemHelper ItemHelper
Reika.DragonAPI.Libraries.ReikaInventoryHelper InventoryHelper
Reika.DragonAPI.Libraries.ReikaPlayerAPI PlayerAPI
Reika.DragonAPI.Libraries.Registry.ReikaPlantHelper PlantHelper
Reika.DragonAPI.Libraries.Registry.ReikaCropHelper CropHelper
Reika.DragonAPI.Libraries.Registry.ReikaOreHelper OreHelper
Reika.DragonAPI.Libraries.Registry.ReikaTreeHelper TreeHelper
Reika.DragonAPI.ModList ModList
Reika.DragonAPI.ModRegistry.ModOreList ModOreList
Reika.DragonAPI.ModRegistry.ModWoodList ModWoodList
Reika.DragonAPI.ModRegistry.ModCropList ModCropList


Parameter Lists

For opcodes which involve invoking methods, such as INVOKESTATIC and NEW, the parameter types need to be explicitly specified. This is done in the form A;B;C;D... where A, B, C, D, etc are the argument types, such as int, double, or an object type (full name or shortcut, eg #String). For no-arg methods, simply provide a single ';', eg invokestatic #SomeClass doThing ; to call fully.qualified.namespace.SomeClass.doThing().

Opcodes

OpcodeDescriptionArgumentsConsumes N Objects From StackAdds N Objects To StackNotes
LDCLoad literal onto stack1 string1The argument will be parsed to null, an integer, then a float (for decimals use the F suffix), then a double, then a string in that order of attempts
NEWInstantiate objectClass Reference, Parameter List StringAny1Consumes as many objects from the stack as the constructor is stated to require
DUPDuplicate top of stack1
POPRemove top of stack1
SWAPSwap stack topSwaps the position of the top two objects on the stack.
INVOKESTATICCall static methodClass Reference, Name, Parameter List StringAny0 or 1Consumes as many objects from the stack as the method has parameters. Will put a return value back on the stack for non-void methods.
INVOKEVIRTUALCall instance methodClass Reference, Name, Parameter List StringAny0 or 1Consumes as many objects from the stack as the method has parameters, plus one for the object instance. Object instance must be below the parameters on the stack. Will put a return value back on the stack for non-void methods.
OBJMETHODCall instance method from objectNameAny0 or 1Finds the named method in the class defining the object on the top of the stack and invokes it. Consumes as many objects from the stack as the method has parameters, plus one for the object instance. Object instance must be the top of the stack. Will put a return value back on the stack for non-void methods.
GETSTATICFetch static fieldClass Reference, Name1
GETFIELDFetch instance fieldClass Reference, Name11Consumes the object instance from the stack
OBJFIELDFetch field value from objectName11Consumes the object on the top of the stack, and returns that object's value of the specified field to the stack.
SETFIELDSet field valueClass Reference, Name2Sets the named field in the specified class, with the top of the stack being the new field value and the value below it being the object instance (use null for static fields)
INSTANCEOFCheck instanceof21Checks if the object represented by the top of the stack is of the class object below it in the stack. Returns boolean.
MAKEARRAYConstruct object arrayArray LengthAny1Constructs a new Object[] whose members consist of the top N objects from the stack, removing all of them in the process.
GETARRAYGet array index21Fetches the object at the Nth index of the array at the top of the stack, where N is the integer below it on the stack.
SETARRAYSet array index3Fetches the array at the top of the stack, and sets its Nth index to X, where N is the integer below the array and X is the object below that.
CONCATConcatenate strings21Pops the two objects off the top of the stack, concatenates their string values (lower-upper order), and returns to the stack.
ITERATEIterate collection or arrayUnimplemented
OUTPUTView stack contents
WRITEWrite stack to fileFile path
FLUSHClear stackAll


As a convenience, you can often preface the opcode argument with '&' to peek rather than pop the stack for the operative object, allowing it to be reused. For example, &invokevirtual name args will not remove the instance object from the stack, allowing for multiple successive &invokevirtual calls without reloading it onto the stack (though any parameters will still need to be).

Method Names And Obfuscation

Unless using this command in a development environment, the copy of Minecraft you will be running with uses obfuscated field and method names, such as func_147439_a instead of getBlock. This means that for vanilla classes, you will need a copy of the mappings to know the names of the members you wish to reference, such as can be found in the standard mcp-srg.srg file.

For ease of use, some commonly-accessed members come with automatic deobfuscation:
Class Deobfuscated Name Obfuscated Name
World getBlock func_147439_a
World getBlockMetadata func_72805_g
World getTileEntity func_147438_o
World getPlayerEntityByName func_72924_a
World getPlayerEntityByUUID func_152378_a
World provider field_73011_w
EntityLivingBase getHealth func_110143_aJ
EntityPlayer getCurrentEquippedItem func_71045_bC
ItemStack getItem func_77973_b
ItemStack getItemDamage func_77960_j
ItemStack stackSize field_77994_a
TileEntity worldObj field_145850_b
TileEntity xCoord field_145851_c
TileEntity yCoord field_145848_d
TileEntity zCoord field_145849_e
Entity worldObj field_70170_p
Entity posX field_70165_t
Entity posY field_70163_u
Entity posZ field_70161_v
BiomeGenBase biomeID field_76756_M
BiomeGenBase theBiomeDecorator field_76760_I


You can also use the loadsrg special action with a filepath argument to load the mcp-srg.srg file from disk, but be aware that like all commands, this runs on the serverside, and so if you are running the command on a non-local server referencing a file on your own PC is not going to work.

Shortcuts And Special Actions

Instead of an opcode, you can supply a "special function name" to perform other actions to help use the command:
Command StringArgumentsDescription
defineFully qualified class nameDefine a class reference shortcut. Can use *stack* to fetch the class defining the object on the top of the stack (popping it off the stack in the process) instead
mapsrgClass Reference, Obf Name, Deobf NameMap one srg name
loadsrgFile pathLoad Forge MCP-SRG file
shortcutsSee class shortcuts
selfLoad self (EntityPlayer object) onto the stack
getplayerNameLoad logged-in player (EntityPlayer object) onto the stack
heldLoad held item (ItemStack object) onto the stack
lookLoad looked-at position onto the stack (World and three ints), ready for an invocation of a world function like getBlock or getTileEntity
getclassQualified Class NameLoad Class object onto the stack
startprogramName, [Properties...]Start 'recording' a bytecodeexec 'program'
saveprogramFinish 'recording' a bytecodeexec 'program' and save to disk
runprogramProgram NameRun a bytecodeexec 'program'

Programs

The command supports the recording of small "programs" which are basically just previously-executed instructions, somewhat akin to OpenGL call lists. Programs are identified by a unique name, and can be set to allow any admin or even any player to run them once recorded (with the admin and public properties respectively). To create a program, start recording, then run the opcode commands as normal. Note that special shortcuts like self or look will not function.

Examples

The following set of commands will spawn an explosion, with the power of a charged creeper (6.0) set to both spawn fires and destroy blocks, at the position -1200, 36, 720 in the overworld.
/bytecodeexec ldc 0
/bytecodeexec invokestatic #DimensionManager getWorld int
/bytecodeexec ldc null
/bytecodeexec ldc -1200
/bytecodeexec ldc 36
/bytecodeexec ldc 720
/bytecodeexec ldc 6F
/bytecodeexec ldc true
/bytecodeexec ldc true
/bytecodeexec invokevirtual #World func_72885_a #Entity;double;double;double;float;boolean;boolean


The following set of commands will spawn a MeteorCraft meteor aimed at player NAME, but set to explode above them (y=120), done by "faking" a use of the /meteor command in that mod.
/bytecodeexec define Reika.MeteorCraft.Entity.EntityMeteor
/bytecodeexec define Reika.MeteorCraft.MeteorCommand
/bytecodeexec define Reika.MeteorCraft.MeteorSpawnController
/bytecodeexec define Reika.MeteorCraft.MeteorGenerator$MeteorType
/bytecodeexec define net.minecraft.entity.player.EntityPlayerMP

/bytecodeexec new #MeteorCommand ;
/bytecodeexec getstatic #MeteorSpawnController instance
/bytecodeexec getplayer NAME
/bytecodeexec dup
/bytecodeexec getfield #Entity worldObj
/bytecodeexec swap
/bytecodeexec invokevirtual #MeteorSpawnController createMeteor #World;#EntityPlayer
/bytecodeexec invokevirtual #EntityMeteor setExploding ;
/bytecodeexec getstatic #MeteorType STONE
/bytecodeexec invokevirtual #EntityMeteor setType #MeteorType
/bytecodeexec getplayer NAME
/bytecodeexec swap
/bytecodeexec invokevirtual #MeteorCommand spawnMeteorAt #EntityPlayerMP;#EntityMeteor
/bytecodeexec dup
/bytecodeexec ldc 120
/bytecodeexec setfield #EntityMeteor explodeY


The following command will change the tree density (ie BiomeDecorator.treesPerChunk) of the Ice Plains biome type to match that of the vanilla Forest biome (whatever it might be, even if mods changed it, instead of a hardcoded value). Obviously, this would only apply to newly generated chunks, and would reset once the server is rebooted.
/bytecodeexec define net.minecraft.world.biome.BiomeGenBase
/bytecodeexec define net.minecraft.world.biome.BiomeDecorator

/bytecodeexec getstatic #BiomeGenBase field_76774_n
/bytecodeexec getfield #BiomeGenBase field_76760_I
/bytecodeexec getstatic #BiomeGenBase field_76767_f
/bytecodeexec getfield #BiomeGenBase field_76760_I
/bytecodeexec setfield #BiomeGenBase field_76832_z