Improved block restore

This commit is contained in:
boy0001 2015-02-08 18:32:44 +11:00
parent 1f0e7126b9
commit 4e5a5284d7
2 changed files with 357 additions and 229 deletions

View File

@ -655,6 +655,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi
}
PlayerFunctions.sendMessage(p, C.NO_PERMISSION, "plots.admin.build.road");
e.setCancelled(true);
return;
} else {
final Plot plot = getCurrentPlot(loc);
if (plot == null || !plot.hasOwner()) {
@ -675,6 +676,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi
if (isPlotArea(loc)) {
PlayerFunctions.sendMessage(p, C.NO_PERMISSION, "plots.admin.build.other");
e.setCancelled(true);
return;
}
}
}
@ -720,6 +722,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi
}
PlayerFunctions.sendMessage(p, C.NO_PERMISSION, "plots.admin.build.road");
e.setCancelled(true);
return;
} else {
final Plot plot = getCurrentPlot(loc);
if (plot == null || !plot.hasOwner()) {
@ -758,6 +761,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi
if (!PlotMain.hasPermission(p, "plots.admin.build.road")) {
PlayerFunctions.sendMessage(p, C.NO_PERMISSION, "plots.admin.build.road");
e.setCancelled(true);
return;
}
} else {
final Plot plot = getCurrentPlot(loc);

View File

@ -6,18 +6,25 @@ import java.util.HashMap;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Note;
import org.bukkit.World;
import org.bukkit.block.Beacon;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
import org.bukkit.block.Chest;
import org.bukkit.block.CommandBlock;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Dispenser;
import org.bukkit.block.Dropper;
import org.bukkit.block.Furnace;
import org.bukkit.block.Hopper;
import org.bukkit.block.Jukebox;
import org.bukkit.block.NoteBlock;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.inventory.ItemStack;
import com.intellectualcrafters.plot.PlotMain;
@ -81,6 +88,22 @@ public class ChunkManager {
return false;
}
private static HashMap<BlockLoc, ItemStack[]> chestContents;
private static HashMap<BlockLoc, ItemStack[]> furnaceContents;
private static HashMap<BlockLoc, ItemStack[]> dispenserContents;
private static HashMap<BlockLoc, ItemStack[]> dropperContents;
private static HashMap<BlockLoc, ItemStack[]> brewingStandContents;
private static HashMap<BlockLoc, ItemStack[]> beaconContents;
private static HashMap<BlockLoc, ItemStack[]> hopperContents;
private static HashMap<BlockLoc, Short[]> furnaceTime;
private static HashMap<BlockLoc, Object[]> skullData;
private static HashMap<BlockLoc, Short> jukeDisc;
private static HashMap<BlockLoc, Short> brewTime;
private static HashMap<BlockLoc, String> spawnerData;
private static HashMap<BlockLoc, String> cmdData;
private static HashMap<BlockLoc, String[]> signContents;
private static HashMap<BlockLoc, Note> noteBlockContents;
public static boolean clearPlotExperimental(final World world, final Plot plot, final boolean isDelete) {
final Location pos1 = PlotHelper.getPlotBottomLoc(world, plot.id).add(1, 0, 1);
final Location pos2 = PlotHelper.getPlotTopLoc(world, plot.id);
@ -124,87 +147,28 @@ public class ChunkManager {
GENERATE_BLOCKS = new HashMap<>();
GENERATE_DATA = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> chestContents = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> furnaceContents = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> dispenserContents = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> brewingStandContents = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> beaconContents = new HashMap<>();
HashMap<BlockLoc, ItemStack[]> hopperContents = new HashMap<>();
HashMap<BlockLoc, Note> noteBlockContents = new HashMap<>();
HashMap<BlockLoc, String[]> signContents = new HashMap<>();
chestContents = new HashMap<>();
furnaceContents = new HashMap<>();
dispenserContents = new HashMap<>();
dropperContents = new HashMap<>();
brewingStandContents = new HashMap<>();
beaconContents = new HashMap<>();
hopperContents = new HashMap<>();
furnaceTime = new HashMap<>();
skullData = new HashMap<>();
brewTime = new HashMap<>();
jukeDisc = new HashMap<>();
spawnerData= new HashMap<>();
noteBlockContents = new HashMap<>();
signContents = new HashMap<>();
cmdData = new HashMap<>();
if (x == c1x || z == c1z) {
for (int X = 0; X < 16; X++) {
for (int Z = 0; Z < 16; Z++) {
if ((X + absX < sx || Z + absZ < sz) || (X + absX > ex || Z + absZ > ez)) {
HashMap<Short, Short> ids = new HashMap<>();
HashMap<Short, Byte> datas = new HashMap<>();
for (short y = 1; y < maxY; y++) {
Block block = world.getBlockAt(X + absX, y, Z + absZ);
short id = (short) block.getTypeId();
if (id != 0) {
ids.put(y, id);
byte data = block.getData();
if (data != 0) {
datas.put(y, data);
}
BlockLoc bl;
switch (id) {
case 54:
bl = new BlockLoc(X + absX, y, Z + absZ);
Chest chest = (Chest) block.getState();
ItemStack[] inventory = chest.getBlockInventory().getContents().clone();
chestContents.put(bl, inventory);
break;
case 63: case 68: case 323:
bl = new BlockLoc(X + absX, y, Z + absZ);
Sign sign = (Sign) block.getState();
sign.getLines();
signContents.put(bl, sign.getLines().clone());
break;
case 61: case 62:
bl = new BlockLoc(X + absX, y, Z + absZ);
Furnace furnace = (Furnace) block.getState();
ItemStack[] invFur = furnace.getInventory().getContents().clone();
furnaceContents.put(bl, invFur);
break;
case 23:
bl = new BlockLoc(X + absX, y, Z + absZ);
Dispenser dispenser = (Dispenser) block.getState();
ItemStack[] invDis = dispenser.getInventory().getContents().clone();
dispenserContents.put(bl, invDis);
break;
case 117:
bl = new BlockLoc(X + absX, y, Z + absZ);
BrewingStand brewingStand = (BrewingStand) block.getState();
ItemStack[] invBre = brewingStand.getInventory().getContents().clone();
brewingStandContents.put(bl, invBre);
break;
case 25:
bl = new BlockLoc(X + absX, y, Z + absZ);
NoteBlock noteBlock = (NoteBlock) block.getState();
Note note = noteBlock.getNote();
noteBlockContents.put(bl, note);
break;
case 138:
bl = new BlockLoc(X + absX, y, Z + absZ);
Beacon beacon = (Beacon) block.getState();
ItemStack[] invBea = beacon.getInventory().getContents().clone();
beaconContents.put(bl, invBea);
break;
case 154:
bl = new BlockLoc(X + absX, y, Z + absZ);
Hopper hopper = (Hopper) block.getState();
ItemStack[] invHop = hopper.getInventory().getContents().clone();
hopperContents.put(bl, invHop);
break;
}
}
}
ChunkLoc loc = new ChunkLoc(X + absX, Z + absZ);
GENERATE_BLOCKS.put(loc, ids);
GENERATE_DATA.put(loc, datas);
saveBlock(world, maxY, X + absX, Z + absZ);
}
}
}
@ -213,79 +177,23 @@ public class ChunkManager {
for (int X = 0; X < 16; X++) {
for (int Z = 0; Z < 16; Z++) {
if ((X + absX > ex || Z + absZ > ez) || (X + absX < sx || Z + absZ < sz)) {
HashMap<Short, Short> ids = new HashMap<>();
HashMap<Short, Byte> datas = new HashMap<>();
for (short y = 1; y < maxY; y++) {
Block block = world.getBlockAt(X + absX, y, Z + absZ);
short id = (short) block.getTypeId();
if (id != 0) {
ids.put(y, id);
byte data = block.getData();
if (data != 0) {
datas.put(y, data);
}
BlockLoc bl;
switch (id) {
case 54:
bl = new BlockLoc(X + absX, y, Z + absZ);
Chest chest = (Chest) block.getState();
ItemStack[] inventory = chest.getBlockInventory().getContents().clone();
chestContents.put(bl, inventory);
break;
case 63: case 68: case 323:
bl = new BlockLoc(X + absX, y, Z + absZ);
Sign sign = (Sign) block.getState();
sign.getLines();
signContents.put(bl, sign.getLines().clone());
break;
case 61: case 62:
bl = new BlockLoc(X + absX, y, Z + absZ);
Furnace furnace = (Furnace) block.getState();
ItemStack[] invFur = furnace.getInventory().getContents().clone();
furnaceContents.put(bl, invFur);
break;
case 23:
bl = new BlockLoc(X + absX, y, Z + absZ);
Dispenser dispenser = (Dispenser) block.getState();
ItemStack[] invDis = dispenser.getInventory().getContents().clone();
dispenserContents.put(bl, invDis);
break;
case 117:
bl = new BlockLoc(X + absX, y, Z + absZ);
BrewingStand brewingStand = (BrewingStand) block.getState();
ItemStack[] invBre = brewingStand.getInventory().getContents().clone();
brewingStandContents.put(bl, invBre);
break;
case 25:
bl = new BlockLoc(X + absX, y, Z + absZ);
NoteBlock noteBlock = (NoteBlock) block.getState();
Note note = noteBlock.getNote();
noteBlockContents.put(bl, note);
break;
case 138:
bl = new BlockLoc(X + absX, y, Z + absZ);
Beacon beacon = (Beacon) block.getState();
ItemStack[] invBea = beacon.getInventory().getContents().clone();
beaconContents.put(bl, invBea);
break;
case 154:
bl = new BlockLoc(X + absX, y, Z + absZ);
Hopper hopper = (Hopper) block.getState();
ItemStack[] invHop = hopper.getInventory().getContents().clone();
hopperContents.put(bl, invHop);
break;
}
}
}
ChunkLoc loc = new ChunkLoc(X + absX, Z + absZ);
GENERATE_BLOCKS.put(loc, ids);
GENERATE_DATA.put(loc, datas);
saveBlock(world, maxY, X + absX, Z + absZ);
}
}
}
}
world.regenerateChunk(x, z);
restoreBlocks(world);
chunk.unload();
chunk.load();
}
}
}
CURRENT_PLOT_CLEAR = null;
return true;
}
public static void restoreBlocks(World world) {
for (BlockLoc loc: chestContents.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
@ -321,7 +229,6 @@ public class ChunkManager {
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate dispenser: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: beaconContents.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
@ -331,7 +238,30 @@ public class ChunkManager {
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate beacon: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: jukeDisc.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof Jukebox) {
((Jukebox) (state)).setPlaying(Material.getMaterial(jukeDisc.get(loc)));
state.update(true);
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: skullData.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof Skull) {
Object[] data = skullData.get(loc);
if (data[0] != null) {
((Skull) (state)).setOwner((String) data[0]);
}
if (((Integer) data[1]) != 0) {
((Skull) (state)).setRotation(getRotation((Integer) data[1]));
}
state.update(true);
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: hopperContents.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
@ -351,7 +281,33 @@ public class ChunkManager {
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate note block: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: brewTime.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof BrewingStand) {
((BrewingStand) (state)).setBrewingTime(brewTime.get(loc));
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore brewing stand cooking: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: spawnerData.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof CreatureSpawner) {
((CreatureSpawner) (state)).setCreatureTypeId(spawnerData.get(loc));
state.update(true);
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore spawner type: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: cmdData.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof CommandBlock) {
((CommandBlock) (state)).setCommand(cmdData.get(loc));
state.update(true);
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore command block: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: brewingStandContents.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
@ -361,7 +317,16 @@ public class ChunkManager {
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate brewing stand: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: furnaceTime.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
if (state instanceof Furnace) {
Short[] time = furnaceTime.get(loc);
((Furnace) (state)).setBurnTime(time[0]);
((Furnace) (state)).setCookTime(time[1]);
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore furnace cooking: "+loc.x+","+loc.y+","+loc.z); }
}
for (BlockLoc loc: furnaceContents.keySet()) {
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
BlockState state = block.getState();
@ -371,12 +336,171 @@ public class ChunkManager {
}
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate furnace: "+loc.x+","+loc.y+","+loc.z); }
}
chunk.unload();
chunk.load();
}
public static void saveBlock(World world, int maxY, int x, int z) {
HashMap<Short, Short> ids = new HashMap<>();
HashMap<Short, Byte> datas = new HashMap<>();
for (short y = 1; y < maxY; y++) {
Block block = world.getBlockAt(x, y, z);
short id = (short) block.getTypeId();
if (id != 0) {
ids.put(y, id);
byte data = block.getData();
if (data != 0) {
datas.put(y, data);
}
BlockLoc bl;
switch (id) {
case 54:
bl = new BlockLoc(x, y, z);
Chest chest = (Chest) block.getState();
ItemStack[] inventory = chest.getBlockInventory().getContents().clone();
chestContents.put(bl, inventory);
break;
case 52:
bl = new BlockLoc(x, y, z);
CreatureSpawner spawner = (CreatureSpawner) block.getState();
String type = spawner.getCreatureTypeId();
if (type != null && type.length() != 0) {
spawnerData.put(bl, type);
}
break;
case 137:
bl = new BlockLoc(x, y, z);
CommandBlock cmd = (CommandBlock) block.getState();
String string = cmd.getCommand();
if (string != null && string.length() > 0) {
cmdData.put(bl, string);
}
break;
case 63: case 68: case 323:
bl = new BlockLoc(x, y, z);
Sign sign = (Sign) block.getState();
sign.getLines();
signContents.put(bl, sign.getLines().clone());
break;
case 61: case 62:
bl = new BlockLoc(x, y, z);
Furnace furnace = (Furnace) block.getState();
short burn = furnace.getBurnTime();
short cook = furnace.getCookTime();
ItemStack[] invFur = furnace.getInventory().getContents().clone();
furnaceContents.put(bl, invFur);
if (cook != 0) {
furnaceTime.put(bl, new Short[] {burn, cook});
}
break;
case 23:
bl = new BlockLoc(x, y, z);
Dispenser dispenser = (Dispenser) block.getState();
ItemStack[] invDis = dispenser.getInventory().getContents().clone();
dispenserContents.put(bl, invDis);
break;
case 117:
bl = new BlockLoc(x, y, z);
BrewingStand brewingStand = (BrewingStand) block.getState();
short time = (short) brewingStand.getBrewingTime();
if (time > 0) {
brewTime.put(bl, time);
}
ItemStack[] invBre = brewingStand.getInventory().getContents().clone();
brewingStandContents.put(bl, invBre);
break;
case 25:
bl = new BlockLoc(x, y, z);
NoteBlock noteBlock = (NoteBlock) block.getState();
Note note = noteBlock.getNote();
noteBlockContents.put(bl, note);
break;
case 138:
bl = new BlockLoc(x, y, z);
Beacon beacon = (Beacon) block.getState();
ItemStack[] invBea = beacon.getInventory().getContents().clone();
beaconContents.put(bl, invBea);
break;
case 84:
bl = new BlockLoc(x, y, z);
Jukebox jukebox = (Jukebox) block.getState();
Material playing = jukebox.getPlaying();
if (playing != null) {
jukeDisc.put(bl, (short) playing.getId());
}
break;
case 154:
bl = new BlockLoc(x, y, z);
Hopper hopper = (Hopper) block.getState();
ItemStack[] invHop = hopper.getInventory().getContents().clone();
hopperContents.put(bl, invHop);
break;
case 397:
bl = new BlockLoc(x, y, z);
Skull skull = (Skull) block.getState();
String o = skull.getOwner();
short rot = (short) skull.getRotation().ordinal();
skullData.put(bl, new Object[] {o, rot});
break;
}
}
}
CURRENT_PLOT_CLEAR = null;
return true;
ChunkLoc loc = new ChunkLoc(x, z);
GENERATE_BLOCKS.put(loc, ids);
GENERATE_DATA.put(loc, datas);
}
public static BlockFace getRotation(int ordinal) {
switch (ordinal) {
case 0: {
return BlockFace.NORTH;
}
case 1: {
return BlockFace.NORTH_NORTH_EAST;
}
case 2: {
return BlockFace.NORTH_EAST;
}
case 3: {
return BlockFace.EAST_NORTH_EAST;
}
case 4: {
return BlockFace.EAST;
}
case 5: {
return BlockFace.EAST_SOUTH_EAST;
}
case 6: {
return BlockFace.SOUTH_EAST;
}
case 7: {
return BlockFace.SOUTH_SOUTH_EAST;
}
case 8: {
return BlockFace.SOUTH;
}
case 9: {
return BlockFace.SOUTH_SOUTH_WEST;
}
case 10: {
return BlockFace.SOUTH_WEST;
}
case 11: {
return BlockFace.WEST_SOUTH_WEST;
}
case 12: {
return BlockFace.WEST;
}
case 13: {
return BlockFace.WEST_NORTH_WEST;
}
case 14: {
return BlockFace.NORTH_WEST;
}
case 15: {
return BlockFace.NORTH_NORTH_WEST;
}
default: {
return BlockFace.NORTH;
}
}
}
}