restoring snapshop code

Discussion in 'Plugin Development' started by rmb938, Jul 10, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    rmb938

    So I was search the bukkit forums on how to restore a worldedit snapshop via code. I found what I am looking for but there is a slight issue. When the restore happens it lags the whole server. Is there a way to get rid of the lag? I tried putting it inside a async delayed task but I end up getting a next tick error that crashes the server.

    This is the code I have:

    Code:
        public static void resetArena() {
     
            /*Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
     
                @Override
                public void run() {*/
     
                    Vector v1 = new Vector(283, 0, -793);//wall1r
                    Vector v2 = new Vector(347, 255, -729);
                    rollbackInstance("wall", "/minecraft/Minecraft/snapshot", "2012-7-7-00-00-00", v1, v2);
                    v1 = new Vector(347, 0, -793);//wall2r
                    v2 = new Vector(411, 255, -729);
                    rollbackInstance("wall", "/minecraft/Minecraft/snapshot", "2012-7-7-00-00-00", v1, v2);
                    v1 = new Vector(347, 0, -857);//wall3r
                    v2 = new Vector(411, 255, -793);
                    rollbackInstance("wall", "/minecraft/Minecraft/snapshot", "2012-7-7-00-00-00", v1, v2);
                    v1 = new Vector(283, 0, -857);//wall4r
                    v2 = new Vector(347, 255, -783);
                    rollbackInstance("wall", "/minecraft/Minecraft/snapshot", "2012-7-7-00-00-00", v1, v2);
     
              /* }
            }, 2L);*/
        }
     
     
        private static void rollbackInstance(String worldName, String snapshotStoreName, String snapshotName, Vector myVector1, Vector myVector2) {
            SnapshotRestore mySnapshotRestore;
            ChunkStore myChunkStore;
            Region myRegion;
            EditSession myEditSession;
            SnapshotRepository myRepo = null;
            Snapshot mySnapshot = null;
            //this.logger("Getting Edit Session..");
            World worldf = Bukkit.getWorld(worldName);
            BukkitWorld BWf = new BukkitWorld(worldf);
            myEditSession = new EditSession(BWf, Integer.MAX_VALUE);
            if (myEditSession == null) {
                plugin.getLogger().info("Could not obtain an edit session..");
                //return;
            }
            //this.logger("Getting ChunkStore..");
            myChunkStore = _getInstanceChunkStore(myEditSession, snapshotStoreName, snapshotName, myRepo, mySnapshot);
            if (myChunkStore == null) {
                plugin.getLogger().info("ChunkStore is null!");
                //return;
            }
            //this.logger("Getting Region ..");
            myRegion = new CuboidRegion(myVector1, myVector2);
            if (myRegion == null) {
                plugin.getLogger().info("Region is null!");
                //return;
            }
            //this.logger("Generating snapshot restore operation");
            //mySnapshotRestore = new SnapshotRestore(_getInstanceChunkStore(), _regionProvider());
            mySnapshotRestore = new SnapshotRestore(myChunkStore, myRegion);
            if (mySnapshotRestore == null) {
                plugin.getLogger().info("Snapshot restore operation is null!");
                //return;
            }
            plugin.getLogger().info("Attempting to call restore..");
            try {
                mySnapshotRestore.restore(myEditSession);
            } catch (MaxChangedBlocksException e) {
                plugin.getLogger().info("MaxChangedBlocksException exception caught.");
            }
            plugin.getLogger().info("rollbackInstance exiting..");
            mySnapshotRestore = null;
            myRegion = null;
            myChunkStore = null;
            mySnapshot = null;
            myRepo = null;
            myEditSession = null;
            BWf = null;
            worldf = null;
        }
     
        private static ChunkStore _getInstanceChunkStore(EditSession myEditSession, String snapshotStoreName, String snapshotName, SnapshotRepository myRepo, Snapshot mySnapshot) {
            //this.logger("_getInstanceChunkStore entered.");
            ChunkStore myChunkStore = null;
            //this.logger("Getting snapshot repository..");
            myRepo = new SnapshotRepository(snapshotStoreName);
     
            if (myRepo == null) {
                plugin.getLogger().info("Snapshot Repository is null");
                return null;
            }
            plugin.getLogger().info("looking up snapshots for world (" + myEditSession.getWorld().getName() + ")");
            try {
                List<Snapshot> snapshots = myRepo.getSnapshots(true, myEditSession.getWorld().getName());
                if (snapshots.size() > 0) {
                    plugin.getLogger().info("atleast one snapshot was located..");
                } else {
                    plugin.getLogger().info("no snapshots located in repository");
                }
                snapshots = null;
            } catch (MissingWorldException e) {
                plugin.getLogger().info("MissingWorldException caught.");
                //return null;
            }
            if (myRepo.isValidSnapshotName(myEditSession.getWorld().getName() + "/" + snapshotName)) {
                plugin.getLogger().info(myEditSession.getWorld().getName() + "/" + snapshotName + " is valid.");
            }
            try {
                mySnapshot = myRepo.getSnapshot(myEditSession.getWorld().getName() + "/" + snapshotName);
            } catch (InvalidSnapshotException e) {
                plugin.getLogger().info("caught InvalidSnapshotException");
                //return null;
            }
            try {
                myChunkStore = mySnapshot.getChunkStore();
            } catch (DataException e) {
                plugin.getLogger().info("caught DataException");
                //return null;
            } catch (IOException e) {
                plugin.getLogger().info("caught IOException");
                //return null;
            }
            //this.logger("_getInstanceChunkStore leaving normally.");
            return myChunkStore;
        }
     
  2. Offline

    Father Of Time

    async task are not thread safe (except for one or two exceptions), so changing world attributes from an async thread is usually problematic...

    Sadly what you are describing is a massive workload for any server; really the only way that immediately comes to mind would be to break your restore up into smaller peices and do them sequentially. If I recall correctly the new RB has chunks broken up into even smaller sections, or sub chunks. Chunks are 16x16 and now rather than being 256 blocks tall they are broken up into 16 block chunks vertically too (I could be slightly off with my numbers).

    I would try breaking it down into those sub chunks, allowing it to restore 16x16x16, then free the main thread for a single tick to allow it to do game updates, then move on to the next chunk... repeat this process until the entire restore is done.

    You are trying to make more changes than your processor can process in a single game tick, so you will likely need to reduce the workload or split it up across game ticks.
     
    ferrybig likes this.
  3. Offline

    rmb938

    Yea that is what I was thinking. Was just wondering if there was a simpler way.
     
  4. Offline

    Father Of Time

    Unfortunately I don't believe so; a processor can only handle a certian workload per tick, anything over that will delay the execution of the next tick and result in game "lag spikes". but remember, even if you break it up across several ticks it will still seem almost instant seeing as a tick is only 20 milliseconds, which is far faster than the human eye can see, so spanning it across 2, 3, 5 or even 10 ticks would still be nearly instant (10 ticks would be 200 milliseconds, or 2/10ths of a second).
     
Thread Status:
Not open for further replies.

Share This Page