mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-04 03:03:43 +01:00 
			
		
		
		
	more efficient plot diff calculations
This commit is contained in:
		@@ -22,7 +22,6 @@ package com.intellectualcrafters.plot.database;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.sql.Blob;
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.DriverManager;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,11 @@
 | 
			
		||||
package com.intellectualcrafters.plot.generator;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.mutable.MutableInt;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Chunk;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
@@ -13,14 +16,82 @@ import com.intellectualcrafters.plot.BukkitMain;
 | 
			
		||||
import com.intellectualcrafters.plot.PlotSquared;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotWorld;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
 | 
			
		||||
 | 
			
		||||
public class BukkitHybridUtils extends HybridUtils {
 | 
			
		||||
	
 | 
			
		||||
	public void checkModified(final Plot plot, final int requiredChanges, final Runnable whenDone) {
 | 
			
		||||
		TaskManager.index.increment();
 | 
			
		||||
		
 | 
			
		||||
		final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
 | 
			
		||||
		final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
 | 
			
		||||
        
 | 
			
		||||
        int bx = bot.getX() >> 4;
 | 
			
		||||
        int bz = bot.getZ() >> 4;
 | 
			
		||||
        
 | 
			
		||||
        int tx = top.getX() >> 4;
 | 
			
		||||
        int tz = top.getZ() >> 4;
 | 
			
		||||
        
 | 
			
		||||
        int size = (tx-bx) << 4;
 | 
			
		||||
        World world = BukkitUtil.getWorld(plot.world);
 | 
			
		||||
        
 | 
			
		||||
        final HashSet<Chunk> chunks = new HashSet<>();
 | 
			
		||||
        for (int X = bx; X <= tx; X++) {
 | 
			
		||||
            for (int Z = bz; Z <= tz; Z++) {
 | 
			
		||||
                chunks.add(world.getChunkAt(X,Z));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        PlotWorld plotworld = PlotSquared.getPlotWorld(plot.world);
 | 
			
		||||
        if (!(plotworld instanceof ClassicPlotWorld)) {
 | 
			
		||||
        	TaskManager.runTaskLater(whenDone, 1);
 | 
			
		||||
        	return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        final ClassicPlotWorld cpw = (ClassicPlotWorld) plotworld;
 | 
			
		||||
        
 | 
			
		||||
        final MutableInt count = new MutableInt(0);
 | 
			
		||||
        
 | 
			
		||||
        final Integer currentIndex = TaskManager.index.toInteger();
 | 
			
		||||
        final Integer task = TaskManager.runTaskRepeat(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
            	if (count.intValue() >= requiredChanges) {
 | 
			
		||||
            		TaskManager.runTaskLater(whenDone, 1);
 | 
			
		||||
            		Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
 | 
			
		||||
                    TaskManager.tasks.remove(currentIndex);
 | 
			
		||||
                    return;
 | 
			
		||||
            	}
 | 
			
		||||
                if (chunks.size() == 0) {
 | 
			
		||||
                    Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
 | 
			
		||||
                    TaskManager.tasks.remove(currentIndex);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                final Chunk chunk = chunks.iterator().next();
 | 
			
		||||
                int bx = Math.max(chunk.getX() >> 4, bot.getX());
 | 
			
		||||
                int bz = Math.max(chunk.getZ() >> 4, bot.getZ());
 | 
			
		||||
                int ex = Math.max((chunk.getX() >> 4) + 15, top.getX());
 | 
			
		||||
                int ez = Math.max((chunk.getZ() >> 4) + 15, top.getZ());
 | 
			
		||||
                // count changes
 | 
			
		||||
                count.add(checkModified(plot.world, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK));
 | 
			
		||||
                count.add(checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK));
 | 
			
		||||
            }
 | 
			
		||||
        }, 1);
 | 
			
		||||
        TaskManager.tasks.put(currentIndex, task);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public int checkModified(final int threshhold, final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks) {
 | 
			
		||||
    public int checkModified(final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks) {
 | 
			
		||||
        final World world = BukkitUtil.getWorld(worldname);
 | 
			
		||||
        int count = 0;
 | 
			
		||||
        for (int y = y1; y <= y2; y++) {
 | 
			
		||||
@@ -37,9 +108,6 @@ public class BukkitHybridUtils extends HybridUtils {
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!same) {
 | 
			
		||||
                        count++;
 | 
			
		||||
                        if (count > threshhold) {
 | 
			
		||||
                            return -1;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,41 +16,14 @@ import com.intellectualcrafters.plot.util.BlockManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
 | 
			
		||||
 | 
			
		||||
public abstract class HybridUtils {
 | 
			
		||||
 | 
			
		||||
    public static HybridUtils manager;
 | 
			
		||||
    
 | 
			
		||||
    public abstract void checkModified(Plot plot, int requiredChanges, Runnable ifPassed);
 | 
			
		||||
 | 
			
		||||
    public boolean checkModified(final Plot plot, int requiredChanges) {
 | 
			
		||||
        final Location bottom = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
 | 
			
		||||
        final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
 | 
			
		||||
        final int botx = bottom.getX();
 | 
			
		||||
        final int botz = bottom.getZ();
 | 
			
		||||
        final int topx = top.getX();
 | 
			
		||||
        final int topz = top.getZ();
 | 
			
		||||
        final HybridPlotWorld hpw = (HybridPlotWorld) PlotSquared.getPlotWorld(plot.world);
 | 
			
		||||
        final PlotBlock[] air = new PlotBlock[] { new PlotBlock((short) 0, (byte) 0) };
 | 
			
		||||
        int changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT, hpw.PLOT_HEIGHT, botz, topz, hpw.TOP_BLOCK);
 | 
			
		||||
        if (changes == -1) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        requiredChanges -= changes;
 | 
			
		||||
        changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT + 1, hpw.PLOT_HEIGHT + 1, botz, topz, air);
 | 
			
		||||
        if (changes == -1) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        requiredChanges -= changes;
 | 
			
		||||
        changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT + 2, BukkitUtil.getMaxHeight(plot.world) - 1, botz, topz, air);
 | 
			
		||||
        if (changes == -1) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        requiredChanges -= changes;
 | 
			
		||||
        changes = checkModified(requiredChanges, plot.world, botx, topx, 1, hpw.PLOT_HEIGHT - 1, botz, topz, hpw.MAIN_BLOCK);
 | 
			
		||||
        return changes == -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract int checkModified(final int threshhold, final String world, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks);
 | 
			
		||||
    public abstract int checkModified(final String world, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks);
 | 
			
		||||
 | 
			
		||||
    public boolean setupRoadSchematic(final Plot plot) {
 | 
			
		||||
        final String world = plot.world;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,17 @@
 | 
			
		||||
package com.intellectualcrafters.plot.util;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang.mutable.MutableInt;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PlotSquared;
 | 
			
		||||
 | 
			
		||||
public abstract class TaskManager {
 | 
			
		||||
    public static HashSet<String> TELEPORT_QUEUE = new HashSet<>();
 | 
			
		||||
    
 | 
			
		||||
    public static MutableInt index = new MutableInt(0);
 | 
			
		||||
    public static HashMap<Integer, Integer> tasks = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public abstract int taskRepeat(final Runnable r, int interval);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,9 +59,6 @@ import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
    public static MutableInt index = new MutableInt(0);
 | 
			
		||||
    public static HashMap<Integer, Integer> tasks = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ArrayList<ChunkLoc> getChunkChunks(final String world) {
 | 
			
		||||
        final String directory = Bukkit.getWorldContainer() + File.separator + world + File.separator + "region";
 | 
			
		||||
@@ -152,7 +149,7 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone) {
 | 
			
		||||
        index.increment();
 | 
			
		||||
    	TaskManager.index.increment();
 | 
			
		||||
        final int relX = newPos.getX() - pos1.getX();
 | 
			
		||||
        final int relZ = newPos.getZ() - pos1.getZ();
 | 
			
		||||
        
 | 
			
		||||
@@ -183,19 +180,19 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final Plugin plugin = BukkitMain.THIS;
 | 
			
		||||
        final Integer currentIndex = index.toInteger();
 | 
			
		||||
        final Integer currentIndex = TaskManager.index.toInteger();
 | 
			
		||||
        final int loadTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                final long start = System.currentTimeMillis();
 | 
			
		||||
                while ((System.currentTimeMillis() - start) < 25) {
 | 
			
		||||
                    if (toGenerate.size() == 0) {
 | 
			
		||||
                        Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
 | 
			
		||||
                        tasks.remove(currentIndex);
 | 
			
		||||
                        Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
 | 
			
		||||
                        TaskManager.tasks.remove(currentIndex);
 | 
			
		||||
                        TaskManager.runTask(new Runnable() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void run() {
 | 
			
		||||
                                index.increment();
 | 
			
		||||
                            	TaskManager.index.increment();
 | 
			
		||||
                                // Copy entities
 | 
			
		||||
                                initMaps();
 | 
			
		||||
                                for (int x = c1x; x <= c2x; x++) {
 | 
			
		||||
@@ -209,7 +206,7 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
                                restoreEntities(newWorld, relX, relZ);
 | 
			
		||||
                                // Copy blocks
 | 
			
		||||
                                final MutableInt mx = new MutableInt(sx);
 | 
			
		||||
                                final Integer currentIndex = index.toInteger();
 | 
			
		||||
                                final Integer currentIndex = TaskManager.index.toInteger();
 | 
			
		||||
                                final int maxY = oldWorld.getMaxHeight();
 | 
			
		||||
                                final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
 | 
			
		||||
                                    @Override
 | 
			
		||||
@@ -234,14 +231,14 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
                                                    chunk.unload(true, true);
 | 
			
		||||
                                                }
 | 
			
		||||
                                                TaskManager.runTask(whenDone);
 | 
			
		||||
                                                Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
 | 
			
		||||
                                                tasks.remove(currentIndex);
 | 
			
		||||
                                                Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
 | 
			
		||||
                                                TaskManager.tasks.remove(currentIndex);
 | 
			
		||||
                                                return;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    };
 | 
			
		||||
                                }, 1, 1);
 | 
			
		||||
                                tasks.put(currentIndex, task);
 | 
			
		||||
                                TaskManager.tasks.put(currentIndex, task);
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                        return;
 | 
			
		||||
@@ -253,13 +250,13 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }, 1l, 1l);
 | 
			
		||||
        tasks.put(currentIndex, loadTask);
 | 
			
		||||
        TaskManager.tasks.put(currentIndex, loadTask);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone) {
 | 
			
		||||
        index.increment();
 | 
			
		||||
    	TaskManager.index.increment();
 | 
			
		||||
        final Plugin plugin = BukkitMain.THIS;
 | 
			
		||||
        final World world = Bukkit.getWorld(pos1.getWorld());
 | 
			
		||||
        final Chunk c1 = world.getChunkAt(pos1.getX() >> 4, pos1.getZ() >> 4);
 | 
			
		||||
@@ -282,14 +279,14 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final int maxY = world.getMaxHeight();
 | 
			
		||||
        final Integer currentIndex = index.toInteger();
 | 
			
		||||
        final Integer currentIndex = TaskManager.index.toInteger();
 | 
			
		||||
        final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if (chunks.size() == 0) {
 | 
			
		||||
                    TaskManager.runTaskLater(whenDone, 1);
 | 
			
		||||
                    Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
 | 
			
		||||
                    tasks.remove(currentIndex);
 | 
			
		||||
                    Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
 | 
			
		||||
                    TaskManager.tasks.remove(currentIndex);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                CURRENT_PLOT_CLEAR = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
 | 
			
		||||
@@ -346,7 +343,7 @@ public class BukkitChunkManager extends ChunkManager {
 | 
			
		||||
                CURRENT_PLOT_CLEAR = null;
 | 
			
		||||
            }
 | 
			
		||||
        }, 1, 1);
 | 
			
		||||
        tasks.put(currentIndex, task);
 | 
			
		||||
        TaskManager.tasks.put(currentIndex, task);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user