Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3faf25636d | |||
| ab3bfbefb4 | |||
| 890e802de4 | |||
| c13bc0cd6e | |||
| 7143b7de08 | |||
| d136d782f5 | |||
| 29a160316c | |||
| 1f6f64d322 | |||
| 37c0af529d | |||
| 1341ea3f3d | |||
| c0bb120669 | |||
| f8887e403f | |||
| 949ee423c8 | |||
| b19ed3f30c | |||
| 2d085e1074 | |||
| 6ba0490cf7 | |||
| b6a0878241 | |||
| 50f5371084 | |||
| df74b8d243 | |||
| fce2868c62 | |||
| a36cd0763b | |||
| 0fba015f54 | |||
| f251c90472 | |||
| 492a051a3b | |||
| 0aa4743c1b | |||
| 85f16944b2 | |||
| dddb0be2ac | |||
| 4a3effa2f5 | |||
| a0a9151bfd | |||
| aa3d15f38f | |||
| adcb2a3a05 | |||
| 78f2cb24cc | |||
| 67945509ed | |||
| c653e526a5 | |||
| 49b50c4c88 | |||
| 7449f46c5e | |||
| 069fc39aad | |||
| 4979ccf3e2 | |||
| dd7f9c20b6 | |||
| e96f9de1f0 | |||
| c902e1957f | |||
| d40afb7a2a | |||
| 01474d72e3 | |||
| 7c5af1836b | |||
| a9bf6ae7e4 | |||
| aef3162246 | |||
| 97ce869076 | |||
| 91b3c83ffd | |||
| 1522df19cb | |||
| 3845564128 | |||
| 23ef7cf27a | |||
| bec28a5694 | |||
| 8f20f103ad | |||
| 246e77cc56 | |||
| 87fa29c77a | |||
| 5010256ce6 | |||
| a66ad19343 | |||
| 913a458a1a | |||
| 093d3a801e | |||
| 61ccf7bf60 | |||
| f948072253 | |||
| b748f27a1c | |||
| 4dd4bb9ef0 | |||
| 5051bde3b0 | |||
| 42cf639acc | |||
| 9e6953a596 | |||
| 7f4f8a40eb | |||
| 89ca535a6f | |||
| 145182502e | |||
| d61dfc9e03 | |||
| 611d7d87ae | |||
| 2f6a2d99ab | |||
| d88ca0c98d | |||
| 521bcdcc0f | |||
| e070bf4244 | |||
| 8287192cd0 | |||
| d40f4dfe19 | |||
| 595cdf011a | |||
| 96f2f8c3b2 | |||
| c883ded7c4 |
@@ -27,6 +27,7 @@ Merged/
|
|||||||
buildAllJars/
|
buildAllJars/
|
||||||
|
|
||||||
relocate_natives/.venv/
|
relocate_natives/.venv/
|
||||||
|
relocate_natives/__pycache__/
|
||||||
relocate_natives/apple-codesign/
|
relocate_natives/apple-codesign/
|
||||||
relocate_natives/cache/
|
relocate_natives/cache/
|
||||||
|
|
||||||
|
|||||||
+11
-24
@@ -44,28 +44,15 @@ build:
|
|||||||
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
|
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./Merged/* . || true
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- Merged/*.jar
|
- ./*.jar
|
||||||
- quilt/build/libs/*.jar
|
|
||||||
- fabric/build/libs/*.jar
|
|
||||||
- forge/build/libs/*.jar
|
|
||||||
- neoforge/build/libs/*.jar
|
|
||||||
exclude:
|
exclude:
|
||||||
# TODO: There is a lot of duplicate stuff here, try to maybe make it smaller
|
- ./*-all.jar
|
||||||
- fabric/build/libs/*-all.jar
|
- ./*-dev.jar
|
||||||
- fabric/build/libs/*-dev.jar
|
- ./*-sources.jar
|
||||||
- fabric/build/libs/*-sources.jar
|
|
||||||
- quilt/build/libs/*-all.jar
|
|
||||||
- quilt/build/libs/*-dev.jar
|
|
||||||
- quilt/build/libs/*-sources.jar
|
|
||||||
- forge/build/libs/*-all.jar
|
|
||||||
- forge/build/libs/*-dev.jar
|
|
||||||
- forge/build/libs/*-sources.jar
|
|
||||||
- neoforge/build/libs/*-all.jar
|
|
||||||
- neoforge/build/libs/*-dev.jar
|
|
||||||
- neoforge/build/libs/*-sources.jar
|
|
||||||
expire_in: 14 days
|
expire_in: 14 days
|
||||||
when: always
|
when: always
|
||||||
extends: .build_java
|
extends: .build_java
|
||||||
@@ -80,15 +67,15 @@ api:
|
|||||||
# this also runs unit tests
|
# this also runs unit tests
|
||||||
- ./gradlew api:build --gradle-user-home cache/;
|
- ./gradlew api:build --gradle-user-home cache/;
|
||||||
- ./gradlew api:addSourcesToCompiledJar --gradle-user-home cache/;
|
- ./gradlew api:addSourcesToCompiledJar --gradle-user-home cache/;
|
||||||
|
- cp ./coreSubProjects/api/build/libs/merged/* .
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "Api_NightlyBuild-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "NightlyBuild_Api-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- coreSubProjects/api/build/libs/merged/*.jar
|
- ./*.jar
|
||||||
# can be uncommented if we don't want a jar with the source code
|
|
||||||
# - coreSubProjects/api/build/libs/*.jar
|
|
||||||
exclude:
|
exclude:
|
||||||
- coreSubProjects/api/build/libs/merged/*-all.jar
|
- ./*-all.jar
|
||||||
- coreSubProjects/api/build/libs/merged/*-sources.jar
|
- ./*-dev.jar
|
||||||
|
- ./*-sources.jar
|
||||||
expire_in: 1 day
|
expire_in: 1 day
|
||||||
when: always
|
when: always
|
||||||
extends: .build_java
|
extends: .build_java
|
||||||
|
|||||||
+19
-9
@@ -78,7 +78,7 @@ forgix {
|
|||||||
String loaderHyphenSeparatedList = ((String)gradle.builds_for).replaceAll(",", "-");
|
String loaderHyphenSeparatedList = ((String)gradle.builds_for).replaceAll(",", "-");
|
||||||
|
|
||||||
group = "com.seibel.distanthorizons"
|
group = "com.seibel.distanthorizons"
|
||||||
mergedJarName = "DistantHorizons-${rootProject.versionStr}-${loaderHyphenSeparatedList}.jar"
|
mergedJarName = "DistantHorizons-${loaderHyphenSeparatedList}-${rootProject.versionStr}.jar"
|
||||||
|
|
||||||
if (findProject(":forge"))
|
if (findProject(":forge"))
|
||||||
forge {
|
forge {
|
||||||
@@ -111,10 +111,11 @@ class NativeTransformer implements Transformer {
|
|||||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||||
private var nativeRelocator
|
private var nativeRelocator
|
||||||
|
|
||||||
|
public File rootDir
|
||||||
|
|
||||||
NativeTransformer() {
|
NativeTransformer() {
|
||||||
try {
|
try {
|
||||||
int exitCode = Runtime.getRuntime().exec(new String[]{"python", "--version"}).waitFor();
|
int exitCode = Runtime.getRuntime().exec(new String[]{"python", "--version"}).waitFor()
|
||||||
if (exitCode == 0) {
|
if (exitCode == 0) {
|
||||||
enabled = true
|
enabled = true
|
||||||
}
|
}
|
||||||
@@ -131,6 +132,11 @@ class NativeTransformer implements Transformer {
|
|||||||
replacements.put(target, replacement)
|
replacements.put(target, replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void before(Closure closure) {
|
||||||
|
if (enabled)
|
||||||
|
closure.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||||
@@ -145,7 +151,7 @@ class NativeTransformer implements Transformer {
|
|||||||
byte[] content = context.is.readAllBytes()
|
byte[] content = context.is.readAllBytes()
|
||||||
|
|
||||||
if (nativeRelocator == null) {
|
if (nativeRelocator == null) {
|
||||||
nativeRelocator = new NativeRelocator()
|
nativeRelocator = new NativeRelocator(rootDir.toPath().resolve("relocate_natives"))
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -388,13 +394,17 @@ subprojects { p ->
|
|||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
||||||
relocate "org.xerial", "dh_sqlite.org.xerial"
|
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
||||||
relocate "org.sqlite", "dh_sqlite", {
|
|
||||||
exclude "org/sqlite/native/**"
|
|
||||||
}
|
|
||||||
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
|
||||||
|
|
||||||
transform(NativeTransformer) {
|
transform(NativeTransformer) {
|
||||||
|
rootDir = project.rootDir
|
||||||
|
|
||||||
|
before {
|
||||||
|
relocate "org.sqlite", "dh_sqlite", {
|
||||||
|
exclude "org/sqlite/native/**"
|
||||||
|
}
|
||||||
|
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||||
|
}
|
||||||
|
|
||||||
relocateNative "org/sqlite", "dh_sqlite"
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
relocateNative "org_sqlite", "dh_1sqlite"
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ for %%f in (versionProperties\*) do (
|
|||||||
|
|
||||||
@rem Clean out the folders, build it, and merge it
|
@rem Clean out the folders, build it, and merge it
|
||||||
echo ==================== Cleaning workspace to build !version! ====================
|
echo ==================== Cleaning workspace to build !version! ====================
|
||||||
call .\gradlew.bat clean -PmcVer="!version!"
|
call .\gradlew.bat clean
|
||||||
echo ==================== Building !version! ====================
|
echo ==================== Building !version! ====================
|
||||||
call .\gradlew.bat build -PmcVer="!version!"
|
call .\gradlew.bat build -PmcVer="!version!"
|
||||||
echo ==================== Merging !version! ====================
|
echo ==================== Merging !version! ====================
|
||||||
|
|||||||
@@ -6,24 +6,32 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
|
|
||||||
class NativeRelocator
|
class NativeRelocator
|
||||||
{
|
{
|
||||||
private static final Path rootDirectory = Path.of(System.getProperty("user.dir"), "relocate_natives");
|
private final Path rootDirectory;
|
||||||
private static final Path cacheRoot = rootDirectory.resolve("cache");
|
private final Path cacheRoot;
|
||||||
|
|
||||||
|
/**
|
||||||
NativeRelocator() throws Exception
|
* Initializes the NativeRelocator by preparing the environment if necessary.
|
||||||
|
* Executes the appropriate preparation script based on the OS.
|
||||||
|
*
|
||||||
|
* @throws Exception if the preparation script fails or an unsupported OS is detected.
|
||||||
|
*/
|
||||||
|
NativeRelocator(Path rootDirectory) throws Exception
|
||||||
{
|
{
|
||||||
if (rootDirectory.resolve(".venv").toFile().exists())
|
this.rootDirectory = rootDirectory;
|
||||||
|
this.cacheRoot = this.rootDirectory.resolve("cache");
|
||||||
|
|
||||||
|
if (this.rootDirectory.resolve(".venv").toFile().exists())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
processBuilder.directory(rootDirectory.toFile());
|
processBuilder.directory(this.rootDirectory.toFile());
|
||||||
|
|
||||||
String os = System.getProperty("os.name").toLowerCase();
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
if (os.contains("win"))
|
if (os.contains("win"))
|
||||||
{
|
{
|
||||||
processBuilder.command("powershell", "./prepare.ps1");
|
processBuilder.command("powershell", "-ExecutionPolicy", "Bypass", "./prepare.ps1");
|
||||||
}
|
}
|
||||||
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
||||||
{
|
{
|
||||||
@@ -46,7 +54,12 @@ class NativeRelocator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and prints the output and error streams of a process asynchronously.
|
||||||
|
*
|
||||||
|
* @param process The process whose streams should be read.
|
||||||
|
* @return A CompletableFuture that completes once all output has been processed.
|
||||||
|
*/
|
||||||
private static CompletableFuture<Void> readOutputStreams(Process process)
|
private static CompletableFuture<Void> readOutputStreams(Process process)
|
||||||
{
|
{
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> {
|
||||||
@@ -79,6 +92,14 @@ class NativeRelocator
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces occurrences of a target string in a byte array, ensuring null termination.
|
||||||
|
*
|
||||||
|
* @param byteArray The byte array where replacements should occur.
|
||||||
|
* @param target The string to replace.
|
||||||
|
* @param replacement The replacement string (must not be longer than the target).
|
||||||
|
* @throws IllegalArgumentException if the replacement is longer than the target.
|
||||||
|
*/
|
||||||
private void replaceInNullTerminatedStrings(byte[] byteArray, String target, String replacement)
|
private void replaceInNullTerminatedStrings(byte[] byteArray, String target, String replacement)
|
||||||
{
|
{
|
||||||
if (target.length() < replacement.length())
|
if (target.length() < replacement.length())
|
||||||
@@ -117,15 +138,23 @@ class NativeRelocator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an external script to fix a modified binary and returns the processed content.
|
||||||
|
*
|
||||||
|
* @param outputFilePath Path to store the processed binary.
|
||||||
|
* @param content The original binary content.
|
||||||
|
* @return The modified binary content.
|
||||||
|
* @throws Exception if the process execution fails.
|
||||||
|
*/
|
||||||
public byte[] fixModifiedBinary(Path outputFilePath, byte[] content) throws Exception
|
public byte[] fixModifiedBinary(Path outputFilePath, byte[] content) throws Exception
|
||||||
{
|
{
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
processBuilder.directory(rootDirectory.toFile());
|
processBuilder.directory(this.rootDirectory.toFile());
|
||||||
|
|
||||||
processBuilder.command(
|
processBuilder.command(
|
||||||
rootDirectory.resolve(".venv/Scripts").toFile().exists()
|
this.rootDirectory.resolve(".venv/Scripts").toFile().exists()
|
||||||
? rootDirectory.resolve(".venv/Scripts/python.exe").toString()
|
? this.rootDirectory.resolve(".venv/Scripts/python.exe").toString()
|
||||||
: rootDirectory.resolve(".venv/bin/python").toString(),
|
: this.rootDirectory.resolve(".venv/bin/python").toString(),
|
||||||
"./fix_modified_binary.py",
|
"./fix_modified_binary.py",
|
||||||
outputFilePath.toString()
|
outputFilePath.toString()
|
||||||
);
|
);
|
||||||
@@ -147,9 +176,18 @@ class NativeRelocator
|
|||||||
return Files.readAllBytes(outputFilePath);
|
return Files.readAllBytes(outputFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a binary file, applying string replacements and fixing modifications.
|
||||||
|
*
|
||||||
|
* @param outputPath The output file path relative to the cache directory.
|
||||||
|
* @param content The binary content to process.
|
||||||
|
* @param replacements A map of string replacements to apply.
|
||||||
|
* @return The modified binary content.
|
||||||
|
* @throws Exception if processing fails.
|
||||||
|
*/
|
||||||
public byte[] processBinary(String outputPath, byte[] content, Map<String, String> replacements) throws Exception
|
public byte[] processBinary(String outputPath, byte[] content, Map<String, String> replacements) throws Exception
|
||||||
{
|
{
|
||||||
Path outputFilePath = cacheRoot.resolve(outputPath);
|
Path outputFilePath = this.cacheRoot.resolve(outputPath);
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
outputFilePath.getParent().toFile().mkdirs();
|
outputFilePath.getParent().toFile().mkdirs();
|
||||||
|
|
||||||
|
|||||||
+35
-23
@@ -20,8 +20,6 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers;
|
package com.seibel.distanthorizons.common.wrappers;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
import net.minecraft.SharedConstants;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
@@ -38,32 +36,46 @@ public class VersionConstants implements IVersionConstants
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinimumWorldHeight()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getWorldGenerationCountPerThread()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVanillaRenderedChunkSquare()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMinecraftVersion()
|
public String getMinecraftVersion()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_19_2
|
// these values are hard-coded to prevent an issue with Forge (specifically 1.18.2) where
|
||||||
return Minecraft.getInstance().getGame().getVersion().getId();
|
// it can't load client classes when running as a dedicated server,
|
||||||
|
// which was how we were dynamically accessing the MC version string
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_16_5
|
||||||
|
return "1.16.5";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_17_1
|
||||||
|
return "1.17.1";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_18_2
|
||||||
|
return "1.18.2";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_19_2
|
||||||
|
return "1.19.2";
|
||||||
|
#elif MC_VER == MC_1_19_4
|
||||||
|
return "1.19.4";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_20_1
|
||||||
|
return "1.20.1";
|
||||||
|
#elif MC_VER == MC_1_20_2
|
||||||
|
return "1.20.2";
|
||||||
|
#elif MC_VER == MC_1_20_4
|
||||||
|
return "1.20.4";
|
||||||
|
#elif MC_VER == MC_1_20_6
|
||||||
|
return "1.20.6";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_21_1
|
||||||
|
return "1.21.1";
|
||||||
|
#elif MC_VER == MC_1_21_3
|
||||||
|
return "1.21.3";
|
||||||
|
#elif MC_VER == MC_1_21_4
|
||||||
|
return "1.21_4";
|
||||||
#else
|
#else
|
||||||
return SharedConstants.getCurrentVersion().getId();
|
ERROR MC version constant missing
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+26
-6
@@ -43,6 +43,8 @@ import java.util.*;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@@ -90,6 +92,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
// properties //
|
// properties //
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public final BlockState blockState;
|
public final BlockState blockState;
|
||||||
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
||||||
private String serialString;
|
private String serialString;
|
||||||
@@ -350,25 +353,42 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get block properties (default to the values used by air)
|
||||||
|
boolean canOcclude = false;
|
||||||
|
boolean propagatesSkyLightDown = true;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
canOcclude = this.blockState.canOcclude();
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
|
#else
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// this method isn't perfect, but works well enough for our use case
|
// this method isn't perfect, but works well enough for our use case
|
||||||
int opacity;
|
int opacity;
|
||||||
if (this.isAir())
|
if (this.isAir())
|
||||||
{
|
{
|
||||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||||
}
|
}
|
||||||
else if (this.isLiquid() && !this.blockState.canOcclude())
|
else if (this.isLiquid() && !canOcclude)
|
||||||
{
|
{
|
||||||
// probably not a waterlogged block (which should block light entirely)
|
// probably not a waterlogged block (which should block light entirely)
|
||||||
|
|
||||||
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
||||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
|
||||||
}
|
}
|
||||||
#if MC_VER < MC_1_21_3
|
else if (propagatesSkyLightDown && !canOcclude)
|
||||||
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
|
||||||
#else
|
|
||||||
else if (this.blockState.propagatesSkylightDown())
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
|
// probably glass or some other fully transparent block
|
||||||
|
|
||||||
|
// !canOcclude is required to ignore stairs and slabs since
|
||||||
|
// propagateSkyLightDown is true for them, but they're solid and don't actually let light through
|
||||||
|
|
||||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+2
-2
@@ -278,14 +278,14 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
// is this block solid?
|
// is this block solid?
|
||||||
if (solidHeight == minInclusiveBuildHeight
|
if (solidHeight == minInclusiveBuildHeight
|
||||||
&& block.isSolid())
|
&& block.isSolid())
|
||||||
{
|
{
|
||||||
solidHeight = y;
|
solidHeight = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is this block light blocking?
|
// is this block light blocking?
|
||||||
if (lightBlockingHeight == minInclusiveBuildHeight
|
if (lightBlockingHeight == minInclusiveBuildHeight
|
||||||
&& block.getOpacity() != LodUtil.BLOCK_FULLY_TRANSPARENT)
|
&& block.getOpacity() != LodUtil.BLOCK_FULLY_TRANSPARENT)
|
||||||
{
|
{
|
||||||
lightBlockingHeight = y;
|
lightBlockingHeight = y;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -214,17 +214,29 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public DhBlockPos getPlayerBlockPos()
|
public DhBlockPos getPlayerBlockPos()
|
||||||
{
|
{
|
||||||
BlockPos playerPos = this.getPlayer().blockPosition();
|
LocalPlayer player = this.getPlayer();
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return new DhBlockPos(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos playerPos = player.blockPosition();
|
||||||
return new DhBlockPos(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
return new DhBlockPos(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhChunkPos getPlayerChunkPos()
|
public DhChunkPos getPlayerChunkPos()
|
||||||
{
|
{
|
||||||
|
LocalPlayer player = this.getPlayer();
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return new DhChunkPos(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
ChunkPos playerPos = new ChunkPos(this.getPlayer().blockPosition());
|
ChunkPos playerPos = new ChunkPos(player.blockPosition());
|
||||||
#else
|
#else
|
||||||
ChunkPos playerPos = this.getPlayer().chunkPosition();
|
ChunkPos playerPos = player.chunkPosition();
|
||||||
#endif
|
#endif
|
||||||
return new DhChunkPos(playerPos.x, playerPos.z);
|
return new DhChunkPos(playerPos.x, playerPos.z);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -180,7 +180,15 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
/** @see GL32#glDeleteBuffers(int) */
|
/** @see GL32#glDeleteBuffers(int) */
|
||||||
@Override
|
@Override
|
||||||
public void glDeleteBuffers(int buffer)
|
public void glDeleteBuffers(int buffer)
|
||||||
{ GlStateManager._glDeleteBuffers(buffer); }
|
{
|
||||||
|
GL32.glDeleteBuffers(buffer);
|
||||||
|
|
||||||
|
// MC's implementation has a bug where it will throw:
|
||||||
|
// GL_INVALID_OPERATION in glBufferData(immutable)
|
||||||
|
// when attempting to delete Storage Buffers
|
||||||
|
// So we need to manually delete the buffers ourselves
|
||||||
|
//GlStateManager._glDeleteBuffers(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// culling //
|
// culling //
|
||||||
|
|||||||
+10
-1
@@ -21,8 +21,10 @@ package com.seibel.distanthorizons.common.wrappers.misc;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -30,6 +32,7 @@ import java.nio.ByteBuffer;
|
|||||||
public class LightMapWrapper implements ILightMapWrapper
|
public class LightMapWrapper implements ILightMapWrapper
|
||||||
{
|
{
|
||||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
private int textureId = 0;
|
private int textureId = 0;
|
||||||
|
|
||||||
@@ -59,7 +62,13 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
GLMC.glBindTexture(this.textureId);
|
GLMC.glBindTexture(this.textureId);
|
||||||
}
|
}
|
||||||
image.upload(0, 0, 0, false);
|
image.upload(0, 0, 0, false);
|
||||||
GLMC.glBindTexture(currentTexture);
|
|
||||||
|
// getActiveTexture() may return textures that aren't valid and attempting to bind them will
|
||||||
|
// throw a GL error in MC 1.21.1
|
||||||
|
if (GL32.glIsTexture(currentTexture))
|
||||||
|
{
|
||||||
|
GLMC.glBindTexture(currentTexture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private void createLightmap(NativeImage image)
|
private void createLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
|
|||||||
+42
-33
@@ -28,72 +28,80 @@ import net.minecraft.world.level.dimension.DimensionType;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 2022-9-16
|
|
||||||
*/
|
*/
|
||||||
public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
||||||
{
|
{
|
||||||
private static final ConcurrentMap<DimensionType, DimensionTypeWrapper> dimensionTypeWrapperMap = new ConcurrentHashMap<>();
|
private static final ConcurrentMap<String, DimensionTypeWrapper> DIMENSION_WRAPPER_BY_NAME = new ConcurrentHashMap<>();
|
||||||
private final DimensionType dimensionType;
|
private final DimensionType dimensionType;
|
||||||
|
|
||||||
public DimensionTypeWrapper(DimensionType dimensionType)
|
|
||||||
{
|
|
||||||
this.dimensionType = dimensionType;
|
//=============//
|
||||||
}
|
// Constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
public DimensionTypeWrapper(DimensionType dimensionType) { this.dimensionType = dimensionType; }
|
||||||
|
|
||||||
public static DimensionTypeWrapper getDimensionTypeWrapper(DimensionType dimensionType)
|
public static DimensionTypeWrapper getDimensionTypeWrapper(DimensionType dimensionType)
|
||||||
{
|
{
|
||||||
//first we check if the biome has already been wrapped
|
String dimName = getName(dimensionType);
|
||||||
if (dimensionTypeWrapperMap.containsKey(dimensionType) && dimensionTypeWrapperMap.get(dimensionType) != null)
|
|
||||||
|
// check if the dimension has already been wrapped
|
||||||
|
if (DIMENSION_WRAPPER_BY_NAME.containsKey(dimName)
|
||||||
|
&& DIMENSION_WRAPPER_BY_NAME.get(dimName) != null)
|
||||||
{
|
{
|
||||||
return dimensionTypeWrapperMap.get(dimensionType);
|
return DIMENSION_WRAPPER_BY_NAME.get(dimName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//if it hasn't been created yet, we create it and save it in the map
|
// create the missing wrapper
|
||||||
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
|
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
|
||||||
dimensionTypeWrapperMap.put(dimensionType, dimensionTypeWrapper);
|
DIMENSION_WRAPPER_BY_NAME.put(dimName, dimensionTypeWrapper);
|
||||||
|
|
||||||
//we return the newly created wrapper
|
|
||||||
return dimensionTypeWrapper;
|
return dimensionTypeWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearMap()
|
public static void clearMap() { DIMENSION_WRAPPER_BY_NAME.clear(); }
|
||||||
{
|
|
||||||
dimensionTypeWrapperMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String getDimensionName()
|
|
||||||
|
//=================//
|
||||||
|
// wrapper methods //
|
||||||
|
//=================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() { return getName(this.dimensionType); }
|
||||||
|
public static String getName(DimensionType dimensionType)
|
||||||
{
|
{
|
||||||
#if MC_VER <= MC_1_16_5
|
#if MC_VER <= MC_1_16_5
|
||||||
// effectsLocation() is marked as client only, so using the backing field directly
|
// effectsLocation() is marked as client only, so using the backing field directly
|
||||||
return dimensionType.effectsLocation.getPath();
|
return dimensionType.effectsLocation.getPath();
|
||||||
#else
|
#else
|
||||||
return this.dimensionType.effectsLocation().getPath();
|
return dimensionType.effectsLocation().getPath();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCeiling()
|
public boolean hasCeiling() { return this.dimensionType.hasCeiling(); }
|
||||||
{
|
|
||||||
return this.dimensionType.hasCeiling();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSkyLight()
|
public boolean hasSkyLight() { return this.dimensionType.hasSkyLight(); }
|
||||||
{
|
|
||||||
return this.dimensionType.hasSkyLight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getWrappedMcObject()
|
public Object getWrappedMcObject() { return this.dimensionType; }
|
||||||
{
|
|
||||||
return this.dimensionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// there's definitely a better way of doing this, but it should work well enough for now
|
// there's definitely a better way of doing this, but it should work well enough for now
|
||||||
@Override
|
@Override
|
||||||
public boolean isTheEnd() { return this.getDimensionName().equalsIgnoreCase("the_end"); }
|
public boolean isTheEnd() { return this.getName().equalsIgnoreCase("the_end"); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCoordinateScale() { return this.dimensionType.coordinateScale(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
@@ -105,9 +113,10 @@ public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DimensionTypeWrapper other = (DimensionTypeWrapper) obj;
|
DimensionTypeWrapper other = (DimensionTypeWrapper) obj;
|
||||||
return other.getDimensionName().equals(this.getDimensionName());
|
return other.getName().equals(this.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-30
@@ -125,7 +125,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
* pull chunks using their async method), or if there
|
* pull chunks using their async method), or if there
|
||||||
* was an issue with the sync pulling method.
|
* was an issue with the sync pulling method.
|
||||||
*/
|
*/
|
||||||
private boolean pullExistingChunkAsync = false;
|
private boolean pullExistingChunkUsingMcAsyncMethod = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -241,19 +241,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
if (MOD_CHECKER.isModLoaded("c2me"))
|
if (MOD_CHECKER.isModLoaded("c2me"))
|
||||||
{
|
{
|
||||||
EVENT_LOGGER.info("C2ME detected: DH's pre-existing chunk accessing will use async methods handled by C2ME.");
|
EVENT_LOGGER.info("C2ME detected: DH's pre-existing chunk accessing will use methods handled by C2ME.");
|
||||||
this.pullExistingChunkAsync = true;
|
this.pullExistingChunkUsingMcAsyncMethod = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//IOWorker ioWorker = level.getChunkSource().chunkMap.worker;
|
|
||||||
//
|
|
||||||
// #if MC_VER <= MC_1_18_2
|
|
||||||
// return CompletableFuture.completedFuture(ioWorker.load(chunkPos));
|
|
||||||
// #else
|
|
||||||
//
|
|
||||||
//// storage will be null if C2ME is installed
|
|
||||||
//if (ioWorker.storage != null)
|
|
||||||
|
|
||||||
this.params = new GlobalParameters(serverlevel);
|
this.params = new GlobalParameters(serverlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,6 +333,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// world generation //
|
// world generation //
|
||||||
//==================//
|
//==================//
|
||||||
|
|
||||||
|
// TODO this is already being run on a generator thread,
|
||||||
|
// why are we passing in an executor?
|
||||||
/** @throws RejectedExecutionException if the given {@link Executor} is cancelled. */
|
/** @throws RejectedExecutionException if the given {@link Executor} is cancelled. */
|
||||||
public CompletableFuture<Void> generateLodFromListAsync(GenerationEvent genEvent, Executor executor) throws RejectedExecutionException, InterruptedException
|
public CompletableFuture<Void> generateLodFromListAsync(GenerationEvent genEvent, Executor executor) throws RejectedExecutionException, InterruptedException
|
||||||
{
|
{
|
||||||
@@ -385,10 +378,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
.map((chunkPos) -> this.createEmptyOrPreExistingChunkAsync(chunkPos.x, chunkPos.z, chunkSkyLightingByDhPos, chunkBlockLightingByDhPos, generatedChunkByDhPos))
|
.map((chunkPos) -> this.createEmptyOrPreExistingChunkAsync(chunkPos.x, chunkPos.z, chunkSkyLightingByDhPos, chunkBlockLightingByDhPos, generatedChunkByDhPos))
|
||||||
.toArray(CompletableFuture[]::new);
|
.toArray(CompletableFuture[]::new);
|
||||||
|
|
||||||
|
// join to prevent an issue where DH queues too many tasks or something(?)
|
||||||
|
// also allows file IO to run in parallel so no one thread is waiting on disk IO (this is only an issue when C2ME is present)
|
||||||
|
CompletableFuture.allOf(readFutures).join();
|
||||||
|
|
||||||
// future chain for generation
|
// future chain for generation
|
||||||
return CompletableFuture.allOf(readFutures)
|
return CompletableFuture.runAsync(() ->
|
||||||
.thenRunAsync(() ->
|
|
||||||
{
|
{
|
||||||
// offset 1 chunk in both X and Z direction so we can generate an even number of chunks wide
|
// offset 1 chunk in both X and Z direction so we can generate an even number of chunks wide
|
||||||
// while still submitting an odd number width to MC's internal generators
|
// while still submitting an odd number width to MC's internal generators
|
||||||
@@ -592,6 +587,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
return newChunk;
|
return newChunk;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// TODO FIXME this method can be called up to 25 times for the same chunk position, why?
|
||||||
private CompletableFuture<CompoundTag> getChunkNbtDataAsync(ChunkPos chunkPos)
|
private CompletableFuture<CompoundTag> getChunkNbtDataAsync(ChunkPos chunkPos)
|
||||||
{
|
{
|
||||||
ServerLevel level = this.params.level;
|
ServerLevel level = this.params.level;
|
||||||
@@ -610,7 +606,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
// storage will be null if C2ME is installed
|
// storage will be null if C2ME is installed
|
||||||
if (!this.pullExistingChunkAsync && ioWorker.storage != null)
|
if (!this.pullExistingChunkUsingMcAsyncMethod && ioWorker.storage != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -624,7 +620,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// ioWorker.storage
|
// ioWorker.storage
|
||||||
// but just in case
|
// but just in case
|
||||||
EVENT_LOGGER.error("Unexpected issue pulling pre-existing chunk ["+chunkPos+"], falling back to async chunk pulling. This may cause server-tick lag.", e);
|
EVENT_LOGGER.error("Unexpected issue pulling pre-existing chunk ["+chunkPos+"], falling back to async chunk pulling. This may cause server-tick lag.", e);
|
||||||
this.pullExistingChunkAsync = true;
|
this.pullExistingChunkUsingMcAsyncMethod = true;
|
||||||
|
|
||||||
// try again now using the async method
|
// try again now using the async method
|
||||||
return this.getChunkNbtDataAsync(chunkPos);
|
return this.getChunkNbtDataAsync(chunkPos);
|
||||||
@@ -633,32 +629,42 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// log if we unexpectedly weren't able to run the sync chunk pulling
|
// log if we unexpectedly weren't able to run the sync chunk pulling
|
||||||
if (!this.pullExistingChunkAsync)
|
if (!this.pullExistingChunkUsingMcAsyncMethod)
|
||||||
{
|
{
|
||||||
// this shouldn't happen, but just in case
|
// this shouldn't happen, but just in case
|
||||||
EVENT_LOGGER.info("Unable to pull pre-existing chunk using synchronous method. Falling back to async method. this may cause server-tick lag.");
|
EVENT_LOGGER.info("Unable to pull pre-existing chunk using synchronous method. Falling back to async method. this may cause server-tick lag.");
|
||||||
this.pullExistingChunkAsync = true;
|
this.pullExistingChunkUsingMcAsyncMethod = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//GET_CHUNK_COUNT_REF.incrementAndGet();
|
||||||
|
|
||||||
// When running in vanilla MC on versions before 1.21.4,
|
// When running in vanilla MC on versions before 1.21.4,
|
||||||
// DH would attempt to run loadAsync on this same thread via a threading mixin,
|
// DH would attempt to run loadAsync on this same thread via a threading mixin,
|
||||||
// to prevent causing lag on the server thread.
|
// to prevent causing lag on the server thread.
|
||||||
// However, if a mod like C2ME is installed this will run on a C2ME thread instead.
|
// However, if a mod like C2ME is installed this will run on a C2ME thread instead.
|
||||||
return ioWorker.loadAsync(chunkPos)
|
return ioWorker.loadAsync(chunkPos)
|
||||||
.thenApply(optional -> optional.orElse(null))
|
.thenApply(optional ->
|
||||||
.exceptionally((throwable) ->
|
|
||||||
{
|
|
||||||
// unwrap the CompletionException if necessary
|
|
||||||
Throwable actualThrowable = throwable;
|
|
||||||
while (actualThrowable instanceof CompletionException completionException)
|
|
||||||
{
|
{
|
||||||
actualThrowable = completionException.getCause();
|
// Debugging note:
|
||||||
}
|
// If there are reports of extreme memory use when C2ME is installed, that probably means
|
||||||
|
// this method is queuing a lot of tasks (1,000+), which causes C2ME to explode.
|
||||||
LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable);
|
|
||||||
return null;
|
//GET_CHUNK_COUNT_REF.decrementAndGet();
|
||||||
});
|
//PREF_LOGGER.info("chunk getter count ["+F3Screen.NUMBER_FORMAT.format(GET_CHUNK_COUNT_REF.get())+"]");
|
||||||
|
return optional.orElse(null);
|
||||||
|
})
|
||||||
|
.exceptionally((throwable) ->
|
||||||
|
{
|
||||||
|
// unwrap the CompletionException if necessary
|
||||||
|
Throwable actualThrowable = throwable;
|
||||||
|
while (actualThrowable instanceof CompletionException completionException)
|
||||||
|
{
|
||||||
|
actualThrowable = completionException.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: 736df9f848...f9bd7e2daf
+19
-10
@@ -76,15 +76,25 @@ public abstract class MixinMinecraft
|
|||||||
|
|
||||||
if (SelfUpdater.onStart() || DEBUG_ALWAYS_SHOW_UPDATER)
|
if (SelfUpdater.onStart() || DEBUG_ALWAYS_SHOW_UPDATER)
|
||||||
{
|
{
|
||||||
instance.setScreen(new UpdateModScreen(
|
try
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
{
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
instance.setScreen(new UpdateModScreen(
|
||||||
));
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
}
|
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
||||||
else
|
));
|
||||||
{
|
return;
|
||||||
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// info instead of error since this can be ignored and probably just means
|
||||||
|
// there isn't a new DH version available
|
||||||
|
LOGGER.info("Unable to show DH update screen, reason: ["+e.getMessage()+"].");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the screen back to the vanilla screen as if nothing ever happened
|
||||||
|
// if not done the game will crash
|
||||||
|
instance.setScreen(guiScreen);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -124,14 +134,13 @@ public abstract class MixinMinecraft
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
versionId
|
versionId
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// info instead of error since this can be ignored and probably just means
|
// info instead of error since this can be ignored and probably just means
|
||||||
// there isn't a new DH version available
|
// there isn't a new DH version available
|
||||||
|
|||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.server;
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
|
|
||||||
import net.minecraft.Util;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link MixinUtilBackgroundThread} was used for versions before 1.21.3
|
|
||||||
* This is just a dummy class/mixin to make the compiler happy.
|
|
||||||
*
|
|
||||||
* @see MixinUtilBackgroundThread
|
|
||||||
*/
|
|
||||||
//@Mixin(net.minecraft.minecraft.class) // TODO we should allow version specific mixins so we don't have to create dummy mixins that exist for all MC versions
|
|
||||||
@Mixin(Util.class)
|
|
||||||
public class MixinLevelTicks
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
|
||||||
|
|
||||||
import net.minecraft.world.ticks.LevelTicks;
|
|
||||||
import net.minecraft.world.ticks.ScheduledTick;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(LevelTicks.class)
|
|
||||||
public class MixinLevelTicks<T>
|
|
||||||
{
|
|
||||||
// TODO put in a common location
|
|
||||||
private static boolean isWorldGenThread()
|
|
||||||
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
|
|
||||||
private void schedule(ScheduledTick<T> tick, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
|
|
||||||
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
|
|
||||||
if (isWorldGenThread())
|
|
||||||
{
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
+10
-10
@@ -105,43 +105,43 @@ public class TestGenericWorldGenerator implements IDhApiWorldGenerator
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
blockResourceLocation = "minecraft:red_wool";
|
blockResourceLocation = "minecraft:red_wool";
|
||||||
maxHeight = 60;
|
maxHeight = 20;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
blockResourceLocation = "minecraft:orange_wool";
|
blockResourceLocation = "minecraft:orange_wool";
|
||||||
maxHeight = 70;
|
maxHeight = 30;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
blockResourceLocation = "minecraft:yellow_wool";
|
blockResourceLocation = "minecraft:yellow_wool";
|
||||||
maxHeight = 80;
|
maxHeight = 40;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
blockResourceLocation = "minecraft:lime_wool";
|
blockResourceLocation = "minecraft:lime_wool";
|
||||||
maxHeight = 90;
|
maxHeight = 50;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
blockResourceLocation = "minecraft:cyan_wool";
|
blockResourceLocation = "minecraft:cyan_wool";
|
||||||
maxHeight = 100;
|
maxHeight = 60;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
blockResourceLocation = "minecraft:blue_wool";
|
blockResourceLocation = "minecraft:blue_wool";
|
||||||
maxHeight = 100;
|
maxHeight = 70;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
blockResourceLocation = "minecraft:magenta_wool";
|
blockResourceLocation = "minecraft:magenta_wool";
|
||||||
maxHeight = 110;
|
maxHeight = 80;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
blockResourceLocation = "minecraft:white_wool";
|
blockResourceLocation = "minecraft:white_wool";
|
||||||
maxHeight = 120;
|
maxHeight = 90;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
blockResourceLocation = "minecraft:gray_wool";
|
blockResourceLocation = "minecraft:gray_wool";
|
||||||
maxHeight = 120;
|
maxHeight = 100;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
blockResourceLocation = "minecraft:black_wool";
|
blockResourceLocation = "minecraft:black_wool";
|
||||||
maxHeight = 140;
|
maxHeight = 110;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ public class TestWorldGenBindingEvent extends DhApiLevelLoadEvent
|
|||||||
ServerLevel level = (ServerLevel) event.value.levelWrapper.getWrappedMcObject();
|
ServerLevel level = (ServerLevel) event.value.levelWrapper.getWrappedMcObject();
|
||||||
|
|
||||||
// override the core DH world generator for this level
|
// override the core DH world generator for this level
|
||||||
//IDhApiWorldGenerator exampleWorldGen = new TestChunkWorldGenerator(level);
|
//IDhApiWorldGenerator exampleWorldGen = new TestChunkWorldGenerator(level); // TODO biomes are broken for some reason
|
||||||
IDhApiWorldGenerator exampleWorldGen = new TestGenericWorldGenerator(event.value.levelWrapper);
|
IDhApiWorldGenerator exampleWorldGen = new TestGenericWorldGenerator(event.value.levelWrapper);
|
||||||
DhApi.worldGenOverrides.registerWorldGeneratorOverride(event.value.levelWrapper, exampleWorldGen);
|
DhApi.worldGenOverrides.registerWorldGeneratorOverride(event.value.levelWrapper, exampleWorldGen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
"server.MixinEntity",
|
"server.MixinEntity",
|
||||||
"server.MixinServerPlayer",
|
"server.MixinServerPlayer",
|
||||||
"server.MixinTracingExecutor",
|
"server.MixinTracingExecutor",
|
||||||
"server.MixinUtilBackgroundThread",
|
"server.MixinUtilBackgroundThread"
|
||||||
"server.MixinLevelTicks"
|
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientLevel",
|
"client.MixinClientLevel",
|
||||||
|
|||||||
@@ -24,13 +24,16 @@ import com.seibel.distanthorizons.common.util.ProxyUtil;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
@@ -52,6 +55,7 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
|||||||
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -90,7 +94,13 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
public void registerEvents()
|
public void registerEvents()
|
||||||
{
|
{
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
ForgePluginPacketSender.setPacketHandler(ClientApi.INSTANCE::pluginMessageReceived);
|
|
||||||
|
// handles singleplayer, LAN, and connecting to a server
|
||||||
|
ForgePluginPacketSender.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
|
ServerApi.INSTANCE.pluginMessageReceived(player, message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,10 +78,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public ForgeServerProxy(boolean isDedicated)
|
public ForgeServerProxy(boolean isDedicated) { this.isDedicated = isDedicated; }
|
||||||
{
|
|
||||||
this.isDedicated = isDedicated;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+19
-9
@@ -57,15 +57,25 @@ public class MixinMinecraft
|
|||||||
|
|
||||||
if (SelfUpdater.onStart())
|
if (SelfUpdater.onStart())
|
||||||
{
|
{
|
||||||
instance.setScreen(new UpdateModScreen(
|
try
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
{
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
instance.setScreen(new UpdateModScreen(
|
||||||
));
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
}
|
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
||||||
else
|
));
|
||||||
{
|
return;
|
||||||
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// info instead of error since this can be ignored and probably just means
|
||||||
|
// there isn't a new DH version available
|
||||||
|
LOGGER.info("Unable to show DH update screen, reason: ["+e.getMessage()+"].");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the screen back to the vanilla screen as if nothing ever happened
|
||||||
|
// if not done the game will crash
|
||||||
|
instance.setScreen(guiScreen);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -108,7 +118,7 @@ public class MixinMinecraft
|
|||||||
versionId
|
versionId
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// info instead of error since this can be ignored and probably just means
|
// info instead of error since this can be ignored and probably just means
|
||||||
// there isn't a new DH version available
|
// there isn't a new DH version available
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=2.3.0-b-dev
|
mod_version=2.3.1-b
|
||||||
api_version=4.0.0
|
api_version=4.0.0
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
mod_readable_name=Distant Horizons
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
@@ -51,6 +53,7 @@ import java.util.function.Consumer;
|
|||||||
import net.neoforged.neoforge.client.ConfigScreenHandler;
|
import net.neoforged.neoforge.client.ConfigScreenHandler;
|
||||||
#else
|
#else
|
||||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,11 +67,16 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
{
|
{
|
||||||
public NeoforgeMain(IEventBus eventBus)
|
public NeoforgeMain(IEventBus eventBus)
|
||||||
{
|
{
|
||||||
eventBus.addListener((FMLClientSetupEvent e) -> {
|
// handles singleplayer, LAN, and connecting to a server
|
||||||
|
eventBus.addListener((FMLClientSetupEvent e) ->
|
||||||
|
{
|
||||||
this.onInitializeClient();
|
this.onInitializeClient();
|
||||||
eventBus.addListener(this::registerNetworkingClient);
|
eventBus.addListener(this::registerNetworkingClientServer);
|
||||||
});
|
});
|
||||||
eventBus.addListener((FMLDedicatedServerSetupEvent e) -> {
|
|
||||||
|
// handles dedicated servers
|
||||||
|
eventBus.addListener((FMLDedicatedServerSetupEvent e) ->
|
||||||
|
{
|
||||||
this.onInitializeServer();
|
this.onInitializeServer();
|
||||||
eventBus.addListener(this::registerNetworkingServer);
|
eventBus.addListener(this::registerNetworkingServer);
|
||||||
});
|
});
|
||||||
@@ -79,13 +87,22 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
//============//
|
//============//
|
||||||
// networking //
|
// networking //
|
||||||
//============//
|
//============//
|
||||||
public void registerNetworkingClient(RegisterPayloadHandlersEvent event)
|
|
||||||
{ NeoforgePluginPacketSender.setPacketHandler(event, ClientApi.INSTANCE::pluginMessageReceived); }
|
public void registerNetworkingClientServer(RegisterPayloadHandlersEvent event)
|
||||||
|
{
|
||||||
|
NeoforgePluginPacketSender.setPacketHandler(event, (IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
|
ServerApi.INSTANCE.pluginMessageReceived(player, message);
|
||||||
|
});
|
||||||
|
}
|
||||||
public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
|
public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
|
||||||
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
|
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IEventProxy createServerProxy(boolean isDedicated) { return new NeoforgeServerProxy(isDedicated); }
|
protected IEventProxy createServerProxy(boolean isDedicated) { return new NeoforgeServerProxy(isDedicated); }
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -76,14 +76,13 @@ public class MixinMinecraft
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
versionId
|
versionId
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// info instead of error since this can be ignored and probably just means
|
// info instead of error since this can be ignored and probably just means
|
||||||
// there isn't a new DH version available
|
// there isn't a new DH version available
|
||||||
|
|||||||
-53
@@ -1,53 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.neoforge.mixins.server;
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
|
|
||||||
import net.minecraft.Util;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link MixinUtilBackgroundThread} was used for versions before 1.21.3
|
|
||||||
* This is just a dummy class/mixin to make the compiler happy.
|
|
||||||
*
|
|
||||||
* @see MixinUtilBackgroundThread
|
|
||||||
*/
|
|
||||||
@Mixin(Util.class) // TODO we should allow version specific mixins so we don't have to create dummy mixins that exist for all MC versions
|
|
||||||
public class MixinLevelTicks<T>
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
|
||||||
|
|
||||||
import net.minecraft.world.ticks.LevelTicks;
|
|
||||||
import net.minecraft.world.ticks.ScheduledTick;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(LevelTicks.class)
|
|
||||||
public class MixinLevelTicks<T>
|
|
||||||
{
|
|
||||||
// TODO put in a common location
|
|
||||||
private static boolean isWorldGenThread()
|
|
||||||
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
|
|
||||||
private void schedule(ScheduledTick<T> tick, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
|
|
||||||
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
|
|
||||||
if (isWorldGenThread())
|
|
||||||
{
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -8,8 +8,7 @@
|
|||||||
"server.MixinServerPlayer",
|
"server.MixinServerPlayer",
|
||||||
"server.MixinTFChunkGenerator",
|
"server.MixinTFChunkGenerator",
|
||||||
"server.MixinTracingExecutor",
|
"server.MixinTracingExecutor",
|
||||||
"server.MixinUtilBackgroundThread",
|
"server.MixinUtilBackgroundThread"
|
||||||
"server.MixinLevelTicks"
|
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
|
|||||||
@@ -4,23 +4,28 @@ import subprocess
|
|||||||
import download_codesign
|
import download_codesign
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Parse the input binary & xit if binary is invalid
|
||||||
output_path = sys.argv[1]
|
output_path = sys.argv[1]
|
||||||
binary = lief.parse(sys.stdin.buffer.read())
|
binary = lief.parse(sys.stdin.buffer.read())
|
||||||
|
|
||||||
if binary is None:
|
if binary is None:
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
# Remove signature from Mac binaries
|
||||||
if isinstance(binary, lief.MachO.Binary):
|
if isinstance(binary, lief.MachO.Binary):
|
||||||
binary.remove_signature()
|
binary.remove_signature()
|
||||||
|
|
||||||
|
# Write the modified binary to the output path
|
||||||
binary.write(output_path)
|
binary.write(output_path)
|
||||||
|
|
||||||
|
# Sign Mac binaries (required to make them usable because apple)
|
||||||
if isinstance(binary, lief.MachO.Binary):
|
if isinstance(binary, lief.MachO.Binary):
|
||||||
print(f"Signing {output_path}...")
|
print(f"Signing {output_path}...")
|
||||||
|
|
||||||
|
# Check if the Apple code-signing files are available, if not, download them
|
||||||
if not Path("./apple-codesign/COPYING").exists():
|
if not Path("./apple-codesign/COPYING").exists():
|
||||||
download_codesign.download_and_unpack()
|
download_codesign.download_and_unpack()
|
||||||
|
|
||||||
|
# Run the code-signing process
|
||||||
sign_process = subprocess.Popen(["./apple-codesign/rcodesign", "sign", output_path], shell=False,
|
sign_process = subprocess.Popen(["./apple-codesign/rcodesign", "sign", output_path], shell=False,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
sign_process.wait()
|
sign_process.wait()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ netty_version=4.1.97.Final
|
|||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.16.9
|
fabric_loader_version=0.16.9
|
||||||
fabric_api_version=0.107.0+1.21.1
|
fabric_api_version=0.115.0+1.21.1
|
||||||
# Fabric mod versions
|
# Fabric mod versions
|
||||||
modmenu_version=11.0.0-beta.1
|
modmenu_version=11.0.0-beta.1
|
||||||
starlight_version_fabric=
|
starlight_version_fabric=
|
||||||
|
|||||||
Reference in New Issue
Block a user