Package com.tommytony.war.mapper

Source Code of com.tommytony.war.mapper.PreDeGaulleZoneVolumeMapper

package com.tommytony.war.mapper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.block.Dispenser;
import org.bukkit.block.Sign;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;

import com.tommytony.war.War;
import com.tommytony.war.job.DeferredBlockResetsJob;
import com.tommytony.war.utility.DeferredBlockReset;
import com.tommytony.war.volume.ZoneVolume;

/**
* The ZoneVolumeMapper take the blocks from disk and sets them in the worlds, since the ZoneVolume doesn't hold its blocks in memory like regular Volumes.
*
* @author tommytony
*
*/
@SuppressWarnings("deprecation")
public class PreDeGaulleZoneVolumeMapper {

  private static List<ItemStack> readInventoryString(String invString) {
    List<ItemStack> items = new ArrayList<ItemStack>();
    String[] itemsStrSplit = invString.split(";;");
    for (String itemStr : itemsStrSplit) {
      String[] itemStrSplit = itemStr.split(";");
      if (itemStrSplit.length == 4) {
        ItemStack stack = new ItemStack(Integer.parseInt(itemStrSplit[0]), Integer.parseInt(itemStrSplit[1]));
        stack.setData(new MaterialData(stack.getTypeId(), Byte.parseByte(itemStrSplit[3])));
        short durability = (short) Integer.parseInt(itemStrSplit[2]);
        stack.setDurability(durability);
        items.add(stack);
      } else if (itemStrSplit.length == 3) {
        ItemStack stack = new ItemStack(Integer.parseInt(itemStrSplit[0]), Integer.parseInt(itemStrSplit[1]));
        short durability = (short) Integer.parseInt(itemStrSplit[2]);
        stack.setDurability(durability);
        items.add(stack);
      } else {
        items.add(new ItemStack(Integer.parseInt(itemStrSplit[0]), Integer.parseInt(itemStrSplit[1])));
      }
    }
    return items;
  }

  public static int load(ZoneVolume volume, String zoneName, World world, boolean onlyLoadCorners) {
    BufferedReader in = null;
    int noOfResetBlocks = 0;
    try {
      in = new BufferedReader(new FileReader(new File(War.war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".dat")));
      String firstLine = in.readLine();

      if (firstLine != null && !firstLine.equals("")) {
        boolean height129Fix = false;
        int x1 = Integer.parseInt(in.readLine());
        int y1 = Integer.parseInt(in.readLine());
        if (y1 == 128) {
          height129Fix = true;
          y1 = 127;
        }
        int z1 = Integer.parseInt(in.readLine());
        in.readLine();
        int x2 = Integer.parseInt(in.readLine());
        int y2 = Integer.parseInt(in.readLine());
        if (y2 == 128) {
          height129Fix = true;
          y2 = 127;
        }
        int z2 = Integer.parseInt(in.readLine());

        volume.setCornerOne(world.getBlockAt(x1, y1, z1));
        volume.setCornerTwo(world.getBlockAt(x2, y2, z2));

        if (!onlyLoadCorners) {
          DeferredBlockResetsJob deferred = new DeferredBlockResetsJob(world);
          int blockReads = 0, visitedBlocks = 0, x = 0, y = 0, z = 0, i = 0, j = 0, k = 0;
          int diskBlockType;
          byte diskBlockData;
          Block worldBlock;
          int worldBlockId;
          volume.clearBlocksThatDontFloat();
          x = volume.getMinX();
          String blockLine;
          String[] blockSplit;
          for (i = 0; i < volume.getSizeX(); i++) {
            y = volume.getMinY();
            for (j = 0; j < volume.getSizeY(); j++) {
              z = volume.getMinZ();
              for (k = 0; k < volume.getSizeZ(); k++) {
                try {
                  blockLine = in.readLine();

                  if (blockLine != null && !blockLine.equals("")) {
                    blockSplit = blockLine.split(",");
                    if (blockLine != null && !blockLine.equals("") && blockSplit.length > 1) {
                      diskBlockType = Integer.parseInt(blockSplit[0]);
                      diskBlockData = Byte.parseByte(blockSplit[1]);
                      worldBlock = volume.getWorld().getBlockAt(x, y, z);
                      worldBlockId = worldBlock.getTypeId();
                      if (worldBlockId != diskBlockType || (worldBlockId == diskBlockType && worldBlock.getData() != diskBlockData) || (worldBlockId == diskBlockType && worldBlock.getData() == diskBlockData && (diskBlockType == Material.WALL_SIGN.getId() || diskBlockType == Material.SIGN_POST.getId() || diskBlockType == Material.CHEST.getId() || diskBlockType == Material.DISPENSER.getId()))) {
                        if (diskBlockType == Material.WALL_SIGN.getId() || diskBlockType == Material.SIGN_POST.getId()) {
                          // Signs read
                          String linesStr = "";
                          if (blockSplit.length > 2) {
                            for (int o = 2; o < blockSplit.length; o++) {
                              linesStr += blockSplit[o];
                            }
                            String[] lines = linesStr.split(";;");

                            // Signs set
                            // A sign post hanging on a wall south of here will
                            if (diskBlockType == Material.SIGN_POST.getId() && ((diskBlockData & 0x04) == 0x04) && i + 1 != volume.getSizeX()) {
                              deferred.add(new DeferredBlockReset(x, y, z, diskBlockType, diskBlockData, lines));
                            } else {
                              worldBlock.setType(Material.getMaterial(diskBlockType));
                              BlockState state = worldBlock.getState();
                              state.setData(new org.bukkit.material.Sign(diskBlockType, diskBlockData));
                              if (state instanceof Sign) {
                                Sign sign = (Sign) state;
                                if (lines != null && sign.getLines() != null) {
                                  if (lines.length > 0) {
                                    sign.setLine(0, lines[0]);
                                  }
                                  if (lines.length > 1) {
                                    sign.setLine(1, lines[1]);
                                  }
                                  if (lines.length > 2) {
                                    sign.setLine(2, lines[2]);
                                  }
                                  if (lines.length > 3) {
                                    sign.setLine(3, lines[3]);
                                  }
                                  sign.update(true);
                                }
                              }
                            }
                          }
                        } else if (diskBlockType == Material.CHEST.getId()) {
                          // Chests read
                          List<ItemStack> items = null;
                          if (blockSplit.length > 2) {
                            String itemsStr = blockSplit[2];
                            items = PreDeGaulleZoneVolumeMapper.readInventoryString(itemsStr);
                          }

                          // Chests set
                          worldBlock.setType(Material.getMaterial(diskBlockType));
                          worldBlock.setData(diskBlockData);
                          BlockState state = worldBlock.getState();
                          if (state instanceof Chest) {
                            Chest chest = (Chest) state;
                            if (items != null) {
                              int ii = 0;
                              chest.getInventory().clear();
                              for (ItemStack item : items) {
                                if (item != null) {
                                  chest.getInventory().setItem(ii, item);
                                  ii++;
                                }
                              }
                              chest.update(true);
                            }
                          }
                        } else if (diskBlockType == Material.DISPENSER.getId()) {
                          // Dispensers read
                          List<ItemStack> items = null;
                          if (blockSplit.length > 2) {
                            String itemsStr = blockSplit[2];
                            // String itemsStr = lineScanner.nextLine();
                            items = PreDeGaulleZoneVolumeMapper.readInventoryString(itemsStr);
                          }

                          // Dispensers set
                          worldBlock.setType(Material.getMaterial(diskBlockType));
                          worldBlock.setData(diskBlockData);
                          BlockState state = worldBlock.getState();
                          if (state instanceof Dispenser) {
                            Dispenser dispenser = (Dispenser) state;
                            if (items != null) {
                              int ii = 0;
                              dispenser.getInventory().clear();
                              for (ItemStack item : items) {
                                if (item != null) {
                                  dispenser.getInventory().setItem(ii, item);
                                  ii++;
                                }
                              }
                              dispenser.update(true);
                            }
                          }
                        } else if (diskBlockType == Material.WOODEN_DOOR.getId() || diskBlockType == Material.IRON_DOOR_BLOCK.getId()) {
                          // Door blocks

                          if (j - 1 > 0) {
                            Block blockBelow = world.getBlockAt(x, y - 1, z);
                            boolean belowIsGlass = blockBelow.getTypeId() == Material.GLASS.getId();
                            // Set current block to glass if block below isn't glass.
                            // Having a glass block below means the current block is a door top.
                            if (belowIsGlass) {
                              // Top door block. Set both it and the block below as door.
                              blockBelow.setType(Material.getMaterial(diskBlockType));
                              blockBelow.setData(diskBlockData);
                              worldBlock.setType(Material.getMaterial(diskBlockType));
                              worldBlock.setData(diskBlockData);
                            } else {
                              worldBlock.setType(Material.GLASS);
                            }
                          }

                        } else if (((diskBlockType == Material.TORCH.getId() && ((diskBlockData & 0x02) == 0x02)) || (diskBlockType == Material.REDSTONE_TORCH_OFF.getId() && ((diskBlockData & 0x02) == 0x02)) || (diskBlockType == Material.REDSTONE_TORCH_ON.getId() && ((diskBlockData & 0x02) == 0x02)) || (diskBlockType == Material.LEVER.getId() && ((diskBlockData & 0x02) == 0x02)) || (diskBlockType == Material.STONE_BUTTON.getId() && ((diskBlockData & 0x02) == 0x02)) || (diskBlockType == Material.LADDER.getId() && ((diskBlockData & 0x04) == 0x04)) || (diskBlockType == Material.RAILS.getId() && ((diskBlockData & 0x02) == 0x02))) && i + 1 != volume.getSizeX()) {
                          // Blocks that hang on a block south of themselves need to make sure that block is there before placing themselves... lol
                          // Change the block itself later on:
                          deferred.add(new DeferredBlockReset(x, y, z, diskBlockType, diskBlockData));
                        } else {
                          // regular block
                          worldBlock.setType(Material.getMaterial(diskBlockType));
                          worldBlock.setData(diskBlockData);
                        }
                        noOfResetBlocks++;
                      }
                      visitedBlocks++;
                    }
                    blockReads++;
                  }

                } catch (Exception e) {
                  War.war.getLogger().warning("Failed to reset block in zone volume " + volume.getName() + ". " + "Blocks read: " + blockReads + ". Visited blocks so far:" + visitedBlocks + ". Blocks reset: " + noOfResetBlocks + ". Error at x:" + x + " y:" + y + " z:" + z + ". Exception:" + e.getClass().toString() + " " + e.getMessage());
                  e.printStackTrace();
                } finally {
                  z++;
                }
              }
              if (height129Fix && j == volume.getSizeY() - 1) {
                for (int skip = 0; skip < volume.getSizeZ(); skip++) {
                  in.readLine(); // throw away the extra vertical block I used to save pre 0.8
                  // scanner.nextLine();
                }
              }
              y++;
            }
            x++;
          }
          if (!deferred.isEmpty()) {
            War.war.getServer().getScheduler().scheduleSyncDelayedTask(War.war, deferred, 1);
          }
        }
      }
    } catch (IOException e) {
      War.war.log("Failed to read volume file " + volume.getName() + " for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage(), Level.WARNING);
      e.printStackTrace();
    } catch (Exception e) {
      War.war.log("Unexpected error caused failure to read volume file " + zoneName + " for warzone " + volume.getName() + ". " + e.getClass().getName() + " " + e.getMessage(), Level.WARNING);
      e.printStackTrace();
    } finally {
      if (in != null) {
        // if (scanner != null)
        try {
          in.close();
          in = null;
          // scanner.close();
          // scanner = null;
        } catch (IOException e) {
          War.war.log("Failed to close file reader for volume " + volume.getName() + " for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage(), Level.WARNING);
          e.printStackTrace();
        }
      }
    }
    return noOfResetBlocks;
  }
}
TOP

Related Classes of com.tommytony.war.mapper.PreDeGaulleZoneVolumeMapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.