Compare commits
194 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e7f82d3e0 | |||
| 931aa2974e | |||
| 1f77a12fe3 | |||
| dcf546a163 | |||
| 81f050dc8b | |||
| 9cd1ada37f | |||
| d29e9085a1 | |||
| d392de3c0d | |||
| 7209193f8f | |||
| ed4f644a3f | |||
| 34038684a7 | |||
| 6fe6694c82 | |||
| 8e52f1aca5 | |||
| 5ce3dda2d5 | |||
| f4f81f4d7f | |||
| 7c37a5c370 | |||
| b495ac4799 | |||
| 2ddeaf50eb | |||
| 3721ebea6e | |||
| 98f8a87362 | |||
| 10a743ddef | |||
| 95c896f964 | |||
| 040bc16874 | |||
| 35d3fdb473 | |||
| 549f7510f7 | |||
| fab64d8477 | |||
| 4a6a35f617 | |||
| 2b519a826f | |||
| 445c01b5ae | |||
| 0f08bd540e | |||
| 77088465f9 | |||
| affe014433 | |||
| 4c06bf6dbd | |||
| dcab616385 | |||
| 89b7d08e9b | |||
| 724e318221 | |||
| a40d62d46a | |||
| 2f6b4c079b | |||
| 951e3c0271 | |||
| 84825c2d09 | |||
| ec627e2eba | |||
| 06bc9a349f | |||
| ff6c4e227b | |||
| a4d46ffe94 | |||
| bd5c140782 | |||
| 229c3f7c91 | |||
| 693369bc08 | |||
| d109fe6c43 | |||
| 3c9d3707cf | |||
| 6e53564835 | |||
| 2480fe0d86 | |||
| 691c9d3f45 | |||
| 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 | |||
| 0f64df7be0 | |||
| 23a1f0b025 | |||
| 4a72e02550 | |||
| 521bcdcc0f | |||
| 4eb20d5ce8 | |||
| 3ad68aaf42 | |||
| 2a9a03771e | |||
| 8f7823a4d2 | |||
| cc4b965966 | |||
| a6418de927 | |||
| 5303415d05 | |||
| 836515934f | |||
| 228dc46d6b | |||
| a91f9670dc | |||
| 81313252f2 | |||
| f65d411978 | |||
| 8c8a5ffeaf | |||
| 68793fbe8d | |||
| d8401a8f49 | |||
| 07ff00f7c9 | |||
| fadaff1113 | |||
| ff6bf7b4c9 | |||
| 082b1224a8 | |||
| bc475373fc | |||
| 498e958eca | |||
| 82e0cfe0b4 | |||
| 31d89e3349 | |||
| a3775c1f88 | |||
| e070bf4244 | |||
| 8287192cd0 | |||
| d40f4dfe19 | |||
| 595cdf011a | |||
| 96f2f8c3b2 | |||
| c883ded7c4 | |||
| 834269da67 | |||
| a9bebf03d5 | |||
| 939f6304bf | |||
| 6e9f466570 | |||
| a0b5cc7a5c | |||
| 82708d998d | |||
| 613e444490 | |||
| f493e201d4 | |||
| 2a8013b1d6 | |||
| 54fed62507 | |||
| e51bec9ce4 | |||
| e47a83b706 | |||
| 8029c7b00c | |||
| 2b38dc2575 | |||
| 46cafb4cbe | |||
| ff96533c93 | |||
| 89e73f6383 | |||
| 069ebfe24e | |||
| 8b374c4734 | |||
| 1febade083 | |||
| deedd85914 | |||
| 218c27adae | |||
| fde48b6f1a | |||
| f2a36e73d0 | |||
| c5429ad139 | |||
| 7bc2ee296c | |||
| 4e26e4ab31 | |||
| a91685b590 | |||
| 06f73c9b0a | |||
| 062dc29fd4 | |||
| 4096a24306 | |||
| 2563de3ba3 | |||
| 4a99b42fa8 | |||
| 775adfaad5 | |||
| 2a9c319935 |
@@ -26,6 +26,10 @@ Merged/
|
|||||||
# Folder created by the buildAll scripts
|
# Folder created by the buildAll scripts
|
||||||
buildAllJars/
|
buildAllJars/
|
||||||
|
|
||||||
|
relocate_natives/.venv/
|
||||||
|
relocate_natives/__pycache__/
|
||||||
|
relocate_natives/apple-codesign/
|
||||||
|
|
||||||
# file from notepad++
|
# file from notepad++
|
||||||
*.bak
|
*.bak
|
||||||
|
|
||||||
|
|||||||
+37
-26
@@ -6,6 +6,7 @@ image: eclipse-temurin:21
|
|||||||
# TODO: Make stages depend on what is in versionProperties
|
# TODO: Make stages depend on what is in versionProperties
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
|
- multiversion
|
||||||
- api
|
- api
|
||||||
- pages
|
- pages
|
||||||
|
|
||||||
@@ -35,39 +36,49 @@ build:
|
|||||||
stage: build
|
stage: build
|
||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4"]
|
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4", "1.21.5"]
|
||||||
script:
|
script:
|
||||||
# this both runs the unit tests and assembles the code
|
# this both runs the unit tests and assembles the code
|
||||||
- ./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 ./build/forgix/* . || true
|
||||||
|
- mkdir -p ./builds
|
||||||
|
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./builds || true
|
||||||
|
# When the archive is created, the merged jar will be the main jar and a subfolder named "builds" will contain the other jars
|
||||||
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
|
- ./builds/*.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
|
- ./builds/*-all.jar
|
||||||
- fabric/build/libs/*-all.jar
|
- ./builds/*-dev.jar
|
||||||
- fabric/build/libs/*-dev.jar
|
- ./builds/*-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
|
||||||
|
|
||||||
|
|
||||||
|
multiversion:
|
||||||
|
stage: multiversion
|
||||||
|
needs: [build]
|
||||||
|
script:
|
||||||
|
# Create a semicolon-separated list of jar paths
|
||||||
|
- MC_VER_PATHS=$(find . -maxdepth 1 -name "*.jar" -type f | tr '\n' ';')
|
||||||
|
# Run the mergeVersions task
|
||||||
|
- ./gradlew mergeVersions -PmergeVersions="${MC_VER_PATHS}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
|
# Clean up existing jars and make sure only the multiversion jar remains which will be uploaded
|
||||||
|
- rm -f ./*.jar
|
||||||
|
- cp ./build/forgix/multiversion/* .
|
||||||
|
artifacts:
|
||||||
|
name: "NightlyBuild_Multiversion-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
paths:
|
||||||
|
- ./*.jar
|
||||||
|
expire_in: 30 days
|
||||||
|
when: always
|
||||||
|
extends: .build_java
|
||||||
|
|
||||||
|
|
||||||
api:
|
api:
|
||||||
stage: api
|
stage: api
|
||||||
needs: []
|
needs: []
|
||||||
@@ -77,15 +88,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
|
||||||
|
|||||||
@@ -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:
|
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:
|
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:
|
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. \
|
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
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. **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**:
|
2. **Describe the improvement**:
|
||||||
|
|||||||
+80
-57
@@ -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 {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
|
|
||||||
@@ -5,15 +13,23 @@ plugins {
|
|||||||
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
||||||
|
|
||||||
// Plugin to create merged jars
|
// Plugin to create merged jars
|
||||||
id "io.github.pacifistmc.forgix" version "1.2.9"
|
id "io.github.pacifistmc.forgix" version "2.0.0-SNAPSHOT.2"
|
||||||
|
|
||||||
// Manifold preprocessor
|
// Manifold preprocessor
|
||||||
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
||||||
|
|
||||||
// Architectury is used here only as a replacement for forge's own loom
|
// Architectury is used here only as a replacement for forge's own loom
|
||||||
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "1.10-SNAPSHOT" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets up Forgix for multiversion merging
|
||||||
|
forgix {
|
||||||
|
if (project.hasProperty('mergeVersions')) { // This is set using -PmergeVersions by the GitLab CI
|
||||||
|
multiversion {
|
||||||
|
inputJars = project.files(project.property('mergeVersions').toString().split(';'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the list of preprocessors to use.
|
* Creates the list of preprocessors to use.
|
||||||
@@ -59,41 +75,64 @@ project.gradle.ext.getProperties().each { prop ->
|
|||||||
// Sets up manifold stuff
|
// Sets up manifold stuff
|
||||||
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sets up the version string (the name we use for our jar)
|
// Sets up the version string (the name we use for our jar)
|
||||||
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
||||||
// Forgix settings (used for merging jars)
|
|
||||||
forgix {
|
|
||||||
|
|
||||||
String loaderHyphenSeparatedList = ((String)gradle.builds_for).replaceAll(",", "-");
|
class NativeTransformer implements Transformer {
|
||||||
|
private final HashMap<String, String> replacements = new HashMap()
|
||||||
|
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||||
|
private var nativeRelocator
|
||||||
|
|
||||||
group = "com.seibel.distanthorizons"
|
public File rootDir
|
||||||
mergedJarName = "DistantHorizons-${rootProject.versionStr}-${loaderHyphenSeparatedList}.jar"
|
|
||||||
|
|
||||||
if (findProject(":forge"))
|
void relocateNative(String target, String replacement) {
|
||||||
forge {
|
if (replacement.length() > target.length()) {
|
||||||
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
|
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (findProject(":neoforge"))
|
replacements.put(target, replacement)
|
||||||
custom {
|
}
|
||||||
projectName = "neoforge"
|
|
||||||
jarLocation = "build/libs/DistantHorizons-neoforge-${rootProject.versionStr}.jar"
|
@Override
|
||||||
|
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||||
|
return replacements.keySet().stream().anyMatch {
|
||||||
|
element.name.startsWith(it as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void transform(@Nonnull TransformerContext context) {
|
||||||
|
byte[] content = context.is.readAllBytes()
|
||||||
|
|
||||||
|
if (nativeRelocator == null) {
|
||||||
|
nativeRelocator = new NativeRelocator(rootDir.toPath().resolve("relocate_natives"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (findProject(":fabric"))
|
try {
|
||||||
fabric {
|
Map.Entry<String, String> pathReplacement = replacements.entrySet().stream().filter {
|
||||||
jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar"
|
context.path.startsWith(it.key as String)
|
||||||
}
|
}.findFirst().orElseThrow()
|
||||||
|
|
||||||
if (findProject(":quilt"))
|
String path = context.path.replace(pathReplacement.key as String, pathReplacement.value as String)
|
||||||
quilt {
|
content = nativeRelocator.processBinary(path, content, replacements)
|
||||||
jarLocation = "build/libs/DistantHorizons-quilt-${rootProject.versionStr}.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
removeDuplicate "com.seibel.distanthorizons"
|
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 ->
|
subprojects { p ->
|
||||||
@@ -307,25 +346,19 @@ subprojects { p ->
|
|||||||
// Logging
|
// Logging
|
||||||
relocate "org.slf4j", "${librariesLocation}.slf4j"
|
relocate "org.slf4j", "${librariesLocation}.slf4j"
|
||||||
|
|
||||||
// // Sqlite Database
|
// Sqlite Database
|
||||||
// // James can't determine how to relocate the library correctly so this is commented out
|
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
||||||
// relocate ("org.sqlite", "${librariesLocation}.sqlite") {
|
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
||||||
// exclude("org/sqlite/core/NativeDB/**")
|
relocate "org.sqlite", "dh_sqlite", {
|
||||||
//
|
exclude "org/sqlite/native/**"
|
||||||
// exclude("org/sqlite/native/FreeBSD/**")
|
}
|
||||||
// exclude("org/sqlite/native/Linux-Android/**")
|
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||||
// exclude("org/sqlite/native/Linux-Musl/**")
|
|
||||||
// exclude("org/sqlite/native/Linux/arm/**")
|
transform(NativeTransformer) {
|
||||||
// exclude("org/sqlite/native/Linux/aarch64/**")
|
rootDir = project.rootDir
|
||||||
// exclude("org/sqlite/native/Linux/armv6/**")
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
// exclude("org/sqlite/native/Linux/x86/**")
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
// 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/**")
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
@@ -500,8 +533,9 @@ allprojects { p ->
|
|||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "maven-publish"
|
apply plugin: "maven-publish"
|
||||||
|
|
||||||
|
// Sets the name of the jar, the version will contain the name of the project if it isn't the root project
|
||||||
archivesBaseName = rootProject.mod_name
|
archivesBaseName = rootProject.mod_name
|
||||||
version = project.name + "-" + rootProject.versionStr
|
version = (project == rootProject ? "" : project.name + "-") + rootProject.versionStr
|
||||||
group = rootProject.maven_group
|
group = rootProject.maven_group
|
||||||
|
|
||||||
// this is the text that appears at the top of the overview (home) page
|
// this is the text that appears at the top of the overview (home) page
|
||||||
@@ -666,14 +700,3 @@ allprojects { p ->
|
|||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete the merged folder when running clean
|
|
||||||
task cleanMergedJars() {
|
|
||||||
def mergedFolder = file("Merged")
|
|
||||||
if (mergedFolder.exists()) {
|
|
||||||
delete(mergedFolder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add cleanMergedJars to the end of the "clean" task
|
|
||||||
tasks["clean"].finalizedBy(cleanMergedJars)
|
|
||||||
|
|||||||
+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! ====================
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
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 final Path rootDirectory;
|
||||||
|
private final Path cacheRoot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the NativeRelocator by preparing the environment if necessary.
|
||||||
|
* Executes the appropriate preparation script based on the OS.
|
||||||
|
*/
|
||||||
|
NativeRelocator(Path rootDirectory)
|
||||||
|
{
|
||||||
|
this.rootDirectory = rootDirectory;
|
||||||
|
this.cacheRoot = this.rootDirectory.resolve("cache");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepare() throws Exception
|
||||||
|
{
|
||||||
|
if (this.rootDirectory.resolve(".venv").toFile().exists())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.directory(this.rootDirectory.toFile());
|
||||||
|
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
if (os.contains("win"))
|
||||||
|
{
|
||||||
|
processBuilder.command("powershell", "-ExecutionPolicy", "Bypass", "./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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.directory(this.rootDirectory.toFile());
|
||||||
|
|
||||||
|
processBuilder.command(
|
||||||
|
this.rootDirectory.resolve(".venv/Scripts").toFile().exists()
|
||||||
|
? this.rootDirectory.resolve(".venv/Scripts/python.exe").toString()
|
||||||
|
: this.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
Path outputFilePath = this.cacheRoot.resolve(outputPath);
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
outputFilePath.getParent().toFile().mkdirs();
|
||||||
|
|
||||||
|
if (outputFilePath.toFile().exists())
|
||||||
|
{
|
||||||
|
return Files.readAllBytes(outputFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Relocating to " + outputPath + "...");
|
||||||
|
this.prepare();
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
||||||
|
{
|
||||||
|
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.fixModifiedBinary(outputFilePath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+23
-4
@@ -1,6 +1,7 @@
|
|||||||
package com.seibel.distanthorizons.common;
|
package com.seibel.distanthorizons.common;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||||
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
|
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
|
||||||
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
||||||
@@ -30,6 +31,16 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// "Forge byte" is an unused packet ID. We have our own system which works with all mod loaders,
|
||||||
|
// so we're just accounting for it by reading the protocol version as a byte instead of a short in Forge, to keep cross-loader compatibility
|
||||||
|
private final boolean forgeByteInProtocolVersion;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractPluginPacketSender() { this(false); }
|
||||||
|
public AbstractPluginPacketSender(boolean forgeByteInProtocolVersion)
|
||||||
|
{
|
||||||
|
this.forgeByteInProtocolVersion = forgeByteInProtocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
||||||
@@ -41,7 +52,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
@Override
|
@Override
|
||||||
public abstract void sendToServer(AbstractNetworkMessage message);
|
public abstract void sendToServer(AbstractNetworkMessage message);
|
||||||
|
|
||||||
public static AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
||||||
{
|
{
|
||||||
AbstractNetworkMessage message = null;
|
AbstractNetworkMessage message = null;
|
||||||
|
|
||||||
@@ -49,7 +60,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
{
|
{
|
||||||
in.markReaderIndex();
|
in.markReaderIndex();
|
||||||
|
|
||||||
int protocolVersion = in.readShort();
|
int protocolVersion = this.forgeByteInProtocolVersion ? in.readByte() : in.readShort();
|
||||||
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
return new IncompatibleMessageInternalEvent(protocolVersion);
|
return new IncompatibleMessageInternalEvent(protocolVersion);
|
||||||
@@ -82,11 +93,19 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
||||||
{
|
{
|
||||||
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild
|
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild
|
||||||
Objects.requireNonNull(message);
|
Objects.requireNonNull(message);
|
||||||
out.writeShort(ModInfo.PROTOCOL_VERSION);
|
|
||||||
|
if (this.forgeByteInProtocolVersion)
|
||||||
|
{
|
||||||
|
out.writeByte(ModInfo.PROTOCOL_VERSION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.writeShort(ModInfo.PROTOCOL_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package com.seibel.distanthorizons.common;
|
|||||||
|
|
||||||
#if MC_VER >= MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
@@ -12,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
||||||
{
|
{
|
||||||
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
|
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
|
||||||
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -23,11 +26,11 @@ public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) impl
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
|
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
|
||||||
{ return new CommonPacketPayload(AbstractPluginPacketSender.decodeMessage(in)); }
|
{ return new CommonPacketPayload(PACKET_SENDER.decodeMessage(in)); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
||||||
{ AbstractPluginPacketSender.encodeMessage(out, payload.message()); }
|
{ PACKET_SENDER.encodeMessage(out, payload.message()); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-4
@@ -30,14 +30,33 @@ public abstract class AbstractCommand
|
|||||||
* @param text The text to display in the success message.
|
* @param text The text to display in the success message.
|
||||||
* @return 1, indicating that the command was successful.
|
* @return 1, indicating that the command was successful.
|
||||||
*/
|
*/
|
||||||
protected int sendSuccessResponse(CommandContext<CommandSourceStack> commandContext, String text)
|
protected int sendSuccessResponse(CommandContext<CommandSourceStack> commandContext, String text, boolean notifyAdmins)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
commandContext.getSource().sendSuccess(() -> Component.literal(text), true);
|
commandContext.getSource().sendSuccess(() -> Component.literal(text), notifyAdmins);
|
||||||
#elif MC_VER >= MC_1_19_2
|
#elif MC_VER >= MC_1_19_2
|
||||||
commandContext.getSource().sendSuccess(Component.literal(text), true);
|
commandContext.getSource().sendSuccess(Component.literal(text), notifyAdmins);
|
||||||
#else
|
#else
|
||||||
commandContext.getSource().sendSuccess(new TranslatableComponent(text), true);
|
commandContext.getSource().sendSuccess(new TranslatableComponent(text), notifyAdmins);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a failure response to the player with the given text.
|
||||||
|
*
|
||||||
|
* @param commandContext The command context to send the response to.
|
||||||
|
* @param text The text to display in the failure message.
|
||||||
|
* @return 1, indicating that the command was successful.
|
||||||
|
*/
|
||||||
|
protected int sendFailureResponse(CommandContext<CommandSourceStack> commandContext, String text)
|
||||||
|
{
|
||||||
|
#if MC_VER >= MC_1_20_1
|
||||||
|
commandContext.getSource().sendFailure(Component.literal(text));
|
||||||
|
#elif MC_VER >= MC_1_19_2
|
||||||
|
commandContext.getSource().sendFailure(Component.literal(text));
|
||||||
|
#else
|
||||||
|
commandContext.getSource().sendFailure(new TranslatableComponent(text));
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -36,6 +36,7 @@ public class CommandInitializer
|
|||||||
|
|
||||||
builder.then(new ConfigCommand().buildCommand());
|
builder.then(new ConfigCommand().buildCommand());
|
||||||
builder.then(new DebugCommand().buildCommand());
|
builder.then(new DebugCommand().buildCommand());
|
||||||
|
builder.then(new PregenCommand().buildCommand());
|
||||||
|
|
||||||
if (DEBUG_CODEC_CRASH_MESSAGE)
|
if (DEBUG_CODEC_CRASH_MESSAGE)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
|||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -40,6 +41,7 @@ public class ConfigCommand extends AbstractCommand
|
|||||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||||
{
|
{
|
||||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
||||||
|
HashSet<String> addedCommands = new HashSet<>();
|
||||||
|
|
||||||
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
||||||
{
|
{
|
||||||
@@ -56,6 +58,11 @@ public class ConfigCommand extends AbstractCommand
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!addedCommands.add(configEntry.getChatCommandName()))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Duplicate command name: " + configEntry.getChatCommandName());
|
||||||
|
}
|
||||||
|
|
||||||
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getChatCommandName())
|
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getChatCommandName())
|
||||||
.executes(commandContext -> this.sendSuccessResponse(commandContext,
|
.executes(commandContext -> this.sendSuccessResponse(commandContext,
|
||||||
"\n" +
|
"\n" +
|
||||||
@@ -63,12 +70,13 @@ public class ConfigCommand extends AbstractCommand
|
|||||||
"§o" + configEntry.getComment().trim() + "§r\n" +
|
"§o" + configEntry.getComment().trim() + "§r\n" +
|
||||||
"§7Config file name: §f" + configEntry.name + "§7, category: §f" + configEntry.category + "\n" +
|
"§7Config file name: §f" + configEntry.name + "§7, category: §f" + configEntry.category + "\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"Current value of " + configEntry.getChatCommandName() + " is §n" + configEntry.get() + "§r"
|
"Current value of " + configEntry.getChatCommandName() + " is §n" + configEntry.get() + "§r",
|
||||||
|
false
|
||||||
));
|
));
|
||||||
|
|
||||||
ToIntBiFunction<CommandContext<CommandSourceStack>, Object> updateConfigValue = (commandContext, value) -> {
|
ToIntBiFunction<CommandContext<CommandSourceStack>, Object> updateConfigValue = (commandContext, value) -> {
|
||||||
configEntry.set(value);
|
configEntry.set(value);
|
||||||
return this.sendSuccessResponse(commandContext, "Changed the value of ["+configEntry.getChatCommandName()+"] to ["+value+"]");
|
return this.sendSuccessResponse(commandContext, "Changed the value of [" + configEntry.getChatCommandName() + "] to [" + value + "]", true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enum type needs a special case since enums aren't represented by existing argument type
|
// Enum type needs a special case since enums aren't represented by existing argument type
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class DebugCommand extends AbstractCommand
|
|||||||
.executes(c -> {
|
.executes(c -> {
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
F3Screen.addStringToDisplay(lines);
|
F3Screen.addStringToDisplay(lines);
|
||||||
return this.sendSuccessResponse(c, String.join("\n", lines));
|
return this.sendSuccessResponse(c, String.join("\n", lines), false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.seibel.distanthorizons.common.commands;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.generation.PregenManager;
|
||||||
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||||
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
import net.minecraft.commands.arguments.DimensionArgument;
|
||||||
|
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
|
||||||
|
import net.minecraft.server.level.ColumnPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||||
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
|
import static net.minecraft.commands.Commands.argument;
|
||||||
|
import static net.minecraft.commands.Commands.literal;
|
||||||
|
|
||||||
|
public class PregenCommand extends AbstractCommand
|
||||||
|
{
|
||||||
|
private final PregenManager pregenManager = new PregenManager();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||||
|
{
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> statusCommand = literal("status")
|
||||||
|
.executes(this::pregenStatus);
|
||||||
|
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> startCommand = literal("start")
|
||||||
|
.then(argument("dimension", DimensionArgument.dimension())
|
||||||
|
.then(argument("origin", ColumnPosArgument.columnPos())
|
||||||
|
.then(argument("chunkRadius", integer(32))
|
||||||
|
.executes(this::pregenStart))));
|
||||||
|
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> stopCommand = literal("stop")
|
||||||
|
.executes(this::pregenStop);
|
||||||
|
|
||||||
|
return literal("pregen")
|
||||||
|
.then(statusCommand)
|
||||||
|
.then(startCommand)
|
||||||
|
.then(stopCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int pregenStatus(CommandContext<CommandSourceStack> c)
|
||||||
|
{
|
||||||
|
String statusString = this.pregenManager.getStatusString();
|
||||||
|
//noinspection ReplaceNullCheck
|
||||||
|
if (statusString != null)
|
||||||
|
{
|
||||||
|
return this.sendSuccessResponse(c, statusString, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this.sendSuccessResponse(c, "Pregen is not running", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int pregenStart(CommandContext<CommandSourceStack> c) throws CommandSyntaxException
|
||||||
|
{
|
||||||
|
this.sendSuccessResponse(c, "Starting pregen. Progress will be in the server console.", true);
|
||||||
|
|
||||||
|
ServerLevel level = DimensionArgument.getDimension(c, "dimension");
|
||||||
|
ColumnPos origin = ColumnPosArgument.getColumnPos(c, "origin");
|
||||||
|
int chunkRadius = getInteger(c, "chunkRadius");
|
||||||
|
|
||||||
|
CompletableFuture<Void> future = this.pregenManager.startPregen(
|
||||||
|
ServerLevelWrapper.getWrapper(level),
|
||||||
|
new DhBlockPos2D(#if MC_VER >= MC_1_19_2 origin.x(), origin.z() #else origin.x, origin.z #endif),
|
||||||
|
chunkRadius
|
||||||
|
);
|
||||||
|
|
||||||
|
future.whenComplete((result, throwable) -> {
|
||||||
|
if (throwable instanceof CancellationException)
|
||||||
|
{
|
||||||
|
this.sendSuccessResponse(c, "Pregen is cancelled", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (throwable != null)
|
||||||
|
{
|
||||||
|
this.sendFailureResponse(c, "Pregen failed: " + throwable.getMessage() + "\n Check the logs for more details.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendSuccessResponse(c, "Pregen is complete", true);
|
||||||
|
});
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int pregenStop(CommandContext<CommandSourceStack> c)
|
||||||
|
{
|
||||||
|
CompletableFuture<Void> runningPregen = this.pregenManager.getRunningPregen();
|
||||||
|
if (runningPregen == null)
|
||||||
|
{
|
||||||
|
return this.sendFailureResponse(c, "Pregen is not running");
|
||||||
|
}
|
||||||
|
|
||||||
|
runningPregen.cancel(true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+38
-24
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -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,48 @@ 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";
|
||||||
|
#elif MC_VER == MC_1_21_5
|
||||||
|
return "1.21.5";
|
||||||
#else
|
#else
|
||||||
return SharedConstants.getCurrentVersion().getId();
|
ERROR MC version constant missing
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+94
-26
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -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;
|
||||||
@@ -84,26 +86,25 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||||
|
|
||||||
/** keep track of broken blocks so we don't log every time */
|
/** 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<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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;
|
||||||
private final int hashCode;
|
private final int hashCode;
|
||||||
/**
|
/** Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE} */
|
||||||
* Cached opacity value, -1 if not populated. <br>
|
private final int opacity;
|
||||||
* Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE}
|
|
||||||
*/
|
|
||||||
private int opacity = -1;
|
|
||||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||||
private byte blockMaterialId = 0;
|
private byte blockMaterialId = 0;
|
||||||
|
|
||||||
private final boolean isBeaconBlock;
|
private final boolean isBeaconBlock;
|
||||||
private final boolean isBeaconBaseBlock;
|
private final boolean isBeaconBaseBlock;
|
||||||
|
private final boolean allowsBeaconBeamPassage;
|
||||||
/** null if this block can't tint beacons */
|
/** null if this block can't tint beacons */
|
||||||
private final Color beaconTintColor;
|
private final Color beaconTintColor;
|
||||||
private final Color mapColor;
|
private final Color mapColor;
|
||||||
@@ -160,9 +161,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.serialString = this.serialize(levelWrapper);
|
this.serialString = this.serialize(levelWrapper);
|
||||||
this.hashCode = Objects.hash(this.serialString);
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
||||||
|
this.opacity = this.calculateOpacity();
|
||||||
|
|
||||||
|
String lowercaseSerial = this.serialString.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
// beacon blocks
|
// beacon blocks
|
||||||
String lowercaseSerial = this.serialString.toLowerCase();
|
|
||||||
boolean isBeaconBaseBlock = false;
|
boolean isBeaconBaseBlock = false;
|
||||||
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -198,6 +202,39 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.beaconTintColor = beaconTintColor;
|
this.beaconTintColor = beaconTintColor;
|
||||||
|
|
||||||
|
|
||||||
|
// allow/deny beacon beam passage
|
||||||
|
boolean allowsBeaconBeamPassage;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
// get block properties (defaults to the values used by air)
|
||||||
|
boolean canOcclude = this.getCanOcclude();
|
||||||
|
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
||||||
|
|
||||||
|
if (lowercaseSerial.contains("minecraft:bedrock"))
|
||||||
|
{
|
||||||
|
// bedrock is a special case fully opaque block that does allow beacons through
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
else if (propagatesSkyLightDown || !canOcclude)
|
||||||
|
{
|
||||||
|
// stairs, cake, fences, etc.
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// non-opaque blocks (glass, mob spawners, etc.)
|
||||||
|
// all allow beacons through
|
||||||
|
allowsBeaconBeamPassage = (this.opacity != LodUtil.BLOCK_FULLY_OPAQUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// air allows beacons through
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
|
||||||
|
|
||||||
|
|
||||||
int mcColor = 0;
|
int mcColor = 0;
|
||||||
if (this.blockState != null)
|
if (this.blockState != null)
|
||||||
{
|
{
|
||||||
@@ -341,13 +378,13 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
//=================//
|
//=================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOpacity()
|
public int getOpacity() { return this.opacity; }
|
||||||
|
private int calculateOpacity()
|
||||||
{
|
{
|
||||||
// use the cached opacity value if possible
|
// get block properties (defaults to the values used by air)
|
||||||
if (this.opacity != -1)
|
boolean canOcclude = this.getCanOcclude();
|
||||||
{
|
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
||||||
return this.opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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
|
||||||
@@ -356,19 +393,20 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
{
|
{
|
||||||
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
|
||||||
@@ -378,9 +416,37 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.opacity = opacity;
|
return opacity;
|
||||||
return this.opacity;
|
|
||||||
}
|
}
|
||||||
|
private boolean getCanOcclude()
|
||||||
|
{
|
||||||
|
// defaults to the value used by air
|
||||||
|
boolean canOcclude = false;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
canOcclude = this.blockState.canOcclude();
|
||||||
|
}
|
||||||
|
|
||||||
|
return canOcclude;
|
||||||
|
}
|
||||||
|
private boolean getPropagatesSkyLightDown()
|
||||||
|
{
|
||||||
|
// defaults to the value used by air
|
||||||
|
boolean propagatesSkyLightDown = true;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
|
#else
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return propagatesSkyLightDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
||||||
@@ -453,6 +519,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
||||||
@Override
|
@Override
|
||||||
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
||||||
|
@Override
|
||||||
|
public boolean allowsBeaconBeamPassage() { return this.allowsBeaconBeamPassage; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getMapColor() { return this.mapColor; }
|
public Color getMapColor() { return this.mapColor; }
|
||||||
@@ -596,9 +664,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
if (block == null)
|
if (block == null)
|
||||||
{
|
{
|
||||||
// shouldn't normally happen, but here to make the compiler happy
|
// 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.");
|
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 +696,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
if (blockStatePropertiesString != null)
|
if (blockStatePropertiesString != null)
|
||||||
{
|
{
|
||||||
// we should have found a blockstate, but didn't
|
// 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.");
|
LOGGER.warn("Unable to find BlockState for Block [" + resourceLocation + "] with properties: [" + blockStatePropertiesString + "]. Using the default block state.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+74
-17
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -40,11 +40,18 @@ import java.util.Random;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModelPart;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This stores and calculates the colors
|
* This stores and calculates the colors
|
||||||
* the given {@link BlockState} should have based
|
* the given {@link BlockState} should have based
|
||||||
@@ -196,9 +203,7 @@ public class ClientBlockStateColorCache
|
|||||||
List<BakedQuad> quads = null;
|
List<BakedQuad> quads = null;
|
||||||
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
||||||
{
|
{
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = this.getQuadsForDirection(direction);
|
||||||
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
|
||||||
|
|
||||||
if (quads != null && !quads.isEmpty()
|
if (quads != null && !quads.isEmpty()
|
||||||
&& !(
|
&& !(
|
||||||
this.blockState.getBlock() instanceof RotatedPillarBlock
|
this.blockState.getBlock() instanceof RotatedPillarBlock
|
||||||
@@ -212,19 +217,37 @@ public class ClientBlockStateColorCache
|
|||||||
|
|
||||||
if (quads == null || quads.isEmpty())
|
if (quads == null || quads.isEmpty())
|
||||||
{
|
{
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = this.getUnculledQuads();
|
||||||
getBlockModel(this.blockState).getQuads(this.blockState, null, RANDOM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quads != null && !quads.isEmpty())
|
if (quads != null
|
||||||
|
&& !quads.isEmpty()
|
||||||
|
&& quads.get(0) != null)
|
||||||
{
|
{
|
||||||
this.needPostTinting = quads.get(0).isTinted();
|
BakedQuad firstQuad = quads.get(0);
|
||||||
this.needShade = quads.get(0).isShade();
|
|
||||||
this.tintIndex = quads.get(0).getTintIndex();
|
this.needPostTinting = firstQuad.isTinted();
|
||||||
|
#if MC_VER <= MC_1_21_4
|
||||||
|
this.needShade = firstQuad.isShade();
|
||||||
|
this.tintIndex = firstQuad.getTintIndex();
|
||||||
|
#else
|
||||||
|
this.needShade = firstQuad.shade();
|
||||||
|
this.tintIndex = firstQuad.tintIndex();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
firstQuad.sprite,
|
||||||
#else quads.get(0).getSprite(), #endif
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
#elif MC_VER < MC_1_21_5
|
||||||
|
this.baseColor = calculateColorFromTexture(
|
||||||
|
firstQuad.getSprite(),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
#else
|
||||||
|
this.baseColor = calculateColorFromTexture(
|
||||||
|
firstQuad.sprite(),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -232,8 +255,7 @@ public class ClientBlockStateColorCache
|
|||||||
this.needPostTinting = false;
|
this.needPostTinting = false;
|
||||||
this.needShade = false;
|
this.needShade = false;
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
this.baseColor = this.getParticleIconColor();
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -242,8 +264,7 @@ public class ClientBlockStateColorCache
|
|||||||
this.needPostTinting = true;
|
this.needPostTinting = true;
|
||||||
this.needShade = false;
|
this.needShade = false;
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
this.baseColor = this.getParticleIconColor();
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isColorResolved = true;
|
this.isColorResolved = true;
|
||||||
@@ -253,6 +274,35 @@ public class ClientBlockStateColorCache
|
|||||||
RESOLVE_LOCK.unlock();
|
RESOLVE_LOCK.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private List<BakedQuad> getUnculledQuads() { return this.getQuadsForDirection(null); }
|
||||||
|
@Nullable
|
||||||
|
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction)
|
||||||
|
{
|
||||||
|
List<BakedQuad> quads = null;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
||||||
|
#else
|
||||||
|
List<BlockModelPart> blockModelPartList = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).collectParts(RANDOM);
|
||||||
|
|
||||||
|
quads = new ArrayList<>();
|
||||||
|
if (blockModelPartList != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < blockModelPartList.size(); i++)
|
||||||
|
{
|
||||||
|
// if direction is null this will return the unculled quads
|
||||||
|
quads.addAll(blockModelPartList.get(i).getQuads(direction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return quads;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Perhaps make this not just use the first frame?
|
//TODO: Perhaps make this not just use the first frame?
|
||||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
||||||
{
|
{
|
||||||
@@ -383,6 +433,13 @@ public class ClientBlockStateColorCache
|
|||||||
return (bias + (scale * t)) >>> 16;
|
return (bias + (scale * t)) >>> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getParticleIconColor()
|
||||||
|
{
|
||||||
|
return calculateColorFromTexture(
|
||||||
|
Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//===============//
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+48
-23
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -19,19 +19,16 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -46,30 +43,61 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|||||||
* but {@link Nullable} is there just in case.
|
* but {@link Nullable} is there just in case.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Biome biome;
|
#if MC_VER >= MC_1_18_2
|
||||||
|
public final Holder<Biome> biome;
|
||||||
|
#else
|
||||||
|
public final Biome biome;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the TintWithoutLevelOverrider, storing the provided Biome Holder for late-binding access.
|
||||||
|
*
|
||||||
|
* <p>Previously, this class might have immediately unwrapped the Holder like this:</p>
|
||||||
|
* <pre>{@code
|
||||||
|
* // Inside constructor (OLD WAY - PROBLEMATIC):
|
||||||
|
* Holder<Biome> biomeHolder = getTheHolderFromSomewhere();
|
||||||
|
* this.biome = biomeHolder.value(); // <-- PROBLEM HERE
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>This approach is problematic because the {@link net.minecraft.core.Holder} system,
|
||||||
|
* particularly {@code Holder.Reference}, is designed for <strong>late binding</strong>. Here's why storing
|
||||||
|
* the Holder itself is now necessary:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>A {@code Holder.Reference<Biome>} might be created initially just with a
|
||||||
|
* {@link net.minecraft.resources.ResourceKey} (like {@code minecraft:plains}), but its actual
|
||||||
|
* {@link net.minecraft.core.Holder#value() value()} (the {@code Biome} object itself) might be {@code null}
|
||||||
|
* at construction time.</li>
|
||||||
|
* <li>Later, during game loading, registry population, or potentially due to modifications by other mods
|
||||||
|
* (e.g., Polytone), the system calls internal binding methods (like {@code bindValue(Biome)})
|
||||||
|
* on the {@code Holder} instance. This sets or <strong>updates</strong> the internal reference to the
|
||||||
|
* actual {@code Biome} object.</li>
|
||||||
|
* <li>Crucially, the binding process might assign a completely <strong>new</strong> {@code Biome} object
|
||||||
|
* instance to the {@code Holder} reference, replacing any previous one.</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* <p>If we unwrapped the {@code Holder} using {@code .value()} within the constructor (the old way),
|
||||||
|
* our class's internal {@code biome} field would permanently store a reference to whatever {@code Biome}
|
||||||
|
* object the {@code Holder} pointed to *at that exact moment*. It would have no link back to the
|
||||||
|
* {@code Holder} and would be unaware if the {@code Holder} was later updated to point to a different
|
||||||
|
* (or the initially missing) {@code Biome} object. This would lead to using stale or even {@code null} data.</p>
|
||||||
|
*
|
||||||
|
* <p>By storing the {@code Holder<Biome>} itself, this class can call {@link net.minecraft.core.Holder#value()}
|
||||||
|
* whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome}
|
||||||
|
* instance associated with the holder at that time.</p>
|
||||||
|
*/
|
||||||
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
||||||
{
|
{
|
||||||
// try to get the wrapped biome
|
#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome = biomeWrapper.biome;
|
||||||
Biome unwrappedBiome = null;
|
if (biome == null) // We are looking at the empty biome wrapper
|
||||||
if (biomeWrapper.biome != null)
|
|
||||||
{
|
{
|
||||||
unwrappedBiome = unwrap(biomeWrapper.biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unwrappedBiome == null)
|
|
||||||
{
|
|
||||||
// we are looking at the empty biome wrapper, try using plains as a backup
|
|
||||||
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper());
|
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper());
|
||||||
if (plainsBiomeWrapper != null)
|
if (plainsBiomeWrapper != null)
|
||||||
{
|
{
|
||||||
unwrappedBiome = unwrap(plainsBiomeWrapper.biome);
|
biome = plainsBiomeWrapper.biome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.biome = unwrappedBiome;
|
this.biome = biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -77,15 +105,12 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|||||||
@Override
|
@Override
|
||||||
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
{
|
{
|
||||||
if (this.biome != null)
|
if (this.biome == null)
|
||||||
{
|
|
||||||
return colorResolver.getColor(this.biome, blockPos.getX(), blockPos.getZ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// hopefully unneeded debug color
|
// hopefully unneeded debug color
|
||||||
return ColorUtil.CYAN;
|
return ColorUtil.CYAN;
|
||||||
}
|
}
|
||||||
|
return colorResolver.getColor(unwrap(biome), blockPos.getX(), blockPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+88
-4
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.chunk;
|
package com.seibel.distanthorizons.common.wrappers.chunk;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
@@ -279,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;
|
||||||
}
|
}
|
||||||
@@ -386,6 +385,91 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(pos), this.wrappedLevel, guess);
|
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(pos), this.wrappedLevel, guess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
// Commented out experimental LevelChunkSection cloning logic to fix extremely rare concurrency modification issue
|
||||||
|
// James has only ever seen a report relating to LevelSection concurrent modification once,
|
||||||
|
// the issue can cause DH lighting/LOD building to fail due to the chunk being modified on the server.
|
||||||
|
// James has only heard of this issue once, so it isn't a high priority issue.
|
||||||
|
// And from James' quick look at a few different MC versions it appears the LevelChunkSection object changes quite drastically between MC versions,
|
||||||
|
// meaning any cloning logic would have to either be a new wrapper or very MC version dependent, either way a lot of additional work.
|
||||||
|
// Due to the large time cost and extremely rare nature of the issue, this logic is commented out unless this issue pops up again in the future.
|
||||||
|
|
||||||
|
// instance variable to hold the cloned sections
|
||||||
|
private final LevelChunkSection[] levelChunkSections;
|
||||||
|
|
||||||
|
// new constructor logic to clone the sections
|
||||||
|
public constructor(...)
|
||||||
|
{
|
||||||
|
// other constructor logic //
|
||||||
|
|
||||||
|
LevelChunkSection[] sections = this.chunk.getSections();
|
||||||
|
this.levelChunkSections = new LevelChunkSection[sections.length];
|
||||||
|
for (int i = 0; i < sections.length; i++)
|
||||||
|
{
|
||||||
|
LevelChunkSection section = sections[i];
|
||||||
|
if (section != null)
|
||||||
|
{
|
||||||
|
// TODO implement section cloning for older MC versions, only 1.21.4 MC (and maybe other semi recent versions) have a clean way to handle this
|
||||||
|
// TODO we probably want a wrapper object instead
|
||||||
|
#if MC_VER < MC_1_21_4
|
||||||
|
this.levelChunkSections[i] = section;
|
||||||
|
#else
|
||||||
|
this.levelChunkSections[i] = section.copy();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replacement getters
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ)
|
||||||
|
{
|
||||||
|
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||||
|
return this.getBlockStateInternal(relX, relY, relZ, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ, IMutableBlockPosWrapper mcBlockPos, IBlockStateWrapper guess)
|
||||||
|
{
|
||||||
|
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||||
|
return this.getBlockStateInternal(relX, relY, relZ, guess);
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal getter logic
|
||||||
|
private IBlockStateWrapper getBlockStateInternal(int relX, int y, int relZ, @Nullable IBlockStateWrapper guess)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// attempt to get the section for this position
|
||||||
|
int i = (y - this.getInclusiveMinBuildHeight()) / 16;
|
||||||
|
if (i >= 0 && i < this.levelChunkSections.length)
|
||||||
|
{
|
||||||
|
LevelChunkSection section = this.levelChunkSections[i];
|
||||||
|
if (!section.hasOnlyAir())
|
||||||
|
{
|
||||||
|
if (guess != null)
|
||||||
|
{
|
||||||
|
return BlockStateWrapper.fromBlockState(section.getBlockState(relX & 15, y & 15, relZ & 15), this.wrappedLevel, guess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BlockStateWrapper.fromBlockState(section.getBlockState(relX & 15, y & 15, relZ & 15), this.wrappedLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BlockStateWrapper.AIR;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return BlockStateWrapper.AIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IMutableBlockPosWrapper getMutableBlockPosWrapper() { return MUTABLE_BLOCK_POS_WRAPPER_REF.get(); }
|
public IMutableBlockPosWrapper getMutableBlockPosWrapper() { return MUTABLE_BLOCK_POS_WRAPPER_REF.get(); }
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -317,10 +317,13 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
System.out.println("ERROR: Failed to show [" + info.getNameWCategory() + "]");
|
String message = "ERROR: Failed to show [\" + info.getNameWCategory() + \"], error: ["+e.getMessage()+"]";
|
||||||
if (info.get() != null)
|
if (info.get() != null)
|
||||||
System.out.print(" with the value [" + info.get() + "] with type [" + info.getType() + "]");
|
{
|
||||||
e.printStackTrace();
|
message += " with the value [" + info.get() + "] with type [" + info.getType() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.error(message, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+32
-15
@@ -1,8 +1,8 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.gui.updater;
|
package com.seibel.distanthorizons.common.wrappers.gui.updater;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
||||||
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.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.jar.installer.MarkdownFormatter;
|
import com.seibel.distanthorizons.core.jar.installer.MarkdownFormatter;
|
||||||
@@ -14,6 +14,7 @@ import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
|||||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
@@ -21,6 +22,7 @@ import net.minecraft.client.gui.narration.NarratableEntry;
|
|||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
import net.minecraft.client.gui.GuiComponent;
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
#endif
|
#endif
|
||||||
@@ -39,6 +41,9 @@ import java.util.*;
|
|||||||
// TODO: Make this
|
// TODO: Make this
|
||||||
public class ChangelogScreen extends DhScreen
|
public class ChangelogScreen extends DhScreen
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
|
||||||
private Screen parent;
|
private Screen parent;
|
||||||
private String versionID;
|
private String versionID;
|
||||||
private List<String> changelog;
|
private List<String> changelog;
|
||||||
@@ -51,24 +56,32 @@ public class ChangelogScreen extends DhScreen
|
|||||||
this(parent, null);
|
this(parent, null);
|
||||||
|
|
||||||
if (!ModrinthGetter.initted) // Make sure the modrinth stuff is initted
|
if (!ModrinthGetter.initted) // Make sure the modrinth stuff is initted
|
||||||
|
{
|
||||||
ModrinthGetter.init();
|
ModrinthGetter.init();
|
||||||
|
}
|
||||||
if (!ModrinthGetter.initted) // If its not initted, then this isnt usable
|
if (!ModrinthGetter.initted) // If its not initted, then this isnt usable
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ModrinthGetter.mcVersions.contains(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()))
|
if (!ModrinthGetter.mcVersions.contains(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String versionID = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
String versionID = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||||
if (versionID == null)
|
if (versionID == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
setupChangelog(versionID);
|
this.setupChangelog(versionID);
|
||||||
usable = true;
|
this.usable = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
LOGGER.error("failed to setup changelog, error: ["+e.getMessage()+"].", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +93,13 @@ public class ChangelogScreen extends DhScreen
|
|||||||
|
|
||||||
|
|
||||||
if (versionID == null)
|
if (versionID == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
setupChangelog(versionID);
|
this.setupChangelog(versionID);
|
||||||
usable = true;
|
this.usable = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -129,8 +144,10 @@ public class ChangelogScreen extends DhScreen
|
|||||||
protected void init()
|
protected void init()
|
||||||
{
|
{
|
||||||
super.init();
|
super.init();
|
||||||
if (!usable)
|
if (!this.usable)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.addBtn( // Close
|
this.addBtn( // Close
|
||||||
@@ -141,9 +158,9 @@ public class ChangelogScreen extends DhScreen
|
|||||||
|
|
||||||
|
|
||||||
this.changelogArea = new TextArea(this.minecraft, this.width * 2, this.height, 32, 32, 10);
|
this.changelogArea = new TextArea(this.minecraft, this.width * 2, this.height, 32, 32, 10);
|
||||||
for (int i = 0; i < changelog.size(); i++)
|
for (int i = 0; i < this.changelog.size(); i++)
|
||||||
{
|
{
|
||||||
this.changelogArea.addButton(TextOrLiteral(changelog.get(i)));
|
this.changelogArea.addButton(TextOrLiteral(this.changelog.get(i)));
|
||||||
// drawString(matrices, this.font, changelog.get(i), this.width / 2 - 175, this.height / 2 - 100 + i*10, 0xFFFFFF);
|
// drawString(matrices, this.font, changelog.get(i), this.width / 2 - 175, this.height / 2 - 100 + i*10, 0xFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,13 +206,13 @@ public class ChangelogScreen extends DhScreen
|
|||||||
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
|
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
|
||||||
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
||||||
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
||||||
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15, 0xFFFFFF); // Render title
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry>
|
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry>
|
||||||
@@ -210,7 +227,7 @@ public class ChangelogScreen extends DhScreen
|
|||||||
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||||
#endif
|
#endif
|
||||||
this.centerListVertically = false;
|
this.centerListVertically = false;
|
||||||
textRenderer = minecraftClient.font;
|
this.textRenderer = minecraftClient.font;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addButton(Component text)
|
public void addButton(Component text)
|
||||||
@@ -252,20 +269,20 @@ public class ChangelogScreen extends DhScreen
|
|||||||
@Override
|
@Override
|
||||||
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
{
|
{
|
||||||
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends GuiEventListener> children()
|
public List<? extends GuiEventListener> children()
|
||||||
{
|
{
|
||||||
return children;
|
return this.children;
|
||||||
}
|
}
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public List<? extends NarratableEntry> narratables()
|
public List<? extends NarratableEntry> narratables()
|
||||||
{
|
{
|
||||||
return children;
|
return this.children;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -4,6 +4,7 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||||
@@ -15,6 +16,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
|
|
||||||
@@ -29,6 +31,9 @@ import java.util.*;
|
|||||||
// and also maybe add this suggestion https://discord.com/channels/881614130614767666/1035863487110467625/1035949054485594192
|
// and also maybe add this suggestion https://discord.com/channels/881614130614767666/1035863487110467625/1035949054485594192
|
||||||
public class UpdateModScreen extends DhScreen
|
public class UpdateModScreen extends DhScreen
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
|
||||||
private Screen parent;
|
private Screen parent;
|
||||||
private String newVersionID;
|
private String newVersionID;
|
||||||
|
|
||||||
@@ -100,7 +105,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to setup update mod screen, error: ["+e.getMessage()+"].", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ModInfo.IS_DEV_BUILD)
|
if (!ModInfo.IS_DEV_BUILD)
|
||||||
|
|||||||
+33
-6
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -293,15 +305,30 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
player.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
|
||||||
#else
|
#else
|
||||||
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendOverlayMessage(String string)
|
||||||
|
{
|
||||||
|
LocalPlayer player = this.getPlayer();
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_19_2
|
||||||
|
player.displayClientMessage(new TextComponent(string), /*isOverlay*/true);
|
||||||
|
#else
|
||||||
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crashes Minecraft, displaying the given errorMessage <br> <br>
|
* Crashes Minecraft, displaying the given errorMessage <br> <br>
|
||||||
* In the following format: <br>
|
* In the following format: <br>
|
||||||
|
|||||||
+110
-31
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -19,7 +19,11 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.minecraft;
|
package com.seibel.distanthorizons.common.wrappers.minecraft;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
#elif MC_VER == MC_1_21_5
|
||||||
|
import com.mojang.blaze3d.opengl.GlStateManager;
|
||||||
|
#endif
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
@@ -29,13 +33,23 @@ import org.lwjgl.opengl.GL32;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that contains everything
|
* <b>Why does DH often call GL methods twice? </b><br>
|
||||||
* related to rendering in Minecraft.
|
* Once using the base {@link GL32} function and a second time using
|
||||||
|
* Minecraft's {@link GlStateManager}?<br><br>
|
||||||
*
|
*
|
||||||
* @author James Seibel
|
* <b>Answer: </b><br>
|
||||||
* @version 12-12-2021
|
* Compatibility and robustness<br>
|
||||||
|
* In general all MC rendering should go through MC's {@link GlStateManager},
|
||||||
|
* however that isn't always the case.
|
||||||
|
* So, to prevent issues if a mod (or MC itself) calls a direct GL function
|
||||||
|
* instead of the {@link GlStateManager} wrapper, we need to be sure about what the actual
|
||||||
|
* set value is (whether setting or getting) and that MC knows what DH has done.
|
||||||
|
* This way whether a mod (or MC) is using the {@link GlStateManager} or direct GL calls,
|
||||||
|
* they should always have the correct value for anything DH has modified.
|
||||||
|
* <br><br>
|
||||||
|
* This may slow down some low end GPUs that are driver limited,
|
||||||
|
* however James would rather have slow correct rendering vs fast broken rendering.
|
||||||
*/
|
*/
|
||||||
//@Environment(EnvType.CLIENT)
|
|
||||||
public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
||||||
{
|
{
|
||||||
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
|
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
|
||||||
@@ -53,10 +67,18 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
|
|
||||||
/** @see GL32#GL_SCISSOR_TEST */
|
/** @see GL32#GL_SCISSOR_TEST */
|
||||||
@Override
|
@Override
|
||||||
public void enableScissorTest() { GlStateManager._enableScissorTest(); }
|
public void enableScissorTest()
|
||||||
|
{
|
||||||
|
GL32.glEnable(GL32.GL_SCISSOR_TEST);
|
||||||
|
GlStateManager._enableScissorTest();
|
||||||
|
}
|
||||||
/** @see GL32#GL_SCISSOR_TEST */
|
/** @see GL32#GL_SCISSOR_TEST */
|
||||||
@Override
|
@Override
|
||||||
public void disableScissorTest() { GlStateManager._disableScissorTest(); }
|
public void disableScissorTest()
|
||||||
|
{
|
||||||
|
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||||
|
GlStateManager._disableScissorTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// stencil //
|
// stencil //
|
||||||
@@ -71,39 +93,77 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
|
|
||||||
/** @see GL32#GL_DEPTH_TEST */
|
/** @see GL32#GL_DEPTH_TEST */
|
||||||
@Override
|
@Override
|
||||||
public void enableDepthTest() { GlStateManager._enableDepthTest(); }
|
public void enableDepthTest()
|
||||||
|
{
|
||||||
|
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||||
|
GlStateManager._enableDepthTest();
|
||||||
|
}
|
||||||
/** @see GL32#GL_DEPTH_TEST */
|
/** @see GL32#GL_DEPTH_TEST */
|
||||||
@Override
|
@Override
|
||||||
public void disableDepthTest() { GlStateManager._disableDepthTest(); }
|
public void disableDepthTest()
|
||||||
|
{
|
||||||
|
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||||
|
GlStateManager._disableDepthTest();
|
||||||
|
}
|
||||||
|
|
||||||
/** @see GL32#glDepthFunc(int) */
|
/** @see GL32#glDepthFunc(int) */
|
||||||
@Override
|
@Override
|
||||||
public void glDepthFunc(int func) { GlStateManager._depthFunc(func); }
|
public void glDepthFunc(int func)
|
||||||
|
{
|
||||||
|
GL32.glDepthFunc(func);
|
||||||
|
GlStateManager._depthFunc(func);
|
||||||
|
}
|
||||||
|
|
||||||
/** @see GL32#glDepthMask(boolean) */
|
/** @see GL32#glDepthMask(boolean) */
|
||||||
@Override
|
@Override
|
||||||
public void enableDepthMask() { GlStateManager._depthMask(true); }
|
public void enableDepthMask()
|
||||||
|
{
|
||||||
|
GL32.glDepthMask(true);
|
||||||
|
GlStateManager._depthMask(true);
|
||||||
|
}
|
||||||
/** @see GL32#glDepthMask(boolean) */
|
/** @see GL32#glDepthMask(boolean) */
|
||||||
@Override
|
@Override
|
||||||
public void disableDepthMask() { GlStateManager._depthMask(false); }
|
public void disableDepthMask()
|
||||||
|
{
|
||||||
|
GL32.glDepthMask(false);
|
||||||
|
GlStateManager._depthMask(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// blending //
|
// blending //
|
||||||
|
|
||||||
/** @see GL32#GL_BLEND */
|
/** @see GL32#GL_BLEND */
|
||||||
@Override
|
@Override
|
||||||
public void enableBlend() { GlStateManager._enableBlend(); }
|
public void enableBlend()
|
||||||
|
{
|
||||||
|
GL32.glEnable(GL32.GL_BLEND);
|
||||||
|
GlStateManager._enableBlend();
|
||||||
|
}
|
||||||
/** @see GL32#GL_BLEND */
|
/** @see GL32#GL_BLEND */
|
||||||
@Override
|
@Override
|
||||||
public void disableBlend() { GlStateManager._disableBlend(); }
|
public void disableBlend()
|
||||||
|
{
|
||||||
|
GL32.glDisable(GL32.GL_BLEND);
|
||||||
|
GlStateManager._disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
/** @see GL32#glBlendFunc */
|
/** @see GL32#glBlendFunc */
|
||||||
@Override
|
@Override
|
||||||
public void glBlendFunc(int sfactor, int dfactor) { GlStateManager._blendFunc(sfactor, dfactor); }
|
public void glBlendFunc(int sfactor, int dfactor)
|
||||||
|
{
|
||||||
|
GL32.glBlendFunc(sfactor, dfactor);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
GlStateManager._blendFunc(sfactor, dfactor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
/** @see GL32#glBlendFuncSeparate */
|
/** @see GL32#glBlendFuncSeparate */
|
||||||
@Override
|
@Override
|
||||||
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha)
|
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha)
|
||||||
{ GlStateManager._blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); }
|
{
|
||||||
|
GL32.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
|
||||||
|
GlStateManager._blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// frame buffers //
|
// frame buffers //
|
||||||
@@ -111,7 +171,10 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
/** @see GL32#glBindFramebuffer */
|
/** @see GL32#glBindFramebuffer */
|
||||||
@Override
|
@Override
|
||||||
public void glBindFramebuffer(int target, int framebuffer)
|
public void glBindFramebuffer(int target, int framebuffer)
|
||||||
{ GlStateManager._glBindFramebuffer(target, framebuffer); }
|
{
|
||||||
|
GL32.glBindFramebuffer(target, framebuffer);
|
||||||
|
GlStateManager._glBindFramebuffer(target, framebuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// buffers //
|
// buffers //
|
||||||
@@ -124,17 +187,33 @@ 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 //
|
||||||
|
|
||||||
/** @see GL32#GL_CULL_FACE */
|
/** @see GL32#GL_CULL_FACE */
|
||||||
@Override
|
@Override
|
||||||
public void enableFaceCulling() { GlStateManager._enableCull(); }
|
public void enableFaceCulling()
|
||||||
|
{
|
||||||
|
GL32.glEnable(GL32.GL_CULL_FACE);
|
||||||
|
GlStateManager._enableCull();
|
||||||
|
}
|
||||||
/** @see GL32#GL_CULL_FACE */
|
/** @see GL32#GL_CULL_FACE */
|
||||||
@Override
|
@Override
|
||||||
public void disableFaceCulling() { GlStateManager._disableCull(); }
|
public void disableFaceCulling()
|
||||||
|
{
|
||||||
|
GL32.glDisable(GL32.GL_CULL_FACE);
|
||||||
|
GlStateManager._disableCull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// textures //
|
// textures //
|
||||||
@@ -148,24 +227,24 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
|
|
||||||
/** @see GL32#glActiveTexture(int) */
|
/** @see GL32#glActiveTexture(int) */
|
||||||
@Override
|
@Override
|
||||||
public void glActiveTexture(int textureId) { GlStateManager._activeTexture(textureId); }
|
public void glActiveTexture(int textureId)
|
||||||
/** only works for textures bound via this system or MC's {@link GlStateManager} */
|
|
||||||
@Override
|
|
||||||
public int getActiveTexture()
|
|
||||||
{
|
{
|
||||||
#if MC_VER <= MC_1_16_5
|
GL32.glActiveTexture(textureId);
|
||||||
return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE);
|
GlStateManager._activeTexture(textureId);
|
||||||
#else
|
|
||||||
return GlStateManager._getActiveTexture();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always binds to {@link GL32#GL_TEXTURE_2D}
|
* Always binds to {@link GL32#GL_TEXTURE_2D}
|
||||||
* @see GL32#glBindTexture(int, int)
|
* @see GL32#glBindTexture(int, int)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void glBindTexture(int texture) { GlStateManager._bindTexture(texture); }
|
public void glBindTexture(int texture)
|
||||||
|
{
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, texture);
|
||||||
|
GlStateManager._bindTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+96
-5
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -71,6 +71,10 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21_5
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that contains everything
|
* A singleton that contains everything
|
||||||
@@ -102,8 +106,15 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
*/
|
*/
|
||||||
public int finalLevelFrameBufferId = -1;
|
public int finalLevelFrameBufferId = -1;
|
||||||
|
|
||||||
|
public boolean colorTextureCastFailLogged = false;
|
||||||
|
public boolean depthTextureCastFailLogged = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========//
|
||||||
|
// methods //
|
||||||
|
//=========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3f getLookAtVector()
|
public Vec3f getLookAtVector()
|
||||||
{
|
{
|
||||||
@@ -250,6 +261,26 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
|
|
||||||
private RenderTarget getRenderTarget() { return MC.getMainRenderTarget(); }
|
private RenderTarget getRenderTarget() { return MC.getMainRenderTarget(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mcRendersToFrameBuffer()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean runningLegacyOpenGL()
|
||||||
|
{
|
||||||
|
#if MC_VER <= MC_1_16_5
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBuffer()
|
public int getTargetFrameBuffer()
|
||||||
{
|
{
|
||||||
@@ -259,27 +290,87 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return this.finalLevelFrameBufferId;
|
return this.finalLevelFrameBufferId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
return this.getRenderTarget().frameBufferId;
|
return this.getRenderTarget().frameBufferId;
|
||||||
|
#else
|
||||||
|
// MC renders to a texture and then directly to the default FBO now
|
||||||
|
// we need to draw to their texture instead of the FBO
|
||||||
|
return 0; // 0 is the ID for the default frame buffer
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTargetFrameBuffer() { this.finalLevelFrameBufferId = -1; }
|
public void clearTargetFrameBuffer() { this.finalLevelFrameBufferId = -1; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDepthTextureId() { return this.getRenderTarget().getDepthTextureId(); }
|
public int getDepthTextureId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return this.getRenderTarget().getDepthTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlTexture glTexture = (GlTexture) this.getRenderTarget().getDepthTexture();
|
||||||
|
if (glTexture == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glTexture.glId();
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.depthTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.depthTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getColorTextureId() { return this.getRenderTarget().getColorTextureId(); }
|
public int getColorTextureId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return this.getRenderTarget().getColorTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlTexture glTexture = (GlTexture) this.getRenderTarget().getColorTexture();
|
||||||
|
if (glTexture == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glTexture.glId();
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.colorTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.colorTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target color texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBufferViewportWidth()
|
public int getTargetFrameBufferViewportWidth()
|
||||||
{
|
{
|
||||||
return getRenderTarget().viewWidth;
|
return this.getRenderTarget().viewWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBufferViewportHeight()
|
public int getTargetFrameBufferViewportHeight()
|
||||||
{
|
{
|
||||||
return getRenderTarget().viewHeight;
|
return this.getRenderTarget().viewHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+19
-2
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -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;
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
|
|
||||||
public void uploadLightmap(NativeImage image)
|
public void uploadLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
int currentTexture = GLMC.getActiveTexture();
|
int currentTexture = GLMC.getActiveTexture();
|
||||||
if (this.textureId == 0)
|
if (this.textureId == 0)
|
||||||
{
|
{
|
||||||
@@ -59,14 +63,27 @@ 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);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
throw new UnsupportedOperationException("setLightmapId should be used for MC versions after 1.21.5"); // TODO that MC version number is wrong, when did we actually start using setLightmapId()?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
private void createLightmap(NativeImage image)
|
private void createLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
this.textureId = GLMC.glGenTextures();
|
this.textureId = GLMC.glGenTextures();
|
||||||
GLMC.glBindTexture(this.textureId);
|
GLMC.glBindTexture(this.textureId);
|
||||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
||||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||||
|
#else
|
||||||
|
throw new UnsupportedOperationException("setLightmapId should be used for MC versions after 1.21.5"); // TODO that MC version number is wrong, when did we actually start using setLightmapId()?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLightmapId(int minecraftLightmapTetxureId)
|
public void setLightmapId(int minecraftLightmapTetxureId)
|
||||||
|
|||||||
+28
-7
@@ -25,7 +25,6 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -33,6 +32,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
@@ -42,6 +45,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
#endif
|
#endif
|
||||||
@@ -49,7 +53,12 @@ import com.seibel.distanthorizons.core.util.ColorUtil;
|
|||||||
public class ClientLevelWrapper implements IClientLevelWrapper
|
public class ClientLevelWrapper implements IClientLevelWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
||||||
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>(); // TODO can leak
|
/**
|
||||||
|
* weak references are to prevent rare issues
|
||||||
|
* where, upon world closure, some levels aren't shutdown/removed properly
|
||||||
|
* and/or for servers were the level object isn't consistent
|
||||||
|
*/
|
||||||
|
private static final Map<ClientLevel, WeakReference<ClientLevelWrapper>> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
||||||
|
|
||||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
@@ -72,9 +81,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//==================//
|
||||||
// wrapper logic //
|
// instance methods //
|
||||||
//===============//
|
//==================//
|
||||||
|
|
||||||
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level) { return getWrapper(level, false); }
|
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level) { return getWrapper(level, false); }
|
||||||
|
|
||||||
@@ -96,7 +105,19 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LEVEL_WRAPPER_BY_CLIENT_LEVEL.computeIfAbsent(level, ClientLevelWrapper::new);
|
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, levelRef) ->
|
||||||
|
{
|
||||||
|
if (levelRef != null)
|
||||||
|
{
|
||||||
|
ClientLevelWrapper oldLevelWrapper = levelRef.get();
|
||||||
|
if (oldLevelWrapper != null)
|
||||||
|
{
|
||||||
|
return levelRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WeakReference<>(new ClientLevelWrapper(newLevel));
|
||||||
|
}).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -265,7 +286,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void onUnload()
|
public void onUnload()
|
||||||
{
|
{
|
||||||
LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level);
|
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.remove(this.level);
|
||||||
this.parentDhLevel = null;
|
this.parentDhLevel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+43
-34
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -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
-11
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -20,6 +20,10 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.world;
|
package com.seibel.distanthorizons.common.wrappers.world;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
@@ -38,6 +42,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
|
|
||||||
@@ -57,7 +62,11 @@ import org.apache.logging.log4j.Logger;
|
|||||||
public class ServerLevelWrapper implements IServerLevelWrapper
|
public class ServerLevelWrapper implements IServerLevelWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper> LEVEL_WRAPPER_BY_SERVER_LEVEL = new ConcurrentHashMap<>();
|
/**
|
||||||
|
* weak references are to prevent rare issues
|
||||||
|
* where, upon world closure, some levels aren't shutdown/removed properly
|
||||||
|
*/
|
||||||
|
private static final Map<ServerLevel, WeakReference<ServerLevelWrapper>> LEVEL_WRAPPER_REF_BY_SERVER_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
private final ServerLevel level;
|
private final ServerLevel level;
|
||||||
@Deprecated // TODO circular references are bad
|
@Deprecated // TODO circular references are bad
|
||||||
@@ -70,15 +79,29 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
||||||
{ return LEVEL_WRAPPER_BY_SERVER_LEVEL.computeIfAbsent(level, ServerLevelWrapper::new); }
|
{
|
||||||
|
return LEVEL_WRAPPER_REF_BY_SERVER_LEVEL.compute(level, (newLevel, levelRef) ->
|
||||||
|
{
|
||||||
|
if (levelRef != null)
|
||||||
|
{
|
||||||
|
ServerLevelWrapper oldLevelWrapper = levelRef.get();
|
||||||
|
if (oldLevelWrapper != null)
|
||||||
|
{
|
||||||
|
return levelRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WeakReference<>(new ServerLevelWrapper(newLevel));
|
||||||
|
}).get();
|
||||||
|
}
|
||||||
|
|
||||||
public ServerLevelWrapper(ServerLevel level) { this.level = level; }
|
public ServerLevelWrapper(ServerLevel level) { this.level = level; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
//==================//
|
||||||
// methods //
|
// instance methods //
|
||||||
//=========//
|
//==================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getMcSaveFolder()
|
public File getMcSaveFolder()
|
||||||
@@ -93,10 +116,12 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
@Override
|
@Override
|
||||||
public String getWorldFolderName()
|
public String getWorldFolderName()
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_17_1
|
// Need specifically overworld since it's the only dimension that is stored in a server root folder
|
||||||
return this.level.getServer().getWorldScreenshotFile().get().getParent().getFileName().toString();
|
|
||||||
#else // <= 1.16.5
|
#if MC_VER >= MC_1_21_3
|
||||||
return this.level.getServer().getWorldScreenshotFile().getParentFile().getName();
|
return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParent().getFileName().toString();
|
||||||
|
#else // <= 1.21.3
|
||||||
|
return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParentFile().getName();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +204,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
public ServerLevel getWrappedMcObject() { return this.level; }
|
public ServerLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
public void onUnload() { LEVEL_WRAPPER_REF_BY_SERVER_LEVEL.remove(this.level); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+52
-33
@@ -3,7 +3,7 @@
|
|||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 Tom Lee (TomTheFurry)
|
* Copyright (C) 2021 Tom Lee (TomTheFurry)
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -113,7 +113,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
() -> Config.Common.Logging.logWorldGenLoadEvent.get());
|
() -> Config.Common.Logging.logWorldGenLoadEvent.get());
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
private static final TicketType<ChunkPos> DH_SERVER_GEN_TICKET = TicketType.create("dh_server_gen_ticket", Comparator.comparingLong(ChunkPos::toLong));
|
private static final TicketType<ChunkPos> DH_SERVER_GEN_TICKET = TicketType.create("dh_server_gen_ticket", Comparator.comparingLong(ChunkPos::toLong));
|
||||||
|
#else
|
||||||
|
private static final TicketType DH_SERVER_GEN_TICKET = new TicketType(/* timeout, 0 = disabled*/0L, /* persist */ false, TicketType.TicketUse.LOADING);
|
||||||
|
#endif
|
||||||
|
|
||||||
private static final IModChecker MOD_CHECKER = SingletonInjector.INSTANCE.get(IModChecker.class);
|
private static final IModChecker MOD_CHECKER = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||||
|
|
||||||
@@ -125,7 +129,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 +245,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,8 +274,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
"Unsafe MultiThreading in Distant Horizons Chunk Generator. \n" +
|
"Unsafe MultiThreading in Distant Horizons Chunk Generator. \n" +
|
||||||
"This can happen if world generation is run on one of Minecraft's thread pools " +
|
"This can happen if world generation is run on one of Minecraft's thread pools " +
|
||||||
"instead of the thread DH provided. \n" +
|
"instead of the thread DH provided. \n" +
|
||||||
"This can likely be ignored, however if world generator crashes occur" +
|
"This can likely be ignored, however if world generator crashes occur " +
|
||||||
"to increase stability, set DH's world generation thread count to 1.",
|
"setting DH's world generation thread count to 1 may improve stability. ",
|
||||||
new RuntimeException("Incorrect thread pool use"));
|
new RuntimeException("Incorrect thread pool use"));
|
||||||
this.unsafeThreadingRecorded = true;
|
this.unsafeThreadingRecorded = true;
|
||||||
}
|
}
|
||||||
@@ -342,6 +337,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 +382,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
|
||||||
@@ -424,7 +423,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
ChunkAccess centerChunk = regionChunks.stream()
|
ChunkAccess centerChunk = regionChunks.stream()
|
||||||
.filter((chunk) -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ)
|
.filter((chunk) -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ)
|
||||||
.findFirst().get();
|
.findFirst()
|
||||||
|
.orElseGet(() -> regionChunks.getFirst());
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
DhLitWorldGenRegion region = new DhLitWorldGenRegion(
|
DhLitWorldGenRegion region = new DhLitWorldGenRegion(
|
||||||
@@ -591,6 +591,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;
|
||||||
@@ -609,7 +610,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
|
||||||
{
|
{
|
||||||
@@ -623,7 +624,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);
|
||||||
@@ -632,32 +633,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);
|
//GET_CHUNK_COUNT_REF.decrementAndGet();
|
||||||
return null;
|
//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
|
||||||
}
|
}
|
||||||
@@ -871,7 +882,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunkLevel = generateUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
chunkLevel = generateUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
level.getChunkSource().distanceManager.addTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
level.getChunkSource().distanceManager.addTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
||||||
|
#else
|
||||||
|
level.getChunkSource().addTicketWithRadius(DH_SERVER_GEN_TICKET, pos, 0);
|
||||||
|
#endif
|
||||||
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap); // probably not the most optimal to run updates here, but fast enough
|
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap); // probably not the most optimal to run updates here, but fast enough
|
||||||
ChunkHolder holder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(pos.toLong());
|
ChunkHolder holder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(pos.toLong());
|
||||||
if (holder == null)
|
if (holder == null)
|
||||||
@@ -908,7 +923,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunkLevel = chunkWasGeneratedUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
chunkLevel = chunkWasGeneratedUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
level.getChunkSource().distanceManager.removeTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
level.getChunkSource().distanceManager.removeTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
||||||
|
#else
|
||||||
|
level.getChunkSource().removeTicketWithRadius(DH_SERVER_GEN_TICKET, pos, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// mitigate OOM issues in vanilla chunk system: see https://github.com/pop4959/Chunky/pull/383
|
// mitigate OOM issues in vanilla chunk system: see https://github.com/pop4959/Chunky/pull/383
|
||||||
level.getChunkSource().chunkMap.tick(() -> false);
|
level.getChunkSource().chunkMap.tick(() -> false);
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+378
-107
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU GPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,6 +29,9 @@ import com.seibel.distanthorizons.core.util.LodUtil;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortList;
|
import it.unimi.dsi.fastutil.shorts.ShortList;
|
||||||
@@ -83,11 +86,13 @@ import net.minecraft.world.level.chunk.status.ChunkType;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
public class ChunkLoader
|
public class ChunkLoader
|
||||||
{
|
{
|
||||||
private static boolean zeroChunkPosErrorLogged = false;
|
private static final AtomicBoolean ZERO_CHUNK_POS_ERROR_LOGGED_REF = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||||
@@ -103,6 +108,8 @@ public class ChunkLoader
|
|||||||
|
|
||||||
private static boolean lightingSectionErrorLogged = false;
|
private static boolean lightingSectionErrorLogged = false;
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<String, Object> LOGGED_ERROR_MESSAGE_MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============//
|
//============//
|
||||||
@@ -117,19 +124,16 @@ public class ChunkLoader
|
|||||||
CompoundTag tagLevel = chunkData;
|
CompoundTag tagLevel = chunkData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
int chunkX = tagGetInt(tagLevel,"xPos");
|
||||||
|
int chunkZ = tagGetInt(tagLevel, "zPos");
|
||||||
|
ChunkPos actualPos = new ChunkPos(chunkX, chunkZ);
|
||||||
|
|
||||||
if (!Objects.equals(chunkPos, actualPos))
|
if (!Objects.equals(chunkPos, actualPos))
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_18_2
|
if (chunkX == 0 && chunkZ == 0)
|
||||||
if (actualPos.equals(ChunkPos.ZERO))
|
|
||||||
#else
|
|
||||||
if (actualPos.equals(ChunkPos.INVALID_CHUNK_POS))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (!zeroChunkPosErrorLogged)
|
if (!ZERO_CHUNK_POS_ERROR_LOGGED_REF.getAndSet(true))
|
||||||
{
|
{
|
||||||
zeroChunkPosErrorLogged = true;
|
|
||||||
|
|
||||||
// explicit chunkPos toString is necessary otherwise the JDK 17 compiler breaks
|
// explicit chunkPos toString is necessary otherwise the JDK 17 compiler breaks
|
||||||
LOGGER.warn("Chunk file at ["+chunkPos.toString()+"] doesn't have a chunk pos. \n" +
|
LOGGER.warn("Chunk file at ["+chunkPos.toString()+"] doesn't have a chunk pos. \n" +
|
||||||
"This might happen if the world was created using an external program. \n" +
|
"This might happen if the world was created using an external program. \n" +
|
||||||
@@ -171,14 +175,27 @@ public class ChunkLoader
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long inhabitedTime = tagLevel.getLong("InhabitedTime");
|
long inhabitedTime = tagGetLong(tagLevel, "InhabitedTime");
|
||||||
|
|
||||||
//================== Read params for making the LevelChunk ==================
|
//================== Read params for making the LevelChunk ==================
|
||||||
UpgradeData upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
|
||||||
? new UpgradeData(tagLevel.getCompound(TAG_UPGRADE_DATA)#if MC_VER >= MC_1_17_1 , level #endif )
|
|
||||||
: UpgradeData.EMPTY;
|
|
||||||
|
|
||||||
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
UpgradeData upgradeData;
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
|
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||||
|
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA))
|
||||||
|
: UpgradeData.EMPTY;
|
||||||
|
#elif MC_VER < MC_1_21_5
|
||||||
|
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||||
|
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
|
||||||
|
: UpgradeData.EMPTY;
|
||||||
|
#else
|
||||||
|
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA)
|
||||||
|
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
|
||||||
|
: UpgradeData.EMPTY;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn");
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
||||||
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if MC_VER >= MC_1_17_1 , level #endif ,
|
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if MC_VER >= MC_1_17_1 , level #endif ,
|
||||||
@@ -195,17 +212,21 @@ public class ChunkLoader
|
|||||||
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
||||||
tagLevel.getList("LiquidsToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
tagLevel.getList("LiquidsToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
||||||
#else
|
#else
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||||
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
#else
|
#elif MC_VER < MC_1_21_4
|
||||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||||
(string -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(string))), chunkPos);
|
(string -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(string))), chunkPos);
|
||||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
string -> BuiltInRegistries.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> BuiltInRegistries.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
#endif
|
#else
|
||||||
|
// do we need the ticks for what we're doing?
|
||||||
|
LevelChunkTicks<Block> blockTicks = new LevelChunkTicks<>();
|
||||||
|
LevelChunkTicks<Fluid> fluidTicks = new LevelChunkTicks<>();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
||||||
@@ -215,7 +236,6 @@ public class ChunkLoader
|
|||||||
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
||||||
fluidTicks, inhabitedTime, levelChunkSections, null);
|
fluidTicks, inhabitedTime, levelChunkSections, null);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks,
|
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks,
|
||||||
fluidTicks, inhabitedTime, levelChunkSections, null, blendingData);
|
fluidTicks, inhabitedTime, levelChunkSections, null, blendingData);
|
||||||
#endif
|
#endif
|
||||||
@@ -249,18 +269,23 @@ public class ChunkLoader
|
|||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||||
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
||||||
|
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
ListTag tagSections = tagGetListTag(chunkData, "Sections", 10);
|
||||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
if (tagSections == null || tagSections.isEmpty())
|
||||||
ListTag tagSections = chunkData.getList("Sections", 10);
|
|
||||||
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
|
||||||
|
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
|
||||||
{
|
{
|
||||||
CompoundTag tagSection = tagSections.getCompound(j);
|
tagSections = tagGetListTag(chunkData, "sections", 10);
|
||||||
int sectionYPos = tagSection.getByte("Y");
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (tagSections != null)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
|
{
|
||||||
|
CompoundTag tagSection = tagGetCompoundTag(tagSections, j);
|
||||||
|
int sectionYPos = tagGetByte(tagSection, "Y");
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||||
@@ -274,63 +299,89 @@ public class ChunkLoader
|
|||||||
= levelChunkSection;
|
= levelChunkSection;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
{
|
{
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
PalettedContainer<Biome> biomeContainer;
|
PalettedContainer<Biome> biomeContainer;
|
||||||
#else
|
#else
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
blockStateContainer = tagSection.contains("block_states", 10)
|
boolean containsBlockStates;
|
||||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
#if MC_VER < MC_1_21_5
|
||||||
#if MC_VER < MC_1_20_6
|
containsBlockStates = tagSection.contains("block_states", 10);
|
||||||
.getOrThrow(false, LOGGER::error)
|
#else
|
||||||
#else
|
containsBlockStates = tagSection.contains("block_states");
|
||||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
#endif
|
||||||
#endif
|
|
||||||
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
if (containsBlockStates)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
|
||||||
|
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
|
.getOrThrow(false, (message) -> logParsingWarningOnce(message));
|
||||||
|
#else
|
||||||
|
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
|
||||||
|
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
|
.getOrThrow((message) -> logErrorAndReturnException(message));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blockStateContainer = new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
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);
|
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
if (tagSection.contains("biomes", 10))
|
boolean containsBiomes;
|
||||||
{
|
#if MC_VER < MC_1_21_5
|
||||||
biomeContainer =
|
containsBiomes = tagSection.contains("biomes", 10);
|
||||||
biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
#else
|
||||||
#if MC_VER < MC_1_20_6
|
containsBiomes = tagSection.contains("biomes");
|
||||||
.getOrThrow(false, LOGGER::error);
|
#endif
|
||||||
#else
|
|
||||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null));
|
if (containsBiomes)
|
||||||
#endif
|
{
|
||||||
}
|
#if MC_VER < MC_1_20_6
|
||||||
else
|
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
|
||||||
{
|
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
biomeContainer = new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(),
|
.getOrThrow(false, (message) -> logParsingWarningOnce(message));
|
||||||
|
#else
|
||||||
|
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
|
||||||
|
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
|
.getOrThrow((message) -> logErrorAndReturnException(message));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
biomeContainer = new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(),
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
biomes.getHolderOrThrow(Biomes.PLAINS),
|
biomes.getHolderOrThrow(Biomes.PLAINS),
|
||||||
#else
|
#else
|
||||||
biomes.getOrThrow(Biomes.PLAINS),
|
biomes.getOrThrow(Biomes.PLAINS),
|
||||||
#endif
|
#endif
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES);
|
PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
#else
|
#else
|
||||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return chunkSections;
|
return chunkSections;
|
||||||
}
|
}
|
||||||
@@ -340,39 +391,54 @@ public class ChunkLoader
|
|||||||
#else ChunkType #endif
|
#else ChunkType #endif
|
||||||
readChunkType(CompoundTag tagLevel)
|
readChunkType(CompoundTag tagLevel)
|
||||||
{
|
{
|
||||||
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
ChunkStatus chunkStatus = ChunkStatus.byName(tagGetString(tagLevel,"Status"));
|
||||||
if (chunkStatus != null)
|
if (chunkStatus != null)
|
||||||
{
|
{
|
||||||
return chunkStatus.getChunkType();
|
return chunkStatus.getChunkType();
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
#if MC_VER <= MC_1_20_4
|
||||||
#if MC_VER <= MC_1_20_4 ChunkStatus.ChunkType.PROTOCHUNK;
|
return ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
#else ChunkType.PROTOCHUNK; #endif
|
#else
|
||||||
|
return ChunkType.PROTOCHUNK;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps");
|
||||||
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
||||||
{
|
{
|
||||||
String heightmap = type.getSerializationKey();
|
String heightmap = type.getSerializationKey();
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
if (tagHeightmaps.contains(heightmap, 12))
|
if (tagHeightmaps.contains(heightmap, 12))
|
||||||
|
{
|
||||||
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (tagHeightmaps.contains(heightmap))
|
||||||
|
{
|
||||||
|
Optional<long[]> optionalHeightmap = tagHeightmaps.getLongArray(heightmap);
|
||||||
|
if (optionalHeightmap.isPresent())
|
||||||
|
{
|
||||||
|
chunk.setHeightmap(type, optionalHeightmap.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
}
|
}
|
||||||
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
|
||||||
for (int i = 0; i < tagPostProcessings.size(); ++i)
|
for (int i = 0; i < tagPostProcessings.size(); ++i)
|
||||||
{
|
{
|
||||||
ListTag listTag3 = tagPostProcessings.getList(i);
|
ListTag listTag3 = tagGetListTag(tagPostProcessings, i);
|
||||||
for (int j = 0; j < listTag3.size(); ++j)
|
for (int j = 0; j < listTag3.size(); ++j)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
chunk.addPackedPostProcess(listTag3.getShort(j), i);
|
chunk.addPackedPostProcess(listTag3.getShort(j), i);
|
||||||
#else
|
#else
|
||||||
chunk.addPackedPostProcess(ShortList.of(listTag3.getShort(j)), i);
|
chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,16 +447,38 @@ public class ChunkLoader
|
|||||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
BlendingData blendingData = null;
|
BlendingData blendingData = null;
|
||||||
if (chunkData.contains("blending_data", 10))
|
|
||||||
|
|
||||||
|
boolean containsBlendingData;
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
containsBlendingData = chunkData.contains("blending_data", 10);
|
||||||
|
#else
|
||||||
|
containsBlendingData = chunkData.contains("blending_data");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (containsBlendingData)
|
||||||
{
|
{
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
try
|
||||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
{
|
||||||
#else
|
#if MC_VER < MC_1_21_3
|
||||||
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null));
|
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null);
|
||||||
#endif
|
#else
|
||||||
|
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
String message = e.getMessage();
|
||||||
|
if (message == null || message.trim().isEmpty())
|
||||||
|
{
|
||||||
|
message = "Failed to parse blending data";
|
||||||
|
}
|
||||||
|
|
||||||
|
logParsingWarningOnce(message, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return blendingData;
|
return blendingData;
|
||||||
}
|
}
|
||||||
@@ -467,33 +555,37 @@ public class ChunkLoader
|
|||||||
|
|
||||||
|
|
||||||
// if null all lights = 0
|
// if null all lights = 0
|
||||||
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
byte[] blockLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "BlockLight");
|
||||||
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
byte[] skyLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "SkyLight");
|
||||||
|
|
||||||
// if any sky light was found then all lights above will be max brightness
|
if (blockLightNibbleArray != null
|
||||||
if (skyLightNibbleArray.length != 0)
|
&& skyLightNibbleArray != null)
|
||||||
{
|
{
|
||||||
foundSkyLight = true;
|
// if any sky light was found then all lights above will be max brightness
|
||||||
}
|
if (skyLightNibbleArray.length != 0)
|
||||||
|
|
||||||
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
|
||||||
{
|
|
||||||
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
|
||||||
{
|
{
|
||||||
// chunk sections are also 16 blocks tall
|
foundSkyLight = true;
|
||||||
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
}
|
||||||
{
|
|
||||||
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
|
||||||
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
|
||||||
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
|
||||||
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
|
||||||
{
|
|
||||||
skyLight = LodUtil.MAX_MC_LIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getInclusiveMinBuildHeight(chunk);
|
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||||
blockLightStorage.set(relX, y, relZ, blockLight);
|
{
|
||||||
skyLightStorage.set(relX, y, relZ, skyLight);
|
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||||
|
{
|
||||||
|
// chunk sections are also 16 blocks tall
|
||||||
|
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
||||||
|
{
|
||||||
|
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
||||||
|
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
||||||
|
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
||||||
|
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
||||||
|
{
|
||||||
|
skyLight = LodUtil.MAX_MC_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getInclusiveMinBuildHeight(chunk);
|
||||||
|
blockLightStorage.set(relX, y, relZ, blockLight);
|
||||||
|
skyLightStorage.set(relX, y, relZ, skyLight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,13 +607,192 @@ public class ChunkLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========//
|
||||||
|
// logging //
|
||||||
|
//=========//
|
||||||
|
|
||||||
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
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)
|
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 logParsingWarningOnce(String message) { logParsingWarningOnce(message, null); }
|
||||||
|
private static void logParsingWarningOnce(String message, Exception e)
|
||||||
|
{
|
||||||
|
if (message == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//====================//
|
||||||
|
// tag helper methods //
|
||||||
|
//====================//
|
||||||
|
|
||||||
|
// TODO move into separate file (this file is getting long)
|
||||||
|
// these tag helpers are to simplify tag accessing between MC versions
|
||||||
|
|
||||||
|
/** defaults to "false" if the tag isn't present */
|
||||||
|
private static boolean tagGetBoolean(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getBoolean(key);
|
||||||
|
#else
|
||||||
|
return tag.getBoolean(key).orElse(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static byte tagGetByte(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getByte(key);
|
||||||
|
#else
|
||||||
|
return tag.getByte(key).orElse((byte)0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static short tagGetShort(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getShort(index);
|
||||||
|
#else
|
||||||
|
return tag.getShort(index).orElse((short)0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static int tagGetInt(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getInt(key);
|
||||||
|
#else
|
||||||
|
return tag.getInt(key).orElse(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static long tagGetLong(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getInt(key);
|
||||||
|
#else
|
||||||
|
return tag.getLong(key).orElse(0L);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
private static String tagGetString(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getString(key);
|
||||||
|
#else
|
||||||
|
return tag.getString(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
private static byte[] tagGetByteArray(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getByteArray(key);
|
||||||
|
#else
|
||||||
|
return tag.getByteArray(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static CompoundTag tagGetCompoundTag(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getCompound(key);
|
||||||
|
#else
|
||||||
|
return tag.getCompound(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static CompoundTag tagGetCompoundTag(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getCompound(index);
|
||||||
|
#else
|
||||||
|
return tag.getCompound(index).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defaults to null if the tag isn't present
|
||||||
|
* @param elementType unused after MC 1.21.5
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static ListTag tagGetListTag(CompoundTag tag, String key, int elementType)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getList(key, elementType);
|
||||||
|
#else
|
||||||
|
return tag.getList(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static ListTag tagGetListTag(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getList(index);
|
||||||
|
#else
|
||||||
|
return tag.getList(index).orElse(null);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -229,8 +229,16 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
{
|
{
|
||||||
ChunkAccess chunkAccess = this.getChunk(blockPos);
|
ChunkAccess chunkAccess = this.getChunk(blockPos);
|
||||||
if (chunkAccess instanceof LevelChunk)
|
if (chunkAccess instanceof LevelChunk)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
chunkAccess.setBlockState(blockPos, blockState, /*isBlockMoving*/false);
|
chunkAccess.setBlockState(blockPos, blockState, /*isBlockMoving*/false);
|
||||||
|
#else
|
||||||
|
chunkAccess.setBlockState(blockPos, blockState, /*flags*/0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is for post ticking for water on gen and stuff like that. Not enabled
|
// This is for post ticking for water on gen and stuff like that. Not enabled
|
||||||
// for now.
|
// for now.
|
||||||
// if (blockState.hasPostProcess(this, blockPos))
|
// if (blockState.hasPostProcess(this, blockPos))
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: 14cd0c4b09...bbb15263f2
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "fabric-loom" version "1.8-SNAPSHOT"
|
id "fabric-loom" version "1.10-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -33,6 +33,7 @@ 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.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
@@ -82,6 +83,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
|
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
|
||||||
@@ -316,9 +318,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
#else
|
#else
|
||||||
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
||||||
{
|
{
|
||||||
// Forge packet ID
|
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
|
||||||
buffer.readByte();
|
|
||||||
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
|
|
||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.pluginMessageReceived(message);
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -90,8 +90,8 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
{
|
{
|
||||||
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
||||||
|
|
||||||
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
// If sodium is installed Indium is also necessary for versions 0.5 and less in order to use the Fabric rendering API
|
||||||
if (!modChecker.isModLoaded("indium"))
|
if (!modChecker.isModLoaded("indium") && SodiumAccessor.isSodiumV5OrLess)
|
||||||
{
|
{
|
||||||
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
||||||
LOGGER.fatal(indiumMissingMessage);
|
LOGGER.fatal(indiumMissingMessage);
|
||||||
|
|||||||
+2
-6
@@ -22,9 +22,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
|
|||||||
ClientPlayNetworking.send(new CommonPacketPayload(message));
|
ClientPlayNetworking.send(new CommonPacketPayload(message));
|
||||||
#else // < 1.20.6
|
#else // < 1.20.6
|
||||||
FriendlyByteBuf buffer = PacketByteBufs.create();
|
FriendlyByteBuf buffer = PacketByteBufs.create();
|
||||||
// Forge packet ID
|
this.encodeMessage(buffer, message);
|
||||||
buffer.writeByte(0);
|
|
||||||
AbstractPluginPacketSender.encodeMessage(buffer, message);
|
|
||||||
ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer);
|
ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -36,9 +34,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
|
|||||||
ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message));
|
ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message));
|
||||||
#else // < 1.20.6
|
#else // < 1.20.6
|
||||||
FriendlyByteBuf buffer = PacketByteBufs.create();
|
FriendlyByteBuf buffer = PacketByteBufs.create();
|
||||||
// Forge packet ID
|
this.encodeMessage(buffer, message);
|
||||||
buffer.writeByte(0);
|
|
||||||
AbstractPluginPacketSender.encodeMessage(buffer, message);
|
|
||||||
ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer);
|
ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
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.common.AbstractPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
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 com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
||||||
@@ -32,7 +35,6 @@ import com.seibel.distanthorizons.common.CommonPacketPayload;
|
|||||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -48,6 +50,8 @@ import java.util.function.Supplier;
|
|||||||
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
private final boolean isDedicatedServer;
|
private final boolean isDedicatedServer;
|
||||||
@@ -192,9 +196,7 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
#else
|
#else
|
||||||
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
|
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
|
||||||
{
|
{
|
||||||
// Forge packet ID
|
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
|
||||||
buffer.readByte();
|
|
||||||
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
|
|
||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
|
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+21
-5
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -34,21 +34,34 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
#else
|
#elif MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Mixin(LightTexture.class)
|
@Mixin(LightTexture.class)
|
||||||
public class MixinLightTexture
|
public class MixinLightTexture
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
private NativeImage lightPixels;
|
private NativeImage lightPixels;
|
||||||
#else
|
#elif MC_VER < MC_1_21_5
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
private TextureTarget target;
|
private TextureTarget target;
|
||||||
|
#else
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private GpuTexture texture;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
@@ -63,8 +76,11 @@ public class MixinLightTexture
|
|||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
||||||
#else
|
#elif MC_VER < MC_1_21_5
|
||||||
MinecraftRenderWrapper.INSTANCE.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
MinecraftRenderWrapper.INSTANCE.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
||||||
|
#else
|
||||||
|
GlTexture glTexture = (GlTexture) this.texture;
|
||||||
|
MinecraftRenderWrapper.INSTANCE.setLightmapId(glTexture.glId(), clientLevel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-13
@@ -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
|
||||||
|
|
||||||
@@ -95,14 +105,16 @@ public abstract class MixinMinecraft
|
|||||||
)
|
)
|
||||||
private void buildInitialScreens(Runnable runnable)
|
private void buildInitialScreens(Runnable runnable)
|
||||||
{
|
{
|
||||||
|
boolean showUpdater = SelfUpdater.onStart(); // always needs to be called, otherwise auto update setup won't be completed
|
||||||
|
|
||||||
// TODO merge logic for forge, neo, and fabric
|
// TODO merge logic for forge, neo, and fabric
|
||||||
if (
|
if (
|
||||||
DEBUG_ALWAYS_SHOW_UPDATER ||
|
|
||||||
(
|
(
|
||||||
// Don't do anything if the user doesn't want it
|
// Don't do anything if the user doesn't want it
|
||||||
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
|
showUpdater
|
||||||
&& SelfUpdater.onStart()
|
&& Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
|
||||||
)
|
)
|
||||||
|
|| DEBUG_ALWAYS_SHOW_UPDATER
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runnable = () ->
|
runnable = () ->
|
||||||
@@ -122,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
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+7
@@ -1,12 +1,15 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
#endif
|
||||||
import com.mojang.blaze3d.platform.TextureUtil;
|
import com.mojang.blaze3d.platform.TextureUtil;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets Minecraft's LOD Bias (looks similar to mipmaps)
|
* Sets Minecraft's LOD Bias (looks similar to mipmaps)
|
||||||
*
|
*
|
||||||
@@ -15,6 +18,9 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
@Mixin(TextureUtil.class)
|
@Mixin(TextureUtil.class)
|
||||||
public class MixinTextureUtil
|
public class MixinTextureUtil
|
||||||
{
|
{
|
||||||
|
// TODO fix for MC 1.21.5+
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_VER == MC_1_16_5 remap = true #else remap = false #endif))
|
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_VER == MC_1_16_5 remap = true #else remap = false #endif))
|
||||||
private static void setLodBias(int target, int pname, float param)
|
private static void setLodBias(int target, int pname, float param)
|
||||||
@@ -27,5 +33,6 @@ public class MixinTextureUtil
|
|||||||
GlStateManager._texParameter(target, pname, biasValue);
|
GlStateManager._texParameter(target, pname, biasValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
-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
|
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+12
-12
@@ -46,8 +46,8 @@ public class TestGenericWorldGenerator implements IDhApiWorldGenerator
|
|||||||
public byte getSmallestDataDetailLevel() { return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
public byte getSmallestDataDetailLevel() { return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
||||||
@Override
|
@Override
|
||||||
public byte getLargestDataDetailLevel()
|
public byte getLargestDataDetailLevel()
|
||||||
//{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel + 12); }
|
{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel + 12); }
|
||||||
{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
//{ return (byte) (EDhApiDetailLevel.BLOCK.detailLevel); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+13
-3
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -43,11 +43,22 @@ import net.minecraft.world.phys.AABB;
|
|||||||
|
|
||||||
public class SodiumAccessor implements ISodiumAccessor
|
public class SodiumAccessor implements ISodiumAccessor
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* True if sodium 0.5 or less is present. <br>
|
||||||
|
* This field is public because it's also used to check if we need Indium to be present. <br>
|
||||||
|
* We need Indium if Sodium 0.5 or less is present.
|
||||||
|
*/
|
||||||
|
public static final boolean isSodiumV5OrLess;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
private static MethodHandle setFogOcclusionMethod;
|
private static MethodHandle setFogOcclusionMethod;
|
||||||
private static Object sodiumPerformanceOptions;
|
private static Object sodiumPerformanceOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static {
|
||||||
|
isSodiumV5OrLess = !classPresent("net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//======================//
|
//======================//
|
||||||
@@ -72,8 +83,7 @@ public class SodiumAccessor implements ISodiumAccessor
|
|||||||
{
|
{
|
||||||
if (sodiumPerformanceOptions == null)
|
if (sodiumPerformanceOptions == null)
|
||||||
{
|
{
|
||||||
boolean sodiumV6 = classPresent("net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer");
|
if (isSodiumV5OrLess)
|
||||||
if (!sodiumV6)
|
|
||||||
{
|
{
|
||||||
// sodium 0.5
|
// sodium 0.5
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@@ -24,13 +24,17 @@ 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.IPluginPacketSender;
|
||||||
|
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 +56,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;
|
||||||
@@ -75,6 +80,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||||||
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
|
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +96,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
|
||||||
|
PACKET_SENDER.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
|
ServerApi.INSTANCE.pluginMessageReceived(player, message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
@@ -45,16 +45,18 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public static void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
|
public ForgePluginPacketSender() { super(true); }
|
||||||
|
|
||||||
|
public void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
|
||||||
{
|
{
|
||||||
setPacketHandler((player, message) -> consumer.accept(message));
|
this.setPacketHandler((player, message) -> consumer.accept(message));
|
||||||
}
|
}
|
||||||
public static void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
public void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_20_2
|
#if MC_VER >= MC_1_20_2
|
||||||
PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0)
|
PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0)
|
||||||
.encoder((wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message))
|
.encoder((wrapper, out) -> this.encodeMessage(out, wrapper.message))
|
||||||
.decoder(in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in)))
|
.decoder(in -> new MessageWrapper(this.decodeMessage(in)))
|
||||||
.consumerNetworkThread((wrapper, context) ->
|
.consumerNetworkThread((wrapper, context) ->
|
||||||
{
|
{
|
||||||
if (wrapper.message != null)
|
if (wrapper.message != null)
|
||||||
@@ -73,8 +75,8 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
|
|||||||
.add();
|
.add();
|
||||||
#else // < 1.20.2
|
#else // < 1.20.2
|
||||||
PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class,
|
PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class,
|
||||||
(wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message),
|
(wrapper, out) -> this.encodeMessage(out, wrapper.message),
|
||||||
in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in)),
|
in -> new MessageWrapper(this.decodeMessage(in)),
|
||||||
(wrapper, context) ->
|
(wrapper, context) ->
|
||||||
{
|
{
|
||||||
if (wrapper.message != null)
|
if (wrapper.message != null)
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
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.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@@ -51,6 +53,8 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
|
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||||
#else
|
#else
|
||||||
@@ -68,7 +72,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
if (this.isDedicated)
|
if (this.isDedicated)
|
||||||
{
|
{
|
||||||
ForgePluginPacketSender.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
|
PACKET_SENDER.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +82,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public ForgeServerProxy(boolean isDedicated)
|
public ForgeServerProxy(boolean isDedicated) { this.isDedicated = isDedicated; }
|
||||||
{
|
|
||||||
this.isDedicated = isDedicated;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+23
-11
@@ -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
|
||||||
|
|
||||||
@@ -76,10 +86,12 @@ public class MixinMinecraft
|
|||||||
)
|
)
|
||||||
private void buildInitialScreens(Runnable runnable)
|
private void buildInitialScreens(Runnable runnable)
|
||||||
{
|
{
|
||||||
|
boolean showUpdater = SelfUpdater.onStart(); // always needs to be called, otherwise auto update setup won't be completed
|
||||||
|
|
||||||
// TODO merge logic for forge, neo, and fabric
|
// TODO merge logic for forge, neo, and fabric
|
||||||
if (
|
if (
|
||||||
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() // Don't do anything if the user doesn't want it
|
showUpdater
|
||||||
&& SelfUpdater.onStart()
|
&& Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() // Don't do anything if the user doesn't want it
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runnable = () ->
|
runnable = () ->
|
||||||
@@ -106,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
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of the Distant Horizons mod
|
* This file is part of the Distant Horizons mod
|
||||||
* licensed under the GNU LGPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
* Copyright (C) 2020 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user