diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java index d53995a3..f33f6af3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java @@ -20,9 +20,7 @@ package de.steamwar.bausystem.features.slaves.laufbau; import com.sk89q.worldedit.EditSession; -import de.steamwar.bausystem.features.slaves.laufbau.states.FilteringTracesState; import de.steamwar.bausystem.features.slaves.laufbau.states.LaufbauState; -import de.steamwar.bausystem.features.slaves.laufbau.states.CreatingLaufState; import de.steamwar.bausystem.features.slaves.laufbau.states.ProcessingTracesState; import de.steamwar.bausystem.utils.WorldEditUtils; import lombok.Getter; @@ -40,9 +38,7 @@ public class Laufbau { private Location pos1; private Location pos2; - private FilteringTracesState filteringTracesState = null; - private ProcessingTracesState processingTracesState = null; - private CreatingLaufState creatingLaufState = null; + private LaufbauState active; private List elements; @@ -62,8 +58,6 @@ public class Laufbau { int zFactor = (int) (Math.abs(selectionSize.getZ()) / 9.875); factor = Math.max(Math.max(xFactor, Math.max(yFactor, zFactor)), 8); - filteringTracesState = new FilteringTracesState(world, this::inRegion); - editSession = WorldEditUtils.getEditSession(player); elements = BlockBoundingBox.elements.stream().filter(blockBoundingBox -> { @@ -86,49 +80,32 @@ public class Laufbau { return -Double.compare(o1.blockData.getMaterial().getBlastResistance(), o2.blockData.getMaterial().getBlastResistance()); }); } - } - private LaufbauState getActive() { - if (creatingLaufState != null) { - return creatingLaufState; - } - if (processingTracesState != null) { - return processingTracesState; - } - return filteringTracesState; + active = new ProcessingTracesState(world, this::inRegion, editSession, elements, factor); } private void createNextState() { - if (creatingLaufState != null) { - return; - } - if (processingTracesState != null) { - creatingLaufState = new CreatingLaufState(processingTracesState.getBlocks(), processingTracesState.getCuboidIntersectionCache(), world, editSession, elements, factor); - return; - } - processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions(), this::inRegion, factor); + if (active == null) return; + active = active.getNextState(); } public String actionBarMessage(Player p) { - return getActive().actionBarMessage(p); + return active.actionBarMessage(p); } public boolean hasNext() { - return getActive().hasNext(); + if (active == null) return false; + return active.hasNext(); } public void next() { - LaufbauState state = getActive(); + LaufbauState state = active; state.next(); if (!state.hasNext()) { createNextState(); } } - private boolean inRegion(Location location, int expansion) { - return inRegion(location.toVector(), expansion); - } - private boolean inRegion(Vector location, int expansion) { if (location.getBlockX() >= pos1.getBlockX() - expansion) { if (location.getBlockY() >= pos1.getBlockY() - expansion) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java index 9522518d..e4ed312b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingLaufState.java @@ -196,4 +196,9 @@ public class CreatingLaufState implements LaufbauState { } } } + + @Override + public LaufbauState getNextState() { + return null; + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java deleted file mode 100644 index 3e91a85b..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.slaves.laufbau.states; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.tracer.TNTRecord; -import de.steamwar.bausystem.features.tracer.Trace; -import de.steamwar.bausystem.features.tracer.TraceManager; -import de.steamwar.bausystem.utils.FlatteningWrapper; -import de.steamwar.linkage.LinkedInstance; -import lombok.Getter; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiPredicate; - -public class FilteringTracesState implements LaufbauState { - - @LinkedInstance - TraceManager traceManager; - private long start = System.currentTimeMillis(); - - private World world; - private BiPredicate inRegionCheck; - - private final int totalRecord; - - List traces; - private List> tntHistories = new ArrayList<>(); - - @Getter - private List tntPositions = new ArrayList<>(); - - public FilteringTracesState(World world, BiPredicate inRegionCheck) { - List traces = new ArrayList<>(traceManager.getAll()); - totalRecord = traces.size(); - - this.world = world; - this.inRegionCheck = inRegionCheck; - } - - @Override - public String actionBarMessage(Player p) { - return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_FILTERING_TRACES", p), totalRecord - traces.size(), totalRecord, eta(p, start, totalRecord - traces.size(), totalRecord)); - } - - @Override - public boolean hasNext() { - return !traces.isEmpty() || !tntHistories.isEmpty(); - } - - @Override - public void next() { - if (tntHistories.isEmpty()) { - Trace trace = traces.remove(0); - tntHistories.addAll(trace.getHistories()); - } - if (tntHistories.isEmpty()) { - return; - } - - List tntRecords = tntHistories.remove(0); - tntRecords.forEach(tntRecord -> { - if (FlatteningWrapper.impl.inWater(world, tntRecord.getLocation().toVector())) { - return; - } - if (inRegionCheck.test(tntRecord.getLocation(), 1)) { - tntPositions.add(tntRecord); - } - if (tntRecord.getPrevious().isPresent() && inRegionCheck.test(tntRecord.getPrevious().get().getLocation(), 1)) { - tntPositions.add(tntRecord); - } - }); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java index 6ece3e22..6843db9e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java @@ -45,4 +45,6 @@ public interface LaufbauState { } return LocalTime.ofNanoOfDay(eta).format(DateTimeFormatter.ofPattern(BauSystem.MESSAGE.parse("TIME", p))); } + + LaufbauState getNextState(); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java index b2a21dd9..e8693105 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java @@ -1,117 +1,128 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * Copyright (C) 2024 SteamWar.de-Serverteam * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.slaves.laufbau.states; +import com.sk89q.worldedit.EditSession; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox; import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; import de.steamwar.bausystem.features.tracer.TNTRecord; +import de.steamwar.bausystem.features.tracer.TraceRecorder; import de.steamwar.bausystem.region.Point; -import lombok.Getter; +import de.steamwar.bausystem.utils.FlatteningWrapper; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.*; import java.util.function.BiPredicate; +import java.util.stream.Collectors; public class ProcessingTracesState implements LaufbauState { - private long start = System.currentTimeMillis(); + private final long start = System.currentTimeMillis(); + private final World world; + private final BiPredicate inRegionCheck; + private final EditSession editSession; + private final List elements; + private final int factor; - private int totalCuboids; - private List tntPositionList; - private BiPredicate inRegionCheck; - private int factor; + private final List tntRecords; + private final int totalTntRecords; - private List toExpand = new ArrayList<>(); + private final Set affectedBlocks = new HashSet<>(); + private final Map> cuboidsPerChunk = new HashMap<>(); - private int cuboidsDone = 0; - - @Getter - private Set blocks = new HashSet<>(); - - @Getter - private Map> cuboidIntersectionCache = new HashMap<>(); - - public ProcessingTracesState(List tntPositionList, BiPredicate inRegionCheck, int factor) { - this.tntPositionList = tntPositionList; - this.totalCuboids = tntPositionList.stream().mapToInt(tntPosition -> tntPosition.getPrevious() == null ? 1 : 3).sum(); + public ProcessingTracesState(World world, BiPredicate inRegionCheck, EditSession editSession, List elements, int factor) { + this.world = world; this.inRegionCheck = inRegionCheck; + this.editSession = editSession; + this.elements = elements; this.factor = factor; + + // TODO: Optimize only retrieving traces inside of the affected regions! + tntRecords = TraceRecorder.instance.manager.getAll() + .stream() + .flatMap(trace -> trace.getHistories().stream()) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + totalTntRecords = tntRecords.size(); } @Override public String actionBarMessage(Player p) { - return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), cuboidsDone, totalCuboids, eta(p, start, cuboidsDone, totalCuboids)); + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalTntRecords - tntRecords.size(), totalTntRecords, eta(p, start, totalTntRecords - tntRecords.size(), totalTntRecords)); + } + + private boolean inRegion(Vector location, int expansion) { + return inRegionCheck.test(location, expansion); } @Override public boolean hasNext() { - return !tntPositionList.isEmpty() || !toExpand.isEmpty(); + return !tntRecords.isEmpty(); } @Override public void next() { - if (!toExpand.isEmpty()) { - Cuboid cuboid = toExpand.remove(0); - expandCuboid(cuboid); - } else { - TNTRecord tntPosition = tntPositionList.remove(0); - createCuboid(tntPosition); - } - } + TNTRecord current = tntRecords.remove(0); + if (FlatteningWrapper.impl.inWater(world, current.getLocation().toVector())) return; + if (!(inRegion(current.getLocation().toVector(), 1) || (current.getPrevious().isPresent() && inRegion(current.getPrevious().get().getLocation().toVector(), 1)))) + return; - private void createCuboid(TNTRecord tntPosition) { - Location location = tntPosition.getLocation(); - Optional previous = tntPosition.getPrevious(); - - if (!previous.isPresent()) { - toExpand.add(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); - } else { - Location previousLocation = tntPosition.getPrevious().get().getLocation(); + Location location = current.getLocation(); + if (current.getPrevious().isPresent()) { + Vector velocity = current.getPrevious().get().getVelocity(); + Location previousLocation = current.getPrevious().get().getLocation(); Location movement = location.clone().subtract(previousLocation); - toExpand.add(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); - if (tntPosition.getVelocity().getX() >= tntPosition.getVelocity().getZ()) { - toExpand.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); - toExpand.add(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + calculateCuboid(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); + if (velocity.getX() >= velocity.getZ()) { + calculateCuboid(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + calculateCuboid(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); } else { - toExpand.add(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); - toExpand.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + calculateCuboid(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + calculateCuboid(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); } + } else { + calculateCuboid(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); } } - private void expandCuboid(Cuboid cuboid) { - cuboidsDone++; + private void calculateCuboid(Cuboid cuboid) { for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) { for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) { for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) { Vector location = new Vector(x, y, z); - if (inRegionCheck.test(location, 0)) { - Point point = new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - blocks.add(point); - cuboidIntersectionCache.computeIfAbsent(point.divide(factor), __ -> new HashSet<>()) + if (inRegion(location, 0)) { + affectedBlocks.add(new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + cuboidsPerChunk.computeIfAbsent(new Point(location.getBlockX() / factor, location.getBlockY() / factor, location.getBlockZ() / factor), __ -> new HashSet<>()) .add(cuboid); } } } } } + + @Override + public LaufbauState getNextState() { + return new CreatingLaufState(affectedBlocks, cuboidsPerChunk, world, editSession, elements, factor); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java index a973da95..68049eb7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java @@ -106,8 +106,8 @@ public class Trace { // TODO: Add UUID for file saving and so on! for (Player player : serverMap.keySet()) { REntityServer server = serverMap.get(player); - BundleFilter bundleFilter = bundleFilterMap.get(player); - ViewFlagHolder viewFlagHolder = viewFlagMap.get(player); + BundleFilter bundleFilter = bundleFilterMap.getOrDefault(player, BundleFilter.DEFAULT); + ViewFlagHolder viewFlagHolder = viewFlagMap.computeIfAbsent(player, ignored -> new ViewFlagHolder()); render(server, records, viewFlagHolder, bundleFilter); }