mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-29 16:46:46 +01:00
Replace Bukkit Metadata for user placed blocks
This commit is contained in:
parent
37d146e8fa
commit
b0157c9bd2
@ -59,16 +59,16 @@ public class BlockListener implements Listener {
|
|||||||
BlockFace direction = event.getDirection();
|
BlockFace direction = event.getDirection();
|
||||||
|
|
||||||
for (Block b : blocks) {
|
for (Block b : blocks) {
|
||||||
if (b.hasMetadata("mcmmoPlacedBlock")) {
|
if (mcMMO.placeStore.isTrue(b)) {
|
||||||
b.getRelative(direction).setMetadata("mcmmoNeedsTracking", new FixedMetadataValue(plugin, true));
|
mcMMO.placeStore.setTrue(b.getRelative(direction));
|
||||||
b.removeMetadata("mcmmoPlacedBlock", plugin);
|
mcMMO.placeStore.setFalse(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Block b : blocks) {
|
for (Block b : blocks) {
|
||||||
if (b.getRelative(direction).hasMetadata("mcmmoNeedsTracking")) {
|
if (mcMMO.placeStore.isTrue(b.getRelative(direction))) {
|
||||||
b.getRelative(direction).setMetadata("mcmmoPlacedBlock", new FixedMetadataValue(plugin, true));
|
mcMMO.placeStore.setTrue(b.getRelative(direction));
|
||||||
b.getRelative(direction).removeMetadata("mcmmoNeedsTracking", plugin);
|
mcMMO.placeStore.setFalse(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,9 +82,9 @@ public class BlockListener implements Listener {
|
|||||||
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||||
Block block = event.getRetractLocation().getBlock();
|
Block block = event.getRetractLocation().getBlock();
|
||||||
|
|
||||||
if (block.hasMetadata("mcmmoPlacedBlock")) {
|
if (mcMMO.placeStore.isTrue(block)) {
|
||||||
block.removeMetadata("mcmmoPlacedBlock", plugin);
|
mcMMO.placeStore.setFalse(block);
|
||||||
event.getBlock().getRelative(event.getDirection()).setMetadata("mcmmoPlacedBlock", new FixedMetadataValue(plugin, true));
|
mcMMO.placeStore.setTrue(event.getBlock().getRelative(event.getDirection()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ public class BlockListener implements Listener {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Block newLocation = block.getRelative(0, y + 1, 0);
|
Block newLocation = block.getRelative(0, y + 1, 0);
|
||||||
newLocation.setMetadata("mcmmoPlacedBlock", new FixedMetadataValue(plugin, true));
|
mcMMO.placeStore.setTrue(newLocation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ public class BlockListener implements Listener {
|
|||||||
|
|
||||||
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
|
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
|
||||||
if (BlockChecks.shouldBeWatched(mat)) {
|
if (BlockChecks.shouldBeWatched(mat)) {
|
||||||
block.setMetadata("mcmmoPlacedBlock", new FixedMetadataValue(plugin, true));
|
mcMMO.placeStore.setTrue(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == Config.getInstance().getRepairAnvilId() && Config.getInstance().getRepairAnvilMessagesEnabled()) {
|
if (id == Config.getInstance().getRepairAnvilId() && Config.getInstance().getRepairAnvilMessagesEnabled()) {
|
||||||
@ -193,7 +193,7 @@ public class BlockListener implements Listener {
|
|||||||
* EXCAVATION
|
* EXCAVATION
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (BlockChecks.canBeGigaDrillBroken(mat) && Permissions.getInstance().excavation(player) && !block.hasMetadata("mcmmoPlacedBlock")) {
|
if (BlockChecks.canBeGigaDrillBroken(mat) && Permissions.getInstance().excavation(player) && !mcMMO.placeStore.isTrue(block)) {
|
||||||
if (Config.getInstance().getExcavationRequiresTool() && ItemChecks.isShovel(inhand)) {
|
if (Config.getInstance().getExcavationRequiresTool() && ItemChecks.isShovel(inhand)) {
|
||||||
Excavation.excavationProcCheck(block, player);
|
Excavation.excavationProcCheck(block, player);
|
||||||
}
|
}
|
||||||
@ -203,8 +203,8 @@ public class BlockListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Remove metadata when broken
|
//Remove metadata when broken
|
||||||
if (block.hasMetadata("mcmmoPlacedBlock") && BlockChecks.shouldBeWatched(mat)) {
|
if (mcMMO.placeStore.isTrue(block) && BlockChecks.shouldBeWatched(mat)) {
|
||||||
block.removeMetadata("mcmmoPlacedBlock", plugin);
|
mcMMO.placeStore.setFalse(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
src/main/java/com/gmail/nossr50/listeners/WorldListener.java
Normal file
43
src/main/java/com/gmail/nossr50/listeners/WorldListener.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package com.gmail.nossr50.listeners;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
|
import org.bukkit.event.world.WorldSaveEvent;
|
||||||
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
|
||||||
|
public class WorldListener implements Listener {
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldLoad(WorldLoadEvent event) {
|
||||||
|
File dataDir = new File(event.getWorld().getWorldFolder(), "mcmmo_data");
|
||||||
|
if(!dataDir.exists()) {
|
||||||
|
dataDir.mkdir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldUnload(WorldUnloadEvent event) {
|
||||||
|
mcMMO.placeStore.unloadWorld(event.getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldSave(WorldSaveEvent event) {
|
||||||
|
mcMMO.placeStore.saveWorld(event.getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
|
mcMMO.placeStore.chunkLoaded(event.getChunk().getX(), event.getChunk().getZ(), event.getChunk().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||||
|
mcMMO.placeStore.chunkUnloaded(event.getChunk().getX(), event.getChunk().getZ(), event.getChunk().getWorld());
|
||||||
|
}
|
||||||
|
}
|
@ -14,10 +14,13 @@ import com.gmail.nossr50.util.Database;
|
|||||||
import com.gmail.nossr50.util.Leaderboard;
|
import com.gmail.nossr50.util.Leaderboard;
|
||||||
import com.gmail.nossr50.util.Metrics;
|
import com.gmail.nossr50.util.Metrics;
|
||||||
import com.gmail.nossr50.util.Users;
|
import com.gmail.nossr50.util.Users;
|
||||||
|
import com.gmail.nossr50.util.blockmeta.ChunkletManager;
|
||||||
|
import com.gmail.nossr50.util.blockmeta.HashChunkletManager;
|
||||||
import com.gmail.nossr50.listeners.BlockListener;
|
import com.gmail.nossr50.listeners.BlockListener;
|
||||||
import com.gmail.nossr50.listeners.EntityListener;
|
import com.gmail.nossr50.listeners.EntityListener;
|
||||||
import com.gmail.nossr50.listeners.HardcoreListener;
|
import com.gmail.nossr50.listeners.HardcoreListener;
|
||||||
import com.gmail.nossr50.listeners.PlayerListener;
|
import com.gmail.nossr50.listeners.PlayerListener;
|
||||||
|
import com.gmail.nossr50.listeners.WorldListener;
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
|
|
||||||
import net.shatteredlands.shatt.backup.ZipLibrary;
|
import net.shatteredlands.shatt.backup.ZipLibrary;
|
||||||
@ -41,6 +44,7 @@ public class mcMMO extends JavaPlugin {
|
|||||||
private final PlayerListener playerListener = new PlayerListener(this);
|
private final PlayerListener playerListener = new PlayerListener(this);
|
||||||
private final BlockListener blockListener = new BlockListener(this);
|
private final BlockListener blockListener = new BlockListener(this);
|
||||||
private final EntityListener entityListener = new EntityListener(this);
|
private final EntityListener entityListener = new EntityListener(this);
|
||||||
|
private final WorldListener worldListener = new WorldListener();
|
||||||
private final HardcoreListener hardcoreListener = new HardcoreListener();
|
private final HardcoreListener hardcoreListener = new HardcoreListener();
|
||||||
|
|
||||||
public HashMap<String, String> aliasMap = new HashMap<String, String>(); //Alias - Command
|
public HashMap<String, String> aliasMap = new HashMap<String, String>(); //Alias - Command
|
||||||
@ -50,6 +54,8 @@ public class mcMMO extends JavaPlugin {
|
|||||||
public static Database database;
|
public static Database database;
|
||||||
public static mcMMO p;
|
public static mcMMO p;
|
||||||
|
|
||||||
|
public static ChunkletManager placeStore = new HashChunkletManager();
|
||||||
|
|
||||||
/* Jar Stuff */
|
/* Jar Stuff */
|
||||||
public File mcmmo;
|
public File mcmmo;
|
||||||
|
|
||||||
@ -84,6 +90,7 @@ public class mcMMO extends JavaPlugin {
|
|||||||
pm.registerEvents(playerListener, this);
|
pm.registerEvents(playerListener, this);
|
||||||
pm.registerEvents(blockListener, this);
|
pm.registerEvents(blockListener, this);
|
||||||
pm.registerEvents(entityListener, this);
|
pm.registerEvents(entityListener, this);
|
||||||
|
pm.registerEvents(worldListener, this);
|
||||||
|
|
||||||
if (configInstance.getHardcoreEnabled()) {
|
if (configInstance.getHardcoreEnabled()) {
|
||||||
pm.registerEvents(hardcoreListener, this);
|
pm.registerEvents(hardcoreListener, this);
|
||||||
@ -186,6 +193,12 @@ public class mcMMO extends JavaPlugin {
|
|||||||
|
|
||||||
getServer().getScheduler().cancelTasks(this); //This removes our tasks
|
getServer().getScheduler().cancelTasks(this); //This removes our tasks
|
||||||
|
|
||||||
|
//Save our metadata
|
||||||
|
placeStore.saveAll();
|
||||||
|
|
||||||
|
//Cleanup empty metadata stores
|
||||||
|
placeStore.cleanUp();
|
||||||
|
|
||||||
//Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
|
//Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
|
||||||
try {
|
try {
|
||||||
ZipLibrary.mcMMObackup();
|
ZipLibrary.mcMMObackup();
|
||||||
|
@ -52,7 +52,7 @@ public class BlastMining {
|
|||||||
blocksDropped.add(temp);
|
blocksDropped.add(temp);
|
||||||
Mining.miningDrops(temp);
|
Mining.miningDrops(temp);
|
||||||
|
|
||||||
if (!temp.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(temp)) {
|
||||||
for (int i = 1 ; i < extraDrops ; i++) {
|
for (int i = 1 ; i < extraDrops ; i++) {
|
||||||
blocksDropped.add(temp);
|
blocksDropped.add(temp);
|
||||||
Mining.miningDrops(temp);
|
Mining.miningDrops(temp);
|
||||||
@ -159,7 +159,7 @@ public class BlastMining {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Block block : xp) {
|
for (Block block : xp) {
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
Mining.miningXP(player, block);
|
Mining.miningXP(player, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public class Excavation {
|
|||||||
public static void gigaDrillBreaker(Player player, Block block) {
|
public static void gigaDrillBreaker(Player player, Block block) {
|
||||||
Skills.abilityDurabilityLoss(player.getItemInHand(), Config.getInstance().getAbilityToolDamage());
|
Skills.abilityDurabilityLoss(player.getItemInHand(), Config.getInstance().getAbilityToolDamage());
|
||||||
|
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
|
FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
|
||||||
mcMMO.p.getServer().getPluginManager().callEvent(armswing);
|
mcMMO.p.getServer().getPluginManager().callEvent(armswing);
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public class Herbalism {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case BROWN_MUSHROOM:
|
case BROWN_MUSHROOM:
|
||||||
case RED_MUSHROOM:
|
case RED_MUSHROOM:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = Material.getMaterial(id);
|
mat = Material.getMaterial(id);
|
||||||
xp = Config.getInstance().getHerbalismXPMushrooms();
|
xp = Config.getInstance().getHerbalismXPMushrooms();
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ public class Herbalism {
|
|||||||
Block b = block.getRelative(0, y, 0);
|
Block b = block.getRelative(0, y, 0);
|
||||||
if (b.getType().equals(Material.CACTUS)) {
|
if (b.getType().equals(Material.CACTUS)) {
|
||||||
mat = Material.CACTUS;
|
mat = Material.CACTUS;
|
||||||
if (!b.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(b)) {
|
||||||
if (herbLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= herbLevel) {
|
if (herbLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= herbLevel) {
|
||||||
catciDrops++;
|
catciDrops++;
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ public class Herbalism {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MELON_BLOCK:
|
case MELON_BLOCK:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = Material.MELON;
|
mat = Material.MELON;
|
||||||
xp = Config.getInstance().getHerbalismXPMelon();
|
xp = Config.getInstance().getHerbalismXPMelon();
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ public class Herbalism {
|
|||||||
|
|
||||||
case PUMPKIN:
|
case PUMPKIN:
|
||||||
case JACK_O_LANTERN:
|
case JACK_O_LANTERN:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = Material.getMaterial(id);
|
mat = Material.getMaterial(id);
|
||||||
xp = Config.getInstance().getHerbalismXPPumpkin();
|
xp = Config.getInstance().getHerbalismXPPumpkin();
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ public class Herbalism {
|
|||||||
|
|
||||||
case RED_ROSE:
|
case RED_ROSE:
|
||||||
case YELLOW_FLOWER:
|
case YELLOW_FLOWER:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = Material.getMaterial(id);
|
mat = Material.getMaterial(id);
|
||||||
xp = Config.getInstance().getHerbalismXPFlowers();
|
xp = Config.getInstance().getHerbalismXPFlowers();
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ public class Herbalism {
|
|||||||
Block b = block.getRelative(0, y, 0);
|
Block b = block.getRelative(0, y, 0);
|
||||||
if (b.getType().equals(Material.SUGAR_CANE_BLOCK)) {
|
if (b.getType().equals(Material.SUGAR_CANE_BLOCK)) {
|
||||||
mat = Material.SUGAR_CANE;
|
mat = Material.SUGAR_CANE;
|
||||||
if (!b.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(b)) {
|
||||||
if (herbLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= herbLevel) {
|
if (herbLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= herbLevel) {
|
||||||
caneDrops++;
|
caneDrops++;
|
||||||
}
|
}
|
||||||
@ -167,14 +167,14 @@ public class Herbalism {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VINE:
|
case VINE:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = type;
|
mat = type;
|
||||||
xp = Config.getInstance().getHerbalismXPVines();
|
xp = Config.getInstance().getHerbalismXPVines();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WATER_LILY:
|
case WATER_LILY:
|
||||||
if (!block.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(block)) {
|
||||||
mat = type;
|
mat = type;
|
||||||
xp = Config.getInstance().getHerbalismXPLilyPads();
|
xp = Config.getInstance().getHerbalismXPLilyPads();
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ public class Mining {
|
|||||||
* @param block The block being broken
|
* @param block The block being broken
|
||||||
*/
|
*/
|
||||||
public static void miningBlockCheck(Player player, Block block) {
|
public static void miningBlockCheck(Player player, Block block) {
|
||||||
if (block.hasMetadata("mcmmoPlacedBlock") || player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
|
if (mcMMO.placeStore.isTrue(block) || player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ public class Mining {
|
|||||||
case NETHERRACK:
|
case NETHERRACK:
|
||||||
case SANDSTONE:
|
case SANDSTONE:
|
||||||
case STONE:
|
case STONE:
|
||||||
if (block.hasMetadata("mcmmoPlacedBlock")) {
|
if (mcMMO.placeStore.isTrue(block)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public class WoodCutting {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(x)) {
|
||||||
WoodCutting.woodCuttingProcCheck(player, x);
|
WoodCutting.woodCuttingProcCheck(player, x);
|
||||||
|
|
||||||
switch (species) {
|
switch (species) {
|
||||||
@ -188,7 +188,7 @@ public class WoodCutting {
|
|||||||
Block zNegative = currentBlock.getRelative(0, 0, -1);
|
Block zNegative = currentBlock.getRelative(0, 0, -1);
|
||||||
Block yPositive = currentBlock.getRelative(0, 1, 0);
|
Block yPositive = currentBlock.getRelative(0, 1, 0);
|
||||||
|
|
||||||
if (!currentBlock.hasMetadata("mcmmoPlacedBlock")) {
|
if (!mcMMO.placeStore.isTrue(currentBlock)) {
|
||||||
if (!isTooAggressive(currentBlock, xPositive) && BlockChecks.treeFellerCompatible(xPositive.getType()) && !toBeFelled.contains(xPositive)) {
|
if (!isTooAggressive(currentBlock, xPositive) && BlockChecks.treeFellerCompatible(xPositive.getType()) && !toBeFelled.contains(xPositive)) {
|
||||||
processTreeFelling(xPositive, toBeFelled);
|
processTreeFelling(xPositive, toBeFelled);
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ public class WoodCutting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BlockChecks.treeFellerCompatible(yPositive.getType())) {
|
if (BlockChecks.treeFellerCompatible(yPositive.getType())) {
|
||||||
if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && !toBeFelled.contains(yPositive)) {
|
if(!mcMMO.placeStore.isTrue(currentBlock) && !toBeFelled.contains(yPositive)) {
|
||||||
processTreeFelling(yPositive, toBeFelled);
|
processTreeFelling(yPositive, toBeFelled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ public class WoodCutting {
|
|||||||
int xp = 0;
|
int xp = 0;
|
||||||
TreeSpecies species = TreeSpecies.getByData(block.getData());
|
TreeSpecies species = TreeSpecies.getByData(block.getData());
|
||||||
|
|
||||||
if (block.hasMetadata("mcmmoPlacedBlock")) {
|
if (mcMMO.placeStore.isTrue(block)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package com.gmail.nossr50.util.blockmeta;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
public interface ChunkletManager {
|
||||||
|
/**
|
||||||
|
* Informs the ChunkletManager a chunk is loaded, it should load appropriate data
|
||||||
|
*
|
||||||
|
* @param cx Chunk X coordiate that is loaded
|
||||||
|
* @param cz Chunk Z coordiate that is loaded
|
||||||
|
* @param world World that the chunk was loaded in
|
||||||
|
*/
|
||||||
|
public void chunkLoaded(int cx, int cz, World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs the ChunkletManager a chunk is unloaded, it should unload and save appropriate data
|
||||||
|
*
|
||||||
|
* @param cx Chunk X coordiate that is unloaded
|
||||||
|
* @param cz Chunk Z coordiate that is unloaded
|
||||||
|
* @param world World that the chunk was unloaded in
|
||||||
|
*/
|
||||||
|
public void chunkUnloaded(int cx, int cz, World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save all ChunkletStores related to the given world
|
||||||
|
*
|
||||||
|
* @param world World to save
|
||||||
|
*/
|
||||||
|
public void saveWorld(World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unload all ChunkletStores from memory related to the given world after saving them
|
||||||
|
*
|
||||||
|
* @param world World to unload
|
||||||
|
*/
|
||||||
|
public void unloadWorld(World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save all ChunkletStores
|
||||||
|
*/
|
||||||
|
public void saveAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unload all ChunkletStores after saving them
|
||||||
|
*/
|
||||||
|
public void unloadAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if a given location is set to true
|
||||||
|
*
|
||||||
|
* @param x X coordinate to check
|
||||||
|
* @param y Y coordinate to check
|
||||||
|
* @param z Z coordinate to check
|
||||||
|
* @param world World to check in
|
||||||
|
* @return true if the given location is set to true, false if otherwise
|
||||||
|
*/
|
||||||
|
public boolean isTrue(int x, int y, int z, World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if a given block location is set to true
|
||||||
|
*
|
||||||
|
* @param block Block location to check
|
||||||
|
* @return true if the given block location is set to true, false if otherwise
|
||||||
|
*/
|
||||||
|
public boolean isTrue(Block block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a given location to true, should create stores as necessary if the location does not exist
|
||||||
|
*
|
||||||
|
* @param x X coordinate to set
|
||||||
|
* @param y Y coordinate to set
|
||||||
|
* @param z Z coordinate to set
|
||||||
|
* @param world World to set in
|
||||||
|
*/
|
||||||
|
public void setTrue(int x, int y, int z, World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a given block location to true, should create stores as necessary if the location does not exist
|
||||||
|
*
|
||||||
|
* @param block Block location to set
|
||||||
|
*/
|
||||||
|
public void setTrue(Block block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a given location to false, should not create stores if one does not exist for the given location
|
||||||
|
*
|
||||||
|
* @param x X coordinate to set
|
||||||
|
* @param y Y coordinate to set
|
||||||
|
* @param z Z coordinate to set
|
||||||
|
* @param world World to set in
|
||||||
|
*/
|
||||||
|
public void setFalse(int x, int y, int z, World world);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a given block location to false, should not create stores if one does not exist for the given location
|
||||||
|
*
|
||||||
|
* @param block Block location to set
|
||||||
|
*/
|
||||||
|
public void setFalse(Block block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete any ChunkletStores that are empty
|
||||||
|
*/
|
||||||
|
public void cleanUp();
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.gmail.nossr50.util.blockmeta;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public interface ChunkletStore extends Serializable {
|
||||||
|
/**
|
||||||
|
* @param x x coordinate in current chunklet
|
||||||
|
* @param y y coordinate in current chunklet
|
||||||
|
* @param z z coordinate in current chunklet
|
||||||
|
* @return true if the value is true at the given coordinates, false if otherwise
|
||||||
|
*/
|
||||||
|
public boolean isTrue(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value to true at the given coordinates
|
||||||
|
*
|
||||||
|
* @param x x coordinate in current chunklet
|
||||||
|
* @param y y coordinate in current chunklet
|
||||||
|
* @param z z coordinate in current chunklet
|
||||||
|
*/
|
||||||
|
public void setTrue(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value to false at the given coordinates
|
||||||
|
*
|
||||||
|
* @param x x coordinate in current chunklet
|
||||||
|
* @param y y coordinate in current chunklet
|
||||||
|
* @param z z coordinate in current chunklet
|
||||||
|
*/
|
||||||
|
public void setFalse(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if all values in the chunklet are false, false if otherwise
|
||||||
|
*/
|
||||||
|
public boolean isEmpty();
|
||||||
|
}
|
@ -0,0 +1,227 @@
|
|||||||
|
package com.gmail.nossr50.util.blockmeta;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
public class HashChunkletManager implements ChunkletManager {
|
||||||
|
private HashMap<String, ChunkletStore> store = new HashMap<String, ChunkletStore>();
|
||||||
|
|
||||||
|
public void chunkLoaded(int cx, int cz, World world) {
|
||||||
|
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||||
|
File cxDir = new File(dataDir, "" + cx);
|
||||||
|
if(!cxDir.exists()) return;
|
||||||
|
File czDir = new File(cxDir, "" + cz);
|
||||||
|
if(!czDir.exists()) return;
|
||||||
|
|
||||||
|
for(int y = 1; y <= 4; y++) {
|
||||||
|
File yFile = new File(czDir, "" + y);
|
||||||
|
if(!yFile.exists()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
ChunkletStore in = deserializeChunkletStore(yFile);
|
||||||
|
if(in != null) {
|
||||||
|
store.put(world.getName() + "," + cx + "," + cz + "," + y, in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void chunkUnloaded(int cx, int cz, World world) {
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
for(String key : store.keySet()) {
|
||||||
|
if(key.startsWith(world.getName() + "," + cx + "," + cz)) found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) return;
|
||||||
|
|
||||||
|
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||||
|
File cxDir = new File(dataDir, "" + cx);
|
||||||
|
if(!cxDir.exists()) cxDir.mkdir();
|
||||||
|
File czDir = new File(cxDir, "" + cz);
|
||||||
|
if(!czDir.exists()) czDir.mkdir();
|
||||||
|
|
||||||
|
for(int y = 1; y <= 4; y++) {
|
||||||
|
File yFile = new File(czDir, "" + y);
|
||||||
|
if(store.containsKey(world.getName() + "," + cx + "," + cz + "," + y)) {
|
||||||
|
ChunkletStore out = store.get(world.getName() + "," + cx + "," + cz + "," + y);
|
||||||
|
serializeChunkletStore(out, yFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveWorld(World world) {
|
||||||
|
String worldName = world.getName();
|
||||||
|
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||||
|
|
||||||
|
for(String key : store.keySet()) {
|
||||||
|
String[] info = key.split(",");
|
||||||
|
if(worldName.equals(info[0])) {
|
||||||
|
File cxDir = new File(dataDir, "" + info[1]);
|
||||||
|
if(!cxDir.exists()) cxDir.mkdir();
|
||||||
|
File czDir = new File(cxDir, "" + info[2]);
|
||||||
|
if(!czDir.exists()) czDir.mkdir();
|
||||||
|
|
||||||
|
File yFile = new File(czDir, "" + info[3]);
|
||||||
|
serializeChunkletStore(store.get(key), yFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadWorld(World world) {
|
||||||
|
saveWorld(world);
|
||||||
|
|
||||||
|
String worldName = world.getName();
|
||||||
|
|
||||||
|
for(String key : store.keySet()) {
|
||||||
|
String tempWorldName = key.split(",")[0];
|
||||||
|
if(tempWorldName.equals(worldName)) {
|
||||||
|
store.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveAll() {
|
||||||
|
for(World world : Bukkit.getWorlds()) {
|
||||||
|
saveWorld(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unloadAll() {
|
||||||
|
saveAll();
|
||||||
|
for(World world : Bukkit.getWorlds()) {
|
||||||
|
unloadWorld(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTrue(int x, int y, int z, World world) {
|
||||||
|
int cx = x / 16;
|
||||||
|
int cz = z / 16;
|
||||||
|
int cy = y / 64;
|
||||||
|
if(!store.containsKey(world.getName() + "," + cx + "," + cz + "," + cy)) return false;
|
||||||
|
|
||||||
|
ChunkletStore check = store.get(world.getName() + "," + cx + "," + cz + "," + cy);
|
||||||
|
int ix = Math.abs(x) % 16;
|
||||||
|
int iz = Math.abs(z) % 16;
|
||||||
|
int iy = Math.abs(y) % 64;
|
||||||
|
|
||||||
|
return check.isTrue(ix, iy, iz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTrue(Block block) {
|
||||||
|
return isTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrue(int x, int y, int z, World world) {
|
||||||
|
int cx = x / 16;
|
||||||
|
int cz = z / 16;
|
||||||
|
int cy = y / 64;
|
||||||
|
|
||||||
|
int ix = Math.abs(x) % 16;
|
||||||
|
int iz = Math.abs(z) % 16;
|
||||||
|
int iy = Math.abs(y) % 64;
|
||||||
|
|
||||||
|
ChunkletStore cStore;
|
||||||
|
if(!store.containsKey(world.getName() + "," + cx + "," + cz + "," + cy)) {
|
||||||
|
cStore = new PrimitiveChunkletStore();
|
||||||
|
store.put(world.getName() + "," + cx + "," + cz + "," + cy, cStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
cStore = store.get(world.getName() + "," + cx + "," + cz + "," + cy);
|
||||||
|
cStore.setTrue(ix, iy, iz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrue(Block block) {
|
||||||
|
setTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFalse(int x, int y, int z, World world) {
|
||||||
|
int cx = x / 16;
|
||||||
|
int cz = z / 16;
|
||||||
|
int cy = y / 64;
|
||||||
|
|
||||||
|
int ix = Math.abs(x) % 16;
|
||||||
|
int iz = Math.abs(z) % 16;
|
||||||
|
int iy = Math.abs(y) % 64;
|
||||||
|
|
||||||
|
ChunkletStore cStore;
|
||||||
|
if(!store.containsKey(world.getName() + "," + cx + "," + cz + "," + cy)) {
|
||||||
|
return; // No need to make a store for something we will be setting to false
|
||||||
|
}
|
||||||
|
|
||||||
|
cStore = store.get(world.getName() + "," + cx + "," + cz + "," + cy);
|
||||||
|
cStore.setFalse(ix, iy, iz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFalse(Block block) {
|
||||||
|
setFalse(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanUp() {
|
||||||
|
for(String key : store.keySet()) {
|
||||||
|
if(store.get(key).isEmpty()) {
|
||||||
|
String[] info = key.split(",");
|
||||||
|
File dataDir = new File(Bukkit.getWorld(info[0]).getWorldFolder(), "mcmmo_data");
|
||||||
|
|
||||||
|
File cxDir = new File(dataDir, "" + info[1]);
|
||||||
|
if(!cxDir.exists()) continue;
|
||||||
|
File czDir = new File(cxDir, "" + info[2]);
|
||||||
|
if(!czDir.exists()) continue;
|
||||||
|
|
||||||
|
File yFile = new File(czDir, "" + info[3]);
|
||||||
|
yFile.delete();
|
||||||
|
|
||||||
|
//Delete empty directories
|
||||||
|
if(czDir.list().length == 0) czDir.delete();
|
||||||
|
if(cxDir.list().length == 0) cxDir.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cStore ChunkletStore to save
|
||||||
|
* @param location Where on the disk to put it
|
||||||
|
*/
|
||||||
|
private void serializeChunkletStore(ChunkletStore cStore, File location) {
|
||||||
|
try {
|
||||||
|
FileOutputStream fileOut = new FileOutputStream(location);
|
||||||
|
ObjectOutputStream objOut = new ObjectOutputStream(fileOut);
|
||||||
|
objOut.writeObject(cStore);
|
||||||
|
objOut.close();
|
||||||
|
fileOut.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param location Where on the disk to read from
|
||||||
|
* @return ChunkletStore from the specified location
|
||||||
|
*/
|
||||||
|
private ChunkletStore deserializeChunkletStore(File location) {
|
||||||
|
ChunkletStore storeIn = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileInputStream fileIn = new FileInputStream(location);
|
||||||
|
ObjectInputStream objIn = new ObjectInputStream(fileIn);
|
||||||
|
storeIn = (ChunkletStore) objIn.readObject();
|
||||||
|
objIn.close();
|
||||||
|
fileIn.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return storeIn;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.gmail.nossr50.util.blockmeta;
|
||||||
|
|
||||||
|
public class PrimitiveChunkletStore implements ChunkletStore {
|
||||||
|
private static final long serialVersionUID = -3453078050608607478L;
|
||||||
|
|
||||||
|
/** X, Z, Y */
|
||||||
|
private boolean[][][] store = new boolean[16][16][64];
|
||||||
|
|
||||||
|
public boolean isTrue(int x, int y, int z) {
|
||||||
|
return store[x][z][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrue(int x, int y, int z) {
|
||||||
|
store[x][z][y] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFalse(int x, int y, int z) {
|
||||||
|
store[x][z][y] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int z = 0; z < 16; z++) {
|
||||||
|
for(int y = 0; y < 64; y++) {
|
||||||
|
if(store[x][z][y]) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ website: http://forums.bukkit.org/threads/rpg-mech-mcmmo-v1-3-05-rpg-addiction-r
|
|||||||
|
|
||||||
main: com.gmail.nossr50.mcMMO
|
main: com.gmail.nossr50.mcMMO
|
||||||
softdepend: [Spout]
|
softdepend: [Spout]
|
||||||
|
load: STARTUP
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
mchud:
|
mchud:
|
||||||
|
Loading…
Reference in New Issue
Block a user