mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-01 02:46:41 +00:00
Added BiomeMask.java and updated minor parts of miscellaneous files
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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() {
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
Reference in New Issue
Block a user