Added BiomeMask.java and updated minor parts of miscellaneous files

This commit is contained in:
MattBDev
2020-08-24 22:04:56 -04:00
parent 02886b0387
commit a9d37fc6e5
45 changed files with 595 additions and 187 deletions

View File

@ -47,7 +47,8 @@ public final class Enums {
for (String val : values) {
try {
return Enum.valueOf(enumType, val);
} catch (IllegalArgumentException ignored) {}
} catch (IllegalArgumentException ignored) {
}
}
return null;
}

View File

@ -65,8 +65,8 @@ public final class FileDialogUtil {
}
private static class ExtensionFilter extends FileFilter {
private Set<String> exts;
private String desc;
private final Set<String> exts;
private final String desc;
private ExtensionFilter(String[] exts) {
this.exts = new HashSet<>(Arrays.asList(exts));

View File

@ -25,7 +25,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class GuavaUtil {
private GuavaUtil() {}
private GuavaUtil() {
}
public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
return first != null ? first : checkNotNull(second);

View File

@ -36,6 +36,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
@ -55,14 +56,25 @@ public class PropertiesConfiguration extends LocalConfiguration {
/**
* Construct the object. The configuration isn't loaded yet.
*
* @param path the path tot he configuration
* @param path the path to the configuration
*/
public PropertiesConfiguration(File path) {
this.path = path;
public PropertiesConfiguration(Path path) {
this.path = path.toFile();
properties = new Properties();
}
/**
* Construct the object. The configuration isn't loaded yet.
*
* @param path the path to the configuration
* @deprecated Use {@link PropertiesConfiguration#PropertiesConfiguration(Path)}
*/
@Deprecated
public PropertiesConfiguration(File path) {
this(path.toPath());
}
@Override
public void load() {
try (InputStream stream = new FileInputStream(path)) {
@ -82,6 +94,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
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);
defaultMaxPolygonalPoints = getInt("default-max-polygon-points", defaultMaxPolygonalPoints);
maxPolygonalPoints = getInt("max-polygon-points", maxPolygonalPoints);
defaultMaxPolyhedronPoints = getInt("default-max-polyhedron-points", defaultMaxPolyhedronPoints);
@ -97,7 +110,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
wandItem = getString("wand-item", wandItem);
try {
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
} catch (Throwable e) {
} catch (Throwable ignored) {
}
superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
@ -107,7 +120,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
navigationWand = getString("nav-wand-item", navigationWand);
try {
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
} catch (Throwable e) {
} catch (Throwable ignored) {
}
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);

View File

@ -24,7 +24,8 @@ import java.util.Locale;
public enum SideEffect {
LIGHTING(State.ON),
NEIGHBORS(State.ON),
VALIDATION(State.ON),
UPDATE(State.ON),
VALIDATION(State.OFF),
ENTITY_AI(State.OFF),
EVENTS(State.OFF);

View File

@ -71,7 +71,9 @@ public class SideEffectSet {
/**
* Gets whether this side effect is not off.
*
* <p>
* This returns whether it is either delayed or on.
* </p>
*
* @param effect The side effect
* @return Whether it should apply

View File

@ -41,7 +41,8 @@ public class TargetBlock {
private final Extent world;
private int maxDistance;
private double checkDistance, curDistance;
private double checkDistance;
private double curDistance;
private BlockVector3 targetPos = BlockVector3.ZERO;
private Vector3 targetPosDouble = Vector3.ZERO;
private BlockVector3 prevPos = BlockVector3.ZERO;
@ -53,16 +54,20 @@ public class TargetBlock {
private Mask solidMask;
/**
* Constructor requiring a player, uses default values
* Constructor requiring a player, uses default values.
*
* @param player player to work with
*/
public TargetBlock(Player player) {
this(player, 300, 0.2);
this.world = player.getWorld();
this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(),
300, 1.65, 0.2);
this.stopMask = new ExistingBlockMask(world);
this.solidMask = new SolidBlockMask(world);
}
/**
* Constructor requiring a player, max distance and a checking distance
* Constructor requiring a player, max distance and a checking distance.
*
* @param player Player to work with
* @param maxDistance how far it checks for blocks
@ -108,27 +113,27 @@ public class TargetBlock {
}
/**
* Set the values, all constructors uses this function
* Set the values, all constructors uses this function.
*
* @param loc location of the view
* @param xRotation the X rotation
* @param yRotation the Y rotation
* @param rotationX the X rotation
* @param rotationY the Y rotation
* @param maxDistance how far it checks for blocks
* @param viewHeight where the view is positioned in y-axis
* @param checkDistance how often to check for blocks, the smaller the more precise
*/
private void setValues(Vector3 loc, double xRotation, double yRotation, int maxDistance, double viewHeight, double checkDistance) {
private void setValues(Vector3 loc, double rotationX, double rotationY, int maxDistance, double viewHeight, double checkDistance) {
this.maxDistance = maxDistance;
this.checkDistance = checkDistance;
this.curDistance = 0;
xRotation = (xRotation + 90) % 360;
yRotation *= -1;
rotationX = (rotationX + 90) % 360;
rotationY *= -1;
double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
double h = (checkDistance * Math.cos(Math.toRadians(rotationY)));
offset = Vector3.at((h * Math.cos(Math.toRadians(xRotation))),
(checkDistance * Math.sin(Math.toRadians(yRotation))),
(h * Math.sin(Math.toRadians(xRotation))));
offset = Vector3.at((h * Math.cos(Math.toRadians(rotationX))),
(checkDistance * Math.sin(Math.toRadians(rotationY))),
(h * Math.sin(Math.toRadians(rotationX))));
targetPosDouble = loc.add(0, viewHeight, 0);
targetPos = targetPosDouble.toBlockPoint();
@ -145,7 +150,7 @@ public class TargetBlock {
boolean searchForLastBlock = true;
Location lastBlock = null;
while (getNextBlock() != null) {
if (stopMask.test(world, targetPos)) {
if (stopMask.test(targetPos)) {
break;
} else {
if (searchForLastBlock) {
@ -168,7 +173,8 @@ public class TargetBlock {
*/
public Location getTargetBlock() {
//noinspection StatementWithEmptyBody
while (getNextBlock() != null && !stopMask.test(world, targetPos)) ;
while (getNextBlock() != null && !stopMask.test(targetPos)) {
}
return getCurrentBlock();
}
@ -180,12 +186,13 @@ public class TargetBlock {
*/
public Location getSolidTargetBlock() {
//noinspection StatementWithEmptyBody
while (getNextBlock() != null && !solidMask.test(world, targetPos)) ;
while (getNextBlock() != null && !solidMask.test(targetPos)) {
}
return getCurrentBlock();
}
/**
* Get next block
* Get next block.
*
* @return next block position
*/
@ -211,7 +218,7 @@ public class TargetBlock {
}
/**
* Returns the current block along the line of vision
* Returns the current block along the line of vision.
*
* @return block position
*/
@ -224,7 +231,7 @@ public class TargetBlock {
}
/**
* Returns the previous block in the aimed path
* Returns the previous block in the aimed path.
*
* @return block position
*/
@ -235,15 +242,18 @@ public class TargetBlock {
public Location getAnyTargetBlockFace() {
getAnyTargetBlock();
Location current = getCurrentBlock();
if (current != null)
if (current != null) {
return current.setDirection(current.toVector().subtract(getPreviousBlock().toVector()));
else
} else {
return new Location(world, targetPos.toVector3(), Float.NaN, Float.NaN);
}
}
public Location getTargetBlockFace() {
getTargetBlock();
if (getCurrentBlock() == null) return null;
if (getCurrentBlock() == null) {
return null;
}
return getCurrentBlock().setDirection(getCurrentBlock().toVector().subtract(getPreviousBlock().toVector()));
}

View File

@ -170,7 +170,7 @@ public class TreeGenerator {
private static final Random RANDOM = new Random();
/**
/**
* Makes a terrible looking pine tree.
*
* @param basePosition the base position

View File

@ -36,7 +36,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class WeightedChoice<T> {
private final Function<T, ? extends Number> function;
private double target;
private final double target;
private double best;
private T current;

View File

@ -61,6 +61,9 @@ public class YAMLConfiguration extends LocalConfiguration {
maxChangeLimit = Math.max(-1,
config.getInt("limits.max-blocks-changed.maximum", maxChangeLimit));
defaultVerticalHeight = Math.max(1,
config.getInt("limits.vertical-height.default", defaultVerticalHeight));
defaultMaxPolygonalPoints = Math.max(-1,
config.getInt("limits.max-polygonal-points.default", defaultMaxPolygonalPoints));
maxPolygonalPoints = Math.max(-1,

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.util.auth;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
/**
* Raised when authorization is not granted.
@ -29,10 +30,20 @@ public class AuthorizationException extends WorldEditException {
public AuthorizationException() {
}
public AuthorizationException(Component message) {
super(message);
}
@Deprecated
public AuthorizationException(String message) {
super(message);
}
public AuthorizationException(Component message, Throwable cause) {
super(message, cause);
}
@Deprecated
public AuthorizationException(String message, Throwable cause) {
super(message, cause);
}

View File

@ -20,10 +20,16 @@
package com.sk89q.worldedit.util.formatting.component;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
public class InvalidComponentException extends WorldEditException {
@Deprecated
public InvalidComponentException(String message) {
super(message);
}
public InvalidComponentException(Component message) {
super(message);
}
}

View File

@ -19,14 +19,20 @@
package com.sk89q.worldedit.util.io.file;
import com.sk89q.worldedit.util.formatting.text.Component;
public class FileSelectionAbortedException extends FilenameException {
public FileSelectionAbortedException() {
super("");
}
@Deprecated
public FileSelectionAbortedException(String msg) {
super("", msg);
}
public FileSelectionAbortedException(Component msg) {
super("", msg);
}
}

View File

@ -20,16 +20,23 @@
package com.sk89q.worldedit.util.io.file;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
public class FilenameException extends WorldEditException {
private String filename;
private final String filename;
public FilenameException(String filename) {
super();
this.filename = filename;
}
public FilenameException(String filename, Component msg) {
super(msg);
this.filename = filename;
}
@Deprecated
public FilenameException(String filename, String msg) {
super(msg);
this.filename = filename;

View File

@ -19,12 +19,19 @@
package com.sk89q.worldedit.util.io.file;
import com.sk89q.worldedit.util.formatting.text.Component;
public class FilenameResolutionException extends FilenameException {
public FilenameResolutionException(String filename) {
super(filename);
}
public FilenameResolutionException(String filename, Component msg) {
super(filename, msg);
}
@Deprecated
public FilenameResolutionException(String filename, String msg) {
super(filename, msg);
}

View File

@ -19,12 +19,19 @@
package com.sk89q.worldedit.util.io.file;
import com.sk89q.worldedit.util.formatting.text.Component;
public class InvalidFilenameException extends FilenameException {
public InvalidFilenameException(String filename) {
super(filename);
}
public InvalidFilenameException(String filename, Component msg) {
super(filename, msg);
}
@Deprecated
public InvalidFilenameException(String filename, String msg) {
super(filename, msg);
}

View File

@ -22,9 +22,14 @@ package com.sk89q.worldedit.util.io.file;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Deque;
import java.util.Spliterator;
import java.util.stream.IntStream;
@ -32,6 +37,20 @@ import java.util.stream.Stream;
public class MorePaths {
public static Comparator<Path> oldestFirst() {
return Comparator.comparing(x -> {
try {
return Files.getLastModifiedTime(x);
} catch (IOException e) {
return FileTime.from(Instant.EPOCH);
}
});
}
public static Comparator<Path> newestFirst() {
return oldestFirst().reversed();
}
/**
* Starting with the first path element, add elements until reaching this path.
*/

View File

@ -19,9 +19,12 @@
package com.sk89q.worldedit.util.io.file;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -64,6 +67,80 @@ public class SafeFiles {
return name.substring(0, name.length() - 1);
}
/**
* Recursively uses {@link #tryHardToDelete(Path)} to cleanup directories before deleting them.
*
* @param directory the directory to delete
* @throws IOException if an error occurs trying to delete the directory
*/
public static void tryHardToDeleteDir(Path directory) throws IOException {
if (!Files.isDirectory(directory)) {
if (!Files.exists(directory)) {
return;
}
throw new IOException(directory + " is not a directory");
}
try (Stream<Path> files = Files.list(directory)) {
for (Iterator<Path> iter = files.iterator(); iter.hasNext(); ) {
Path next = iter.next();
if (Files.isDirectory(next)) {
tryHardToDeleteDir(next);
} else {
tryHardToDelete(next);
}
}
}
tryHardToDelete(directory);
}
/**
* Tries to delete a path. If it fails the first time, uses an implementation detail to try
* and make it possible to delete the path, and then tries again. If that fails, throws an
* {@link IOException} with both errors.
*
* @param path the path to delete
* @throws IOException if the path could not be deleted after multiple attempts
*/
public static void tryHardToDelete(Path path) throws IOException {
IOException suppressed = tryDelete(path);
if (suppressed == null) {
return;
}
// This is copied from Ant (see org.apache.tools.ant.util.FileUtils.tryHardToDelete).
// It mentions that there is a bug in the Windows JDK implementations that this is a valid
// workaround for. I've been unable to find a definitive reference to this bug.
// The thinking is that if this is good enough for Ant, it's good enough for us.
System.gc();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
IOException suppressed2 = tryDelete(path);
if (suppressed2 == null) {
return;
}
IOException ex = new IOException("Failed to delete " + path, suppressed2);
ex.addSuppressed(suppressed);
throw ex;
}
@Nullable
private static IOException tryDelete(Path path) {
try {
Files.deleteIfExists(path);
if (Files.exists(path)) {
return new IOException(path + " still exists after deleting");
}
return null;
} catch (IOException e) {
return e;
}
}
private SafeFiles() {
}
}

View File

@ -68,7 +68,7 @@ public class DynamicStreamHandler extends StreamHandler {
handler.setFilter(filter);
try {
handler.setEncoding(encoding);
} catch (UnsupportedEncodingException ignore) {
} catch (UnsupportedEncodingException ignored) {
}
handler.setLevel(level);
}

View File

@ -19,6 +19,9 @@
package com.sk89q.worldedit.util.net;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.google.common.net.UrlEscapers;
import com.sk89q.worldedit.util.io.Closer;
import java.io.BufferedInputStream;
@ -31,19 +34,16 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkState;
import java.util.concurrent.ThreadLocalRandom;
public class HttpRequest implements Closeable {
@ -89,9 +89,21 @@ public class HttpRequest implements Closeable {
* @param form the form
* @return this object
*/
public HttpRequest bodyForm(Form form) {
public HttpRequest bodyUrlEncodedForm(Form form) {
contentType = "application/x-www-form-urlencoded";
body = form.toString().getBytes();
body = form.toUrlEncodedString().getBytes(StandardCharsets.UTF_8);
return this;
}
/**
* Submit form data.
*
* @param form the form
* @return this object
*/
public HttpRequest bodyMultipartForm(Form form) {
contentType = "multipart/form-data;boundary=" + form.getFormDataSeparator();
body = form.toFormDataString().getBytes(StandardCharsets.UTF_8);
return this;
}
@ -155,8 +167,9 @@ public class HttpRequest implements Closeable {
out.close();
}
inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK ?
conn.getInputStream() : conn.getErrorStream();
inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK
? conn.getInputStream()
: conn.getErrorStream();
successful = true;
} finally {
@ -202,13 +215,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.
*
@ -223,8 +229,9 @@ public class HttpRequest implements Closeable {
*
* @return the buffered response
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public BufferedResponse returnContent() throws IOException {
public BufferedResponse returnContent() throws IOException, InterruptedException {
if (inputStream == null) {
throw new IllegalArgumentException("No input stream available");
}
@ -247,8 +254,9 @@ public class HttpRequest implements Closeable {
* @param file the file
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public HttpRequest saveContent(File file) throws IOException {
public HttpRequest saveContent(File file) throws IOException, InterruptedException {
Closer closer = Closer.create();
try {
@ -269,8 +277,9 @@ public class HttpRequest implements Closeable {
* @param out the output stream
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public HttpRequest saveContent(OutputStream out) throws IOException {
public HttpRequest saveContent(OutputStream out) throws IOException, InterruptedException {
BufferedInputStream bis;
try {
@ -301,8 +310,10 @@ public class HttpRequest implements Closeable {
}
@Override
public void close() throws IOException {
if (conn != null) conn.disconnect();
public void close() {
if (conn != null) {
conn.disconnect();
}
}
/**
@ -366,18 +377,24 @@ public class HttpRequest implements Closeable {
url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
return url;
} catch (MalformedURLException e) {
return existing;
} catch (URISyntaxException e) {
} catch (MalformedURLException | URISyntaxException e) {
return existing;
}
}
/**
* Used with {@link #bodyForm(Form)}.
* Used with {@link #bodyUrlEncodedForm(Form)}.
*/
public final static class Form {
public final List<String> elements = new ArrayList<>();
public static final class Form {
private static final Joiner.MapJoiner URL_ENCODER = Joiner.on('&')
.withKeyValueSeparator('=');
private static final Joiner CRLF_JOINER = Joiner.on("\r\n");
public final Map<String, String> elements = new LinkedHashMap<>();
private final String formDataSeparator = "EngineHubFormData"
+ ThreadLocalRandom.current().nextInt(10000, 99999);
private Form() {
}
@ -390,30 +407,45 @@ public class HttpRequest implements Closeable {
* @return this object
*/
public Form add(String key, String value) {
try {
elements.add(URLEncoder.encode(key, "UTF-8") +
"=" + URLEncoder.encode(value, "UTF-8"));
return this;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
elements.put(key, value);
return this;
}
@Override
public String toString() {
public String getFormDataSeparator() {
return formDataSeparator;
}
public String toFormDataString() {
String separatorWithDashes = "--" + formDataSeparator;
StringBuilder builder = new StringBuilder();
boolean first = true;
for (String element : elements) {
if (first) {
first = false;
} else {
builder.append("&");
}
builder.append(element);
for (Map.Entry<String, String> element : elements.entrySet()) {
CRLF_JOINER.appendTo(
builder,
separatorWithDashes,
"Content-Disposition: form-data; name=\"" + element.getKey() + "\"",
"",
element.getValue(),
""
);
}
builder.append(separatorWithDashes).append("--");
return builder.toString();
}
public String toUrlEncodedString() {
return URL_ENCODER.join(
elements.entrySet().stream()
.map(e -> Maps.immutableEntry(
UrlEscapers.urlFormParameterEscaper().escape(e.getKey()),
UrlEscapers.urlFormParameterEscaper().escape(e.getValue())
))
.iterator()
);
}
/**
* Create a new form.
*

View File

@ -27,13 +27,9 @@ import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EngineHubPaste implements Paster {
private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$");
private static final Gson GSON = new Gson();
@Override
@ -50,31 +46,34 @@ public class EngineHubPaste implements Paster {
@Override
public URL call() throws IOException, InterruptedException {
URL initialUrl = HttpRequest.url("https://paste.enginehub.org/signed_paste");
SignedPasteResponse response = GSON.fromJson(HttpRequest.get(initialUrl)
.execute()
.expectResponseCode(200)
.returnContent()
.asString("UTF-8"), TypeToken.get(SignedPasteResponse.class).getType());
HttpRequest.Form form = HttpRequest.Form.create();
form.add("content", content);
form.add("from", "enginehub");
URL url = HttpRequest.url("https://paste.enginehub.org/paste");
String result = HttpRequest.post(url)
.bodyForm(form)
.execute()
.expectResponseCode(200)
.returnContent()
.asString("UTF-8").trim();
Map<Object, Object> object = GSON.fromJson(result, new TypeToken<Map<Object, Object>>() {
}.getType());
if (object != null) {
String urlString = String.valueOf(object.get("url"));
Matcher m = URL_PATTERN.matcher(urlString);
if (m.matches()) {
return new URL(urlString);
}
for (Map.Entry<String, String> entry : response.uploadFields.entrySet()) {
form.add(entry.getKey(), entry.getValue());
}
form.add("file", content);
throw new IOException("Failed to save paste; instead, got: " + result);
URL url = HttpRequest.url(response.uploadUrl);
// If this succeeds, it will not return any data aside from a 204 status.
HttpRequest.post(url)
.bodyMultipartForm(form)
.execute()
.expectResponseCode(200, 204);
return new URL(response.viewUrl);
}
}
private static final class SignedPasteResponse {
String viewUrl;
String uploadUrl;
Map<String, String> uploadFields;
}
}

View File

@ -65,11 +65,11 @@ public class FileNameDateTimeParser implements SnapshotDateTimeParser {
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})" +
"^(?<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})" +
")?"
+ "(?:" + "[ \\-_:T]"
+ "(?<hour>\\d{1,2})" + SEP + "(?<minute>\\d{1,2})" + SEP + "(?<second>\\d{1,2})"
+ ")?"
);
private FileNameDateTimeParser() {