mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-01 02:46:41 +00:00
Upstream Merge
This commit is contained in:
@ -127,9 +127,8 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||
|
||||
String snapshotsDir = getString("snapshots-dir", "");
|
||||
if (!snapshotsDir.isEmpty()) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
}
|
||||
boolean experimentalSnapshots = getBool("snapshots-experimental", false);
|
||||
initializeSnapshotConfiguration(snapshotsDir, experimentalSnapshots);
|
||||
|
||||
path.getParentFile().mkdirs();
|
||||
try (OutputStream output = new FileOutputStream(path)) {
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.collection;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.collection;
|
||||
|
||||
import com.google.common.collect.AbstractIterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Additionally stream facilities.
|
||||
*/
|
||||
public class MoreStreams {
|
||||
|
||||
/**
|
||||
* Emit elements from {@code stream} until {@code predicate} returns {@code false}.
|
||||
*/
|
||||
public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) {
|
||||
return takeUntil(stream, predicate.negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit elements from {@code stream} until {@code predicate} returns {@code true}.
|
||||
*/
|
||||
public static <T> Stream<T> takeUntil(Stream<T> stream, Predicate<T> predicate) {
|
||||
Spliterator<T> spliterator = stream.spliterator();
|
||||
Iterator<T> iter = new AbstractIterator<T>() {
|
||||
|
||||
private Iterator<T> source = Spliterators.iterator(spliterator);
|
||||
|
||||
@Override
|
||||
protected T computeNext() {
|
||||
Iterator<T> src = requireNonNull(source);
|
||||
if (!src.hasNext()) {
|
||||
return done();
|
||||
}
|
||||
T next = src.next();
|
||||
if (predicate.test(next)) {
|
||||
return done();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
private T done() {
|
||||
// allow GC of source
|
||||
source = null;
|
||||
return endOfData();
|
||||
}
|
||||
};
|
||||
int chars = spliterator.characteristics();
|
||||
// Not SIZED, Not SUBSIZED
|
||||
chars &= ~(Spliterator.SIZED | Spliterator.SUBSIZED);
|
||||
return StreamSupport.stream(Spliterators.spliterator(
|
||||
iter, spliterator.estimateSize(), chars
|
||||
), stream.isParallel()).onClose(stream::close);
|
||||
}
|
||||
|
||||
private MoreStreams() {
|
||||
}
|
||||
}
|
@ -71,4 +71,5 @@ public class LazyReference<T> {
|
||||
refInfo.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,8 +20,6 @@
|
||||
package com.sk89q.worldedit.util.eventbus;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import org.slf4j.Logger;
|
||||
@ -37,6 +35,8 @@ import java.util.Set;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Dispatches events to listeners, and provides ways for listeners to register
|
||||
* themselves.
|
||||
|
@ -47,6 +47,7 @@ public class TextUtils {
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Java Locale object by the Minecraft locale tag.
|
||||
*
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.function;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* I/O runnable type.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IORunnable {
|
||||
|
||||
void run() throws IOException;
|
||||
|
||||
}
|
@ -51,4 +51,4 @@ public class ResourceLoader {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ArchiveNioSupports {
|
||||
|
||||
private static final List<ArchiveNioSupport> SUPPORTS;
|
||||
|
||||
static {
|
||||
ImmutableList.Builder<ArchiveNioSupport> builder = ImmutableList.builder();
|
||||
try {
|
||||
builder.add(TrueVfsArchiveNioSupport.getInstance());
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
// No TrueVFS available. That's OK.
|
||||
}
|
||||
SUPPORTS = builder.add(ZipArchiveNioSupport.getInstance())
|
||||
.addAll(ServiceLoader.load(ArchiveNioSupport.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Optional<Path> tryOpenAsDir(Path archive) throws IOException {
|
||||
for (ArchiveNioSupport support : SUPPORTS) {
|
||||
Optional<Path> fs = support.tryOpenAsDir(archive);
|
||||
if (fs.isPresent()) {
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static final ArchiveNioSupport COMBINED = ArchiveNioSupports::tryOpenAsDir;
|
||||
|
||||
/**
|
||||
* Get an {@link ArchiveNioSupport} that combines all known instances.
|
||||
* @return a combined {@link ArchiveNioSupport} instance
|
||||
*/
|
||||
public static ArchiveNioSupport combined() {
|
||||
return COMBINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* If root contains a folder with the same name as {@code name}, and no regular files,
|
||||
* returns the path to that folder. Otherwise, return the root path.
|
||||
*
|
||||
* <p>
|
||||
* This method is used to provide equal outputs for archives that do and do not contain
|
||||
* their name as part of their root folder.
|
||||
* </p>
|
||||
*
|
||||
* @param root the root path
|
||||
* @param name the name that might exist inside root
|
||||
* @return the corrected path
|
||||
*/
|
||||
public static Path skipRootSameName(Path root, String name) throws IOException {
|
||||
Path innerDir = root.resolve(name);
|
||||
if (Files.isDirectory(innerDir)) {
|
||||
try (Stream<Path> files = Files.list(root)) {
|
||||
// The reason we check this, is that macOS creates a __MACOSX directory inside
|
||||
// its zip files. We want to allow this to pass if that exists, or a similar
|
||||
// mechanism, but fail if there are regular files, since that indicates that
|
||||
// it may not be the right thing to do.
|
||||
if (files.allMatch(Files::isDirectory)) {
|
||||
return innerDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
private ArchiveNioSupports() {
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Streams;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MorePaths {
|
||||
|
||||
/**
|
||||
* Starting with the first path element, add elements until reaching this path.
|
||||
*/
|
||||
public static Stream<Path> iterPaths(Path path) {
|
||||
Deque<Path> parents = new ArrayDeque<>(path.getNameCount());
|
||||
// Push parents to the front of the stack, so the "root" is at the front
|
||||
Path next = path;
|
||||
while (next != null) {
|
||||
parents.addFirst(next);
|
||||
next = next.getParent();
|
||||
}
|
||||
// now just iterate straight over them
|
||||
return ImmutableList.copyOf(parents).stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an efficiently-splittable spliterator for the given path elements.
|
||||
*
|
||||
* <p>
|
||||
* Since paths are so small, this is only useful for preventing heavy computations
|
||||
* on later parts of the stream from occurring when using
|
||||
* {@link Streams#findLast(IntStream)}, and not for parallelism.
|
||||
* </p>
|
||||
*
|
||||
* @param path the path to create a spliterator for
|
||||
* @return the spliterator
|
||||
*/
|
||||
public static Spliterator<Path> optimizedSpliterator(Path path) {
|
||||
return Arrays.spliterator(Streams.stream(path).toArray(Path[]::new));
|
||||
}
|
||||
|
||||
private MorePaths() {
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.java.truevfs.access.TArchiveDetector;
|
||||
import net.java.truevfs.access.TPath;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public final class TrueVfsArchiveNioSupport implements ArchiveNioSupport {
|
||||
|
||||
private static final TrueVfsArchiveNioSupport INSTANCE = new TrueVfsArchiveNioSupport();
|
||||
|
||||
public static TrueVfsArchiveNioSupport getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final Set<String> ALLOWED_EXTENSIONS = ImmutableSet.copyOf(
|
||||
Splitter.on('|').split(TArchiveDetector.ALL.getExtensions())
|
||||
);
|
||||
|
||||
private TrueVfsArchiveNioSupport() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> tryOpenAsDir(Path archive) throws IOException {
|
||||
String fileName = archive.getFileName().toString();
|
||||
int dot = fileName.indexOf('.');
|
||||
if (dot < 0 || dot >= fileName.length() || !ALLOWED_EXTENSIONS.contains(fileName.substring(dot + 1))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
TPath root = new TPath(archive).getFileSystem().getPath("/");
|
||||
return Optional.of(ArchiveNioSupports.skipRootSameName(
|
||||
root, fileName.substring(0, dot)
|
||||
));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.io.file;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ZipArchiveNioSupport implements ArchiveNioSupport {
|
||||
|
||||
private static final ZipArchiveNioSupport INSTANCE = new ZipArchiveNioSupport();
|
||||
|
||||
public static ZipArchiveNioSupport getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ZipArchiveNioSupport() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> tryOpenAsDir(Path archive) throws IOException {
|
||||
if (!archive.getFileName().toString().endsWith(".zip")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
FileSystem zipFs = FileSystems.newFileSystem(
|
||||
archive, getClass().getClassLoader()
|
||||
);
|
||||
return Optional.of(ArchiveNioSupports.skipRootSameName(
|
||||
zipFs.getPath("/"), archive.getFileName().toString()
|
||||
.replaceFirst("\\.zip$", "")
|
||||
));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.time;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.io.file.MorePaths;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* Parses date-times by looking at the file name. File names without a time
|
||||
* will use 00:00:00.
|
||||
*
|
||||
* <p>
|
||||
* Elements may be separated by a space, dash, or colon.
|
||||
* The date and time may additionally be separated by a 'T'.
|
||||
* Only the year must have all digits, others may omit padding
|
||||
* zeroes.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Valid file name examples:
|
||||
* <ul>
|
||||
* <li>{@code 2019-06-15}</li>
|
||||
* <li>{@code 2019-06-15 10:20:30}</li>
|
||||
* <li>{@code 2019-06-15 10:20:30}</li>
|
||||
* <li>{@code 2019-06-15T10:20:30}</li>
|
||||
* <li>{@code 2019 06 15 10 20 30}</li>
|
||||
* <li>{@code 2019-06-15-10-20-30}</li>
|
||||
* <li>{@code 2019-6-1-1-2-3}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class FileNameDateTimeParser implements SnapshotDateTimeParser {
|
||||
|
||||
private static final FileNameDateTimeParser INSTANCE = new FileNameDateTimeParser();
|
||||
|
||||
public static FileNameDateTimeParser getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final String SEP = "[ \\-_:]";
|
||||
|
||||
private static final Pattern BASIC_FILTER = Pattern.compile(
|
||||
"^(?<year>\\d{4})" + SEP + "(?<month>\\d{1,2})" + SEP + "(?<day>\\d{1,2})" +
|
||||
// Optionally:
|
||||
"(?:" + "[ \\-_:T]" +
|
||||
"(?<hour>\\d{1,2})" + SEP + "(?<minute>\\d{1,2})" + SEP + "(?<second>\\d{1,2})" +
|
||||
")?"
|
||||
);
|
||||
|
||||
private FileNameDateTimeParser() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ZonedDateTime detectDateTime(Path path) {
|
||||
// Make this perform a little better:
|
||||
Matcher matcher = Streams.findLast(
|
||||
StreamSupport.stream(MorePaths.optimizedSpliterator(path), false)
|
||||
.map(p -> BASIC_FILTER.matcher(p.toString()))
|
||||
.filter(Matcher::find)
|
||||
).orElse(null);
|
||||
if (matcher != null) {
|
||||
int year = matchAndParseOrZero(matcher, "year");
|
||||
int month = matchAndParseOrZero(matcher, "month");
|
||||
int day = matchAndParseOrZero(matcher, "day");
|
||||
int hour = matchAndParseOrZero(matcher, "hour");
|
||||
int minute = matchAndParseOrZero(matcher, "minute");
|
||||
int second = matchAndParseOrZero(matcher, "second");
|
||||
return ZonedDateTime.of(year, month, day, hour, minute, second,
|
||||
0, ZoneId.systemDefault());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int matchAndParseOrZero(Matcher matcher, String group) {
|
||||
String match = matcher.group(group);
|
||||
if (match == null) {
|
||||
return 0;
|
||||
}
|
||||
return Integer.parseInt(match);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.time;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class ModificationDateTimeParser implements SnapshotDateTimeParser {
|
||||
|
||||
private static final ModificationDateTimeParser INSTANCE = new ModificationDateTimeParser();
|
||||
|
||||
public static ModificationDateTimeParser getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ModificationDateTimeParser() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime detectDateTime(Path path) {
|
||||
if (!Files.exists(path)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Files.getLastModifiedTime(path).toInstant().atZone(ZoneId.systemDefault());
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.time;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* Instances of this interface try to determine an {@link ZonedDateTime} from a given
|
||||
* {@link Path}.
|
||||
*/
|
||||
public interface SnapshotDateTimeParser {
|
||||
|
||||
/**
|
||||
* Attempt to detect an ZonedDateTime from a path.
|
||||
*
|
||||
* <p>
|
||||
* The path is not guaranteed to exist.
|
||||
* </p>
|
||||
*
|
||||
* @param path the path
|
||||
* @return date-time, if it can be parsed
|
||||
*/
|
||||
@Nullable
|
||||
ZonedDateTime detectDateTime(Path path);
|
||||
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.translation;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@ -29,6 +27,7 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.renderer.FriendlyComponentRenderer;
|
||||
import com.sk89q.worldedit.util.io.ResourceLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -43,6 +42,8 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
/**
|
||||
* Handles translations for the plugin.
|
||||
*
|
||||
|
Reference in New Issue
Block a user