package org.ultramine.mods.hawkeye; import java.util.Iterator; import org.ultramine.mods.hawkeye.Rollback.RollbackType; import org.ultramine.mods.hawkeye.database.DataManager; import org.ultramine.mods.hawkeye.entry.DataEntry; import org.ultramine.mods.hawkeye.util.HawkUtil; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraftforge.common.util.BlockSnapshot; /** * Runnable class for reversing a {@link Rollback}. This class should always be * run in a separate thread to avoid impacting on server performance * * @author oliverw92 */ public class Undo { private final PlayerSession session; private Iterator<DataEntry> undoQueue; private int counter = 0; private RollbackType undoType = RollbackType.GLOBAL; /** * @param session * {@link PlayerSession} to retrieve undo results from */ public Undo(RollbackType undoType, PlayerSession session) { this.undoType = undoType; this.session = session; undoQueue = session.getRollbackResults().iterator(); //Check if already rolling back if(session.doingRollback()) { HawkUtil.sendMessage(session.getSender(), "&cYour previous rollback is still processing, please wait before performing an undo!"); return; } //Check that we actually have results if(!undoQueue.hasNext()) { HawkUtil.sendMessage(session.getSender(), "&cNo results found to undo"); return; } HawkUtil.debug("Starting undo of " + session.getRollbackResults().size() + " results"); //Start undo session.setDoingRollback(true); HawkUtil.sendMessage(session.getSender(), "&cAttempting to undo &7" + session.getRollbackResults().size() + "&c rollback edits"); FMLCommonHandler.instance().bus().register(this); } /** * Run the undo. Contains appropriate methods of catching errors and * notifying the player */ @SubscribeEvent public void onServerTick(TickEvent.ServerTickEvent e) { if(e.phase == TickEvent.Phase.END) return; //Start rollback process int i = 0; while(i < 200 && undoQueue.hasNext()) { //If undo doesn't exist DataEntry entry = undoQueue.next(); if(entry.getUndoState() == null) continue; //Global undo if(undoType == RollbackType.GLOBAL) { BlockSnapshot block = entry.getUndoState(); block.world.restoringBlockSnapshots = true; block.restore(true); block.world.restoringBlockSnapshots = false; //Add back into database if delete data is on if(HawkEye.instance.config.general.deleteDataOnRollback) DataManager.addEntry(entry); } //Player undo else { EntityPlayerMP player = (EntityPlayerMP) session.getSender(); BlockSnapshot block = entry.getUndoState(); S23PacketBlockChange p = new S23PacketBlockChange(block.x, block.y, block.z, block.world); p.field_148883_d = block.getReplacedBlock(); p.field_148884_e = block.meta; player.playerNetServerHandler.sendPacket(p); } counter++; } //Check if undo is finished if(!undoQueue.hasNext()) { //End timer FMLCommonHandler.instance().bus().unregister(this); session.setDoingRollback(false); session.setRollbackResults(null); HawkUtil.sendMessage(session.getSender(), "&cUndo complete, &7" + counter + " &cedits performed"); HawkUtil.debug("Undo complete, " + counter + " edits performed"); } } }