mirror of
https://github.com/taoneill/war.git
synced 2024-11-23 18:55:28 +01:00
Closes gh-223. New zone file format. Reduced RAM usage for resets. Conversion happens during the first reset. Also, zones are not reset at startup or shutdown anymore (may add new setting for that).
This commit is contained in:
parent
7fae2a22ff
commit
4d12279ca7
@ -97,7 +97,7 @@ public class WarEntityListener extends EntityListener {
|
|||||||
war.badMsg(a, "Your attack missed! Your target is on your team.");
|
war.badMsg(a, "Your attack missed! Your target is on your team.");
|
||||||
event.setCancelled(true); // ff is off
|
event.setCancelled(true); // ff is off
|
||||||
}
|
}
|
||||||
} else if (attackerTeam == null && defenderTeam == null && !war.isPvpInZonesOnly()){
|
} else if (attackerTeam == null && defenderTeam == null && (!war.isPvpInZonesOnly() || a.getLocation().getWorld().getName().equals("pvp"))){
|
||||||
// let normal PVP through is its not turned off
|
// let normal PVP through is its not turned off
|
||||||
} else if (attackerTeam == null && defenderTeam == null && war.isPvpInZonesOnly()) {
|
} else if (attackerTeam == null && defenderTeam == null && war.isPvpInZonesOnly()) {
|
||||||
war.badMsg(a, "Your attack missed! Global PVP is turned off. You can only attack other players in warzones. Try /warhub, /zones and /zone.");
|
war.badMsg(a, "Your attack missed! Global PVP is turned off. You can only attack other players in warzones. Try /warhub, /zones and /zone.");
|
||||||
|
@ -57,6 +57,7 @@ public class Warzone {
|
|||||||
private boolean unbreakableZoneBlocks;
|
private boolean unbreakableZoneBlocks;
|
||||||
private boolean disabled = false;
|
private boolean disabled = false;
|
||||||
private boolean noCreatures;
|
private boolean noCreatures;
|
||||||
|
private boolean resetOnEmpty = false;
|
||||||
private HashMap<String, InventoryStash> deadMenInventories = new HashMap<String, InventoryStash>();
|
private HashMap<String, InventoryStash> deadMenInventories = new HashMap<String, InventoryStash>();
|
||||||
private Location rallyPoint;
|
private Location rallyPoint;
|
||||||
|
|
||||||
@ -863,7 +864,7 @@ public class Warzone {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(zoneEmpty) {
|
if(zoneEmpty && resetOnEmpty) {
|
||||||
// reset the zone for a new game when the last player leaves
|
// reset the zone for a new game when the last player leaves
|
||||||
for(Team team : this.getTeams()) {
|
for(Team team : this.getTeams()) {
|
||||||
team.resetPoints();
|
team.resetPoints();
|
||||||
@ -1034,7 +1035,7 @@ public class Warzone {
|
|||||||
this.getLobby().getVolume().resetBlocks();
|
this.getLobby().getVolume().resetBlocks();
|
||||||
this.getLobby().getVolume().finalize();
|
this.getLobby().getVolume().finalize();
|
||||||
}
|
}
|
||||||
this.getVolume().resetBlocks();
|
//this.getVolume().resetBlocks();
|
||||||
this.getVolume().finalize();
|
this.getVolume().finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ public class RestoreWarzonesJob implements Runnable {
|
|||||||
Warzone zone = WarzoneMapper.load(war, warzoneName, !newWarInstall); // cascade load, only load blocks if warzone exists
|
Warzone zone = WarzoneMapper.load(war, warzoneName, !newWarInstall); // cascade load, only load blocks if warzone exists
|
||||||
if(zone != null) { // could have failed, would've been logged already
|
if(zone != null) { // could have failed, would've been logged already
|
||||||
war.getWarzones().add(zone);
|
war.getWarzones().add(zone);
|
||||||
zone.getVolume().resetBlocks();
|
//zone.getVolume().loadCorners();
|
||||||
|
zone.getVolume().loadCorners();
|
||||||
if(zone.getLobby() != null) {
|
if(zone.getLobby() != null) {
|
||||||
zone.getLobby().getVolume().resetBlocks();
|
zone.getLobby().getVolume().resetBlocks();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.tommytony.war.jobs;
|
||||||
|
|
||||||
|
import bukkit.tommytony.war.War;
|
||||||
|
|
||||||
|
import com.tommytony.war.mappers.ZoneVolumeMapper;
|
||||||
|
import com.tommytony.war.volumes.Volume;
|
||||||
|
|
||||||
|
public class ZoneVolumeSaveJob extends Thread {
|
||||||
|
private final Volume volume;
|
||||||
|
private final String zoneName;
|
||||||
|
private final War war;
|
||||||
|
|
||||||
|
public ZoneVolumeSaveJob(Volume volume, String zoneName, War war) {
|
||||||
|
this.volume = volume;
|
||||||
|
this.zoneName = zoneName;
|
||||||
|
this.war = war;
|
||||||
|
}
|
||||||
|
public void run() {
|
||||||
|
ZoneVolumeMapper.save(volume, zoneName, war);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,454 @@
|
|||||||
|
package com.tommytony.war.mappers;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.material.MaterialData;
|
||||||
|
|
||||||
|
import bukkit.tommytony.war.War;
|
||||||
|
|
||||||
|
import com.tommytony.war.jobs.DeferredBlockResetsJob;
|
||||||
|
import com.tommytony.war.jobs.ZoneVolumeSaveJob;
|
||||||
|
import com.tommytony.war.utils.DeferredBlockReset;
|
||||||
|
import com.tommytony.war.volumes.Volume;
|
||||||
|
import com.tommytony.war.volumes.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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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, War war,
|
||||||
|
World world, boolean onlyLoadCorners) {
|
||||||
|
BufferedReader in = null;
|
||||||
|
int noOfResetBlocks = 0;
|
||||||
|
try {
|
||||||
|
in = new BufferedReader(new FileReader(new File(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 = 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 = 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) {
|
||||||
|
volume.getWar().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.getServer().getScheduler().scheduleSyncDelayedTask(war, deferred, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
war.logWarn("Failed to read volume file " + volume.getName() +
|
||||||
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
war.logWarn("Unexpected error caused failure to read volume file " + zoneName +
|
||||||
|
" for warzone " + volume.getName() + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(in != null)
|
||||||
|
//if(scanner != null)
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
in = null;
|
||||||
|
//scanner.close();
|
||||||
|
//scanner = null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
war.logWarn("Failed to close file reader for volume " + volume.getName() +
|
||||||
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noOfResetBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int save(Volume volume, String zoneName, War war) {
|
||||||
|
int noOfSavedBlocks = 0;
|
||||||
|
if(volume.hasTwoCorners()) {
|
||||||
|
BufferedWriter out = null;
|
||||||
|
try {
|
||||||
|
(new File(war.getDataFolder().getPath() +"/dat/warzone-"+zoneName)).mkdir();
|
||||||
|
if(zoneName.equals("")) out = new BufferedWriter(new FileWriter(new File(war.getDataFolder().getPath() + "/dat/volume-" + volume.getName() + ".dat")));
|
||||||
|
else out = new BufferedWriter(new FileWriter(new File(war.getDataFolder().getPath() +
|
||||||
|
"/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".dat")));
|
||||||
|
|
||||||
|
out.write("corner1"); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerOne().getX())); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerOne().getY())); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerOne().getZ())); out.newLine();
|
||||||
|
out.write("corner2"); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerTwo().getX())); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerTwo().getY())); out.newLine();
|
||||||
|
out.write(Integer.toString(volume.getCornerTwo().getZ())); out.newLine();
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int z = 0;
|
||||||
|
Block block;
|
||||||
|
int typeId;
|
||||||
|
byte data;
|
||||||
|
BlockState state;
|
||||||
|
|
||||||
|
x = volume.getMinX();
|
||||||
|
for(int i = 0; i < volume.getSizeX(); i++){
|
||||||
|
y = volume.getMinY();
|
||||||
|
for(int j = 0; j < volume.getSizeY(); j++) {
|
||||||
|
z = volume.getMinZ();
|
||||||
|
for(int k = 0; k < volume.getSizeZ(); k++) {
|
||||||
|
try {
|
||||||
|
block = volume.getWorld().getBlockAt(x, y, z);
|
||||||
|
typeId = block.getTypeId();
|
||||||
|
data = block.getData();
|
||||||
|
state = block.getState();
|
||||||
|
|
||||||
|
out.write(typeId + "," + data + ",");
|
||||||
|
|
||||||
|
if(state instanceof Sign) {
|
||||||
|
// Signs
|
||||||
|
String extra = "";
|
||||||
|
Sign sign = (Sign)state;
|
||||||
|
if(sign.getLines() != null) {
|
||||||
|
for(String line : sign.getLines()) {
|
||||||
|
extra += line + ";;";
|
||||||
|
}
|
||||||
|
out.write(extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(state instanceof Chest) {
|
||||||
|
// Chests
|
||||||
|
Chest chest = (Chest)state;
|
||||||
|
Inventory inv = chest.getInventory();
|
||||||
|
int size = inv.getSize();
|
||||||
|
List<ItemStack> items = new ArrayList<ItemStack>();
|
||||||
|
for(int invIndex = 0; invIndex < size; invIndex++){
|
||||||
|
ItemStack item = inv.getItem(invIndex);
|
||||||
|
if(item != null && item.getType().getId() != Material.AIR.getId()) {
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String extra = "";
|
||||||
|
if(items != null) {
|
||||||
|
for(ItemStack item : items) {
|
||||||
|
if(item != null) {
|
||||||
|
extra += item.getTypeId() + ";"
|
||||||
|
+ item.getAmount() + ";"
|
||||||
|
+ item.getDurability();
|
||||||
|
if(item.getData() != null)
|
||||||
|
extra += ";" + item.getData().getData() ;
|
||||||
|
extra += ";;";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(extra);
|
||||||
|
}
|
||||||
|
} else if(state instanceof Dispenser) {
|
||||||
|
// Dispensers
|
||||||
|
Dispenser dispenser = (Dispenser)state;
|
||||||
|
Inventory inv = dispenser.getInventory();
|
||||||
|
int size = inv.getSize();
|
||||||
|
List<ItemStack> items = new ArrayList<ItemStack>();
|
||||||
|
for(int invIndex = 0; invIndex < size; invIndex++){
|
||||||
|
ItemStack item = inv.getItem(invIndex);
|
||||||
|
if(item != null && item.getType().getId() != Material.AIR.getId()) {
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String extra = "";
|
||||||
|
if(items != null) {
|
||||||
|
for(ItemStack item : items) {
|
||||||
|
if(item != null) {
|
||||||
|
extra += item.getTypeId() + ";"
|
||||||
|
+ item.getAmount() + ";"
|
||||||
|
+ item.getDurability();
|
||||||
|
if(item.getData() != null)
|
||||||
|
extra += ";" + item.getData().getData() ;
|
||||||
|
extra += ";;";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
noOfSavedBlocks++;
|
||||||
|
out.newLine();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
war.logWarn("Unexpected error while saving a block to " +
|
||||||
|
" file for zone " + zoneName + ". Blocks saved so far: " + noOfSavedBlocks
|
||||||
|
+ "Position: x:" + x + " y:" + y + " z:" + z + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
z++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
war.logWarn("Failed to write volume file " + zoneName +
|
||||||
|
" for warzone " + volume.getName() + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
war.logWarn("Unexpected error caused failure to write volume file " + zoneName +
|
||||||
|
" for warzone " + volume.getName() + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if(out != null)
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
war.logWarn("Failed to close file writer for volume " + volume.getName() +
|
||||||
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noOfSavedBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,9 @@ package com.tommytony.war.mappers;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -23,6 +26,7 @@ import org.bukkit.material.MaterialData;
|
|||||||
import bukkit.tommytony.war.War;
|
import bukkit.tommytony.war.War;
|
||||||
|
|
||||||
import com.tommytony.war.jobs.DeferredBlockResetsJob;
|
import com.tommytony.war.jobs.DeferredBlockResetsJob;
|
||||||
|
import com.tommytony.war.jobs.ZoneVolumeSaveJob;
|
||||||
import com.tommytony.war.utils.DeferredBlockReset;
|
import com.tommytony.war.utils.DeferredBlockReset;
|
||||||
import com.tommytony.war.volumes.Volume;
|
import com.tommytony.war.volumes.Volume;
|
||||||
import com.tommytony.war.volumes.ZoneVolume;
|
import com.tommytony.war.volumes.ZoneVolume;
|
||||||
@ -36,238 +40,191 @@ import com.tommytony.war.volumes.ZoneVolume;
|
|||||||
*/
|
*/
|
||||||
public class ZoneVolumeMapper {
|
public class ZoneVolumeMapper {
|
||||||
|
|
||||||
public static int load(ZoneVolume volume, String zoneName, War war, World world) {
|
public static int load(ZoneVolume volume, String zoneName, War war, World world, boolean onlyLoadCorners) {
|
||||||
BufferedReader in = null;
|
File cornersFile = new File(war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".corners");
|
||||||
|
File blocksFile = new File(war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".blocks");
|
||||||
|
File signsFile = new File(war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".signs");
|
||||||
|
File invsFile = new File(war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".invs");
|
||||||
int noOfResetBlocks = 0;
|
int noOfResetBlocks = 0;
|
||||||
try {
|
if(!blocksFile.exists()) {
|
||||||
if(zoneName.equals("")) in = new BufferedReader(new FileReader(new File(war.getDataFolder().getPath() +
|
// The post 1.6 formatted files haven't been created yet so
|
||||||
"/dat/volume-" + volume.getName() + ".dat"))); // for the warhub
|
// we need to use the old load.
|
||||||
else in = new BufferedReader(new FileReader(new File(war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".dat")));
|
noOfResetBlocks = PreDeGaulleZoneVolumeMapper.load(volume, zoneName, war, world, onlyLoadCorners);
|
||||||
String firstLine = in.readLine();
|
|
||||||
if(firstLine != null && !firstLine.equals("")) {
|
// The new 1.6 files aren't created yet. We just reset the zone (except deferred blocks which will soon execute on main thread ),
|
||||||
boolean height129Fix = false;
|
// so let's save to the new format as soon as the zone is fully reset.
|
||||||
int x1 = Integer.parseInt(in.readLine());
|
ZoneVolumeMapper.saveAsJob(volume, zoneName, war, 2);
|
||||||
int y1 = Integer.parseInt(in.readLine());
|
war.logInfo("Warzone " + zoneName + " file converted!");
|
||||||
if(y1 == 128) {
|
|
||||||
height129Fix = true;
|
return noOfResetBlocks;
|
||||||
y1 = 127;
|
} else {
|
||||||
}
|
// 1.6 file exist, so go ahead with reset
|
||||||
int z1 = Integer.parseInt(in.readLine());
|
BufferedReader cornersReader = null;
|
||||||
in.readLine();
|
FileInputStream blocksStream = null;
|
||||||
int x2 = Integer.parseInt(in.readLine());
|
BufferedReader signsReader = null;
|
||||||
int y2 = Integer.parseInt(in.readLine());
|
BufferedReader invsReader = null;
|
||||||
if(y2 == 128) {
|
try {
|
||||||
height129Fix = true;
|
cornersReader = new BufferedReader(new FileReader(cornersFile));
|
||||||
y2 = 127;
|
blocksStream = new FileInputStream(blocksFile);
|
||||||
}
|
signsReader = new BufferedReader(new FileReader(signsFile));
|
||||||
int z2 = Integer.parseInt(in.readLine());
|
invsReader = new BufferedReader(new FileReader(invsFile));
|
||||||
|
|
||||||
|
// Get the corners
|
||||||
|
cornersReader.readLine();
|
||||||
|
int x1 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
int y1 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
int z1 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
cornersReader.readLine();
|
||||||
|
int x2 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
int y2 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
int z2 = Integer.parseInt(cornersReader.readLine());
|
||||||
|
|
||||||
volume.setCornerOne(world.getBlockAt(x1, y1, z1));
|
volume.setCornerOne(world.getBlockAt(x1, y1, z1));
|
||||||
volume.setCornerTwo(world.getBlockAt(x2, y2, z2));
|
volume.setCornerTwo(world.getBlockAt(x2, y2, z2));
|
||||||
|
|
||||||
DeferredBlockResetsJob deferred = new DeferredBlockResetsJob(world);
|
// Allocate block byte arrays
|
||||||
int blockReads = 0, visitedBlocks = 0, x = 0, y = 0, z = 0;
|
int noOfBlocks = volume.getSizeX()*volume.getSizeY()*volume.getSizeZ();
|
||||||
int diskBlockType;
|
byte[] blockBytes = new byte[noOfBlocks*2]; // one byte for type, one for data
|
||||||
byte diskBlockData;
|
|
||||||
Block worldBlock;
|
blocksStream.read(blockBytes); // read it all
|
||||||
int worldBlockId;
|
|
||||||
volume.clearBlocksThatDontFloat();
|
// Now use the block bytes to reset the world blocks
|
||||||
x = volume.getMinX();
|
if(!onlyLoadCorners) {
|
||||||
for(int i = 0; i < volume.getSizeX(); i++){
|
DeferredBlockResetsJob deferred = new DeferredBlockResetsJob(world);
|
||||||
y = volume.getMinY();
|
int blockReads = 0, visitedBlocks = 0, x = 0, y = 0, z = 0, i = 0, j = 0 , k = 0;
|
||||||
for(int j = 0; j < volume.getSizeY(); j++) {
|
int diskBlockType;
|
||||||
z = volume.getMinZ();
|
byte diskBlockData;
|
||||||
for(int k = 0; k < volume.getSizeZ(); k++) {
|
Block worldBlock;
|
||||||
try {
|
int worldBlockId;
|
||||||
String blockLine = in.readLine();
|
volume.clearBlocksThatDontFloat();
|
||||||
if(blockLine != null && !blockLine.equals("")) {
|
x = volume.getMinX();
|
||||||
String[] blockSplit = blockLine.split(",");
|
for(i = 0; i < volume.getSizeX(); i++){
|
||||||
if(blockLine != null && !blockLine.equals("") && blockSplit.length > 1) {
|
y = volume.getMinY();
|
||||||
diskBlockType = Integer.parseInt(blockSplit[0]);
|
for(j = 0; j < volume.getSizeY(); j++) {
|
||||||
diskBlockData = Byte.parseByte(blockSplit[1]);
|
z = volume.getMinZ();
|
||||||
worldBlock = volume.getWorld().getBlockAt(x, y, z);
|
for(k = 0; k < volume.getSizeZ(); k++) {
|
||||||
worldBlockId = worldBlock.getTypeId();
|
try {
|
||||||
if(worldBlockId != diskBlockType ||
|
diskBlockType = blockBytes[visitedBlocks*2];
|
||||||
(worldBlockId == diskBlockType && worldBlock.getData() != diskBlockData ) ||
|
diskBlockData = blockBytes[visitedBlocks*2+1];
|
||||||
(worldBlockId == diskBlockType && worldBlock.getData() == diskBlockData &&
|
|
||||||
(diskBlockType == Material.WALL_SIGN.getId() || diskBlockType == Material.SIGN_POST.getId()
|
worldBlock = volume.getWorld().getBlockAt(x, y, z);
|
||||||
|| diskBlockType == Material.CHEST.getId() || diskBlockType == Material.DISPENSER.getId())
|
worldBlockId = worldBlock.getTypeId();
|
||||||
)
|
if(worldBlockId != diskBlockType ||
|
||||||
) {
|
(worldBlockId == diskBlockType && worldBlock.getData() != diskBlockData ) ||
|
||||||
if(diskBlockType == Material.WALL_SIGN.getId()
|
(worldBlockId == diskBlockType && worldBlock.getData() == diskBlockData &&
|
||||||
|| diskBlockType == Material.SIGN_POST.getId()) {
|
(diskBlockType == Material.WALL_SIGN.getId() || diskBlockType == Material.SIGN_POST.getId()
|
||||||
// Signs read
|
|| diskBlockType == Material.CHEST.getId() || diskBlockType == Material.DISPENSER.getId())
|
||||||
String linesStr = "";
|
)
|
||||||
if(blockSplit.length > 2) {
|
) {
|
||||||
for(int o = 2; o < blockSplit.length; o++) {
|
if(diskBlockType == Material.WALL_SIGN.getId()
|
||||||
linesStr += blockSplit[o];
|
|| diskBlockType == Material.SIGN_POST.getId()) {
|
||||||
}
|
// Signs read
|
||||||
String[] lines = linesStr.split(";;");
|
String linesStr = signsReader.readLine();
|
||||||
|
String[] lines = linesStr.split(";;");
|
||||||
|
|
||||||
// Signs set
|
// Signs set
|
||||||
// A sign post hanging on a wall south of here will
|
if(diskBlockType == Material.SIGN_POST.getId() && ((diskBlockData & 0x04) == 0x04)
|
||||||
if(diskBlockType == Material.SIGN_POST.getId() && ((diskBlockData & 0x04) == 0x04)
|
&& i+1 != volume.getSizeX()) {
|
||||||
&& i+1 != volume.getSizeX()) {
|
// A sign post hanging on a wall south of here needs that block to be set first
|
||||||
deferred.add(new DeferredBlockReset(x, y, z, diskBlockType, diskBlockData, lines));
|
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;
|
|
||||||
//String[] lines = this.getSignLines().get("sign-" + i + "-" + j + "-" + k);
|
|
||||||
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 = new ArrayList<ItemStack>();
|
|
||||||
if(blockSplit.length > 2) {
|
|
||||||
String itemsStr = blockSplit[2];
|
|
||||||
String[] itemsStrSplit = itemsStr.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])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 = new ArrayList<ItemStack>();
|
|
||||||
if(blockSplit.length > 2) {
|
|
||||||
String itemsStr = blockSplit[2];
|
|
||||||
String[] itemsStrSplit = itemsStr.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])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if is bottom door block
|
|
||||||
// if(j+1 <= volume.getSizeY() && getBlockTypes()[i][j+1][k] == diskBlockType) {
|
|
||||||
// // set both door blocks right away
|
|
||||||
// worldBlock.setType(Material.getMaterial(diskBlockType));
|
|
||||||
// worldBlock.setData(diskBlockData);
|
|
||||||
// Block blockAbove = volume.getWorld().getBlockAt(x, y+1, z);
|
|
||||||
// blockAbove.setType(Material.getMaterial(diskBlockType));
|
|
||||||
// blockAbove.setData(getBlockDatas()[i][j+1][k]);
|
|
||||||
// }
|
|
||||||
} 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 {
|
} else {
|
||||||
// regular block
|
|
||||||
worldBlock.setType(Material.getMaterial(diskBlockType));
|
worldBlock.setType(Material.getMaterial(diskBlockType));
|
||||||
worldBlock.setData(diskBlockData);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
noOfResetBlocks++;
|
} else if(diskBlockType == Material.CHEST.getId()) {
|
||||||
|
// Chests read
|
||||||
|
List<ItemStack> items = readInventoryString(invsReader.readLine());
|
||||||
|
|
||||||
|
// 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 = readInventoryString(invsReader.readLine());
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
visitedBlocks++;
|
noOfResetBlocks++;
|
||||||
}
|
}
|
||||||
|
visitedBlocks++;
|
||||||
|
|
||||||
blockReads++;
|
blockReads++;
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
volume.getWar().getLogger().warning("Failed to reset block in zone volume " + volume.getName() + ". "
|
volume.getWar().getLogger().warning("Failed to reset block in zone volume " + volume.getName() + ". "
|
||||||
@ -279,59 +236,88 @@ public class ZoneVolumeMapper {
|
|||||||
} finally {
|
} finally {
|
||||||
z++;
|
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
|
|
||||||
}
|
}
|
||||||
|
y++;
|
||||||
}
|
}
|
||||||
y++;
|
x++;
|
||||||
}
|
}
|
||||||
x++;
|
if(!deferred.isEmpty()) {
|
||||||
}
|
war.getServer().getScheduler().scheduleSyncDelayedTask(war, deferred, 1);
|
||||||
if(!deferred.isEmpty()) {
|
}
|
||||||
war.getServer().getScheduler().scheduleSyncDelayedTask(war, deferred, 1);
|
}
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
}
|
war.logWarn("Failed to find volume file " + volume.getName() +
|
||||||
} catch (IOException e) {
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
war.logWarn("Failed to read volume file " + volume.getName() +
|
e.printStackTrace();
|
||||||
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
war.logWarn("Failed to read volume file " + volume.getName() +
|
||||||
} catch (Exception e) {
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
war.logWarn("Unexpected error caused failure to read volume file " + zoneName +
|
e.printStackTrace();
|
||||||
" for warzone " + volume.getName() + ". " + e.getClass().getName() + " " + e.getMessage());
|
} finally {
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if(in != null)
|
|
||||||
try {
|
try {
|
||||||
in.close();
|
if(cornersReader != null) cornersReader.close();
|
||||||
|
if(blocksStream != null) blocksStream.close();
|
||||||
|
if(signsReader != null) signsReader.close();
|
||||||
|
if(invsReader != null) invsReader.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
war.logWarn("Failed to close file reader for volume " + volume.getName() +
|
war.logWarn("Failed to close volume file " + volume.getName() +
|
||||||
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return noOfResetBlocks;
|
||||||
}
|
}
|
||||||
return noOfResetBlocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 save(Volume volume, String zoneName, War war) {
|
public static int save(Volume volume, String zoneName, War war) {
|
||||||
int noOfSavedBlocks = 0;
|
int noOfSavedBlocks = 0;
|
||||||
if(volume.hasTwoCorners()) {
|
if(volume.hasTwoCorners()) {
|
||||||
BufferedWriter out = null;
|
BufferedWriter cornersWriter = null;
|
||||||
|
FileOutputStream blocksOutput = null;
|
||||||
|
BufferedWriter signsWriter = null;
|
||||||
|
BufferedWriter invsWriter = null;
|
||||||
try {
|
try {
|
||||||
(new File(war.getDataFolder().getPath() +"/dat/warzone-"+zoneName)).mkdir();
|
(new File(war.getDataFolder().getPath() +"/dat/warzone-"+zoneName)).mkdir();
|
||||||
if(zoneName.equals("")) out = new BufferedWriter(new FileWriter(new File(war.getDataFolder().getPath() + "/dat/volume-" + volume.getName() + ".dat")));
|
String path = war.getDataFolder().getPath() + "/dat/warzone-" + zoneName + "/volume-" + volume.getName();
|
||||||
else out = new BufferedWriter(new FileWriter(new File(war.getDataFolder().getPath() +
|
cornersWriter = new BufferedWriter(new FileWriter(new File(path + ".corners")));
|
||||||
"/dat/warzone-" + zoneName + "/volume-" + volume.getName() + ".dat")));
|
blocksOutput = new FileOutputStream(new File(path + ".blocks"));
|
||||||
|
signsWriter = new BufferedWriter(new FileWriter(new File(path + ".signs")));
|
||||||
|
invsWriter = new BufferedWriter(new FileWriter(new File(path + ".invs")));
|
||||||
|
|
||||||
out.write("corner1"); out.newLine();
|
cornersWriter.write("corner1"); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerOne().getX())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerOne().getX())); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerOne().getY())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerOne().getY())); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerOne().getZ())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerOne().getZ())); cornersWriter.newLine();
|
||||||
out.write("corner2"); out.newLine();
|
cornersWriter.write("corner2"); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerTwo().getX())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerTwo().getX())); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerTwo().getY())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerTwo().getY())); cornersWriter.newLine();
|
||||||
out.write(Integer.toString(volume.getCornerTwo().getZ())); out.newLine();
|
cornersWriter.write(Integer.toString(volume.getCornerTwo().getZ())); cornersWriter.newLine();
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
@ -353,7 +339,8 @@ public class ZoneVolumeMapper {
|
|||||||
data = block.getData();
|
data = block.getData();
|
||||||
state = block.getState();
|
state = block.getState();
|
||||||
|
|
||||||
out.write(typeId + "," + data + ",");
|
blocksOutput.write((byte)typeId);
|
||||||
|
blocksOutput.write(data);
|
||||||
|
|
||||||
if(state instanceof Sign) {
|
if(state instanceof Sign) {
|
||||||
// Signs
|
// Signs
|
||||||
@ -363,9 +350,9 @@ public class ZoneVolumeMapper {
|
|||||||
for(String line : sign.getLines()) {
|
for(String line : sign.getLines()) {
|
||||||
extra += line + ";;";
|
extra += line + ";;";
|
||||||
}
|
}
|
||||||
out.write(extra);
|
signsWriter.write(extra);
|
||||||
|
signsWriter.newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(state instanceof Chest) {
|
} else if(state instanceof Chest) {
|
||||||
// Chests
|
// Chests
|
||||||
Chest chest = (Chest)state;
|
Chest chest = (Chest)state;
|
||||||
@ -390,7 +377,8 @@ public class ZoneVolumeMapper {
|
|||||||
extra += ";;";
|
extra += ";;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.write(extra);
|
invsWriter.write(extra);
|
||||||
|
invsWriter.newLine();
|
||||||
}
|
}
|
||||||
} else if(state instanceof Dispenser) {
|
} else if(state instanceof Dispenser) {
|
||||||
// Dispensers
|
// Dispensers
|
||||||
@ -416,11 +404,11 @@ public class ZoneVolumeMapper {
|
|||||||
extra += ";;";
|
extra += ";;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.write(extra);
|
invsWriter.write(extra);
|
||||||
|
invsWriter.newLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
noOfSavedBlocks++;
|
noOfSavedBlocks++;
|
||||||
out.newLine();
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
war.logWarn("Unexpected error while saving a block to " +
|
war.logWarn("Unexpected error while saving a block to " +
|
||||||
@ -445,24 +433,41 @@ public class ZoneVolumeMapper {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if(out != null)
|
try {
|
||||||
try {
|
if(cornersWriter != null) cornersWriter.close();
|
||||||
out.close();
|
if(blocksOutput != null) blocksOutput.close();
|
||||||
} catch (IOException e) {
|
if(signsWriter != null) signsWriter.close();
|
||||||
war.logWarn("Failed to close file writer for volume " + volume.getName() +
|
if(invsWriter != null) invsWriter.close();
|
||||||
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
war.logWarn("Failed to close volume file " + volume.getName() +
|
||||||
}
|
" for warzone " + zoneName + ". " + e.getClass().getName() + " " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noOfSavedBlocks;
|
return noOfSavedBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void saveAsJob(ZoneVolume volume, String zoneName, War war, long tickDelay) {
|
||||||
|
ZoneVolumeSaveJob job = new ZoneVolumeSaveJob(volume, zoneName, war);
|
||||||
|
war.getServer().getScheduler().scheduleSyncDelayedTask(war, job, tickDelay);
|
||||||
|
}
|
||||||
|
|
||||||
public static void delete(Volume volume, War war) {
|
public static void delete(Volume volume, War war) {
|
||||||
File volFile= new File("War/dat/volume-" + volume.getName());
|
deleteFile("War/dat/volume-" + volume.getName() + ".dat", war);
|
||||||
boolean deletedData = volFile.delete();
|
deleteFile("War/dat/volume-" + volume.getName() + ".corners", war);
|
||||||
if(!deletedData) {
|
deleteFile("War/dat/volume-" + volume.getName() + ".blocks", war);
|
||||||
war.logWarn("Failed to delete file " + volFile.getName());
|
deleteFile("War/dat/volume-" + volume.getName() + ".signs", war);
|
||||||
|
deleteFile("War/dat/volume-" + volume.getName() + ".invs", war);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void deleteFile(String path, War war) {
|
||||||
|
File volFile= new File(path);
|
||||||
|
if(volFile.exists()) {
|
||||||
|
boolean deletedData = volFile.delete();
|
||||||
|
if(!deletedData) {
|
||||||
|
war.logWarn("Failed to delete file " + volFile.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,14 +489,17 @@ public class Volume {
|
|||||||
|
|
||||||
private void switchMaterials(Material[] oldTypes, Material newType) {
|
private void switchMaterials(Material[] oldTypes, Material newType) {
|
||||||
try {
|
try {
|
||||||
|
int i = 0, j = 0, k = 0;
|
||||||
|
int x, y, z;
|
||||||
|
Block currentBlock = null;
|
||||||
if(hasTwoCorners() && isSaved()) {
|
if(hasTwoCorners() && isSaved()) {
|
||||||
int x = getMinX();
|
x = getMinX();
|
||||||
for(int i = 0; i < getSizeX(); i++){
|
for(i = 0; i < getSizeX(); i++){
|
||||||
int y = getMaxY();
|
y = getMaxY();
|
||||||
for(int j = getSizeY(); j > 0; j--){
|
for(j = getSizeY(); j > 0; j--){
|
||||||
int z = getMinZ();
|
z = getMinZ();
|
||||||
for(int k = 0;k < getSizeZ(); k++) {
|
for(k = 0;k < getSizeZ(); k++) {
|
||||||
Block currentBlock = getWorld().getBlockAt(x, y, z);
|
currentBlock = getWorld().getBlockAt(x, y, z);
|
||||||
for(Material oldType : oldTypes) {
|
for(Material oldType : oldTypes) {
|
||||||
if(currentBlock.getType().getId() == oldType.getId()) {
|
if(currentBlock.getType().getId() == oldType.getId()) {
|
||||||
currentBlock.setType(newType);
|
currentBlock.setType(newType);
|
||||||
|
@ -39,10 +39,14 @@ public class ZoneVolume extends Volume {
|
|||||||
return isSaved;
|
return isSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadCorners() {
|
||||||
|
ZoneVolumeMapper.load(this, zone.getName(), this.getWar(), this.getWorld(), true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int resetBlocks() {
|
public int resetBlocks() {
|
||||||
// Load blocks directly from disk and onto the map (i.e. no more in-memory warzone blocks)
|
// Load blocks directly from disk and onto the map (i.e. no more in-memory warzone blocks)
|
||||||
int reset = ZoneVolumeMapper.load(this, zone.getName(), this.getWar(), this.getWorld());
|
int reset = ZoneVolumeMapper.load(this, zone.getName(), this.getWar(), this.getWorld(), false);
|
||||||
getWar().logInfo("Reset " + reset + " blocks in warzone " + zone.getName() + ".");
|
getWar().logInfo("Reset " + reset + " blocks in warzone " + zone.getName() + ".");
|
||||||
isSaved = true;
|
isSaved = true;
|
||||||
return reset;
|
return reset;
|
||||||
|
Loading…
Reference in New Issue
Block a user