Sync. Server -- Client + Adding Blocks to a Bukkit Server

Discussion in 'Plugin Development' started by R4ID3R, Jun 13, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    R4ID3R

    Hello Bukkit Community,

    I try to write a plugin that adds sand-stairs to the game, and maybe later also other stairs. I know the client needs these blocks as well as the server and on my client the stairs work well. Here some source code how I did that (quite simple :)) :
    In the class net.minecraft.src.Block of my client I simply added:
    Code:
    /* MOD */
            //sandstonestairs = (new BlockStairs(100, sand)).setBlockName("stairsSand").disableNeighborNotifyOnMetadataChange().setBlockName("SandStairs");
            sandstonestairs = (new BlockSand(100, 18)).setHardness(0.5F).setStepSound(soundSandFootstep).setBlockName("sandi");
    /* MOD */
    The one in the comment are the real stairs. I just wanted to try out the sync. between the server and the client by making simply a "new" sand-block with ID 100 (2nd line).
    And of course the recipe added in net.minecraft.src.CraftingManager:
    Code:
    /* MOD */
            addRecipe(new ItemStack(Block.sandstonestairs, 64), new Object[] {
                "#  ", "## ", "###", Character.valueOf('#'), Block.sand
            });
    /* MOD */
    That works fine in Singleplayer! And the stairs also do!

    And so I tryed to write a plugin for my bukkit server (Build 818):

    Sandstonestairs.java:
    Code:
    package me.r4id3r.sandstonestairs;
    
    import java.util.logging.Logger;
    
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.BlockFace;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Item;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Event;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    import net.minecraft.server.Block;
    import net.minecraft.server.BlockStairs;
    
    
    public class Sandstonestairs extends JavaPlugin{
        private Logger log = Logger.getLogger("Minecrat");
        private SandstonestairsListener listen = new SandstonestairsListener(this);
        public static final SandstonestairsBlock block = new SandstonestairsBlock();
    
        public void onEnable(){
        log.info("Starting SANDSTONESTAIRS ...");
        try{
        ShapedRecipe recipe = new ShapedRecipe(new ItemStack(100,64));
        recipe.shape(new String[] {"#  ", "## ","###"});
        recipe.setIngredient('#', Material.SAND);
        getServer().addRecipe(recipe);
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvent(Event.Type.BLOCK_DAMAGE, listen, Event.Priority.Normal, this);
        log.info("...successful!");
        }
        catch (Exception e){
            log.warning("Failed loading SANDSTONESTAIRS:");
            log.warning(e.toString());
        }
        }
        public void onDisable(){
            log.info("Disabling SANDSTONESTAIRS ...");
            try{
            getServer().getScheduler().cancelTasks(this);
            log.info("... successful!");
            }
            catch (Exception e){
                log.warning("Failed disabling SANDSTONESTAIRS:");
                log.warning(e.toString());
            }
        }
    }
    SandstonestairsListener.java:
    Code:
    package me.r4id3r.sandstonestairs;
    
    import org.bukkit.event.block.BlockDamageEvent;
    import org.bukkit.event.block.BlockListener;
    import org.bukkit.inventory.ItemStack;
    
    public class SandstonestairsListener extends BlockListener {
        public static Sandstonestairs plugin;
    
        public SandstonestairsListener(Sandstonestairs instance) {
            plugin = instance;
        }
        public void onDamage(BlockDamageEvent event){
            if (event.getBlock().getTypeId() == 100){
                event.setCancelled(true);
                event.getBlock().setTypeId(0);
    
                event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(100,64));
            }
        }
    }
    
    SandstonestairsBlock.java:

    Code:
    package me.r4id3r.sandstonestairs;
    
    import net.minecraft.server.Block;
    import net.minecraft.server.Material;
    
    public class SandstonestairsBlock extends Block {
    
        protected SandstonestairsBlock() {
            super(100, Material.SAND);
        }
    
    }
    
    Notice: As I already said: Here I try to add simple "new" sand-blocks to the game, NOT stairs!
    They work fine in SinglePlayer, but when I try to build them in Multiplayer my Minecraft crashes, and there's also an error on the server:

    [WARNING] Failed to handle packet: java.lang.NullPointerException
    java.lang.NullPointerException
    at net.minecraft.server.ItemStack.b(ItemStack.java:204)
    at net.minecraft.server.SlotResult.a(SourceFile:25)
    at net.minecraft.server.Container.a(SourceFile:155)
    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:901)
    at net.minecraft.server.Packet102WindowClick.a(SourceFile:28)
    at net.minecraft.server.NetworkManager.b(NetworkManager.java:217)
    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:75)
    at net.minecraft.server.NetworkListenThread.a(SourceFile:105)
    at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:401)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:311)
    at net.minecraft.server.ThreadServerApplication.run(SourceFile:422)

    Error at the Client:

    java.lang.NullPointerException
    at net.minecraft.src.Container.onCraftGuiClosed(Container.java:203)
    at net.minecraft.src.ContainerWorkbench.onCraftGuiClosed(ContainerWorkbench.java:59)
    at net.minecraft.src.GuiCrafting.onGuiClosed(GuiCrafting.java:25)
    at net.minecraft.client.Minecraft.displayGuiScreen(Minecraft.java:340)
    at net.minecraft.src.NetClientHandler.handleKickDisconnect(NetClientHandler.java:366)
    at net.minecraft.src.Packet255KickDisconnect.processPacket(Packet255KickDisconnect.java:38)
    at net.minecraft.src.NetworkManager.processReadPackets(NetworkManager.java:203)
    at net.minecraft.src.NetClientHandler.processReadPackets(NetClientHandler.java:57)
    at net.minecraft.src.WorldClient.tick(WorldClient.java:52)
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1192)
    at net.minecraft.client.Minecraft.run(Minecraft.java:480)
    at java.lang.Thread.run(Unknown Source)

    The server starts without any problems. Only when I try to build my block it crashes!
    Anyone knows what I did wrong? And for future: Any idea how to add Stairs to a bukkit server? (maybe with BlockStairs?)

    plz help :(

    R4ID3R
     
  2. Offline

    guile2912

    I would love to have this basic example working :)
     
  3. Offline

    nisovin

    At the very least, you'd have to add your new block type to the Block array (byId) in net.minecraft.server.Block.
     
  4. Offline

    R4ID3R

    Isn't that done in the constructor by the super?
    protected SandstonestairsBlock() { super(100, Material.SAND); }
    The 100 should be the ID but i try it now.

    Thanks for the answer anyway :)
     
  5. Offline

    nisovin

  6. Offline

    R4ID3R

    Ok tried it. Doesn't work. I also checked wether my block is in the array byId:

    I added in the method onEnable():

    log.info(""+Block.byId[100]);

    It tells me something like "net.minecraft.server.BlockSand@acdd02"
    So it's defintly in the list.
    Also i changed my source code a bit but doesn't work at all :oops::
    Now i only have two classes left:

    Sandstonestairs.java:
    Code:
    package me.r4id3r.sandstonestairs;
    
    import java.util.logging.Logger;
    
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.BlockFace;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Item;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Event;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    import net.minecraft.server.Block;
    import net.minecraft.server.BlockSand;
    import net.minecraft.server.BlockStairs;
      
    public class Sandstonestairs extends JavaPlugin{
        private Logger log = Logger.getLogger("Minecrat");
        private SandstonestairsListener listen;
        public static final Block sandstonestairs = (new BlockSand(100, 18));
    
        public void onEnable(){
        log.info("Starting SANDSTONESTAIRS ...");
        listen = new SandstonestairsListener(this);
        try{
        ShapedRecipe recipe = new ShapedRecipe(new ItemStack(100,64));
        recipe.shape(new String[] {"###", "###","###"});
        recipe.setIngredient('#', Material.SAND);
        getServer().addRecipe(recipe);
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvent(Event.Type.BLOCK_DAMAGE, listen, Event.Priority.Normal, this);
        // Block.byId[100]=sandstonestairs;   // you don't need this, it's also added without that line
        log.info(""+Block.byId[100]);
        log.info("...successful!");
        }
        catch (Exception e){
            log.warning("Failed loading SANDSTONESTAIRS:");
            log.warning(e.toString());
        }
        }
        public void onDisable(){
            log.info("Disabling SANDSTONESTAIRS ...");
            try{
            getServer().getScheduler().cancelTasks(this);
            log.info("... successful!");
            }
            catch (Exception e){
                log.warning("Failed disabling SANDSTONESTAIRS:");
                log.warning(e.toString());
            }
        }
    }
    and of course my Listener, but didn't change that at all.

    Did... and I don't understand a thing :confused: :( it's too complicated for me

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 16, 2016
  7. Offline

    Elvers

    I know this is a late response, but I found this thread and had the same problem. After figuring it out, I thought an answer would be needed for anyone else who finds themselves in a similar situation.
    The reason you get a NullPointerException is that the Block constructor only adds your stair block to the Block.byId[], but the ItemStack created with the recipe references Item.byId[]. So you basically have a block that only exists as a block, and not an item.
    Adding this line in the onEnable() method should correct it ("i" is the BlockID):
    Code:
    Item.byId[i] = new ItemBlock(i - 256);
     
  8. Offline

    tboss

    I had the same problem yesterday and I finally found this after 1 hour searching x)
    After having done that, I get issues with other plugins witch uses getType().
    Has anyone an idea on how to correct this ?
     
Thread Status:
Not open for further replies.

Share This Page