Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f64df7be0 | |||
| 23a1f0b025 | |||
| 4a72e02550 | |||
| 4eb20d5ce8 | |||
| 3ad68aaf42 | |||
| 2a9a03771e | |||
| 8f7823a4d2 | |||
| cc4b965966 | |||
| a6418de927 | |||
| 5303415d05 | |||
| 836515934f | |||
| 228dc46d6b | |||
| a91f9670dc | |||
| 81313252f2 | |||
| f65d411978 | |||
| 8c8a5ffeaf | |||
| 68793fbe8d | |||
| d8401a8f49 | |||
| 07ff00f7c9 | |||
| fadaff1113 | |||
| ff6bf7b4c9 | |||
| 082b1224a8 | |||
| bc475373fc | |||
| 498e958eca | |||
| 82e0cfe0b4 | |||
| 31d89e3349 | |||
| a3775c1f88 | |||
| 834269da67 | |||
| a9bebf03d5 | |||
| 939f6304bf | |||
| a0b5cc7a5c |
@@ -26,6 +26,10 @@ Merged/
|
||||
# Folder created by the buildAll scripts
|
||||
buildAllJars/
|
||||
|
||||
relocate_natives/.venv/
|
||||
relocate_natives/apple-codesign/
|
||||
relocate_natives/cache/
|
||||
|
||||
# file from notepad++
|
||||
*.bak
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ variables:
|
||||
# These can be extended so code is a bit less duplicated
|
||||
.build_java:
|
||||
#image: eclipse-temurin:17
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install python3 python3-pip python-is-python3 python3-venv -y --no-install-recommends
|
||||
cache:
|
||||
key: "gradleCache_$CI_JOB_NAME_SLUG"
|
||||
policy: pull-push
|
||||
|
||||
@@ -6,13 +6,13 @@ Or click the checkbox once the issue has been created.
|
||||
-->
|
||||
|
||||
1. [ ] Check the FAQ to see if your issue has already been reported and has a solution:
|
||||
[Problems-and-solutions](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
[Problems-and-solutions](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
|
||||
2. [ ] Make sure you are not using any mods on the incompatible list:
|
||||
[Mod support FAQ](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
[Mod support FAQ](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
|
||||
3. [ ] Check the existing issues to verify that your bug hasn't already been submitted:
|
||||
[Issues](https://gitlab.com/jeseibel/distant-horizons/-/issues/)
|
||||
[Issues](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues)
|
||||
|
||||
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- [ ] Check the existing [feature requests](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=Feature) to verify that your feature hasn't already been suggested.
|
||||
- [ ] Check the existing [feature requests](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues?sort=updated_desc&state=opened&label_name%5B%5D=Feature) to verify that your feature hasn't already been suggested.
|
||||
|
||||
1. **Describe the feature**:
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
1. Check the existing [improvement requests](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Improvement) to verify that your improvement hasn't already been suggested.
|
||||
1. Check the existing [improvement requests](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues?sort=updated_desc&state=all&label_name%5B%5D=Improvement) to verify that your improvement hasn't already been suggested.
|
||||
|
||||
2. **Describe the improvement**:
|
||||
|
||||
+92
-20
@@ -1,3 +1,11 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
||||
import org.apache.tools.zip.ZipEntry
|
||||
|
||||
import javax.annotation.Nonnull
|
||||
import org.apache.tools.zip.ZipOutputStream
|
||||
|
||||
|
||||
plugins {
|
||||
id "java"
|
||||
|
||||
@@ -96,6 +104,77 @@ forgix {
|
||||
removeDuplicate "com.seibel.distanthorizons"
|
||||
}
|
||||
|
||||
|
||||
class NativeTransformer implements Transformer {
|
||||
private boolean enabled = false
|
||||
private final HashMap<String, String> replacements = new HashMap()
|
||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||
private var nativeRelocator
|
||||
|
||||
|
||||
NativeTransformer() {
|
||||
try {
|
||||
int exitCode = Runtime.getRuntime().exec(new String[]{"python", "--version"}).waitFor();
|
||||
if (exitCode == 0) {
|
||||
enabled = true
|
||||
}
|
||||
} catch (IOException e) {
|
||||
println(e)
|
||||
}
|
||||
}
|
||||
|
||||
void relocateNative(String target, String replacement) {
|
||||
if (replacement.length() > target.length()) {
|
||||
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
||||
}
|
||||
|
||||
replacements.put(target, replacement)
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||
return enabled && replacements.keySet().stream().anyMatch {
|
||||
element.name.startsWith(it as String)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void transform(@Nonnull TransformerContext context) {
|
||||
println("Transforming $context.path...")
|
||||
byte[] content = context.is.readAllBytes()
|
||||
|
||||
if (nativeRelocator == null) {
|
||||
nativeRelocator = new NativeRelocator()
|
||||
}
|
||||
|
||||
try {
|
||||
Map.Entry<String, String> pathReplacement = replacements.entrySet().stream().filter {
|
||||
context.path.startsWith(it.key as String)
|
||||
}.findFirst().orElseThrow()
|
||||
|
||||
String path = context.path.replace(pathReplacement.key as String, pathReplacement.value as String)
|
||||
content = nativeRelocator.processBinary(path, content, replacements)
|
||||
|
||||
rewrittenFiles.put(path, content)
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new GradleException("Failed to relocate", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasTransformedResource() { return !rewrittenFiles.isEmpty() }
|
||||
|
||||
@Override
|
||||
void modifyOutputStream(@Nonnull ZipOutputStream os, boolean preserveFileTimestamps) {
|
||||
for (Map.Entry<String, byte[]> rewrittenFile : rewrittenFiles.entrySet()) {
|
||||
os.putNextEntry(new ZipEntry(rewrittenFile.key))
|
||||
os.write(rewrittenFile.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subprojects { p ->
|
||||
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")"
|
||||
// Useful later on so we dont have duplicated code
|
||||
@@ -306,26 +385,19 @@ subprojects { p ->
|
||||
|
||||
// Logging
|
||||
relocate "org.slf4j", "${librariesLocation}.slf4j"
|
||||
|
||||
// // Sqlite Database
|
||||
// // James can't determine how to relocate the library correctly so this is commented out
|
||||
// relocate ("org.sqlite", "${librariesLocation}.sqlite") {
|
||||
// exclude("org/sqlite/core/NativeDB/**")
|
||||
//
|
||||
// exclude("org/sqlite/native/FreeBSD/**")
|
||||
// exclude("org/sqlite/native/Linux-Android/**")
|
||||
// exclude("org/sqlite/native/Linux-Musl/**")
|
||||
// exclude("org/sqlite/native/Linux/arm/**")
|
||||
// exclude("org/sqlite/native/Linux/aarch64/**")
|
||||
// exclude("org/sqlite/native/Linux/armv6/**")
|
||||
// exclude("org/sqlite/native/Linux/x86/**")
|
||||
// exclude("org/sqlite/native/Linux/armv7/**")
|
||||
// exclude("org/sqlite/native/Linux/ppc64/**")
|
||||
// exclude("org/sqlite/native/Linux/riscv64/**")
|
||||
// exclude("org/sqlite/native/Windows/armv7/**")
|
||||
// exclude("org/sqlite/native/Windows/aarch64/**")
|
||||
// exclude("org/sqlite/native/Windows/armv7/**")
|
||||
// }
|
||||
|
||||
// Sqlite Database
|
||||
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
||||
relocate "org.xerial", "dh_sqlite.org.xerial"
|
||||
relocate "org.sqlite", "dh_sqlite", {
|
||||
exclude "org/sqlite/native/**"
|
||||
}
|
||||
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||
|
||||
transform(NativeTransformer) {
|
||||
relocateNative "org/sqlite", "dh_sqlite"
|
||||
relocateNative "org_sqlite", "dh_1sqlite"
|
||||
}
|
||||
|
||||
|
||||
// JOML
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
class NativeRelocator
|
||||
{
|
||||
private static final Path rootDirectory = Path.of(System.getProperty("user.dir"), "relocate_natives");
|
||||
private static final Path cacheRoot = rootDirectory.resolve("cache");
|
||||
|
||||
|
||||
NativeRelocator() throws Exception
|
||||
{
|
||||
if (rootDirectory.resolve(".venv").toFile().exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.directory(rootDirectory.toFile());
|
||||
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.contains("win"))
|
||||
{
|
||||
processBuilder.command("powershell", "./prepare.ps1");
|
||||
}
|
||||
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
||||
{
|
||||
processBuilder.command("./prepare.sh");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Unsupported operating system: " + os);
|
||||
}
|
||||
|
||||
Process process = processBuilder.start();
|
||||
CompletableFuture<Void> outputFuture = readOutputStreams(process);
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
outputFuture.get();
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
throw new Exception("Prepare failed: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static CompletableFuture<Void> readOutputStreams(Process process)
|
||||
{
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try
|
||||
{
|
||||
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
|
||||
{
|
||||
if (process.getInputStream().available() > 0)
|
||||
{
|
||||
byte[] data = new byte[process.getInputStream().available()];
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
process.getInputStream().read(data);
|
||||
System.out.write(data);
|
||||
}
|
||||
if (process.getErrorStream().available() > 0)
|
||||
{
|
||||
byte[] data = new byte[process.getErrorStream().available()];
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
process.getErrorStream().read(data);
|
||||
System.err.write(data);
|
||||
}
|
||||
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
catch (Throwable ignored)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void replaceInNullTerminatedStrings(byte[] byteArray, String target, String replacement)
|
||||
{
|
||||
if (target.length() < replacement.length())
|
||||
{
|
||||
throw new IllegalArgumentException("Replacement must be the same length or shorter than the target.");
|
||||
}
|
||||
|
||||
byte[] targetBytes = target.getBytes(StandardCharsets.US_ASCII);
|
||||
byte[] replacementBytes = replacement.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
byte nullByte = 0;
|
||||
|
||||
for (int endPos = 0; endPos < byteArray.length - targetBytes.length - 1; endPos++)
|
||||
{
|
||||
int startPos = endPos;
|
||||
int targetPos = 0;
|
||||
while (targetPos < targetBytes.length && byteArray[endPos] == targetBytes[targetPos])
|
||||
{
|
||||
targetPos++;
|
||||
endPos++;
|
||||
}
|
||||
|
||||
if (targetPos == targetBytes.length)
|
||||
{
|
||||
System.arraycopy(replacementBytes, 0, byteArray, startPos, replacementBytes.length);
|
||||
|
||||
startPos = startPos + replacementBytes.length;
|
||||
while (byteArray[endPos] != nullByte)
|
||||
{
|
||||
byteArray[startPos] = byteArray[endPos];
|
||||
endPos++;
|
||||
startPos++;
|
||||
}
|
||||
byteArray[startPos] = nullByte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] fixModifiedBinary(Path outputFilePath, byte[] content) throws Exception
|
||||
{
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.directory(rootDirectory.toFile());
|
||||
|
||||
processBuilder.command(
|
||||
rootDirectory.resolve(".venv/Scripts").toFile().exists()
|
||||
? rootDirectory.resolve(".venv/Scripts/python.exe").toString()
|
||||
: rootDirectory.resolve(".venv/bin/python").toString(),
|
||||
"./fix_modified_binary.py",
|
||||
outputFilePath.toString()
|
||||
);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
CompletableFuture<Void> outputFuture = readOutputStreams(process);
|
||||
|
||||
process.getOutputStream().write(content);
|
||||
process.getOutputStream().close();
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
outputFuture.get();
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
throw new Exception("Process failed: " + exitCode);
|
||||
}
|
||||
|
||||
return Files.readAllBytes(outputFilePath);
|
||||
}
|
||||
|
||||
public byte[] processBinary(String outputPath, byte[] content, Map<String, String> replacements) throws Exception
|
||||
{
|
||||
Path outputFilePath = cacheRoot.resolve(outputPath);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
outputFilePath.getParent().toFile().mkdirs();
|
||||
|
||||
if (outputFilePath.toFile().exists())
|
||||
{
|
||||
return Files.readAllBytes(outputFilePath);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
||||
{
|
||||
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
|
||||
}
|
||||
|
||||
return this.fixModifiedBinary(outputFilePath, content);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
@@ -40,6 +41,7 @@ public class ConfigCommand extends AbstractCommand
|
||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
||||
HashSet<String> addedCommands = new HashSet<>();
|
||||
|
||||
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
||||
{
|
||||
@@ -56,6 +58,11 @@ public class ConfigCommand extends AbstractCommand
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addedCommands.add(configEntry.getChatCommandName()))
|
||||
{
|
||||
throw new IllegalStateException("Duplicate command name: " + configEntry.getChatCommandName());
|
||||
}
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getChatCommandName())
|
||||
.executes(commandContext -> this.sendSuccessResponse(commandContext,
|
||||
"\n" +
|
||||
|
||||
+5
-5
@@ -84,7 +84,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||
|
||||
/** keep track of broken blocks so we don't log every time */
|
||||
private static final HashSet<ResourceLocation> BrokenResourceLocations = new HashSet<>();
|
||||
private static final HashSet<ResourceLocation> BROKEN_RESOURCE_LOCATIONS = new HashSet<>();
|
||||
|
||||
|
||||
|
||||
@@ -596,9 +596,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
if (block == null)
|
||||
{
|
||||
// shouldn't normally happen, but here to make the compiler happy
|
||||
if (!BrokenResourceLocations.contains(resourceLocation))
|
||||
if (!BROKEN_RESOURCE_LOCATIONS.contains(resourceLocation))
|
||||
{
|
||||
BrokenResourceLocations.add(resourceLocation);
|
||||
BROKEN_RESOURCE_LOCATIONS.add(resourceLocation);
|
||||
LOGGER.warn("Unable to find BlockState with the resourceLocation [" + resourceLocation + "] and properties: [" + blockStatePropertiesString + "]. Air will be used instead, some data may be lost.");
|
||||
}
|
||||
|
||||
@@ -628,9 +628,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
if (blockStatePropertiesString != null)
|
||||
{
|
||||
// we should have found a blockstate, but didn't
|
||||
if (!BrokenResourceLocations.contains(resourceLocation))
|
||||
if (!BROKEN_RESOURCE_LOCATIONS.contains(resourceLocation))
|
||||
{
|
||||
BrokenResourceLocations.add(resourceLocation);
|
||||
BROKEN_RESOURCE_LOCATIONS.add(resourceLocation);
|
||||
LOGGER.warn("Unable to find BlockState for Block [" + resourceLocation + "] with properties: [" + blockStatePropertiesString + "]. Using the default block state.");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -424,7 +424,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
|
||||
ChunkAccess centerChunk = regionChunks.stream()
|
||||
.filter((chunk) -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ)
|
||||
.findFirst().get();
|
||||
.findFirst()
|
||||
.orElseGet(() -> regionChunks.getFirst());
|
||||
|
||||
genEvent.refreshTimeout();
|
||||
DhLitWorldGenRegion region = new DhLitWorldGenRegion(
|
||||
|
||||
+62
-11
@@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
import it.unimi.dsi.fastutil.shorts.ShortList;
|
||||
@@ -103,6 +104,8 @@ public class ChunkLoader
|
||||
|
||||
private static boolean lightingSectionErrorLogged = false;
|
||||
|
||||
private static final ConcurrentHashMap<String, Object> LOGGED_ERROR_MESSAGE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
@@ -285,17 +288,18 @@ public class ChunkLoader
|
||||
#endif
|
||||
|
||||
blockStateContainer = tagSection.contains("block_states", 10)
|
||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states"))
|
||||
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||
#if MC_VER < MC_1_20_6
|
||||
.getOrThrow(false, LOGGER::error)
|
||||
.getOrThrow(false, (message) -> logWarningOnce(message))
|
||||
#else
|
||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||
.getOrThrow((message) -> logErrorAndReturnException(message))
|
||||
#endif
|
||||
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||
|
||||
#if MC_VER < MC_1_18_2
|
||||
biomeContainer = tagSection.contains("biomes", 10)
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message))
|
||||
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
#else
|
||||
|
||||
@@ -303,11 +307,12 @@ public class ChunkLoader
|
||||
if (tagSection.contains("biomes", 10))
|
||||
{
|
||||
biomeContainer =
|
||||
biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||
biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes"))
|
||||
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||
#if MC_VER < MC_1_20_6
|
||||
.getOrThrow(false, LOGGER::error);
|
||||
.getOrThrow(false, (message) -> logWarningOnce(message));
|
||||
#else
|
||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null));
|
||||
.getOrThrow((message) -> logErrorAndReturnException(message));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -387,9 +392,9 @@ public class ChunkLoader
|
||||
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
||||
|
||||
#if MC_VER < MC_1_21_3
|
||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logWarningOnce(message)).orElse(null);
|
||||
#else
|
||||
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null));
|
||||
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logWarningOnce(message)).orElse(null));
|
||||
#endif
|
||||
}
|
||||
return blendingData;
|
||||
@@ -515,15 +520,61 @@ public class ChunkLoader
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// logging //
|
||||
//=========//
|
||||
|
||||
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize blocks for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize blocks for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+newMessage+"]. " +
|
||||
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
|
||||
return newMessage;
|
||||
});
|
||||
}
|
||||
private static void logBiomeDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize biomes for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize biomes for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+newMessage+"]. " +
|
||||
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
|
||||
return newMessage;
|
||||
});
|
||||
}
|
||||
|
||||
private static void logWarningOnce(String message) { logWarningOnce(message, null); }
|
||||
private static void logWarningOnce(String message, Exception e)
|
||||
{
|
||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
||||
{
|
||||
LOGGER.warn("Parsing error: ["+newMessage+"]. " +
|
||||
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.",
|
||||
e);
|
||||
|
||||
return newMessage;
|
||||
});
|
||||
}
|
||||
|
||||
private static RuntimeException logErrorAndReturnException(String message)
|
||||
{
|
||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
||||
{
|
||||
LOGGER.warn("Parsing error: ["+newMessage+"]. " +
|
||||
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
|
||||
return newMessage;
|
||||
});
|
||||
|
||||
// Currently we want to ignore these errors, if returning null is a problem, we can change this later
|
||||
return null; //new RuntimeException(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
|
||||
+1
-1
Submodule coreSubProjects updated: 863bfbaff5...736df9f848
+2
-2
@@ -46,8 +46,8 @@ public class TestGenericWorldGenerator implements IDhApiWorldGenerator
|
||||
public byte getSmallestDataDetailLevel() { return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
||||
@Override
|
||||
public byte getLargestDataDetailLevel()
|
||||
//{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel + 12); }
|
||||
{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
||||
{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel + 12); }
|
||||
//{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import os
|
||||
import platform
|
||||
import requests
|
||||
import tarfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_platform_specific_filename():
|
||||
system = platform.system()
|
||||
machine = platform.machine()
|
||||
|
||||
if system == "Darwin":
|
||||
if machine == "arm64":
|
||||
return "apple-codesign-*-aarch64-apple-darwin.tar.gz"
|
||||
else:
|
||||
return "apple-codesign-*-x86_64-apple-darwin.tar.gz"
|
||||
elif system == "Linux":
|
||||
if machine == "aarch64":
|
||||
return "apple-codesign-*-aarch64-unknown-linux-musl.tar.gz"
|
||||
else:
|
||||
return "apple-codesign-*-x86_64-unknown-linux-musl.tar.gz"
|
||||
elif system == "Windows":
|
||||
if machine.endswith("64"):
|
||||
return "apple-codesign-*-x86_64-pc-windows-msvc.zip"
|
||||
else:
|
||||
return "apple-codesign-*-i686-pc-windows-msvc.zip"
|
||||
else:
|
||||
raise Exception(f"Unsupported platform: {system} {machine}")
|
||||
|
||||
|
||||
def download_and_unpack():
|
||||
dest_dir = Path("./apple-codesign")
|
||||
|
||||
repo_url = "https://api.github.com/repos/indygreg/apple-platform-rs/releases/latest"
|
||||
dest_dir.mkdir(exist_ok=True)
|
||||
|
||||
# Fetch the latest release info from GitHub
|
||||
print("Fetching latest release information...")
|
||||
response = requests.get(repo_url)
|
||||
response.raise_for_status()
|
||||
release_data = response.json()
|
||||
|
||||
# Ensure release data has assets
|
||||
if "assets" not in release_data:
|
||||
raise Exception("Release data does not contain assets.")
|
||||
|
||||
# Determine the correct asset
|
||||
platform_filename = get_platform_specific_filename()
|
||||
asset = next((asset for asset in release_data["assets"] if asset["name"].startswith("apple-codesign-") and asset["name"].endswith(platform_filename.split("*")[-1])), None)
|
||||
|
||||
if not asset:
|
||||
raise Exception(f"No matching asset found for platform: {platform_filename}")
|
||||
|
||||
# Download the archive
|
||||
print(f"Downloading {asset['name']}...")
|
||||
download_url = asset["browser_download_url"]
|
||||
archive_path = dest_dir / asset["name"]
|
||||
|
||||
with requests.get(download_url, stream=True) as r:
|
||||
r.raise_for_status()
|
||||
with open(archive_path, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
print(f"Downloaded to {archive_path}")
|
||||
|
||||
# Extract the archive
|
||||
print("Extracting archive...")
|
||||
temp_extract_dir = dest_dir / "temp_extract"
|
||||
temp_extract_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if archive_path.suffix == ".zip":
|
||||
with zipfile.ZipFile(archive_path, "r") as zip_ref:
|
||||
zip_ref.extractall(temp_extract_dir)
|
||||
elif archive_path.suffixes[-2:] == [".tar", ".gz"]:
|
||||
with tarfile.open(archive_path, "r:gz") as tar_ref:
|
||||
tar_ref.extractall(temp_extract_dir)
|
||||
else:
|
||||
raise Exception(f"Unknown archive format: {archive_path}")
|
||||
|
||||
# Move contents of the root directory inside the archive to dest_dir
|
||||
root_dir = next(temp_extract_dir.iterdir()) # Assuming only one root directory
|
||||
for item in root_dir.iterdir():
|
||||
target_path = dest_dir / item.name
|
||||
if target_path.exists():
|
||||
if target_path.is_dir():
|
||||
os.rmdir(target_path)
|
||||
else:
|
||||
os.remove(target_path)
|
||||
item.rename(target_path)
|
||||
|
||||
# Clean up temporary directories
|
||||
for item in temp_extract_dir.iterdir():
|
||||
if item.is_dir():
|
||||
os.rmdir(item)
|
||||
temp_extract_dir.rmdir()
|
||||
|
||||
print(f"Extracted to {dest_dir}")
|
||||
|
||||
# Clean up the archive
|
||||
os.remove(archive_path)
|
||||
print(f"Removed archive {archive_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
download_and_unpack()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
@@ -0,0 +1,26 @@
|
||||
import sys
|
||||
import lief
|
||||
import subprocess
|
||||
import download_codesign
|
||||
from pathlib import Path
|
||||
|
||||
output_path = sys.argv[1]
|
||||
binary = lief.parse(sys.stdin.buffer.read())
|
||||
|
||||
if binary is None:
|
||||
exit(1)
|
||||
|
||||
if isinstance(binary, lief.MachO.Binary):
|
||||
binary.remove_signature()
|
||||
|
||||
binary.write(output_path)
|
||||
|
||||
if isinstance(binary, lief.MachO.Binary):
|
||||
print(f"Signing {output_path}...")
|
||||
|
||||
if not Path("./apple-codesign/COPYING").exists():
|
||||
download_codesign.download_and_unpack()
|
||||
|
||||
sign_process = subprocess.Popen(["./apple-codesign/rcodesign", "sign", output_path], shell=False,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
sign_process.wait()
|
||||
@@ -0,0 +1,5 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
python -m venv .venv
|
||||
.\.venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
python -m venv .venv
|
||||
. ./.venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
Binary file not shown.
Reference in New Issue
Block a user