mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-13 14:58:35 +00:00
Feature/propagate diff and object cleanup (#1190)
* Feature/main/propagate diff annotations (#1187) * 25% done * More work * More work * 50% * More work * 75% * 100% & cleanup * Update adapters * Squish squash, applesauce commit275ba9bd84
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:10:20 2021 +0200 Update dependency com.comphenix.protocol:ProtocolLib to v4.7.0 (#1173) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit9fd8984804
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:09:29 2021 +0200 Update dependency org.checkerframework:checker-qual to v3.16.0 (#1184) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit861fb45e5c
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 19:07:02 2021 +0100 Fix #1075 commit420c45a29a
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 18:48:21 2021 +0100 Entity removal should be on the main thread as we're just passing through rather than doing chunk operations - Fixes #1164 - Not working: butcher/remove history commit4d4db7dcd0
Author: SirYwell <hannesgreule@outlook.de> Date: Fri Jul 16 17:52:44 2021 +0200 Make sure leaves category is loaded for heightmaps (fixes #1176) commitc98f6e4f37
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:44:52 2021 +0100 Do not allow generation commands to generate outside selection commit2485f5eccc
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:43:15 2021 +0100 EditSession needs to override some Extent methods to ensure block changes are correctly set through the various extents Fixes #1152 commitd9418ec8ae
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 09:52:44 2021 +0100 Undo part of41073bb1a0
Fixes #1178 * Update Upstream fb1fb84 Fixed typo and grammar * We don't support custom heights yet * Casing inconsistency * Address a few comments * Address comments * Don't refactor to AP classpath * Document annotation style * Refactoring & shade cleanup * Address a few comments * More work * Resolve comments not being resolved yet * Feature/main/propagate diff annotations (#1187) (#1194) * Remove beta package, fix history packages, move classes out of object package * Resolve comments not being resolved yet * Remove beta package, fix history packages, move classes out of object package Co-authored-by: NotMyFault <mc.cache@web.de> * brushes should be under brush * More refactoring - Filters/processors should be in the same place and are related to extents - Transforms are in `extent.transform` in upstream * Move history classes under history * Update adapters Co-authored-by: dordsor21 <dordsor21@gmail.com>
This commit is contained in:
@ -35,6 +35,7 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public enum Direction {
|
||||
|
||||
//FAWE start - left, right
|
||||
NORTH(Vector3.at(0, 0, -1), Flag.CARDINAL, 3, 1),
|
||||
EAST(Vector3.at(1, 0, 0), Flag.CARDINAL, 0, 2),
|
||||
SOUTH(Vector3.at(0, 0, 1), Flag.CARDINAL, 1, 3),
|
||||
@ -62,14 +63,18 @@ public enum Direction {
|
||||
ASCENDING_SOUTH(Vector3.at(0, 1, 1), Flag.ASCENDING_CARDINAL, 1 + 18, 3 + 18),
|
||||
ASCENDING_WEST(Vector3.at(-1, 1, 0), Flag.ASCENDING_CARDINAL, 2 + 18, 0 + 18),
|
||||
;
|
||||
//FAWE end
|
||||
|
||||
private final Vector3 direction;
|
||||
private final int flags;
|
||||
//FAWE start
|
||||
private final int left;
|
||||
private final int right;
|
||||
//FAWE end
|
||||
private final BlockVector3 blockPoint;
|
||||
|
||||
private static HashMap<String, Direction> map = new HashMap<>();
|
||||
//FAWE start
|
||||
private static final HashMap<String, Direction> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (Direction dir : Direction.values()) {
|
||||
@ -121,6 +126,7 @@ public enum Direction {
|
||||
public int getBlockZ() {
|
||||
return blockPoint.getZ();
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Return true if the direction is of a cardinal direction (north, west
|
||||
@ -326,9 +332,13 @@ public enum Direction {
|
||||
public static int ORDINAL = 0x2;
|
||||
public static int SECONDARY_ORDINAL = 0x4;
|
||||
public static int UPRIGHT = 0x8;
|
||||
//FAWE start
|
||||
public static int ASCENDING_CARDINAL = 0xF;
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - ASCENDING_CARDINAL
|
||||
public static int ALL = CARDINAL | ORDINAL | SECONDARY_ORDINAL | UPRIGHT | ASCENDING_CARDINAL;
|
||||
//FAWE end
|
||||
|
||||
private Flag() {
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ public interface Identifiable {
|
||||
*/
|
||||
UUID getUniqueId();
|
||||
|
||||
//FAWE start
|
||||
UUID CONSOLE = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
|
||||
UUID EVERYONE = UUID.fromString("1-1-3-3-7");
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit.util;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.math.Vector3Impl;
|
||||
import com.fastasyncworldedit.core.math.Vector3Impl;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -36,7 +36,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
* {@link #equals(Object)} are subject to minor differences caused by
|
||||
* floating point errors.</p>
|
||||
*/
|
||||
//FAWE start - extends Vector3Impl
|
||||
public class Location extends Vector3Impl {
|
||||
//FAWE end
|
||||
|
||||
private final Extent extent;
|
||||
private final float pitch;
|
||||
@ -127,7 +129,9 @@ public class Location extends Vector3Impl {
|
||||
* @param pitch the pitch, in degrees
|
||||
*/
|
||||
public Location(Extent extent, Vector3 position, float yaw, float pitch) {
|
||||
//FAWE start
|
||||
super(position);
|
||||
//FAWE end
|
||||
checkNotNull(extent);
|
||||
checkNotNull(position);
|
||||
this.extent = extent;
|
||||
@ -293,6 +297,7 @@ public class Location extends Vector3Impl {
|
||||
return new Location(extent, position, yaw, pitch);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override public Location clampY(int min, int max) {
|
||||
checkArgument(min <= max, "minimum cannot be greater than maximum");
|
||||
if (getY() < min) {
|
||||
@ -304,6 +309,7 @@ public class Location extends Vector3Impl {
|
||||
return this;
|
||||
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@ -322,6 +328,7 @@ public class Location extends Vector3Impl {
|
||||
if (Double.doubleToLongBits(yaw) != Double.doubleToLongBits(location.yaw)) {
|
||||
return false;
|
||||
}
|
||||
//FAWE start
|
||||
if (this.getX() != location.getX()) {
|
||||
return false;
|
||||
}
|
||||
@ -334,6 +341,7 @@ public class Location extends Vector3Impl {
|
||||
if (!extent.equals(location.extent)) {
|
||||
return false;
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -90,9 +90,6 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
||||
profile = getBool("profile", profile);
|
||||
traceUnflushedSessions = getBool("trace-unflushed-sessions", traceUnflushedSessions);
|
||||
disallowedBlocks = getStringSet("disallowed-blocks", getDefaultDisallowedBlocks());
|
||||
disallowedBlocksMask = null;
|
||||
allowedDataCycleBlocks =
|
||||
new HashSet<>(getStringSet("limits.allowed-data-cycle-blocks", null));
|
||||
defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
|
||||
maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
|
||||
defaultVerticalHeight = getInt("default-vertical-height", defaultVerticalHeight);
|
||||
|
@ -39,9 +39,11 @@ public class SideEffectSet {
|
||||
private final Set<SideEffect> appliedSideEffects;
|
||||
private final boolean appliesAny;
|
||||
|
||||
//FAWE start
|
||||
private SideEffectSet() {
|
||||
this(ImmutableMap.of());
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
public SideEffectSet(Map<SideEffect, SideEffect.State> sideEffects) {
|
||||
this.sideEffects = Maps.immutableEnumMap(sideEffects);
|
||||
|
@ -38,7 +38,9 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public class TargetBlock {
|
||||
|
||||
//FAWE start - Extent > World
|
||||
private final Extent world;
|
||||
//FAWE end
|
||||
|
||||
private int maxDistance;
|
||||
private double checkDistance;
|
||||
@ -74,15 +76,19 @@ public class TargetBlock {
|
||||
* @param checkDistance how often to check for blocks, the smaller the more precise
|
||||
*/
|
||||
public TargetBlock(Player player, int maxDistance, double checkDistance) {
|
||||
//FAWE start
|
||||
this(player, player.getWorld(), maxDistance, checkDistance);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start - Extend > World
|
||||
public TargetBlock(Player player, Extent extent, int maxDistance, double checkDistance) {
|
||||
this.world = player.getWorld();
|
||||
this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(), maxDistance, 1.65, checkDistance);
|
||||
this.stopMask = new ExistingBlockMask(world);
|
||||
this.solidMask = new SolidBlockMask(world);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Set the mask used for determine where to stop traces.
|
||||
|
@ -40,7 +40,7 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* Tree generator.
|
||||
*/
|
||||
public class TreeGenerator {
|
||||
public final class TreeGenerator {
|
||||
|
||||
public enum TreeType {
|
||||
TREE("Oak tree", "oak", "tree", "regular"),
|
||||
@ -171,7 +171,7 @@ public class TreeGenerator {
|
||||
*/
|
||||
@Nullable
|
||||
public static TreeType lookup(String name) {
|
||||
return lookup.get(name.replace("_", "").toLowerCase(Locale.ROOT));
|
||||
return lookup.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A less simple implementation of {@link LocalConfiguration}
|
||||
@ -54,7 +55,7 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
|
||||
profile = config.getBoolean("debug", profile);
|
||||
traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions);
|
||||
wandItem = convertLegacyItem(config.getString("wand-item", wandItem));
|
||||
wandItem = convertLegacyItem(config.getString("wand-item", wandItem)).toLowerCase(Locale.ROOT);
|
||||
|
||||
defaultChangeLimit = Math.max(-1, config.getInt(
|
||||
"limits.max-blocks-changed.default", defaultChangeLimit));
|
||||
@ -81,7 +82,6 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius));
|
||||
|
||||
disallowedBlocks = new HashSet<>(config.getStringList("limits.disallowed-blocks", Lists.newArrayList(getDefaultDisallowedBlocks())));
|
||||
disallowedBlocksMask = null;
|
||||
allowedDataCycleBlocks = new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null));
|
||||
|
||||
registerHelp = config.getBoolean("register-help", true);
|
||||
@ -100,7 +100,7 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
useInventoryCreativeOverride = config.getBoolean("use-inventory.creative-mode-overrides",
|
||||
useInventoryCreativeOverride);
|
||||
|
||||
navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand));
|
||||
navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand)).toLowerCase(Locale.ROOT);
|
||||
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);
|
||||
|
||||
|
@ -48,6 +48,7 @@ public interface Subject {
|
||||
*/
|
||||
boolean hasPermission(String permission);
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Add and remove permissions from a subject to show and hide certain messages.
|
||||
*
|
||||
@ -65,4 +66,5 @@ public interface Subject {
|
||||
}
|
||||
|
||||
void setPermission(String permission, boolean value);
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ import java.util.NoSuchElementException;
|
||||
*/
|
||||
public class DoubleArrayList<A, B> implements Iterable<Map.Entry<A, B>> {
|
||||
|
||||
private List<A> listA = new ArrayList<>();
|
||||
private List<B> listB = new ArrayList<>();
|
||||
private final List<A> listA = new ArrayList<>();
|
||||
private final List<B> listB = new ArrayList<>();
|
||||
private boolean isReversed = false;
|
||||
|
||||
/**
|
||||
@ -102,8 +102,8 @@ public class DoubleArrayList<A, B> implements Iterable<Map.Entry<A, B>> {
|
||||
public class ForwardEntryIterator<T extends Map.Entry<A, B>>
|
||||
implements Iterator<Map.Entry<A, B>> {
|
||||
|
||||
private Iterator<A> keyIterator;
|
||||
private Iterator<B> valueIterator;
|
||||
private final Iterator<A> keyIterator;
|
||||
private final Iterator<B> valueIterator;
|
||||
|
||||
public ForwardEntryIterator(Iterator<A> keyIterator, Iterator<B> valueIterator) {
|
||||
this.keyIterator = keyIterator;
|
||||
@ -132,8 +132,8 @@ public class DoubleArrayList<A, B> implements Iterable<Map.Entry<A, B>> {
|
||||
public class ReverseEntryIterator<T extends Map.Entry<A, B>>
|
||||
implements Iterator<Map.Entry<A, B>> {
|
||||
|
||||
private ListIterator<A> keyIterator;
|
||||
private ListIterator<B> valueIterator;
|
||||
private final ListIterator<A> keyIterator;
|
||||
private final ListIterator<B> valueIterator;
|
||||
|
||||
public ReverseEntryIterator(ListIterator<A> keyIterator, ListIterator<B> valueIterator) {
|
||||
this.keyIterator = keyIterator;
|
||||
@ -160,8 +160,8 @@ public class DoubleArrayList<A, B> implements Iterable<Map.Entry<A, B>> {
|
||||
* Class to masquerade as Map.Entry.
|
||||
*/
|
||||
public class Entry<C, D> implements Map.Entry<A, B> {
|
||||
private A key;
|
||||
private B value;
|
||||
private final A key;
|
||||
private final B value;
|
||||
|
||||
private Entry(A key, B value) {
|
||||
this.key = key;
|
||||
|
@ -32,6 +32,7 @@ public class LazyReference<T> {
|
||||
return new LazyReference<>(valueComputation);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Pre-computed reference, for setting a lazy reference field with a known value.
|
||||
*
|
||||
@ -42,6 +43,7 @@ public class LazyReference<T> {
|
||||
public static <T> LazyReference<T> computed(T value) {
|
||||
return new LazyReference<>(value);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
// Memory saving technique: hold the computation info in the same reference field that we'll
|
||||
// put the value into, so the memory possibly retained by those parts is GC'able as soon as
|
||||
@ -62,9 +64,11 @@ public class LazyReference<T> {
|
||||
this.value = new RefInfo<>(valueComputation);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
private LazyReference(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
// casts are safe, value is either RefInfo or T
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -61,7 +61,7 @@ public final class EventBus {
|
||||
*/
|
||||
private final SubscriberFindingStrategy finder = new AnnotatedSubscriberFinder();
|
||||
|
||||
private HierarchyCache flattenHierarchyCache = new HierarchyCache();
|
||||
private final HierarchyCache flattenHierarchyCache = new HierarchyCache();
|
||||
|
||||
/**
|
||||
* Registers the given handler for the given class to receive events.
|
||||
|
@ -30,9 +30,9 @@ import java.util.List;
|
||||
|
||||
public class CommandListBox extends PaginationBox {
|
||||
|
||||
private List<CommandEntry> commands = Lists.newArrayList();
|
||||
private final List<CommandEntry> commands = Lists.newArrayList();
|
||||
private final String helpCommand;
|
||||
private boolean hideHelp;
|
||||
private String helpCommand;
|
||||
|
||||
/**
|
||||
* Create a new box.
|
||||
|
@ -35,8 +35,8 @@ public class MessageBox extends TextComponentProducer {
|
||||
|
||||
private static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47;
|
||||
|
||||
private TextComponentProducer contents;
|
||||
private TextColor borderColor;
|
||||
private final TextComponentProducer contents;
|
||||
private final TextColor borderColor;
|
||||
|
||||
/**
|
||||
* Create a new box.
|
||||
|
@ -78,11 +78,13 @@ public abstract class PaginationBox extends MessageBox {
|
||||
super(title, new TextComponentProducer());
|
||||
|
||||
if (pageCommand != null && !pageCommand.contains("%page%")) {
|
||||
//FAWE start
|
||||
if (pageCommand.contains("-p ")) {
|
||||
pageCommand = pageCommand.replaceAll("-p [0-9]+", "-p %page%");
|
||||
} else {
|
||||
pageCommand = pageCommand + " -p %page%";
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
this.pageCommand = pageCommand;
|
||||
}
|
||||
@ -171,6 +173,7 @@ public abstract class PaginationBox extends MessageBox {
|
||||
}
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
public static class MergedPaginationBox extends PaginationBox {
|
||||
private final PaginationBox[] values;
|
||||
|
||||
@ -182,9 +185,11 @@ public abstract class PaginationBox extends MessageBox {
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
for (PaginationBox box : values) {
|
||||
//FAWE start
|
||||
if (box == null) {
|
||||
continue;
|
||||
}
|
||||
//FAWE end
|
||||
int size = box.getComponentsSize();
|
||||
if (size > number) {
|
||||
return box.getComponent(number);
|
||||
@ -198,12 +203,15 @@ public abstract class PaginationBox extends MessageBox {
|
||||
public int getComponentsSize() {
|
||||
int size = 0;
|
||||
for (PaginationBox box : values) {
|
||||
//FAWE start
|
||||
if (box == null) {
|
||||
continue;
|
||||
}
|
||||
//FAWE end
|
||||
size += box.getComponentsSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -41,12 +41,14 @@ public class SideEffectBox extends PaginationBox {
|
||||
private SideEffectSet sideEffectSet;
|
||||
|
||||
private static List<SideEffect> getSideEffects() {
|
||||
//FAWE start
|
||||
if (sideEffects == null) {
|
||||
sideEffects = WorldEdit.getInstance().getPlatformManager().getSupportedSideEffects()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(Enum::name))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
return sideEffects;
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteProcessor;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public final class ArchiveUnpacker {
|
||||
|
||||
private static final String UNPACK_FINISHED = ".unpack_finished";
|
||||
|
||||
private static final Lock lock = new ReentrantLock();
|
||||
|
||||
private final Path unpackDir;
|
||||
|
||||
public ArchiveUnpacker(Path unpackDir) throws IOException {
|
||||
this.unpackDir = unpackDir;
|
||||
Files.createDirectories(unpackDir);
|
||||
}
|
||||
|
||||
public Path unpackArchive(URL archiveUrl) throws IOException {
|
||||
String hash;
|
||||
try (InputStream data = archiveUrl.openStream()) {
|
||||
hash = ByteStreams.readBytes(data, new ByteProcessor<String>() {
|
||||
private final Hasher hasher = Hashing.crc32c().newHasher();
|
||||
|
||||
@Override
|
||||
public boolean processBytes(byte[] buf, int off, int len) {
|
||||
hasher.putBytes(buf, off, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return hasher.hash().toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
Path dest = unpackDir.resolve(hash);
|
||||
if (Files.exists(dest.resolve(UNPACK_FINISHED))) {
|
||||
// trust this, no other option :)
|
||||
return dest;
|
||||
}
|
||||
lock.lock();
|
||||
try {
|
||||
// check again after exclusive acquire
|
||||
if (Files.exists(dest.resolve(UNPACK_FINISHED))) {
|
||||
return dest;
|
||||
}
|
||||
try (InputStream in = archiveUrl.openStream();
|
||||
ZipInputStream zipReader = new ZipInputStream(in)) {
|
||||
ZipEntry next;
|
||||
while ((next = zipReader.getNextEntry()) != null) {
|
||||
Path resolved = dest.resolve(next.getName());
|
||||
if (!resolved.startsWith(dest)) {
|
||||
// bad entry
|
||||
continue;
|
||||
}
|
||||
if (next.isDirectory()) {
|
||||
Files.createDirectories(
|
||||
resolved,
|
||||
SafeFiles.getOwnerOnlyFileAttributes(AttributeTarget.DIRECTORY)
|
||||
);
|
||||
} else {
|
||||
try (SeekableByteChannel channel = Files.newByteChannel(
|
||||
resolved,
|
||||
ImmutableSet.of(
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.WRITE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING
|
||||
),
|
||||
SafeFiles.getOwnerOnlyFileAttributes(AttributeTarget.FILE)
|
||||
)) {
|
||||
ByteStreams.copy(
|
||||
Channels.newChannel(zipReader),
|
||||
channel
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Files.createFile(dest.resolve(UNPACK_FINISHED));
|
||||
return dest;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,22 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Something that can provide access to an archive file as a file system.
|
||||
*/
|
||||
public interface ArchiveNioSupport {
|
||||
|
||||
/**
|
||||
* Try to open the given archive as a file system.
|
||||
*
|
||||
* @param archive the archive to open
|
||||
* @return the path for the root of the archive, if available
|
||||
*/
|
||||
Optional<Path> tryOpenAsDir(Path archive) throws IOException;
|
||||
|
||||
public enum AttributeTarget {
|
||||
FILE, DIRECTORY
|
||||
}
|
@ -19,15 +19,20 @@
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SafeFiles {
|
||||
|
||||
@ -141,6 +146,54 @@ public class SafeFiles {
|
||||
}
|
||||
}
|
||||
|
||||
private static final FileAttribute<?>[] OWNER_ONLY_FILE_ATTRS;
|
||||
private static final FileAttribute<?>[] OWNER_ONLY_DIR_ATTRS;
|
||||
|
||||
static {
|
||||
if (FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) {
|
||||
OWNER_ONLY_FILE_ATTRS = new FileAttribute<?>[] {
|
||||
PosixFilePermissions.asFileAttribute(
|
||||
ImmutableSet.of(
|
||||
PosixFilePermission.OWNER_READ,
|
||||
PosixFilePermission.OWNER_WRITE
|
||||
)
|
||||
)
|
||||
};
|
||||
OWNER_ONLY_DIR_ATTRS = new FileAttribute<?>[] {
|
||||
PosixFilePermissions.asFileAttribute(
|
||||
ImmutableSet.of(
|
||||
PosixFilePermission.OWNER_READ,
|
||||
PosixFilePermission.OWNER_WRITE,
|
||||
PosixFilePermission.OWNER_EXECUTE
|
||||
)
|
||||
)
|
||||
};
|
||||
} else {
|
||||
OWNER_ONLY_FILE_ATTRS = new FileAttribute<?>[0];
|
||||
OWNER_ONLY_DIR_ATTRS = new FileAttribute<?>[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of file attributes for file creation with owner-only access, if possible.
|
||||
*
|
||||
* <p>
|
||||
* On POSIX, this returns o+rw (and o+x if directory), on Windows it returns nothing.
|
||||
* </p>
|
||||
*
|
||||
* @return the owner-only file attributes
|
||||
*/
|
||||
public static FileAttribute<?>[] getOwnerOnlyFileAttributes(AttributeTarget attributeTarget) {
|
||||
switch (attributeTarget) {
|
||||
case FILE:
|
||||
return OWNER_ONLY_FILE_ATTRS;
|
||||
case DIRECTORY:
|
||||
return OWNER_ONLY_DIR_ATTRS;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown attribute target " + attributeTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private SafeFiles() {
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.nbt;
|
||||
|
||||
import com.sk89q.worldedit.world.storage.InvalidFormatException;
|
||||
|
||||
public class NbtUtils {
|
||||
|
||||
/**
|
||||
* Get child tag of a NBT structure.
|
||||
*
|
||||
* @param tag the tag to read from
|
||||
* @param key the key to look for
|
||||
* @param expected the expected NBT class type
|
||||
* @return child tag
|
||||
* @throws InvalidFormatException if the format of the items is invalid
|
||||
*/
|
||||
public static <T extends BinaryTag> T getChildTag(CompoundBinaryTag tag, String key, BinaryTagType<T> expected) throws InvalidFormatException {
|
||||
BinaryTag childTag = tag.get(key);
|
||||
if (childTag == null) {
|
||||
throw new InvalidFormatException("Missing a \"" + key + "\" tag");
|
||||
}
|
||||
|
||||
if (childTag.type().id() != expected.id()) {
|
||||
throw new InvalidFormatException(key + " tag is not of tag type " + expected.toString());
|
||||
}
|
||||
// SAFETY: same binary tag type checked above
|
||||
@SuppressWarnings("unchecked")
|
||||
T childTagCast = (T) childTag;
|
||||
return childTagCast;
|
||||
}
|
||||
|
||||
}
|
@ -217,13 +217,6 @@ public class HttpRequest implements Closeable {
|
||||
return conn.getResponseCode();
|
||||
}
|
||||
|
||||
public String getSingleHeaderValue(String header) {
|
||||
checkState(conn != null, "No connection has been made");
|
||||
|
||||
// maybe we should check for multi-header?
|
||||
return conn.getHeaderField(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input stream.
|
||||
*
|
||||
|
@ -72,7 +72,7 @@ public final class ActorCallbackPaste {
|
||||
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(supervisor, "Submitting content to a pastebin service.")
|
||||
.sendMessageAfterDelay(Caption.of("worldedit.pastebin.uploading"))
|
||||
.setDelayMessage(Caption.of("worldedit.pastebin.uploading"))
|
||||
.onSuccess((String) null, url -> sender.printInfo(successMessage.args(TextComponent.of(url.toString())).build()))
|
||||
.onFailure("Failed to submit paste", null)
|
||||
.buildAndExec(Pasters.getExecutor());
|
||||
|
@ -1,53 +0,0 @@
|
||||
package com.sk89q.worldedit.util.task;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class LinkedFuture<T extends Future<T>> implements Future<T> {
|
||||
private Future<T> task;
|
||||
|
||||
public LinkedFuture(Future<T> task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return task.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return task.isDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T get() throws InterruptedException, ExecutionException {
|
||||
if (task != null) {
|
||||
task = task.get();
|
||||
if (task != null) {
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (task != null) {
|
||||
task = task.get(timeout, unit);
|
||||
if (task != null) {
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -31,7 +31,9 @@ public class TaskStateComparator implements Comparator<Task<?>> {
|
||||
public int compare(com.sk89q.worldedit.util.task.Task<?> o1, Task<?> o2) {
|
||||
int ordinal1 = o1.getState().ordinal();
|
||||
int ordinal2 = o2.getState().ordinal();
|
||||
//FAWE start - use Integer#compare
|
||||
return Integer.compare(ordinal1, ordinal2);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user