I am trying to update blocks in Minecraft within a Bukkit mod and be able to //undo
those changes within Minecraft. I can change the block but I cannot //undo
the change.
I must be missing something simple since Google hasn't helped me find a solution.
Here is my mod. It sets a single block from the currently selected region to air. The commented out lines are things I have tried that didn't work for me.
public class Main extends JavaPlugin implements Listener
{
// ... //
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
{
if (command.getName().equalsIgnoreCase("setair"))
{
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) sender;
WorldEditPlugin worldEditPlugin = null;
worldEditPlugin = (WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
if(worldEditPlugin == null){
bukkitPlayer.sendMessage("Error: WorldEdit is null.");
}
else
{
com.sk89q.worldedit.bukkit.selections.Selection s = worldEditPlugin.getSelection(bukkitPlayer);
com.sk89q.worldedit.LocalSession localSession = worldEditPlugin.getSession(bukkitPlayer);
com.sk89q.worldedit.world.World localWorld = localSession.getSelectionWorld();
com.sk89q.worldedit.bukkit.BukkitPlayer wrappedPlayer = worldEditPlugin.wrapPlayer(bukkitPlayer);
com.sk89q.worldedit.LocalPlayer localPlayer = wrappedPlayer;
//com.sk89q.worldedit.world.World localWorld2 = localPlayer.getWorld();
com.sk89q.worldedit.EditSession editSession = worldEditPlugin.getWorldEdit().getEditSessionFactory().getEditSession(localWorld, -1, localPlayer);
//com.sk89q.worldedit.EditSession editSession = worldEditPlugin.createEditSession(bukkitPlayer);
//localSession.remember(editSession);
Vector minV = s.getNativeMinimumPoint();
try {
editSession.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
} catch (MaxChangedBlocksException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//try {
// localWorld.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
//} catch (WorldEditException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
//}
localSession.getRegionSelector(localWorld).learnChanges();
localSession.getRegionSelector(localWorld).explainRegionAdjust(localPlayer, localSession);
bukkitPlayer.performCommand("tellraw @p \"Done setair\"");
}
return true;
}
}
}
EDIT: Here is what works. Thanks sorifiend for the answer below. To get it to work, I also had to move localSession.remember(editSession)
to after the setBlock call.
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
{
if (command.getName().equalsIgnoreCase("setair"))
{
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) sender;
WorldEditPlugin worldEditPlugin = null;
worldEditPlugin = (WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
if(worldEditPlugin == null){
bukkitPlayer.sendMessage("Error: WorldEdit is null.");
}
else
{
com.sk89q.worldedit.bukkit.selections.Selection s = worldEditPlugin.getSelection(bukkitPlayer);
com.sk89q.worldedit.LocalSession localSession = worldEditPlugin.getSession(bukkitPlayer);
com.sk89q.worldedit.EditSession editSession = worldEditPlugin.createEditSession(bukkitPlayer);
Vector minV = s.getNativeMinimumPoint();
try {
editSession.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
} catch (MaxChangedBlocksException e) {
e.printStackTrace();
}
localSession.remember(editSession);
bukkitPlayer.performCommand("tellraw @p \"Done setair\"");
}
return true;
}
}
Now I can select something with WorldEdit, run /setair
to set one of the blocks to air. And //undo
does what you'd expect.