public void readPlayerData(GlowPlayer player) {
    Map<String, Tag> playerData = new HashMap<String, Tag>();
    CompoundTag playerTag = null;
    // Map<PlayerData, Object> ret = new HashMap<PlayerData, Object>();

    File playerDir = new File(world.getName(), "players");
    if (!playerDir.exists()) playerDir.mkdirs();

    File playerFile = new File(playerDir, player.getName() + ".dat");
    if (!playerFile.exists()) {
      try {
        playerFile.createNewFile();
      } catch (IOException e) {
        e.printStackTrace();
      }
    } else {
      try {
        NBTInputStream in = new NBTInputStream(new FileInputStream(playerFile));
        playerTag = (CompoundTag) in.readTag();
        in.close();
        if (playerTag != null) playerData.putAll(playerTag.getValue());
      } catch (EOFException e) {
      } catch (IOException e) {
        player.kickPlayer("Failed to read " + player.getName() + ".dat!");
        server
            .getLogger()
            .severe(
                "Failed to read player.dat for player "
                    + player.getName()
                    + " in world "
                    + world.getName()
                    + "!");
        e.printStackTrace();
      }
    }

    if (playerTag == null) playerTag = new CompoundTag("", new HashMap<String, Tag>());
    EntityStoreLookupService.find(GlowPlayer.class).load(player, playerTag);
  }
  public void writePlayerData(GlowPlayer player) {

    File playerDir = new File(world.getName(), "players");
    if (!playerDir.exists()) playerDir.mkdirs();

    File playerFile = new File(playerDir, player.getName() + ".dat");
    if (!playerFile.exists())
      try {
        playerFile.createNewFile();
      } catch (IOException e) {
        player.getSession().disconnect("Failed to access player.dat");
        server
            .getLogger()
            .severe(
                "Failed to access player.dat for player "
                    + player.getName()
                    + " in world "
                    + world.getName()
                    + "!");
      }

    Map<String, Tag> out = EntityStoreLookupService.find(GlowPlayer.class).save(player);
    try {
      NBTOutputStream outStream = new NBTOutputStream(new FileOutputStream(playerFile));
      outStream.writeTag(new CompoundTag("", out));
      outStream.close();
    } catch (IOException e) {
      player.getSession().disconnect("Failed to write player.dat", true);
      server
          .getLogger()
          .severe(
              "Failed to write player.dat for player "
                  + player.getName()
                  + " in world "
                  + world.getName()
                  + "!");
    }
  }
  public void writeWorldData() throws IOException {
    Map<String, Tag> out = new HashMap<String, Tag>();
    File uuidFile = new File(dir, "uid.dat");
    if (!uuidFile.exists()) {
      try {
        uuidFile.createNewFile();
      } catch (IOException e) {
        handleWorldException("uid.dat", e);
      }
    } else {
      UUID uuid = world.getUID();
      DataOutputStream str = new DataOutputStream(new FileOutputStream(uuidFile));
      str.writeLong(uuid.getLeastSignificantBits());
      str.writeLong(uuid.getMostSignificantBits());
      str.close();
    }
    out.putAll(unknownTags);
    unknownTags.clear();
    // Normal level data
    out.put("thundering", new ByteTag("thundering", (byte) (world.isThundering() ? 1 : 0)));
    out.put("RandomSeed", new LongTag("RandomSeed", world.getSeed()));
    out.put("Time", new LongTag("Time", world.getTime()));
    out.put("raining", new ByteTag("raining", (byte) (world.hasStorm() ? 1 : 0)));
    out.put("thunderTime", new IntTag("thunderTime", world.getThunderDuration()));
    out.put("rainTime", new IntTag("rainTime", world.getWeatherDuration()));
    Location loc = world.getSpawnLocation();
    out.put("SpawnX", new IntTag("SpawnX", loc.getBlockX()));
    out.put("SpawnY", new IntTag("SpawnY", loc.getBlockY()));
    out.put("SpawnZ", new IntTag("SpawnZ", loc.getBlockZ()));
    // Format-specific
    out.put("LevelName", new StringTag("LevelName", world.getName()));
    out.put("LastPlayed", new LongTag("LastPlayed", Calendar.getInstance().getTimeInMillis()));
    out.put("version", new IntTag("version", 19132));

    if (!out.containsKey("SizeOnDisk"))
      out.put(
          "SizeOnDisk",
          new LongTag("SizeOnDisk", 0)); // Not sure how to calculate this, so ignoring for now
    try {
      NBTOutputStream nbtOut =
          new NBTOutputStream(new FileOutputStream(new File(dir, "level.dat")));
      nbtOut.writeTag(new CompoundTag("Data", out));
      nbtOut.close();
    } catch (IOException e) {
      handleWorldException("level.dat", e);
    }
  }
 private void handleWorldException(String file, IOException e) {
   server.unloadWorld(world, false);
   server.getLogger().severe("Unable to access " + file + " for world " + world.getName());
   e.printStackTrace();
 }