Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-24 18:10:08 +01:00
wip chunk based bitset
Dieser Commit ist enthalten in:
Ursprung
d6a8e9738a
Commit
14d5275e05
@ -17,6 +17,7 @@ import com.sk89q.worldedit.function.operation.Operations;
|
|||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Countable;
|
import com.sk89q.worldedit.util.Countable;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
@ -103,6 +104,10 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
|
|||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getChanges() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countBlocks(final Region region, final Mask searchMask) {
|
public int countBlocks(final Region region, final Mask searchMask) {
|
||||||
return
|
return
|
||||||
@ -116,19 +121,25 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
|
|||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||||
apply(region, block);
|
apply(region, block);
|
||||||
return 0;
|
return getChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||||
apply(region, pattern);
|
apply(region, pattern);
|
||||||
return 0;
|
return getChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
|
||||||
|
TODO
|
||||||
|
return getChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||||
apply(region, mask.toFilter(pattern));
|
apply(region, mask.toFilter(pattern));
|
||||||
return 0;
|
return getChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -686,39 +686,4 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tracked EditSession(s) for this player<br>
|
|
||||||
* - Queued or autoqueued EditSessions are considered tracked
|
|
||||||
*
|
|
||||||
* @param requiredStage
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Map<EditSession, SetQueue.QueueStage> getTrackedSessions(SetQueue.QueueStage requiredStage) {
|
|
||||||
Map<EditSession, SetQueue.QueueStage> map = new ConcurrentHashMap<>(8, 0.9f, 1);
|
|
||||||
if (requiredStage == null || requiredStage == SetQueue.QueueStage.ACTIVE) {
|
|
||||||
for (FaweQueue queue : SetQueue.IMP.getActiveQueues()) {
|
|
||||||
Collection<EditSession> sessions = queue.getEditSessions();
|
|
||||||
for (EditSession session : sessions) {
|
|
||||||
FawePlayer currentPlayer = session.getPlayer();
|
|
||||||
if (currentPlayer == this) {
|
|
||||||
map.put(session, SetQueue.QueueStage.ACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (requiredStage == null || requiredStage == SetQueue.QueueStage.INACTIVE) {
|
|
||||||
for (FaweQueue queue : SetQueue.IMP.getInactiveQueues()) {
|
|
||||||
Collection<EditSession> sessions = queue.getEditSessions();
|
|
||||||
for (EditSession session : sessions) {
|
|
||||||
FawePlayer currentPlayer = session.getPlayer();
|
|
||||||
if (currentPlayer == this) {
|
|
||||||
map.put(session, SetQueue.QueueStage.INACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.boydti.fawe.object.collection;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ChunkBVecSet implements Set<BlockVector3> {
|
||||||
|
private final int offsetX, offsetZ;
|
||||||
|
private final ChunkBitSet set;
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
public ChunkBVecSet(int size) {
|
||||||
|
this(Integer.MAX_VALUE, Integer.MAX_VALUE, new ChunkBitSet(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkBVecSet(ChunkBitSet set, int offsetX, int offsetZ) {
|
||||||
|
this.offsetX = offsetX;
|
||||||
|
this.offsetZ = offsetZ;
|
||||||
|
this.set = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkBitSet getBitSet() {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
try {
|
||||||
|
return contain((BlockVector3) o);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contain(BlockVector3 obj) {
|
||||||
|
return contain(obj.getX(), obj.getY(), obj.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contain(int x, int y, int z) {
|
||||||
|
return set.get(x - offsetX, y, z - offsetZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<BlockVector3> iterator() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
return new Object[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public <T> T[] toArray(@NotNull T[] a) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(BlockVector3 blockVector3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(@NotNull Collection<?> c) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(@NotNull Collection<? extends BlockVector3> c) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,10 @@ public class ChunkBitSet {
|
|||||||
return rows[x >> 4].get(this.rows, x, y, z);
|
return rows[x >> 4].get(this.rows, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(int x, int y, int z) {
|
||||||
|
rows[x >> 4].add(this.rows, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
public void set(int x, int y, int z) {
|
public void set(int x, int y, int z) {
|
||||||
rows[x >> 4].set(this.rows, x, y, z);
|
rows[x >> 4].set(this.rows, x, y, z);
|
||||||
}
|
}
|
||||||
@ -37,6 +41,10 @@ public class ChunkBitSet {
|
|||||||
private interface IRow {
|
private interface IRow {
|
||||||
default boolean get(IRow[] rows, int x, int y, int z) { return false; }
|
default boolean get(IRow[] rows, int x, int y, int z) { return false; }
|
||||||
void set(IRow[] rows, int x, int y, int z);
|
void set(IRow[] rows, int x, int y, int z);
|
||||||
|
default boolean add(IRow[] rows, int x, int y, int z) {
|
||||||
|
set(rows, x, y, z);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default void clear(IRow[] rows, int x, int y, int z) { return; }
|
default void clear(IRow[] rows, int x, int y, int z) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +93,11 @@ public class ChunkBitSet {
|
|||||||
this.rows[z >> 4].set(this.rows, x, y, z);
|
this.rows[z >> 4].set(this.rows, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||||
|
return this.rows[z >> 4].add(this.rows, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear(IRow[] parent, int x, int y, int z) {
|
public void clear(IRow[] parent, int x, int y, int z) {
|
||||||
this.rows[z >> 4].clear(this.rows, x, y, z);
|
this.rows[z >> 4].clear(this.rows, x, y, z);
|
||||||
@ -109,6 +122,11 @@ public class ChunkBitSet {
|
|||||||
this.rows[y >> 4].set(this.rows, x, y, z);
|
this.rows[y >> 4].set(this.rows, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||||
|
return this.rows[y >> 4].add(this.rows, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear(IRow[] parent, int x, int y, int z) {
|
public void clear(IRow[] parent, int x, int y, int z) {
|
||||||
this.rows[y >> 4].set(this.rows, x, y, z);
|
this.rows[y >> 4].set(this.rows, x, y, z);
|
||||||
@ -134,6 +152,19 @@ public class ChunkBitSet {
|
|||||||
bits[i >> 6] |= (1L << (i & 0x3F));
|
bits[i >> 6] |= (1L << (i & 0x3F));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||||
|
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
|
||||||
|
int offset = i >> 6;
|
||||||
|
long value = bits[offset];
|
||||||
|
long mask = (1L << (i & 0x3F));
|
||||||
|
if ((value & mask) != 0) {
|
||||||
|
bits[offset] = value | mask;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear(IRow[] parent, int x, int y, int z) {
|
public void clear(IRow[] parent, int x, int y, int z) {
|
||||||
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
|
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
|
||||||
|
@ -24,8 +24,6 @@ import com.boydti.fawe.config.BBC;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
|
||||||
import com.boydti.fawe.object.HasFaweQueue;
|
|
||||||
import com.boydti.fawe.object.HistoryExtent;
|
import com.boydti.fawe.object.HistoryExtent;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
@ -45,7 +43,6 @@ import com.boydti.fawe.util.EditSessionBuilder;
|
|||||||
import com.boydti.fawe.util.ExtentTraverser;
|
import com.boydti.fawe.util.ExtentTraverser;
|
||||||
import com.boydti.fawe.util.MaskTraverser;
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.SetQueue;
|
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -944,7 +941,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
||||||
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern), this);
|
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
|
||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
changes += visitor.getAffected();
|
changes += visitor.getAffected();
|
||||||
return changes;
|
return changes;
|
||||||
|
@ -581,4 +581,10 @@ public interface Extent extends InputExtent, OutputExtent {
|
|||||||
return setBlocks(centerRegion, pattern);
|
return setBlocks(centerRegion, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
||||||
|
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
|
||||||
|
Operations.completeBlindly(visitor);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,6 @@
|
|||||||
package com.sk89q.worldedit.function.visitor;
|
package com.sk89q.worldedit.function.visitor;
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
|
||||||
import com.boydti.fawe.example.MappedFaweQueue;
|
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
|
||||||
import com.boydti.fawe.object.HasFaweQueue;
|
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.function.RegionFunction;
|
import com.sk89q.worldedit.function.RegionFunction;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
@ -34,7 +27,6 @@ import com.sk89q.worldedit.function.operation.RunContext;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +38,6 @@ public class RegionVisitor implements Operation {
|
|||||||
public final RegionFunction function;
|
public final RegionFunction function;
|
||||||
public int affected = 0;
|
public int affected = 0;
|
||||||
public final Iterable<? extends BlockVector3> iterable;
|
public final Iterable<? extends BlockVector3> iterable;
|
||||||
private final MappedFaweQueue queue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated in favor of the other constructors which will preload chunks during iteration
|
* Deprecated in favor of the other constructors which will preload chunks during iteration
|
||||||
@ -56,22 +47,14 @@ public class RegionVisitor implements Operation {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public RegionVisitor(Region region, RegionFunction function) {
|
public RegionVisitor(Region region, RegionFunction function) {
|
||||||
this(region, function, (FaweQueue) null);
|
this((Iterable<BlockVector3>) region, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionVisitor(Region region, RegionFunction function, EditSession editSession) {
|
@Deprecated
|
||||||
this(region, function, editSession != null ? editSession.getQueue() : null);
|
public RegionVisitor(Iterable<BlockVector3> iterable, RegionFunction function) {
|
||||||
}
|
|
||||||
|
|
||||||
public RegionVisitor(Region region, RegionFunction function, FaweQueue queue) {
|
|
||||||
this((Iterable<BlockVector3>) region, function, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionVisitor(Iterable<? extends BlockVector3> iterable, RegionFunction function, HasFaweQueue hasQueue) {
|
|
||||||
this.region = iterable instanceof Region ? (Region) iterable : null;
|
this.region = iterable instanceof Region ? (Region) iterable : null;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.iterable = iterable;
|
this.iterable = iterable;
|
||||||
this.queue = hasQueue != null && hasQueue.getQueue() instanceof MappedFaweQueue ? (MappedFaweQueue) hasQueue.getQueue() : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,100 +68,8 @@ public class RegionVisitor implements Operation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Operation resume(RunContext run) throws WorldEditException {
|
public Operation resume(RunContext run) throws WorldEditException {
|
||||||
if (queue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 1) {
|
for (BlockVector3 pt : iterable) {
|
||||||
/*
|
apply(pt);
|
||||||
* The following is done to reduce iteration cost
|
|
||||||
* - Preload chunks just in time
|
|
||||||
* - Only check every 16th block for potential chunk loads
|
|
||||||
* - Stop iteration on exception instead of hasNext
|
|
||||||
* - Do not calculate the stacktrace as it is expensive
|
|
||||||
*/
|
|
||||||
Iterator<? extends BlockVector3> trailIter = iterable.iterator();
|
|
||||||
Iterator<? extends BlockVector3> leadIter = iterable.iterator();
|
|
||||||
int lastTrailChunkX = Integer.MIN_VALUE;
|
|
||||||
int lastTrailChunkZ = Integer.MIN_VALUE;
|
|
||||||
int lastLeadChunkX = Integer.MIN_VALUE;
|
|
||||||
int lastLeadChunkZ = Integer.MIN_VALUE;
|
|
||||||
int loadingTarget = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
|
|
||||||
try {
|
|
||||||
for (; ; ) {
|
|
||||||
BlockVector3 pt = trailIter.next();
|
|
||||||
apply(pt);
|
|
||||||
int cx = pt.getBlockX() >> 4;
|
|
||||||
int cz = pt.getBlockZ() >> 4;
|
|
||||||
if (cx != lastTrailChunkX || cz != lastTrailChunkZ) {
|
|
||||||
lastTrailChunkX = cx;
|
|
||||||
lastTrailChunkZ = cz;
|
|
||||||
int amount;
|
|
||||||
if (lastLeadChunkX == Integer.MIN_VALUE) {
|
|
||||||
lastLeadChunkX = cx;
|
|
||||||
lastLeadChunkZ = cz;
|
|
||||||
amount = loadingTarget;
|
|
||||||
} else {
|
|
||||||
amount = 1;
|
|
||||||
}
|
|
||||||
for (int count = 0; count < amount; ) {
|
|
||||||
BlockVector3 v = leadIter.next();
|
|
||||||
int vcx = v.getBlockX() >> 4;
|
|
||||||
int vcz = v.getBlockZ() >> 4;
|
|
||||||
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
|
|
||||||
lastLeadChunkX = vcx;
|
|
||||||
lastLeadChunkZ = vcz;
|
|
||||||
queue.queueChunkLoad(vcx, vcz);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
// Skip the next 15 blocks
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
leadIter.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
}
|
|
||||||
} catch (FaweException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (Throwable ignore) {
|
|
||||||
ignore.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
while (true) {
|
|
||||||
apply(trailIter.next());
|
|
||||||
apply(trailIter.next());
|
|
||||||
}
|
|
||||||
} catch (FaweException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (Throwable ignore) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (BlockVector3 pt : iterable) {
|
|
||||||
apply(pt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren