Search in sources :

Example 1 with RollbackOptimizedHistory

use of com.fastasyncworldedit.core.history.RollbackOptimizedHistory in project FastAsyncWorldEdit by IntellectualSites.

the class RollbackDatabase method sendBatch.

private boolean sendBatch() throws SQLException {
    int size = Math.min(1048572, historyChanges.size());
    if (size == 0) {
        return false;
    }
    commit();
    if (connection.getAutoCommit()) {
        connection.setAutoCommit(false);
    }
    RollbackOptimizedHistory[] copy = IntStream.range(0, size).mapToObj(i -> historyChanges.poll()).toArray(RollbackOptimizedHistory[]::new);
    try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "edits`" + " (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")) {
        // `player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
        for (RollbackOptimizedHistory change : copy) {
            UUID uuid = change.getUUID();
            byte[] uuidBytes = toBytes(uuid);
            stmt.setBytes(1, uuidBytes);
            stmt.setInt(2, change.getIndex());
            stmt.setInt(3, (int) (change.getTime() / 1000));
            BlockVector3 pos1 = change.getMinimumPoint();
            BlockVector3 pos2 = change.getMaximumPoint();
            stmt.setInt(4, pos1.getX());
            stmt.setInt(5, pos2.getX());
            stmt.setInt(6, pos1.getZ());
            stmt.setInt(7, pos2.getZ());
            stmt.setByte(8, (byte) (pos1.getY() - 128));
            stmt.setByte(9, (byte) (pos2.getY() - 128));
            stmt.setString(10, change.getCommand());
            stmt.setInt(11, change.size());
            stmt.executeUpdate();
            stmt.clearParameters();
        }
    } finally {
        commit();
    }
    return true;
}
Also used : IntStream(java.util.stream.IntStream) MainUtil(com.fastasyncworldedit.core.util.MainUtil) AsyncNotifyQueue(com.fastasyncworldedit.core.util.task.AsyncNotifyQueue) Connection(java.sql.Connection) BlockVector3(com.sk89q.worldedit.math.BlockVector3) CuboidRegion(com.sk89q.worldedit.regions.CuboidRegion) World(com.sk89q.worldedit.world.World) Fawe(com.fastasyncworldedit.core.Fawe) Supplier(java.util.function.Supplier) ByteBuffer(java.nio.ByteBuffer) YieldIterable(com.fastasyncworldedit.core.util.collection.YieldIterable) SQLException(java.sql.SQLException) Future(java.util.concurrent.Future) ResultSet(java.sql.ResultSet) Nonnull(javax.annotation.Nonnull) LogManagerCompat(com.sk89q.worldedit.internal.util.LogManagerCompat) IOException(java.io.IOException) UUID(java.util.UUID) PreparedStatement(java.sql.PreparedStatement) Settings(com.fastasyncworldedit.core.configuration.Settings) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Logger(org.apache.logging.log4j.Logger) DriverManager(java.sql.DriverManager) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) PreparedStatement(java.sql.PreparedStatement) UUID(java.util.UUID) BlockVector3(com.sk89q.worldedit.math.BlockVector3) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory)

Example 2 with RollbackOptimizedHistory

use of com.fastasyncworldedit.core.history.RollbackOptimizedHistory in project FastAsyncWorldEdit by IntellectualSites.

the class HistorySubCommands method importdb.

@Command(name = "import", desc = "Import history into the database" + " - The time uses s, m, h, d, y.\n" + " - Import from disk: /history import")
@CommandPermissions("fawe.rollback.import")
@Confirm
public synchronized void importdb(Actor actor) throws WorldEditException {
    File folder = MainUtil.getFile(Fawe.platform().getDirectory(), Settings.settings().PATHS.HISTORY);
    if (folder.exists()) {
        for (File worldFolder : Objects.requireNonNull(folder.listFiles())) {
            if (worldFolder != null && worldFolder.isDirectory()) {
                String worldName = worldFolder.getName();
                World world = FaweAPI.getWorld(worldName);
                if (world != null) {
                    for (File userFolder : worldFolder.listFiles()) {
                        if (!userFolder.isDirectory()) {
                            continue;
                        }
                        String userUUID = userFolder.getName();
                        try {
                            UUID uuid = UUID.fromString(userUUID);
                            for (File historyFile : userFolder.listFiles()) {
                                String name = historyFile.getName();
                                if (!name.endsWith(".bd")) {
                                    continue;
                                }
                                RollbackOptimizedHistory rollback = new RollbackOptimizedHistory(world, uuid, Integer.parseInt(name.substring(0, name.length() - 3)));
                                SimpleChangeSetSummary summary = rollback.summarize(RegionWrapper.GLOBAL(), false);
                                if (summary != null) {
                                    rollback.setDimensions(BlockVector3.at(summary.minX, world.getMinY(), summary.minZ), BlockVector3.at(summary.maxX, world.getMaxY(), summary.maxZ));
                                    rollback.setTime(historyFile.lastModified());
                                    RollbackDatabase db = DBHandler.IMP.getDatabase(world);
                                    db.logEdit(rollback);
                                    actor.print(TextComponent.of("Logging: " + historyFile));
                                }
                            }
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        actor.print(TextComponent.of("Done import!"));
    }
}
Also used : SimpleChangeSetSummary(com.fastasyncworldedit.core.history.changeset.SimpleChangeSetSummary) World(com.sk89q.worldedit.world.World) UUID(java.util.UUID) File(java.io.File) RollbackDatabase(com.fastasyncworldedit.core.database.RollbackDatabase) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory) Command(org.enginehub.piston.annotation.Command) Confirm(com.sk89q.worldedit.command.util.annotation.Confirm) CommandPermissions(com.sk89q.worldedit.command.util.CommandPermissions)

Example 3 with RollbackOptimizedHistory

use of com.fastasyncworldedit.core.history.RollbackOptimizedHistory in project FastAsyncWorldEdit by IntellectualSites.

the class EditSessionBuilder method compile.

/**
 * Compile the builder to the settings given. Prepares history, limits, lighting, etc.
 */
public EditSessionBuilder compile() {
    if (compiled) {
        return this;
    }
    compiled = true;
    wrapped = false;
    if (event == null) {
        event = new EditSessionEvent(world, actor, -1, null);
    }
    if (actor == null && event.getActor() != null) {
        actor = event.getActor();
    }
    if (limit == null) {
        if (actor == null) {
            limit = FaweLimit.MAX;
        } else {
            limit = actor.getLimit();
        }
    }
    if (fastMode == null) {
        if (actor == null) {
            fastMode = !Settings.settings().HISTORY.ENABLE_FOR_CONSOLE;
        } else {
            fastMode = actor.getSession().hasFastMode();
        }
    }
    if (checkMemory == null) {
        checkMemory = actor != null && !this.fastMode;
    }
    if (checkMemory) {
        if (MemUtil.isMemoryLimitedSlow()) {
            if (Permission.hasPermission(actor, "worldedit.fast")) {
                actor.print(Caption.of("fawe.info.worldedit.oom.admin"));
            }
            throw FaweCache.LOW_MEMORY;
        }
    }
    // this.originalLimit = limit;
    this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
    this.limit = limit.copy();
    if (extent == null) {
        IQueueExtent<IQueueChunk> queue = null;
        World unwrapped = WorldWrapper.unwrap(world);
        boolean placeChunks = (this.fastMode || this.limit.FAST_PLACEMENT) && (wnaMode == null || !wnaMode);
        if (placeChunks) {
            wnaMode = false;
            if (unwrapped instanceof IQueueExtent) {
                extent = queue = (IQueueExtent) unwrapped;
            } else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1 && !Fawe.isMainThread()) {
                ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.instance().getQueueHandler(), world, fastMode);
                queue = parallel.getExtent();
                extent = parallel;
            } else {
                extent = queue = Fawe.instance().getQueueHandler().getQueue(world);
            }
        } else {
            wnaMode = true;
            extent = world;
        }
        if (combineStages == null) {
            combineStages = // If it's enabled in the settings
            Settings.settings().HISTORY.COMBINE_STAGES && // If fast placement is disabled, it's slower to perform a copy on each chunk
            this.limit.FAST_PLACEMENT && // If the edit uses items from the inventory we can't use a delayed task
            this.blockBag == null;
        }
        extent = this.bypassAll = wrapExtent(extent, eventBus, event, EditSession.Stage.BEFORE_CHANGE);
        this.bypassHistory = this.extent = wrapExtent(bypassAll, eventBus, event, EditSession.Stage.BEFORE_REORDER);
        if (!this.fastMode || changeSet != null) {
            if (changeSet == null) {
                if (Settings.settings().HISTORY.USE_DISK) {
                    UUID uuid = actor == null ? Identifiable.CONSOLE : actor.getUniqueId();
                    if (Settings.settings().HISTORY.USE_DATABASE) {
                        changeSet = new RollbackOptimizedHistory(world, uuid);
                    } else {
                        changeSet = new DiskStorageHistory(world, uuid);
                    }
                // } else if (combineStages && Settings.settings().HISTORY.COMPRESSION_LEVEL == 0) {
                // changeSet = new CPUOptimizedChangeSet(world);
                } else {
                    if (combineStages && Settings.settings().HISTORY.COMPRESSION_LEVEL == 0) {
                    // TODO add CPUOptimizedChangeSet
                    }
                    changeSet = new MemoryOptimizedHistory(world);
                }
            }
            if (this.limit.SPEED_REDUCTION > 0) {
                this.extent = this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
            }
            if (command != null && changeSet instanceof RollbackOptimizedHistory) {
                ((RollbackOptimizedHistory) changeSet).setCommand(this.command);
            }
            if (!(changeSet instanceof NullChangeSet)) {
                if (this.blockBag != null) {
                    // TODO implement block bag as IBatchProcessor
                    changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
                }
                if (combineStages) {
                    changeTask = changeSet;
                    this.extent = extent.enableHistory(changeSet);
                } else {
                    this.extent = new HistoryExtent(extent, changeSet);
                // if (this.blockBag != null) {
                // this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
                // }
                }
            }
        }
        if (allowedRegions == null && Settings.settings().REGION_RESTRICTIONS) {
            if (actor != null && !actor.hasPermission("fawe.bypass") && !actor.hasPermission("fawe.bypass.regions")) {
                if (actor instanceof Player) {
                    Player player = (Player) actor;
                    allowedRegions = player.getAllowedRegions();
                }
            }
        }
        if (disallowedRegions == null && Settings.settings().REGION_RESTRICTIONS && Settings.settings().REGION_RESTRICTIONS_OPTIONS.ALLOW_BLACKLISTS) {
            if (actor != null && !actor.hasPermission("fawe.bypass") && !actor.hasPermission("fawe.bypass.regions")) {
                if (actor instanceof Player) {
                    Player player = (Player) actor;
                    disallowedRegions = player.getDisallowedRegions();
                }
            }
        }
        FaweRegionExtent regionExtent = null;
        if (disallowedRegions != null) {
            // Always use MultiRegionExtent if we have blacklist regions
            regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, disallowedRegions);
        } else if (allowedRegions == null) {
            allowedRegions = new Region[] { RegionWrapper.GLOBAL() };
        } else {
            if (allowedRegions.length == 0) {
                regionExtent = new NullExtent(this.extent, FaweCache.NO_REGION);
            } else {
                if (allowedRegions.length == 1) {
                    regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
                } else {
                    regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, null);
                }
            }
        }
        // There's no need to do lighting (and it'll also just be a pain to implement) if we're not placing chunks
        if (placeChunks) {
            if (((relightMode != null && relightMode != RelightMode.NONE) || (relightMode == null && Settings.settings().LIGHTING.MODE > 0))) {
                relighter = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getRelighterFactory().createRelighter(relightMode, world, queue);
                extent.addProcessor(new RelightProcessor(relighter));
            }
            extent.addProcessor(new HeightmapProcessor(world.getMinY(), world.getMaxY()));
        } else {
            relighter = NullRelighter.INSTANCE;
        }
        if (limit != null && !limit.isUnlimited() && regionExtent != null) {
            this.extent = new LimitExtent(regionExtent, limit);
        } else if (limit != null && !limit.isUnlimited()) {
            this.extent = new LimitExtent(this.extent, limit);
        } else if (regionExtent != null) {
            this.extent = regionExtent;
        }
        if (this.limit != null && this.limit.STRIP_NBT != null && !this.limit.STRIP_NBT.isEmpty()) {
            if (placeChunks) {
                extent.addProcessor(new StripNBTExtent(this.extent, this.limit.STRIP_NBT));
            } else {
                this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT);
            }
        }
        if (this.limit != null && !this.limit.isUnlimited()) {
            Set<String> limitBlocks = new HashSet<>();
            if ((getActor() == null || getActor().hasPermission("worldedit.anyblock") && this.limit.UNIVERSAL_DISALLOWED_BLOCKS)) {
                limitBlocks.addAll(WorldEdit.getInstance().getConfiguration().disallowedBlocks);
            }
            if (this.limit.DISALLOWED_BLOCKS != null && !this.limit.DISALLOWED_BLOCKS.isEmpty()) {
                limitBlocks.addAll(this.limit.DISALLOWED_BLOCKS);
            }
            Set<PropertyRemap<?>> remaps = this.limit.REMAP_PROPERTIES;
            if (!limitBlocks.isEmpty() || (remaps != null && !remaps.isEmpty())) {
                if (placeChunks) {
                    extent.addProcessor(new DisallowedBlocksExtent(this.extent, limitBlocks, remaps));
                } else {
                    this.extent = new DisallowedBlocksExtent(this.extent, limitBlocks, remaps);
                }
            }
        }
        this.extent = wrapExtent(this.extent, eventBus, event, EditSession.Stage.BEFORE_HISTORY);
    }
    return this;
}
Also used : LimitExtent(com.fastasyncworldedit.core.extent.LimitExtent) IQueueChunk(com.fastasyncworldedit.core.queue.IQueueChunk) BlockBagChangeSet(com.fastasyncworldedit.core.history.changeset.BlockBagChangeSet) SingleRegionExtent(com.fastasyncworldedit.core.extent.SingleRegionExtent) PropertyRemap(com.fastasyncworldedit.core.limit.PropertyRemap) World(com.sk89q.worldedit.world.World) SlowExtent(com.fastasyncworldedit.core.extent.SlowExtent) DiskStorageHistory(com.fastasyncworldedit.core.history.DiskStorageHistory) MemoryOptimizedHistory(com.fastasyncworldedit.core.history.MemoryOptimizedHistory) MultiRegionExtent(com.fastasyncworldedit.core.extent.MultiRegionExtent) ParallelQueueExtent(com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent) UUID(java.util.UUID) RelightProcessor(com.fastasyncworldedit.core.extent.processor.lighting.RelightProcessor) HashSet(java.util.HashSet) Player(com.sk89q.worldedit.entity.Player) HeightmapProcessor(com.fastasyncworldedit.core.extent.processor.heightmap.HeightmapProcessor) StripNBTExtent(com.fastasyncworldedit.core.extent.StripNBTExtent) NullExtent(com.fastasyncworldedit.core.extent.NullExtent) NullChangeSet(com.fastasyncworldedit.core.history.changeset.NullChangeSet) FaweRegionExtent(com.fastasyncworldedit.core.extent.FaweRegionExtent) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory) HistoryExtent(com.fastasyncworldedit.core.extent.HistoryExtent) IQueueExtent(com.fastasyncworldedit.core.queue.IQueueExtent) Region(com.sk89q.worldedit.regions.Region) EditSessionEvent(com.sk89q.worldedit.event.extent.EditSessionEvent) DisallowedBlocksExtent(com.fastasyncworldedit.core.extent.DisallowedBlocksExtent)

Example 4 with RollbackOptimizedHistory

use of com.fastasyncworldedit.core.history.RollbackOptimizedHistory in project FastAsyncWorldEdit by IntellectualSites.

the class InspectBrush method perform.

public boolean perform(final Player player, LocalSession session, boolean rightClick) {
    if (!player.hasPermission("worldedit.tool.inspect")) {
        player.print(Caption.of("fawe.error.no-perm", "worldedit.tool.inspect"));
        return false;
    }
    if (!Settings.settings().HISTORY.USE_DATABASE) {
        player.print(Caption.of("fawe.error.setting.disable", "history.use-database (Import with /history import )"));
        return false;
    }
    try {
        BlockVector3 target = getTarget(player, rightClick).toBlockPoint();
        final int x = target.getBlockX();
        final int y = target.getBlockY();
        final int z = target.getBlockZ();
        World world = player.getWorld();
        RollbackDatabase db = DBHandler.dbHandler().getDatabase(world);
        int count = 0;
        for (Supplier<RollbackOptimizedHistory> supplier : db.getEdits(target, false)) {
            count++;
            RollbackOptimizedHistory edit = supplier.get();
            Iterator<MutableFullBlockChange> iter = edit.getFullBlockIterator(null, 0, false);
            while (iter.hasNext()) {
                MutableFullBlockChange change = iter.next();
                if (change.x != x || change.y != y || change.z != z) {
                    continue;
                }
                int from = change.from;
                int to = change.to;
                UUID uuid = edit.getUUID();
                String name = Fawe.platform().getName(uuid);
                int index = edit.getIndex();
                long age = System.currentTimeMillis() - edit.getBDFile().lastModified();
                String ageFormatted = MainUtil.secToTime(age / 1000);
                BlockState blockFrom = BlockState.getFromOrdinal(from);
                BlockState blockTo = BlockState.getFromOrdinal(to);
                TranslatableComponent msg = Caption.of("fawe.worldedit.tool.tool.inspect.info", name, blockFrom, blockTo, ageFormatted);
                TextComponent hover = TextComponent.of("/tool inspect", TextColor.GOLD);
                String infoCmd = "//history summary " + uuid + " " + index;
                msg = msg.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hover));
                msg = msg.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, infoCmd));
                player.print(msg);
            }
        }
        player.print(Caption.of("fawe.worldedit.tool.tool.inspect.info.footer", count));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    return true;
}
Also used : TextComponent(com.sk89q.worldedit.util.formatting.text.TextComponent) IOException(java.io.IOException) BlockVector3(com.sk89q.worldedit.math.BlockVector3) World(com.sk89q.worldedit.world.World) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory) BlockState(com.sk89q.worldedit.world.block.BlockState) TranslatableComponent(com.sk89q.worldedit.util.formatting.text.TranslatableComponent) MutableFullBlockChange(com.fastasyncworldedit.core.history.change.MutableFullBlockChange) UUID(java.util.UUID) RollbackDatabase(com.fastasyncworldedit.core.database.RollbackDatabase)

Example 5 with RollbackOptimizedHistory

use of com.fastasyncworldedit.core.history.RollbackOptimizedHistory in project FastAsyncWorldEdit by IntellectualSites.

the class RollbackDatabase method create.

private Supplier<RollbackOptimizedHistory> create(ResultSet result) throws SQLException {
    byte[] uuidBytes = result.getBytes("player");
    int index = result.getInt("id");
    int x1 = result.getInt("x1");
    int x2 = result.getInt("x2");
    int y1 = result.getByte("y1") + 128;
    int y2 = result.getByte("y2") + 128;
    int z1 = result.getInt("z1");
    int z2 = result.getInt("z2");
    CuboidRegion region = new CuboidRegion(BlockVector3.at(x1, y1, z1), BlockVector3.at(x2, y2, z2));
    long time = result.getInt("time") * 1000L;
    long size = result.getInt("size");
    String command = result.getString("command");
    ByteBuffer bb = ByteBuffer.wrap(uuidBytes);
    long high = bb.getLong();
    long low = bb.getLong();
    UUID uuid = new UUID(high, low);
    return () -> new RollbackOptimizedHistory(world, uuid, index, time, size, region, command);
}
Also used : CuboidRegion(com.sk89q.worldedit.regions.CuboidRegion) UUID(java.util.UUID) ByteBuffer(java.nio.ByteBuffer) RollbackOptimizedHistory(com.fastasyncworldedit.core.history.RollbackOptimizedHistory)

Aggregations

RollbackOptimizedHistory (com.fastasyncworldedit.core.history.RollbackOptimizedHistory)9 UUID (java.util.UUID)6 CommandPermissions (com.sk89q.worldedit.command.util.CommandPermissions)4 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)4 World (com.sk89q.worldedit.world.World)4 Command (org.enginehub.piston.annotation.Command)3 RollbackDatabase (com.fastasyncworldedit.core.database.RollbackDatabase)2 SimpleChangeSetSummary (com.fastasyncworldedit.core.history.changeset.SimpleChangeSetSummary)2 YieldIterable (com.fastasyncworldedit.core.util.collection.YieldIterable)2 Confirm (com.sk89q.worldedit.command.util.annotation.Confirm)2 CuboidRegion (com.sk89q.worldedit.regions.CuboidRegion)2 Location (com.sk89q.worldedit.util.Location)2 TextComponent (com.sk89q.worldedit.util.formatting.text.TextComponent)2 TranslatableComponent (com.sk89q.worldedit.util.formatting.text.TranslatableComponent)2 File (java.io.File)2 IOException (java.io.IOException)2 ByteBuffer (java.nio.ByteBuffer)2 Fawe (com.fastasyncworldedit.core.Fawe)1 Settings (com.fastasyncworldedit.core.configuration.Settings)1 DisallowedBlocksExtent (com.fastasyncworldedit.core.extent.DisallowedBlocksExtent)1