Skip to content

Instantly share code, notes, and snippets.

@aadnk
Last active October 12, 2015 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aadnk/4068363 to your computer and use it in GitHub Desktop.
Save aadnk/4068363 to your computer and use it in GitHub Desktop.
Using Google Guava to restore blocks after a certain amount of time.
package com.comphenix.example;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.BlockVector;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
public class TemporaryModifcations extends JavaPlugin implements Listener {
public static int TICKS_PER_SECOND = 20;
private static class BlockData {
private WeakReference<World> worldReference;
private int typeID;
private byte data;
public BlockData(Block block) {
this.worldReference = new WeakReference<World>(block.getWorld());
this.typeID = block.getTypeId();
this.data = block.getData();
}
/**
* Restore the current block.
* @return TRUE if the block was restored, FALSE otherwise.
*/
public boolean restore(BlockVector vector) {
if (getWorld() != null) {
Block block = getWorld().getBlockAt(vector.toLocation(getWorld()));
// Restore type and data
block.setTypeId(typeID);
block.setData(data);
return true;
} else {
return false;
}
}
public World getWorld() {
return worldReference.get();
}
}
private Cache<BlockVector, BlockData> restoreQueue;
@Override
public void onLoad() {
restoreQueue = CacheBuilder.
newBuilder().
concurrencyLevel(2).
weakValues().
expireAfterWrite(10, TimeUnit.SECONDS).
removalListener(new RemovalListener<BlockVector, BlockData>() {
@Override
public void onRemoval(RemovalNotification<BlockVector, BlockData> entry) {
entry.getValue().restore(entry.getKey());
}
}).
build(new CacheLoader<BlockVector, BlockData>() {
@Override
public BlockData load(BlockVector arg0) throws Exception {
throw new RuntimeException("Unsupported! Cannot generate entries, must be placed manually.");
}
});
}
@Override
public void onEnable() {
PluginManager manager = getServer().getPluginManager();
manager.registerEvents(this, this);
// Run the block cleanup once per second
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
@Override
public void run() {
restoreQueue.cleanUp();
}
}, TICKS_PER_SECOND, TICKS_PER_SECOND);
}
@EventHandler
public void onBlockBreakEvent(BlockBreakEvent event) {
BlockData data = new BlockData(event.getBlock());
BlockVector vector = new BlockVector(event.getBlock().getLocation().toVector());
// Expire after two minutes
restoreQueue.asMap().put(vector, data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment