Solved ClassCastException when setting command in a command block

Discussion in 'Spigot Plugin Development' started by DOGC_Kyle, May 3, 2017.

  1. I'm trying to create a command block and set the command inside it with setCommand(String command). I was able to set the block to a command block, but when I try to set the command, I get this exception (casting CommandBlock to BlockState):
    Code (Text):
    3:48:54 PM [WARNING] [Warpstones] Task #4290 for Warpstones v1.0.3.2 generated an exception
    3:48:54 PM java.lang.ClassCastException: org.bukkit.craftbukkit.v1_11_R1.block.CraftBlockState cannot be cast to org.bukkit.block.CommandBlock
    3:48:54 PM     at com.KyleNecrowolf.Warpstones.EventListener$1.run(EventListener.java:53) ~[?:?]
    3:48:54 PM     at org.bukkit.craftbukkit.v1_11_R1.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:54 PM     at org.bukkit.craftbukkit.v1_11_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:353) [spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:54 PM     at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:738) [spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:54 PM     at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:54 PM     at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:678) [spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:54 PM     at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:576) [spigot-1.11.2.jar:git-Spigot-3fb9445-fecf4b4]
    3:48:55 PM     at java.lang.Thread.run(Unknown Source) [?:1.8.0_131]
    Here is the code I am using. I looked for past threads with this issue, but the way I am doing this looks to be the same as what was suggested in other threads (here's one I looked at)

    Code (Text):
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event){
            // If this is a pressure plate, check if they're setting a command block
            if(event.getAction() == Action.PHYSICAL && event.getClickedBlock().getType() == Material.STONE_PLATE){
                Player player = event.getPlayer();
                if(Common.warpstoneCmdSet.containsKey(player)){
                    // Set the command block
                    String warpName = Common.warpstoneCmdSet.get(player);
                    BlockState cmdBlock = player.getLocation().subtract(0, 2, 0).getBlock().getState();
                    cmdBlock.setType(Material.COMMAND);
                    cmdBlock.update(true);
                   
                    // Delay
                    Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getProvidingPlugin(EventListener.class), new Runnable() {
                        @Override
                        public void run(){
                            // Update the command block after five seconds so the player has time to move
    // FOLLOWING LINE CAUSES ERROR
                            ((CommandBlock) cmdBlock).setCommand("/warpstone enter "+warpName+" @p[r=2]");
                            cmdBlock.update(true);
                        }
                    }, 20 * 3);
                   
                    // If they've done this four times, automatically exit
                    timesSetCmd++;
                    if(timesSetCmd>=4){
                        timesSetCmd = 0;
                        Common.warpstoneCmdSet.remove(player);
                    }
                   
                    Common.sendActionBar(player, Common.messageText+""+timesSetCmd+" warpstone command blocks set");
                }
            }
        }
    I'm trying to set the command block when a player steps on a pressure plate, after a five second delay (so the player has time to step away without triggering the command). As I mentioned, the command block is placed correctly, I just can't set the command.

    Usually I'd assume the block isn't a command block and therefore won't cast, but in this case I know for certain that it is a command block.

    Any help would be greatly appreciated.
     
  2. You're trying to cast a Block to a BlockState. Pretty sure that's not how it works
     
  3. Nah that's not it.

    @DOGC_Kyle You're getting the current state of the block before setting it to a command block. This results in you getting the improper state. Swap the 2 lines.
     
    • Useful Useful x 1
  4. Thanks, that worked. I ended up changing the block first , then taking the blockstate and setting the command.
    Code (Text):
    // Set the command block
                        Block cmdBlock = player.getLocation().subtract(0, 2, 0).getBlock();
                        cmdBlock.setType(Material.COMMAND);
                        BlockState cmdBlockState = cmdBlock.getState();

                        // Delay
                        Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getProvidingPlugin(EventListener.class), new Runnable() {
                            @Override
                            public void run(){
                                // Update the command block after five seconds so the player has time to move
                                ((CommandBlock) cmdBlockState).setCommand("/warpstone enter "+warpName+" @p[r=2]");
                                cmdBlockState.update(true);
                            }
                        }, 20 * 3);