Move Clipboards to /tmp + Update upstream #3

Zusammengeführt
Lixfel hat 18 Commits von upstream nach main 2022-09-24 19:48:10 +02:00 zusammengeführt
5 geänderte Dateien mit 150 neuen und 49 gelöschten Zeilen
Nur Änderungen aus Commit c0a135acc9 werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -23,7 +23,7 @@ logger.lifecycle("""
******************************************* *******************************************
""") """)
var rootVersion by extra("2.4.5") var rootVersion by extra("2.4.7")
var snapshot by extra("SNAPSHOT") var snapshot by extra("SNAPSHOT")
var revision: String by extra("") var revision: String by extra("")
var buildNumber by extra("") var buildNumber by extra("")

Datei anzeigen

@ -12,7 +12,7 @@ griefprevention = "16.18"
griefdefender = "2.1.0-SNAPSHOT" griefdefender = "2.1.0-SNAPSHOT"
mcore = "7.0.1" mcore = "7.0.1"
residence = "4.5._13.1" residence = "4.5._13.1"
towny = "0.98.3.6" towny = "0.98.3.8"
redprotect = "1.9.6" redprotect = "1.9.6"
# Third party # Third party
@ -38,7 +38,7 @@ text = "3.0.4"
piston = "0.5.7" piston = "0.5.7"
# Tests # Tests
mockito = "4.7.0" mockito = "4.8.0"
# Gradle plugins # Gradle plugins
pluginyml = "0.5.2" pluginyml = "0.5.2"

Datei anzeigen

@ -66,7 +66,7 @@ public class SaturatePattern extends AbstractPattern {
} }
int newColor = TextureUtil.multiplyColor(currentColor, color); int newColor = TextureUtil.multiplyColor(currentColor, color);
BlockType newBlock = util.getNearestBlock(newColor); BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock.equals(type)) { if (newBlock == null || newBlock.equals(type)) {
return false; return false;
} }
return set.setBlock(extent, newBlock.getDefaultState()); return set.setBlock(extent, newBlock.getDefaultState());

Datei anzeigen

@ -5,6 +5,9 @@ import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.extent.filter.block.SingleFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.SingleFilterBlock;
import com.fastasyncworldedit.core.util.image.ImageUtil; import com.fastasyncworldedit.core.util.image.ImageUtil;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
@ -24,19 +27,26 @@ import org.apache.logging.log4j.Logger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.HexFormat;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -321,6 +331,8 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F)}; new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F)};
private static final String VERSION_MANIFEST = "https://piston-meta.mojang.com/mc/game/version_manifest.json";
private final BlockType[] layerBuffer = new BlockType[2]; private final BlockType[] layerBuffer = new BlockType[2];
protected int[] blockColors = new int[BlockTypes.size()]; protected int[] blockColors = new int[BlockTypes.size()];
protected long[] blockDistance = new long[BlockTypes.size()]; protected long[] blockDistance = new long[BlockTypes.size()];
@ -352,17 +364,43 @@ public class TextureUtil implements TextureHolder {
try { try {
LOGGER.info("Downloading asset jar from Mojang, please wait..."); LOGGER.info("Downloading asset jar from Mojang, please wait...");
new File(Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/").mkdirs(); new File(Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/").mkdirs();
try (BufferedInputStream in = new BufferedInputStream(
new URL("https://piston-data.mojang.com/v1/objects/c0898ec7c6a5a2eaa317770203a1554260699994/client.jar") try {
.openStream()); VersionMetadata metadata = getLatestVersion();
FileOutputStream fileOutputStream = new FileOutputStream( LOGGER.info("Latest release version is {}", metadata.version());
Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/1.19.2.jar")) { HashedResource resource = getLatestClientJarUrl(metadata);
byte[] dataBuffer = new byte[1024];
int bytesRead; Path out = Path.of(
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { Fawe.platform().getDirectory().getPath(),
fileOutputStream.write(dataBuffer, 0, bytesRead); Settings.settings().PATHS.TEXTURES,
metadata.version() + ".jar"
);
// Copy resource to local fs
try (final InputStream stream = new URL(resource.resource()).openStream();
final OutputStream writer = Files.newOutputStream(out)) {
stream.transferTo(writer);
} }
LOGGER.info("Asset jar down has been downloaded successfully."); // Validate sha-1 hash
try {
final String sha1 = calculateSha1(out);
if (!sha1.equals(resource.hash())) {
Files.deleteIfExists(out);
LOGGER.error(
"Hash comparison of final file failed (Expected: '{}', Calculated: '{}')",
resource.hash(), sha1
);
LOGGER.error("To prevent possibly malicious intentions, the downloaded file has been removed");
return;
}
} catch (NoSuchAlgorithmException e) {
LOGGER.warn("Couldn't verify integrity of downloaded client file");
LOGGER.warn(
"Please verify that the downloaded files '{}' hash is equal to '{}'",
out, resource.hash()
);
return;
}
LOGGER.info("Asset jar has been downloaded and validated successfully.");
} catch (IOException e) { } catch (IOException e) {
LOGGER.error( LOGGER.error(
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " + "Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " +
@ -388,7 +426,7 @@ public class TextureUtil implements TextureHolder {
HashSet<BlockType> blocks = new HashSet<>(); HashSet<BlockType> blocks = new HashSet<>();
for (int typeId = 0; typeId < ids.length; typeId++) { for (int typeId = 0; typeId < ids.length; typeId++) {
if (ids[typeId]) { if (ids[typeId]) {
blocks.add(BlockTypes.get(typeId)); blocks.add(BlockTypesCache.values[typeId]);
} }
} }
return fromBlocks(blocks); return fromBlocks(blocks);
@ -406,7 +444,7 @@ public class TextureUtil implements TextureHolder {
TextureUtil tu = Fawe.instance().getTextureUtil(); TextureUtil tu = Fawe.instance().getTextureUtil();
for (int typeId : tu.getValidBlockIds()) { for (int typeId : tu.getValidBlockIds()) {
BlockType block = BlockTypes.get(typeId); BlockType block = BlockTypesCache.values[typeId];
extent.init(0, 0, 0, block.getDefaultState().toBaseBlock()); extent.init(0, 0, 0, block.getDefaultState().toBaseBlock());
if (mask.test(extent)) { if (mask.test(extent)) {
blocks.add(block); blocks.add(block);
@ -555,6 +593,66 @@ public class TextureUtil implements TextureHolder {
return totalDistSqr / area; return totalDistSqr / area;
} }
/**
* Retrieves the minecraft versions manifest (containing all released versions) and returns the first {@code release}
* version (latest)
*
* @return {@link VersionMetadata} containing the id (= version) and url to the client manifest itself
* @throws IOException If any http / i/o operation fails.
* @since 2.4.6
*/
private static VersionMetadata getLatestVersion() throws IOException {
try (BufferedInputStream in = new BufferedInputStream(new URL(VERSION_MANIFEST).openStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
final JsonElement element = JsonParser.parseReader(reader);
for (final JsonElement versions : element.getAsJsonObject().getAsJsonArray("versions")) {
JsonObject version = versions.getAsJsonObject();
if (!version.get("type").getAsString().equals("release")) {
continue;
}
final String clientJsonUrl = version.get("url").getAsString();
final String id = version.get("id").getAsString();
return new VersionMetadata(id, clientJsonUrl);
}
}
throw new IOException("Failed to get latest version metadata");
}
/**
* Retrieves the url to the client.jar based on the previously retrieved {@link VersionMetadata}
*
* @param metadata The version metadata containing the url to the client.jar
* @return The full url to the client.jar including the expected file hash for validation purposes
* @throws IOException If any http / i/o operation fails.
* @since 2.4.6
*/
private static HashedResource getLatestClientJarUrl(VersionMetadata metadata) throws IOException {
try (BufferedInputStream in = new BufferedInputStream(new URL(metadata.url()).openStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
final JsonObject object = JsonParser.parseReader(reader).getAsJsonObject();
final JsonObject client = object.getAsJsonObject("downloads").getAsJsonObject("client");
return new HashedResource(client.get("url").getAsString(), client.get("sha1").getAsString());
}
}
/**
* Calculates the sha-1 hash based on the content of the provided file.
*
* @param path The path of the resource to generate the sha-1 hash for
* @return The hash of the file contents
* @throws NoSuchAlgorithmException If the SHA-1 algorithm could not be resolved
* @throws IOException If any I/O operation failed
* @since 2.4.6
*/
private static String calculateSha1(Path path) throws NoSuchAlgorithmException, IOException {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
try (final BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(path));
final DigestOutputStream digestOutputStream = new DigestOutputStream(OutputStream.nullOutputStream(), digest)) {
stream.transferTo(digestOutputStream);
return HexFormat.of().formatHex(digest.digest());
}
}
@Override @Override
public TextureUtil getTextureUtil() { public TextureUtil getTextureUtil() {
return this; return this;
@ -586,7 +684,7 @@ public class TextureUtil implements TextureHolder {
if (min == Long.MAX_VALUE) { if (min == Long.MAX_VALUE) {
return null; return null;
} }
return BlockTypes.get(closest); return BlockTypesCache.values[closest];
} }
/** /**
@ -615,7 +713,7 @@ public class TextureUtil implements TextureHolder {
if (min == Long.MAX_VALUE) { if (min == Long.MAX_VALUE) {
return null; return null;
} }
return BlockTypes.get(closest); return BlockTypesCache.values[closest];
} }
/** /**
@ -638,8 +736,8 @@ public class TextureUtil implements TextureHolder {
} }
} }
} }
layerBuffer[0] = BlockTypes.get(closest[0]); layerBuffer[0] = BlockTypesCache.values[closest[0]];
layerBuffer[1] = BlockTypes.get(closest[1]); layerBuffer[1] = BlockTypesCache.values[closest[1]];
return layerBuffer; return layerBuffer;
} }
@ -806,36 +904,25 @@ public class TextureUtil implements TextureHolder {
if (folder.exists()) { if (folder.exists()) {
// Get all the jar files // Get all the jar files
File[] files = folder.listFiles((dir, name) -> name.endsWith(".jar")); File[] files = folder.listFiles((dir, name) -> name.endsWith(".jar"));
if (files.length == 0) { // We expect the latest version to be already there, due to the download in TextureUtil#<init>
new File(Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/") if (files == null || files.length == 0) {
.mkdirs(); LOGGER.error("No version jar found in {}. Delete the named folder and restart your server to download the " +
try (BufferedInputStream in = new BufferedInputStream( "missing assets.", folder.getPath());
new URL("https://piston-data.mojang.com/v1/objects/c0898ec7c6a5a2eaa317770203a1554260699994/client.jar") LOGGER.error(
.openStream()); "If no asset jar is created, please do so manually by creating a `FastAsyncWorldEdit/textures` " +
FileOutputStream fileOutputStream = new FileOutputStream( "folder with a `.minecraft/versions` jar or mods in it.");
Fawe.platform().getDirectory() + "/" + Settings.settings().PATHS.TEXTURES + "/1.19.2.jar")) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
fileOutputStream.close();
files = folder.listFiles((dir, name) -> name.endsWith(".jar"));
} catch (IOException e) {
LOGGER.error(
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " +
"folder with a `.minecraft/versions` jar or mods in it.");
LOGGER.error("If the file exists, please make sure the server has read access to the directory.");
}
} }
if ((files.length > 0)) { if (files != null && (files.length > 0)) {
for (File file : files) { for (File file : files) {
ZipFile zipFile = new ZipFile(file); ZipFile zipFile = new ZipFile(file);
// Get all the groups in the current jar // Get all the groups in the current jar
// The vanilla textures are in `assets/minecraft` // The vanilla textures are in `assets/minecraft`
// A jar may contain textures for multiple mods // A jar may contain textures for multiple mods
String modelsDir = "assets/%1$s/models/block/%2$s.json"; String[] modelsDir = {
"assets/%1$s/models/block/%2$s.json",
"assets/%1$s/models/item/%2$s.json"
};
String texturesDir = "assets/%1$s/textures/%2$s.png"; String texturesDir = "assets/%1$s/textures/%2$s.png";
Type typeToken = new TypeToken<Map<String, Object>>() { Type typeToken = new TypeToken<Map<String, Object>>() {
@ -859,10 +946,15 @@ public class TextureUtil implements TextureHolder {
String nameSpace = split.length == 1 ? "" : split[0]; String nameSpace = split.length == 1 ? "" : split[0];
// Read models // Read models
String modelFileName = String.format(modelsDir, nameSpace, name); ZipEntry entry = null;
ZipEntry entry = getEntry(zipFile, modelFileName); for (final String dir : modelsDir) {
String modelFileName = String.format(dir, nameSpace, name);
if ((entry = getEntry(zipFile, modelFileName)) != null) {
break;
}
}
if (entry == null) { if (entry == null) {
LOGGER.error("Cannot find {} in {}", modelFileName, file); LOGGER.error("Cannot find {} in {}", modelsDir, file);
continue; continue;
} }
@ -1080,7 +1172,8 @@ public class TextureUtil implements TextureHolder {
if (min == Long.MAX_VALUE) { if (min == Long.MAX_VALUE) {
return null; return null;
} }
return BlockTypes.get(closest);
return BlockTypesCache.values[closest];
} }
private String getFileName(String path) { private String getFileName(String path) {
@ -1130,4 +1223,12 @@ public class TextureUtil implements TextureHolder {
} }
private record VersionMetadata(String version, String url) {
}
private record HashedResource(String resource, String hash) {
}
} }

Datei anzeigen

@ -28,7 +28,7 @@ dependencies {
}) })
api("org.apache.logging.log4j:log4j-api") api("org.apache.logging.log4j:log4j-api")
api("org.bstats:bstats-sponge:1.7") api("org.bstats:bstats-sponge:1.7")
testImplementation("org.mockito:mockito-core:4.7.0") testImplementation("org.mockito:mockito-core:4.8.0")
} }
<<<<<<< HEAD <<<<<<< HEAD