Solved Block Serializable

Discussion in 'Spigot Plugin Development' started by Sonicboum, Aug 6, 2018.

  1. Hello to you !

    I'm currently doing a new plugin,
    I am currently looking for how to simply serialize a block in 1.13.

    I try to use the .toString ();
    But I do not see how to make the way back ...

    Thank you.​
     
  2. Use
    Keep in mind that this will not serialize the tile entity if there is one. To my knowledge, there is no API method to (de)serialize that.
     
    • Agree Agree x 1
    • Useful Useful x 1
  3. Correct. If you need those, use:
    • net.minecraft.server.v1_13_R1.TileEntity.load(NBTTagCompound)
    • net.minecraft.server.v1_13_R1.TileEntity.save(NBTTagCompound)
    You can use the common methods to save and load NBT files:
    • net.minecraft.server.v1_13_R1.NBTCompressedStreamTools.a(InputStream)
    • net.minecraft.server.v1_13_R1.NBTCompressedStreamTools.a(NBTTagCompound, OutputStream)
    EDIT:
    Code (Java):
    // org.bukkit.craftbukkit.v1_13_R1.block.data.CraftBlockData.getAsString()
    public String getAsString() {
      return this.state.toString();
    }
    // this.state is net.minecraft.server.v1_13_R1.IBlockData
     
    #3 Michel_0, Aug 6, 2018
    Last edited: Aug 6, 2018
    • Informative Informative x 1
  4. Hmmm agree.
    I do not understand command use createBlockData compared to getAsString I do not see how to take it.

    Thank you for your answers.
     
  5. getAsString returns you the block data serialized as a String. createBlockData takes a String and returns a deserialized BlockData, which you can then set on a Block.
     
    • Agree Agree x 1
  6. I can not find this method?
    How can I use it?
    Do you have an example?
     
  7. Are you building against the 1.13 API?
     
  8. I use API 1.13
     
  9. Code (Java):
    Bukkit.getWorlds().get(0).getBlockAt(0, 0, 0).getBlockData().getAsString()
     
    • Agree Agree x 1
  10. No, that's not what I'm looking for.

    How to pass from my String value to my BlockData value.
     
  11. StarTux linked you to the exact API methods you need to use

    EDIT: Literally just BlockData data = Bukkit.createBlockData(yourSerializedString);
     
    • Agree Agree x 1
  12. Code (Java):
    Bukkit.getWorlds().get(0).getBlockAt(0, 0, 0).setBlockData(Bukkit.createBlockData("..."));
     
    • Agree Agree x 1
  13. Here I am again an error that I obtained.
    Can you enlighten me on this one?

    Recovery code:

    Code (Java):
    private void load() {
            File file = new File(FILE_CONFIG + "/" + blockFace + ".properties");
            FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
            String d = "Structure.";
            for (int i = 0; i < 30; i++) {
                Location loc = (Location) fc.get(d + i + ".loc");
                BlockData blockData = Bukkit.createBlockData(Material.getMaterial(fc.getString(d + i + ".block.mat")),
                        fc.getString(d + i + ".block.data"));
                structureBlock.put(loc, blockData);
            }
        }
    File containing the backup:

    Code (Text):
    Structure:
      '0':
        loc:
          ==: org.bukkit.Location
          world: world
          x: 2.0
          y: 0.0
          z: 0.0
          pitch: 0.0
          yaw: 0.0
        block:
          mat: CHEST
          data: minecraft:chest[facing=north,type=right,waterlogged=false]
    Error:

    [​IMG]
     
  14. Try calling the Bukkit.createBlockData(String) version, don't pass in the Material.
     
  15. Also I guess it's worth noting, that getBlockData isn't a completely serialized block, it's just containing state info. It's not going to have any TileEntity data in it, so for instance chest inventories won't be saved.
     
  16. I wouldn't say that.
    This all is saved in there https://minecraft.gamepedia.com/Block_states, which is quite a lot and worth pretty much.

    Furthermore you'll still need the block state when you deserialize block tile entities, because the tiles doesn't contain the block state. So you'll again need the same stuff anyway.
     
  17. Ok, ça marche.
    Je ne pense pas que cela fonctionne de cette façon.
    Je vous remercie.
     
  18. Not saying that BlockData isn't useful, it's a great way to serialize basic block state. Just saying that TileEntity data isn't in there at all, so anything more complex than some simple directional or state flags isn't going to get saved. OP pasted an example with a chest in it, so it seemed worth mentioning that chest contents won't be saved.
     
  19. Just hacked something together…. but might work for saving:
    Code (Java):
    public String getTile(Location pos) {
        Block block = pos.getWorld().getBlockAt(pos);
        Chunk chunk = ((CraftChunk) block.getChunk()).getHandle();
        TileEntity tile = chunk.getTileEntity(new BlockPosition(pos.getBlockX() - (chunk.locX * 16), pos.getBlockY(), pos.getBlockZ() - (chunk.locZ * 16)));
        if (tile != null) {
            return tile.save(new NBTTagCompound()).toString();
        } else {
            return null;
        }
    }