mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 08:08:34 +00:00
Improve exceptions (#1256)
- Kick more exceptions further up the pipeline to be more likely to be shown to player - Try to avoid lots of console spamming when it's the same error multiple times - Allow parsing of FaweExceptions during commands to better give information to players
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
package com.fastasyncworldedit.core.extent.processor;
|
||||
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.queue.IChunk;
|
||||
@ -9,6 +12,8 @@ import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.util.StringMan;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
@ -26,9 +31,16 @@ import java.util.function.Supplier;
|
||||
|
||||
public class MultiBatchProcessor implements IBatchProcessor {
|
||||
|
||||
private IBatchProcessor[] processors;
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final LoadingCache<Class<?>, Map<Long, Filter>> classToThreadIdToFilter =
|
||||
FaweCache.IMP.createCache((Supplier<Map<Long, Filter>>) ConcurrentHashMap::new);
|
||||
// Array for lazy avoidance of concurrent modification exceptions and needless overcomplication of code (synchronisation is
|
||||
// not very important)
|
||||
private boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
||||
private IBatchProcessor[] processors;
|
||||
private int lastException = Integer.MIN_VALUE;
|
||||
private int exceptionCount = 0;
|
||||
|
||||
public MultiBatchProcessor(IBatchProcessor... processors) {
|
||||
this.processors = processors;
|
||||
@ -72,41 +84,36 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
||||
@Override
|
||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||
Map<Integer, Set<IBatchProcessor>> ordered = new HashMap<>();
|
||||
try {
|
||||
IChunkSet chunkSet = set;
|
||||
for (IBatchProcessor processor : processors) {
|
||||
if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) {
|
||||
ordered.merge(
|
||||
processor.getScope().intValue(),
|
||||
new HashSet<>(Collections.singleton(processor)),
|
||||
(existing, theNew) -> {
|
||||
existing.add(processor);
|
||||
return existing;
|
||||
}
|
||||
);
|
||||
IChunkSet chunkSet = set;
|
||||
for (IBatchProcessor processor : processors) {
|
||||
if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) {
|
||||
ordered.merge(
|
||||
processor.getScope().intValue(),
|
||||
new HashSet<>(Collections.singleton(processor)),
|
||||
(existing, theNew) -> {
|
||||
existing.add(processor);
|
||||
return existing;
|
||||
}
|
||||
);
|
||||
continue;
|
||||
}
|
||||
chunkSet = processSet(processor, chunk, get, chunkSet);
|
||||
}
|
||||
if (ordered.size() > 0) {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
Set<IBatchProcessor> processors = ordered.get(i);
|
||||
if (processors == null) {
|
||||
continue;
|
||||
}
|
||||
chunkSet = processSet(processor, chunk, get, chunkSet);
|
||||
}
|
||||
if (ordered.size() > 0) {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
Set<IBatchProcessor> processors = ordered.get(i);
|
||||
if (processors == null) {
|
||||
continue;
|
||||
}
|
||||
for (IBatchProcessor processor : processors) {
|
||||
chunkSet = processSet(processor, chunk, get, chunkSet);
|
||||
if (chunkSet == null) {
|
||||
return null;
|
||||
}
|
||||
for (IBatchProcessor processor : processors) {
|
||||
chunkSet = processSet(processor, chunk, get, chunkSet);
|
||||
if (chunkSet == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunkSet;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
return chunkSet;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -139,7 +146,22 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
||||
}
|
||||
return CompletableFuture.completedFuture(set);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof FaweException) {
|
||||
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) e, LOGGER);
|
||||
} else if (e.getCause() instanceof FaweException) {
|
||||
Fawe.handleFaweException(faweExceptionReasonsUsed, (FaweException) e.getCause(), LOGGER);
|
||||
} else {
|
||||
String message = e.getMessage();
|
||||
int hash = message.hashCode();
|
||||
if (lastException != hash) {
|
||||
lastException = hash;
|
||||
exceptionCount = 0;
|
||||
LOGGER.catching(e);
|
||||
} else if (exceptionCount < Settings.IMP.QUEUE.PARALLEL_THREADS) {
|
||||
exceptionCount++;
|
||||
LOGGER.warn(message);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -214,4 +236,16 @@ public class MultiBatchProcessor implements IBatchProcessor {
|
||||
return ProcessorScope.valueOf(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cached boolean array of length {@code FaweException.Type.values().length} that determines if a thrown
|
||||
* {@link FaweException} of type {@link FaweException.Type} should be output to console, rethrown to attempt to be visible
|
||||
* to the player, etc. Allows the same array to be used as widely as possible across the edit to avoid spam to console.
|
||||
*
|
||||
* @param faweExceptionReasonsUsed boolean array that should be cached where this method is called from of length {@code
|
||||
* FaweException.Type.values().length}
|
||||
*/
|
||||
public void setFaweExceptionArray(final boolean[] faweExceptionReasonsUsed) {
|
||||
this.faweExceptionReasonsUsed = faweExceptionReasonsUsed;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public interface HeightMap {
|
||||
@ -60,7 +61,7 @@ public interface HeightMap {
|
||||
.getConstructors()[0].newInstance(5, 1));
|
||||
int diameter = 2 * size + 1;
|
||||
data[1] = filter.filter(data[1], diameter, diameter);
|
||||
} catch (Throwable e) {
|
||||
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -864,25 +864,21 @@ public class NMSRelighter implements Relighter {
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (sky) {
|
||||
fixSkyLighting();
|
||||
} else {
|
||||
synchronized (this) {
|
||||
Map<Long, RelightSkyEntry> map = getSkyMap();
|
||||
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = map.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||
chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
|
||||
iter.remove();
|
||||
}
|
||||
if (sky) {
|
||||
fixSkyLighting();
|
||||
} else {
|
||||
synchronized (this) {
|
||||
Map<Long, RelightSkyEntry> map = getSkyMap();
|
||||
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = map.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||
chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
fixBlockLighting();
|
||||
sendChunks();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fixBlockLighting();
|
||||
sendChunks();
|
||||
}
|
||||
|
||||
public void fixBlockLighting() {
|
||||
@ -930,11 +926,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
try {
|
||||
close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
public synchronized void sendChunks() {
|
||||
|
Reference in New Issue
Block a user