Trace Refactor #233
@ -20,9 +20,7 @@
|
|||||||
package de.steamwar.bausystem.features.slaves.laufbau;
|
package de.steamwar.bausystem.features.slaves.laufbau;
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
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.LaufbauState;
|
||||||
import de.steamwar.bausystem.features.slaves.laufbau.states.CreatingLaufState;
|
|
||||||
import de.steamwar.bausystem.features.slaves.laufbau.states.ProcessingTracesState;
|
import de.steamwar.bausystem.features.slaves.laufbau.states.ProcessingTracesState;
|
||||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -40,9 +38,7 @@ public class Laufbau {
|
|||||||
private Location pos1;
|
private Location pos1;
|
||||||
private Location pos2;
|
private Location pos2;
|
||||||
|
|
||||||
private FilteringTracesState filteringTracesState = null;
|
private LaufbauState active;
|
||||||
private ProcessingTracesState processingTracesState = null;
|
|
||||||
private CreatingLaufState creatingLaufState = null;
|
|
||||||
|
|
||||||
private List<BlockBoundingBox> elements;
|
private List<BlockBoundingBox> elements;
|
||||||
|
|
||||||
@ -62,8 +58,6 @@ public class Laufbau {
|
|||||||
int zFactor = (int) (Math.abs(selectionSize.getZ()) / 9.875);
|
int zFactor = (int) (Math.abs(selectionSize.getZ()) / 9.875);
|
||||||
factor = Math.max(Math.max(xFactor, Math.max(yFactor, zFactor)), 8);
|
factor = Math.max(Math.max(xFactor, Math.max(yFactor, zFactor)), 8);
|
||||||
|
|
||||||
filteringTracesState = new FilteringTracesState(world, this::inRegion);
|
|
||||||
|
|
||||||
editSession = WorldEditUtils.getEditSession(player);
|
editSession = WorldEditUtils.getEditSession(player);
|
||||||
|
|
||||||
elements = BlockBoundingBox.elements.stream().filter(blockBoundingBox -> {
|
elements = BlockBoundingBox.elements.stream().filter(blockBoundingBox -> {
|
||||||
@ -86,49 +80,32 @@ public class Laufbau {
|
|||||||
return -Double.compare(o1.blockData.getMaterial().getBlastResistance(), o2.blockData.getMaterial().getBlastResistance());
|
return -Double.compare(o1.blockData.getMaterial().getBlastResistance(), o2.blockData.getMaterial().getBlastResistance());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private LaufbauState getActive() {
|
active = new ProcessingTracesState(world, this::inRegion, editSession, elements, factor);
|
||||||
if (creatingLaufState != null) {
|
|
||||||
return creatingLaufState;
|
|
||||||
}
|
|
||||||
if (processingTracesState != null) {
|
|
||||||
return processingTracesState;
|
|
||||||
}
|
|
||||||
return filteringTracesState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNextState() {
|
private void createNextState() {
|
||||||
if (creatingLaufState != null) {
|
if (active == null) return;
|
||||||
return;
|
active = active.getNextState();
|
||||||
}
|
|
||||||
if (processingTracesState != null) {
|
|
||||||
creatingLaufState = new CreatingLaufState(processingTracesState.getBlocks(), processingTracesState.getCuboidIntersectionCache(), world, editSession, elements, factor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions(), this::inRegion, factor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String actionBarMessage(Player p) {
|
public String actionBarMessage(Player p) {
|
||||||
return getActive().actionBarMessage(p);
|
return active.actionBarMessage(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return getActive().hasNext();
|
if (active == null) return false;
|
||||||
|
return active.hasNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void next() {
|
public void next() {
|
||||||
LaufbauState state = getActive();
|
LaufbauState state = active;
|
||||||
state.next();
|
state.next();
|
||||||
if (!state.hasNext()) {
|
if (!state.hasNext()) {
|
||||||
createNextState();
|
createNextState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inRegion(Location location, int expansion) {
|
|
||||||
return inRegion(location.toVector(), expansion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean inRegion(Vector location, int expansion) {
|
private boolean inRegion(Vector location, int expansion) {
|
||||||
if (location.getBlockX() >= pos1.getBlockX() - expansion) {
|
if (location.getBlockX() >= pos1.getBlockX() - expansion) {
|
||||||
if (location.getBlockY() >= pos1.getBlockY() - expansion) {
|
if (location.getBlockY() >= pos1.getBlockY() - expansion) {
|
||||||
|
@ -196,4 +196,9 @@ public class CreatingLaufState implements LaufbauState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LaufbauState getNextState() {
|
||||||
|
return 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<Location, Integer> inRegionCheck;
|
|
||||||
|
|
||||||
private final int totalRecord;
|
|
||||||
|
|
||||||
List<Trace> traces;
|
|
||||||
private List<List<TNTRecord>> tntHistories = new ArrayList<>();
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private List<TNTRecord> tntPositions = new ArrayList<>();
|
|
||||||
|
|
||||||
public FilteringTracesState(World world, BiPredicate<Location, Integer> inRegionCheck) {
|
|
||||||
List<Trace> 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<TNTRecord> 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -45,4 +45,6 @@ public interface LaufbauState {
|
|||||||
}
|
}
|
||||||
return LocalTime.ofNanoOfDay(eta).format(DateTimeFormatter.ofPattern(BauSystem.MESSAGE.parse("TIME", p)));
|
return LocalTime.ofNanoOfDay(eta).format(DateTimeFormatter.ofPattern(BauSystem.MESSAGE.parse("TIME", p)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaufbauState getNextState();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -19,99 +19,110 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.slaves.laufbau.states;
|
package de.steamwar.bausystem.features.slaves.laufbau.states;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
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.slaves.laufbau.Cuboid;
|
||||||
import de.steamwar.bausystem.features.tracer.TNTRecord;
|
import de.steamwar.bausystem.features.tracer.TNTRecord;
|
||||||
|
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import lombok.Getter;
|
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ProcessingTracesState implements LaufbauState {
|
public class ProcessingTracesState implements LaufbauState {
|
||||||
|
|
||||||
private long start = System.currentTimeMillis();
|
private final long start = System.currentTimeMillis();
|
||||||
|
private final World world;
|
||||||
|
private final BiPredicate<Vector, Integer> inRegionCheck;
|
||||||
|
private final EditSession editSession;
|
||||||
|
private final List<BlockBoundingBox> elements;
|
||||||
|
private final int factor;
|
||||||
|
|
||||||
private int totalCuboids;
|
private final List<TNTRecord> tntRecords;
|
||||||
private List<TNTRecord> tntPositionList;
|
private final int totalTntRecords;
|
||||||
private BiPredicate<Vector, Integer> inRegionCheck;
|
|
||||||
private int factor;
|
|
||||||
|
|
||||||
private List<Cuboid> toExpand = new ArrayList<>();
|
private final Set<Point> affectedBlocks = new HashSet<>();
|
||||||
|
private final Map<Point, Set<Cuboid>> cuboidsPerChunk = new HashMap<>();
|
||||||
|
|
||||||
private int cuboidsDone = 0;
|
public ProcessingTracesState(World world, BiPredicate<Vector, Integer> inRegionCheck, EditSession editSession, List<BlockBoundingBox> elements, int factor) {
|
||||||
|
this.world = world;
|
||||||
@Getter
|
|
||||||
private Set<Point> blocks = new HashSet<>();
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private Map<Point, Set<Cuboid>> cuboidIntersectionCache = new HashMap<>();
|
|
||||||
|
|
||||||
public ProcessingTracesState(List<TNTRecord> tntPositionList, BiPredicate<Vector, Integer> inRegionCheck, int factor) {
|
|
||||||
this.tntPositionList = tntPositionList;
|
|
||||||
this.totalCuboids = tntPositionList.stream().mapToInt(tntPosition -> tntPosition.getPrevious() == null ? 1 : 3).sum();
|
|
||||||
this.inRegionCheck = inRegionCheck;
|
this.inRegionCheck = inRegionCheck;
|
||||||
|
this.editSession = editSession;
|
||||||
|
this.elements = elements;
|
||||||
this.factor = factor;
|
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
|
@Override
|
||||||
public String actionBarMessage(Player p) {
|
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
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return !tntPositionList.isEmpty() || !toExpand.isEmpty();
|
return !tntRecords.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void next() {
|
public void next() {
|
||||||
if (!toExpand.isEmpty()) {
|
TNTRecord current = tntRecords.remove(0);
|
||||||
Cuboid cuboid = toExpand.remove(0);
|
if (FlatteningWrapper.impl.inWater(world, current.getLocation().toVector())) return;
|
||||||
expandCuboid(cuboid);
|
if (!(inRegion(current.getLocation().toVector(), 1) || (current.getPrevious().isPresent() && inRegion(current.getPrevious().get().getLocation().toVector(), 1))))
|
||||||
} else {
|
return;
|
||||||
TNTRecord tntPosition = tntPositionList.remove(0);
|
|
||||||
createCuboid(tntPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createCuboid(TNTRecord tntPosition) {
|
Location location = current.getLocation();
|
||||||
Location location = tntPosition.getLocation();
|
if (current.getPrevious().isPresent()) {
|
||||||
Optional<TNTRecord> previous = tntPosition.getPrevious();
|
Vector velocity = current.getPrevious().get().getVelocity();
|
||||||
|
Location previousLocation = current.getPrevious().get().getLocation();
|
||||||
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 movement = location.clone().subtract(previousLocation);
|
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));
|
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 (tntPosition.getVelocity().getX() >= tntPosition.getVelocity().getZ()) {
|
if (velocity.getX() >= velocity.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));
|
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));
|
||||||
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(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 {
|
} 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));
|
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));
|
||||||
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(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) {
|
private void calculateCuboid(Cuboid cuboid) {
|
||||||
cuboidsDone++;
|
|
||||||
for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) {
|
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 y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) {
|
||||||
for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) {
|
for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) {
|
||||||
Vector location = new Vector(x, y, z);
|
Vector location = new Vector(x, y, z);
|
||||||
if (inRegionCheck.test(location, 0)) {
|
if (inRegion(location, 0)) {
|
||||||
Point point = new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
affectedBlocks.add(new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
|
||||||
blocks.add(point);
|
cuboidsPerChunk.computeIfAbsent(new Point(location.getBlockX() / factor, location.getBlockY() / factor, location.getBlockZ() / factor), __ -> new HashSet<>())
|
||||||
cuboidIntersectionCache.computeIfAbsent(point.divide(factor), __ -> new HashSet<>())
|
|
||||||
.add(cuboid);
|
.add(cuboid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LaufbauState getNextState() {
|
||||||
|
return new CreatingLaufState(affectedBlocks, cuboidsPerChunk, world, editSession, elements, factor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,8 @@ public class Trace { // TODO: Add UUID for file saving and so on!
|
|||||||
|
|
||||||
for (Player player : serverMap.keySet()) {
|
for (Player player : serverMap.keySet()) {
|
||||||
REntityServer server = serverMap.get(player);
|
REntityServer server = serverMap.get(player);
|
||||||
BundleFilter bundleFilter = bundleFilterMap.get(player);
|
BundleFilter bundleFilter = bundleFilterMap.getOrDefault(player, BundleFilter.DEFAULT);
|
||||||
ViewFlagHolder viewFlagHolder = viewFlagMap.get(player);
|
ViewFlagHolder viewFlagHolder = viewFlagMap.computeIfAbsent(player, ignored -> new ViewFlagHolder());
|
||||||
|
|
||||||
render(server, records, viewFlagHolder, bundleFilter);
|
render(server, records, viewFlagHolder, bundleFilter);
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren