Compare commits
316 Commits
2.3.3b
..
serverside
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a771a3e21 | |||
| 0aa109a341 | |||
| 6d44255175 | |||
| f8bb35cb2b | |||
| 52f1aed124 | |||
| 6ae1ba1e17 | |||
| 9105f30fec | |||
| 839c849a9d | |||
| 275f507096 | |||
| 01c5a4072a | |||
| 1697707114 | |||
| 34b0b7dc31 | |||
| 691e1022e3 | |||
| 18fd157474 | |||
| 4948158fa8 | |||
| e3b972c928 | |||
| ad056cb64e | |||
| 3e22ddead5 | |||
| 5c7e27c52d | |||
| 3a5c6f12c0 | |||
| 627eee7a6d | |||
| 7c4c99089b | |||
| 00ec14d319 | |||
| 56188bc7d2 | |||
| 9b2429d388 | |||
| 2aa68ec41d | |||
| 13c9f95750 | |||
| b0549cecff | |||
| 95fb4a0e6a | |||
| 2a3aadc2fa | |||
| 52bddca0df | |||
| 606dede9ef | |||
| e8c9d8391a | |||
| 88ca223bbc | |||
| 4a51bbc796 | |||
| 94ca0e2729 | |||
| 5befdbcddc | |||
| 3e02d7f9dc | |||
| 48b38d9285 | |||
| 8c7c787a8f | |||
| fc0cf56b48 | |||
| 32c63ae15b | |||
| bbf62f7ee3 | |||
| 6211542708 | |||
| a2d5e8cdb3 | |||
| 692b304898 | |||
| 0ca93e311c | |||
| c7aab012ae | |||
| 80ccab21da | |||
| 663ce3cde6 | |||
| 43fee18ae4 | |||
| 014310631e | |||
| 4f7e934c98 | |||
| 563dcd7de6 | |||
| 0a5cc734de | |||
| 0da158fecc | |||
| a7e8bbaf6a | |||
| 80732943c8 | |||
| 994c86d5ba | |||
| 18ccbbbb8e | |||
| 31c3fb9a1e | |||
| 8bdb383b2e | |||
| d13ec687ed | |||
| 43069703cd | |||
| 6d76ace604 | |||
| 9b139575e7 | |||
| efb9129edf | |||
| 6a380f6a7b | |||
| 0798ca01c5 | |||
| 8bfc1430c8 | |||
| bd6621183d | |||
| ccc8076c66 | |||
| 004103551f | |||
| ea47e11ecf | |||
| 8a3837b04b | |||
| edfeaa618b | |||
| 961cdbe868 | |||
| ff6ab67b69 | |||
| c01fb4a716 | |||
| 8bd524791f | |||
| 26059d5656 | |||
| 3f23281e8d | |||
| fb25423deb | |||
| 6928c8dc28 | |||
| 7dfe0e4c50 | |||
| 1429ae5434 | |||
| 3fb4d5a233 | |||
| 872226e5c5 | |||
| fb46820b1f | |||
| a786678bcb | |||
| 0d35a3ea8e | |||
| 6f87e22048 | |||
| 7c07c1e5bd | |||
| 4ddb9659f5 | |||
| e74b8c89ba | |||
| 1b536e4aef | |||
| 335f11acd3 | |||
| b55b560cce | |||
| d87a152052 | |||
| db5a9c7c84 | |||
| 2508efdd91 | |||
| 4852720e14 | |||
| f39d156b11 | |||
| e21eb61335 | |||
| c49f385e3c | |||
| 0584b0e593 | |||
| 220ac89ad8 | |||
| e8e56b66a3 | |||
| 634d8a5b52 | |||
| b621c9fb8d | |||
| 696f84a064 | |||
| 5c13ff8960 | |||
| e102cd78cd | |||
| c5a782acba | |||
| 2008ea2b0c | |||
| 0f349461d9 | |||
| baf464aa02 | |||
| 51d83d803a | |||
| 2b3244159b | |||
| 9255c22d0e | |||
| 4d573c4aea | |||
| a59f359133 | |||
| c83d02c30c | |||
| d01573b03e | |||
| b1fb74539f | |||
| 40962ec9ba | |||
| 0515ac2919 | |||
| 8072695391 | |||
| 2c140bf7d7 | |||
| d3e88b40f4 | |||
| 5e0e15777c | |||
| b57fc5c9aa | |||
| 91ea68075e | |||
| 0840ec8b00 | |||
| d9f37ad7d6 | |||
| 992a7129e5 | |||
| 1d5ea329de | |||
| 00d0a0d2fc | |||
| 95d4314982 | |||
| b588b937ea | |||
| f524ad027e | |||
| b3111b9548 | |||
| 6c38cb3dee | |||
| d75b2dfc1c | |||
| a5b44d65c6 | |||
| 7a1c61405c | |||
| bcb8794d30 | |||
| f9775b115e | |||
| a56a2c2ba3 | |||
| b2efb33a5b | |||
| 5928cfe4b4 | |||
| 234204590f | |||
| e3838c560a | |||
| 6cbc9db1d8 | |||
| 127dcfcb46 | |||
| d1abdd822d | |||
| 85b7ccb38e | |||
| fc157b738e | |||
| 977afffe98 | |||
| 180b22f21a | |||
| d0330ad62f | |||
| 4d22b18f3c | |||
| df797b240e | |||
| a50ef86302 | |||
| 4aede27d75 | |||
| e616c63ebe | |||
| 03ec333a26 | |||
| 27446965db | |||
| c6d7313225 | |||
| 160912a17a | |||
| d408aacbc8 | |||
| 4889287e69 | |||
| 6acdfabb7f | |||
| 3c01d00772 | |||
| 736bb022d2 | |||
| e92130d6cc | |||
| a44dfa92a6 | |||
| 4c8ee862e5 | |||
| 73b89fe573 | |||
| fed2600dbe | |||
| 1d7d94cfec | |||
| 5577261774 | |||
| bf0f3131a0 | |||
| 1b98ea59d7 | |||
| c38efd9d6b | |||
| 4889119061 | |||
| accb2d6af3 | |||
| 24b426a17b | |||
| 8c1bccb430 | |||
| 3cb2a70f4d | |||
| a313cb3db1 | |||
| c29c6d1870 | |||
| b4a64b0c3d | |||
| 1439ca5c08 | |||
| 97ad3bc78f | |||
| b59d8cff8d | |||
| 0e93aa4aea | |||
| 28f8099777 | |||
| c83b0ae533 | |||
| 5ceeebe567 | |||
| e8db9803be | |||
| f009fd41ab | |||
| 9faa3b0a54 | |||
| 0e70478dd3 | |||
| 309b6c6013 | |||
| f20af18b62 | |||
| 7d3329fd98 | |||
| 9a880c3ab1 | |||
| 0b247f04b4 | |||
| 7f1d664731 | |||
| a2288d740b | |||
| 958f0347a3 | |||
| 859bb2e34e | |||
| a2acd08e0d | |||
| b986583fc4 | |||
| c6355f96a6 | |||
| 723d171746 | |||
| 63098d8519 | |||
| 44b743267b | |||
| 720155c408 | |||
| 334b487e23 | |||
| 6e674f3732 | |||
| d130a602d6 | |||
| 8d1ff02937 | |||
| 15b1603e35 | |||
| 4ad0a22db7 | |||
| 35bc1df32c | |||
| bb2a1158c2 | |||
| 76f6f6f746 | |||
| 3b771b5300 | |||
| 9497918e06 | |||
| e52c5d5c67 | |||
| 1ce4750dfc | |||
| 2b371340ff | |||
| e8d906b407 | |||
| 572973c69a | |||
| 9f2d6b9c78 | |||
| 54277040e9 | |||
| bbe333fab7 | |||
| 37fed5a924 | |||
| 5fc29334cd | |||
| 9d32e92e0a | |||
| b08ee76a00 | |||
| 2a4cc6e63d | |||
| 6b2560f98b | |||
| 08111d8874 | |||
| 80f48cd5a4 | |||
| 40cd6c1386 | |||
| e9a13dffb8 | |||
| 22680baad7 | |||
| cca480e5d8 | |||
| 249c3423d9 | |||
| 15cb6468d9 | |||
| f24019d648 | |||
| 733d03c630 | |||
| c3e84648f1 | |||
| 76c33b6b58 | |||
| 26a947ea13 | |||
| 91334c0e5c | |||
| 172b05aeac | |||
| b84e5ca265 | |||
| 20ef5a10fc | |||
| 33640fd35d | |||
| e5f7c5728f | |||
| 5a9bbf9829 | |||
| 23ca022ee9 | |||
| 6c80165523 | |||
| d598061fa7 | |||
| 02498aa189 | |||
| d535f6aa57 | |||
| 933753a38a | |||
| 5483cdbc51 | |||
| 1ea62fd5ec | |||
| aaf0361c50 | |||
| a08feebde0 | |||
| f7131fd2ca | |||
| 2100f4a6fe | |||
| 996f097b9d | |||
| 2e1d737268 | |||
| d374870fb7 | |||
| 5c303df32c | |||
| dfc4b51e89 | |||
| 765202d582 | |||
| 0d2e5adbed | |||
| 68e9d64779 | |||
| b64b44f301 | |||
| 8c07bb37f3 | |||
| c1f6c2dbbd | |||
| 2eb1c16837 | |||
| e5fb8477d3 | |||
| 428cacd262 | |||
| 76926d38db | |||
| 9fec679b03 | |||
| 853a1d1490 | |||
| 01273e31bc | |||
| ebb4808bdc | |||
| fd09adb1a7 | |||
| 82b7b439a4 | |||
| f1b3ae120b | |||
| 70ee20e817 | |||
| f713d65f9c | |||
| c2b98ef694 | |||
| 140c9f6a50 | |||
| c704d61d03 | |||
| aae484fbdf | |||
| a546a97e34 | |||
| 3ca9d98c05 | |||
| 460b73e35c | |||
| 8901a191d9 | |||
| 1bbe35c9f1 | |||
| f92e957826 | |||
| 636e6736a3 | |||
| 8e29f65815 | |||
| a9309078f3 | |||
| 9692e978de | |||
| 914372b858 |
+3
-2
@@ -5,6 +5,7 @@ root = true
|
|||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
end_of_line = crlf
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
@@ -537,7 +538,7 @@ ij_groovy_wrap_chain_calls_after_dot = false
|
|||||||
ij_groovy_wrap_long_lines = false
|
ij_groovy_wrap_long_lines = false
|
||||||
|
|
||||||
[{*.har,*.json,*.png.mcmeta,mcmod.info,pack.mcmeta}]
|
[{*.har,*.json,*.png.mcmeta,mcmod.info,pack.mcmeta}]
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
ij_json_array_wrapping = split_into_lines
|
ij_json_array_wrapping = split_into_lines
|
||||||
ij_json_keep_blank_lines_in_code = 0
|
ij_json_keep_blank_lines_in_code = 0
|
||||||
ij_json_keep_indents_on_empty_lines = false
|
ij_json_keep_indents_on_empty_lines = false
|
||||||
@@ -687,7 +688,7 @@ ij_markdown_wrap_text_inside_blockquotes = true
|
|||||||
ij_toml_keep_indents_on_empty_lines = false
|
ij_toml_keep_indents_on_empty_lines = false
|
||||||
|
|
||||||
[{*.yaml,*.yml}]
|
[{*.yaml,*.yml}]
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
ij_yaml_align_values_properties = do_not_align
|
ij_yaml_align_values_properties = do_not_align
|
||||||
ij_yaml_autoinsert_sequence_marker = true
|
ij_yaml_autoinsert_sequence_marker = true
|
||||||
ij_yaml_block_mapping_on_new_line = false
|
ij_yaml_block_mapping_on_new_line = false
|
||||||
|
|||||||
@@ -26,10 +26,6 @@ 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
|
||||||
|
|
||||||
|
|||||||
+27
-14
@@ -35,27 +35,40 @@ 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", "1.21.5", "1.21.6", "1.21.7"]
|
- 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"]
|
||||||
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 clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./build/merged/* . || true
|
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- ./*.jar
|
- Merged/*.jar
|
||||||
|
- quilt/build/libs/*.jar
|
||||||
|
- fabric/build/libs/*.jar
|
||||||
|
- forge/build/libs/*.jar
|
||||||
|
- neoforge/build/libs/*.jar
|
||||||
exclude:
|
exclude:
|
||||||
- ./*-all.jar
|
# TODO: There is a lot of duplicate stuff here, try to maybe make it smaller
|
||||||
- ./*-dev.jar
|
- fabric/build/libs/*-all.jar
|
||||||
- ./*-sources.jar
|
- fabric/build/libs/*-dev.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
|
||||||
|
|
||||||
|
|
||||||
api:
|
.api:
|
||||||
stage: api
|
stage: api
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
@@ -64,22 +77,22 @@ 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: "NightlyBuild_Api-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "Api_NightlyBuild-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- ./*.jar
|
- coreSubProjects/api/build/libs/merged/*.jar
|
||||||
|
# can be uncommented if we don't want a jar with the source code
|
||||||
|
# - coreSubProjects/api/build/libs/*.jar
|
||||||
exclude:
|
exclude:
|
||||||
- ./*-all.jar
|
- coreSubProjects/api/build/libs/merged/*-all.jar
|
||||||
- ./*-dev.jar
|
- coreSubProjects/api/build/libs/merged/*-sources.jar
|
||||||
- ./*-sources.jar
|
|
||||||
expire_in: 1 day
|
expire_in: 1 day
|
||||||
when: always
|
when: always
|
||||||
extends: .build_java
|
extends: .build_java
|
||||||
|
|
||||||
|
|
||||||
# generate and publish API javadocs
|
# generate and publish API javadocs
|
||||||
pages:
|
.pages:
|
||||||
stage: pages
|
stage: pages
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
|
|||||||
@@ -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/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
[Problems-and-solutions](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-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/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/4-mod-support/Mod-Support)
|
[Mod support FAQ](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-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/distant-horizons-team/distant-horizons/-/issues)
|
[Issues](https://gitlab.com/jeseibel/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/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.
|
- [ ] 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.
|
||||||
|
|
||||||
1. **Describe the feature**:
|
1. **Describe the feature**:
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
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.
|
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.
|
||||||
|
|
||||||
2. **Describe the improvement**:
|
2. **Describe the improvement**:
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
[submodule "coreSubProjects"]
|
[submodule "coreSubProjects"]
|
||||||
path = coreSubProjects
|
path = coreSubProjects
|
||||||
url = https://gitlab.com/jeseibel/distant-horizons-core.git
|
url = https://gitlab.com/jeseibel/distant-horizons-core.git
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [build]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="build" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [clean]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="clean" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [core:build]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="core:build" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [fabric:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="fabric:runClient" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [forge:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="forge:runClient" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [mergeJars]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="mergeJars" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [neoforge:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="neoforge:runClient" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="distant-horizons [test]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="test" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Distant Horizons logos © 2024 by Pankakes are licensed under CC BY-SA 4.0
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# <img src="https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/_Misc%20Files/logo%20files/new/SVG/Distant-Horizons.svg" height="128px">
|
# <img src="https://gitlab.com/jeseibel/distant-horizons-core/-/raw/main/_Misc%20Files/logo%20files/LOD%20logo%20flat%20-%20with%20boarder.png" width="32"> Distant Horizons
|
||||||
_See farther without turning your game into a slide show._
|
_See farther without turning your game into a slide show._
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -131,14 +131,14 @@ Prerequisites:
|
|||||||
|
|
||||||
From the File Explorer:
|
From the File Explorer:
|
||||||
1. Download and extract the project zip
|
1. Download and extract the project zip
|
||||||
2. Download the core from https://gitlab.com/distant-horizons-team/distant-horizons-core and extract into a folder called `coreSubProjects`
|
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `coreSubProjects`
|
||||||
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
||||||
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
||||||
5. Merge the jars with `./gradlew mergeJars`
|
5. Merge the jars with `./gradlew mergeJars`
|
||||||
6. The compiled jar file will be in the folder `Merged`
|
6. The compiled jar file will be in the folder `Merged`
|
||||||
|
|
||||||
From the command line:
|
From the command line:
|
||||||
1. `git clone --recurse-submodules https://gitlab.com/distant-horizons-team/distant-horizons.git`
|
1. `git clone --recurse-submodules https://gitlab.com/jeseibel/distant-horizons.git`
|
||||||
2. `cd distant-horizons`
|
2. `cd distant-horizons`
|
||||||
3. `./gradlew assemble`
|
3. `./gradlew assemble`
|
||||||
4. `./gradlew mergeJars`
|
4. `./gradlew mergeJars`
|
||||||
|
|||||||
+60
-116
@@ -1,11 +1,3 @@
|
|||||||
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"
|
||||||
|
|
||||||
@@ -13,13 +5,13 @@ 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.3.4"
|
id "io.github.pacifistmc.forgix" version "1.2.9"
|
||||||
|
|
||||||
// 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.10-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -35,8 +27,8 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
|
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < mcVers.size(); i++)
|
for (int i = 0; i < mcVers.size(); i++)
|
||||||
{
|
{
|
||||||
String verStr = mcVers[i].replace(".", "_");
|
String verStr = mcVers[i].replace(".", "_");
|
||||||
@@ -67,64 +59,38 @@ 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 {
|
||||||
|
group = "com.seibel.distanthorizons"
|
||||||
|
mergedJarName = "DistantHorizons-${rootProject.versionStr}.jar"
|
||||||
|
|
||||||
class NativeTransformer implements Transformer {
|
if (findProject(":forge"))
|
||||||
private final HashMap<String, String> replacements = new HashMap()
|
forge {
|
||||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
|
||||||
private var nativeRelocator
|
}
|
||||||
|
|
||||||
public File rootDir
|
if (findProject(":neoforge"))
|
||||||
|
custom {
|
||||||
void relocateNative(String target, String replacement) {
|
projectName = "neoforge"
|
||||||
if (replacement.length() > target.length()) {
|
jarLocation = "build/libs/DistantHorizons-neoforge-${rootProject.versionStr}.jar"
|
||||||
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements.put(target, replacement)
|
if (findProject(":fabric"))
|
||||||
}
|
fabric {
|
||||||
|
jarLocation = "build/libs/DistantHorizons-fabric-${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"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (findProject(":quilt"))
|
||||||
Map.Entry<String, String> pathReplacement = replacements.entrySet().stream().filter {
|
quilt {
|
||||||
context.path.startsWith(it.key as String)
|
jarLocation = "build/libs/DistantHorizons-quilt-${rootProject.versionStr}.jar"
|
||||||
}.findFirst().orElseThrow()
|
|
||||||
|
|
||||||
String path = context.path.replace(pathReplacement.key as String, pathReplacement.value as String)
|
|
||||||
content = nativeRelocator.processBinary(path, content, replacements)
|
|
||||||
|
|
||||||
rewrittenFiles.put(path, content)
|
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
|
||||||
throw new GradleException("Failed to relocate", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
removeDuplicate "com.seibel.distanthorizons"
|
||||||
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 ->
|
||||||
@@ -138,7 +104,7 @@ subprojects { p ->
|
|||||||
apply plugin: "com.github.johnrengelman.shadow"
|
apply plugin: "com.github.johnrengelman.shadow"
|
||||||
if (isMinecraftSubProject)
|
if (isMinecraftSubProject)
|
||||||
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
||||||
|
|
||||||
// Apply forge's loom
|
// Apply forge's loom
|
||||||
if ((findProject(":forge") && p == project(":forge")) ||
|
if ((findProject(":forge") && p == project(":forge")) ||
|
||||||
(findProject(":neoforge") && p == project(":neoforge"))
|
(findProject(":neoforge") && p == project(":neoforge"))
|
||||||
@@ -152,7 +118,7 @@ subprojects { p ->
|
|||||||
manifold {
|
manifold {
|
||||||
manifoldVersion = rootProject.manifold_version
|
manifoldVersion = rootProject.manifold_version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set up custom configurations (configurations are a way to handle dependencies)
|
// set up custom configurations (configurations are a way to handle dependencies)
|
||||||
configurations {
|
configurations {
|
||||||
@@ -193,7 +159,6 @@ subprojects { p ->
|
|||||||
if (findProject(":neoforge"))
|
if (findProject(":neoforge"))
|
||||||
developmentNeoForge.extendsFrom coreProjects
|
developmentNeoForge.extendsFrom coreProjects
|
||||||
|
|
||||||
// TODO remove unused fabricLike
|
|
||||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||||
// Shadow fabricLike
|
// Shadow fabricLike
|
||||||
fabricLike
|
fabricLike
|
||||||
@@ -214,28 +179,19 @@ subprojects { p ->
|
|||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log4j
|
|
||||||
if (p == project(":core"))
|
|
||||||
{
|
|
||||||
// the standalone core jar needs logging shaded otherwise it won't run
|
|
||||||
forgeShadowMe("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
|
|
||||||
forgeShadowMe("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// When running in MC, MC already includes logging
|
|
||||||
implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
|
|
||||||
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Log4j
|
||||||
|
// TODO: Change to shadowMe later to work in the standalone jar
|
||||||
|
// We cannot do this now as it would break Quilt
|
||||||
|
implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
|
||||||
|
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
|
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
|
||||||
else
|
else
|
||||||
implementation("org.joml:joml:${rootProject.joml_version}")
|
implementation("org.joml:joml:${rootProject.joml_version}")
|
||||||
|
|
||||||
// JUnit tests
|
// JUnit tests
|
||||||
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
||||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||||
@@ -246,23 +202,21 @@ subprojects { p ->
|
|||||||
// We cannot relocate this library since we call some MC classes that reference it
|
// We cannot relocate this library since we call some MC classes that reference it
|
||||||
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
|
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
|
||||||
|
|
||||||
//forgeShadowMe("com.github.luben:zstd-jni:1.5.7-3")
|
|
||||||
//forgeShadowMe("org.apache.commons:commons-compress:1.27.1")
|
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
||||||
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
|
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
|
||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
||||||
|
|
||||||
// NightConfig (includes Toml & Json)
|
// NightConfig (includes Toml & Json)
|
||||||
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||||
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
||||||
|
|
||||||
// SVG (not needed atm)
|
// SVG (not needed atm)
|
||||||
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
||||||
|
|
||||||
// Netty
|
// Netty
|
||||||
implementation("io.netty:netty-buffer:${rootProject.netty_version}")
|
implementation("io.netty:netty-buffer:${rootProject.netty_version}")
|
||||||
|
|
||||||
@@ -322,7 +276,7 @@ subprojects { p ->
|
|||||||
if (isMinecraftSubProject && p != project(":common")) {
|
if (isMinecraftSubProject && p != project(":common")) {
|
||||||
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
|
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
|
||||||
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
|
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
|
||||||
|
|
||||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||||
configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject
|
configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject
|
||||||
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
||||||
@@ -336,25 +290,11 @@ subprojects { p ->
|
|||||||
|
|
||||||
// Compression (LZ4)
|
// Compression (LZ4)
|
||||||
relocate "net.jpountz", "${librariesLocation}.jpountz"
|
relocate "net.jpountz", "${librariesLocation}.jpountz"
|
||||||
|
|
||||||
// Logging
|
|
||||||
relocate "org.slf4j", "${librariesLocation}.slf4j"
|
|
||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
||||||
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
||||||
relocate "org.sqlite", "dh_sqlite", {
|
|
||||||
exclude "org/sqlite/native/**"
|
|
||||||
}
|
|
||||||
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
|
||||||
|
|
||||||
transform(NativeTransformer) {
|
|
||||||
rootDir = project.rootDir
|
|
||||||
relocateNative "org/sqlite", "dh_sqlite"
|
|
||||||
relocateNative "org_sqlite", "dh_1sqlite"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
relocate "org.joml", "${librariesLocation}.joml"
|
relocate "org.joml", "${librariesLocation}.joml"
|
||||||
@@ -364,7 +304,7 @@ subprojects { p ->
|
|||||||
|
|
||||||
// SVG (not needed atm)
|
// SVG (not needed atm)
|
||||||
// relocate "com.kitfox.svg", "${librariesLocation}.kitfox.svg"
|
// relocate "com.kitfox.svg", "${librariesLocation}.kitfox.svg"
|
||||||
|
|
||||||
// Netty
|
// Netty
|
||||||
// Don't relocate, it causes problems with using MC's FriendlyByteBufs
|
// Don't relocate, it causes problems with using MC's FriendlyByteBufs
|
||||||
// relocate "io.netty", "${librariesLocation}.netty"
|
// relocate "io.netty", "${librariesLocation}.netty"
|
||||||
@@ -389,7 +329,7 @@ subprojects { p ->
|
|||||||
"META-INF/neoforge.mods.toml",
|
"META-INF/neoforge.mods.toml",
|
||||||
|
|
||||||
// The mixins for each of the loaders
|
// The mixins for each of the loaders
|
||||||
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
"DistantHorizons." + p.name + ".fabricLike.mixins.json"
|
||||||
]
|
]
|
||||||
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||||
|
|
||||||
@@ -446,18 +386,16 @@ subprojects { p ->
|
|||||||
info_build_source : infoBuildSource,
|
info_build_source : infoBuildSource,
|
||||||
|
|
||||||
fabric_incompatibility_list : fabric_incompatibility_list,
|
fabric_incompatibility_list : fabric_incompatibility_list,
|
||||||
fabric_recommend_list : fabric_recommend_list,
|
fabric_recommend_list : fabric_recommend_list,
|
||||||
|
|
||||||
neoforge_version_range : neoforge_version_range,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// replace any properties in the sub-projects with the values defined here
|
// replace any properties in the sub-projects with the values defined here
|
||||||
inputs.properties replaceProperties
|
inputs.properties replaceProperties
|
||||||
replaceProperties.put "project", project
|
replaceProperties.put "project", project
|
||||||
filesMatching(resourceTargets) {
|
filesMatching(resourceTargets) {
|
||||||
expand replaceProperties
|
expand replaceProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
intoTargets.each { target ->
|
intoTargets.each { target ->
|
||||||
if (file(target).exists()) {
|
if (file(target).exists()) {
|
||||||
copy {
|
copy {
|
||||||
@@ -496,8 +434,7 @@ subprojects { p ->
|
|||||||
attributes(
|
attributes(
|
||||||
'Implementation-Title': rootProject.mod_name,
|
'Implementation-Title': rootProject.mod_name,
|
||||||
'Implementation-Version': rootProject.mod_version,
|
'Implementation-Version': rootProject.mod_version,
|
||||||
'Multi-Release': true, // needed for logging in the standalone core jar
|
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain' // When changing the main of the jar change this line
|
||||||
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain', // When changing the main of the jar change this line
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,9 +466,8 @@ 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 == rootProject ? "" : project.name + "-") + rootProject.versionStr
|
version = 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
|
||||||
@@ -553,9 +489,6 @@ allprojects { p ->
|
|||||||
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Mojang overrides (added to fix downloading the wrong LWJGL libs on M1 Mac's and potentially other arm64 based machines)
|
|
||||||
maven { url "https://libraries.minecraft.net/" }
|
|
||||||
|
|
||||||
// The central repo
|
// The central repo
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
@@ -563,7 +496,6 @@ allprojects { p ->
|
|||||||
maven { url "https://repo.enonic.com/public/" }
|
maven { url "https://repo.enonic.com/public/" }
|
||||||
|
|
||||||
// For parchment mappings
|
// For parchment mappings
|
||||||
// versions can be found here: https://ldtteam.jfrog.io/ui/native/parchmentmc-public/org/parchmentmc/data/
|
|
||||||
maven { url "https://maven.parchmentmc.org" }
|
maven { url "https://maven.parchmentmc.org" }
|
||||||
|
|
||||||
// For Architectury API
|
// For Architectury API
|
||||||
@@ -685,6 +617,7 @@ allprojects { p ->
|
|||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
options.release = rootProject.java_version as Integer
|
options.release = rootProject.java_version as Integer
|
||||||
|
options.compilerArgs += ["-Xplugin:Manifold"]
|
||||||
} else {
|
} else {
|
||||||
options.release = 8; // Core & Api should use Java 8 no matter what
|
options.release = 8; // Core & Api should use Java 8 no matter what
|
||||||
//options.release = rootProject.java_version as Integer // But if you want to test some stuff, then this can be enabled
|
//options.release = rootProject.java_version as Integer // But if you want to test some stuff, then this can be enabled
|
||||||
@@ -696,3 +629,14 @@ 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)
|
||||||
@@ -22,7 +22,7 @@ for d in versionProperties/*; do
|
|||||||
echo "==================== Merging $version ===================="
|
echo "==================== Merging $version ===================="
|
||||||
sh gradlew mergeJars -PmcVer=$version
|
sh gradlew mergeJars -PmcVer=$version
|
||||||
if [ $? != 0 ]; then continue; fi
|
if [ $? != 0 ]; then continue; fi
|
||||||
|
|
||||||
echo "==================== Moving jar ===================="
|
echo "==================== Moving jar ===================="
|
||||||
mv build/merged/*.jar buildAllJars/
|
mv Merged/*.jar buildAllJars/
|
||||||
done
|
done
|
||||||
|
|||||||
+6
-10
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
echo ==================== Note: All build jars will be in the folder called 'buildAllJars' ====================
|
echo ==================== Note: All build jars will be in the folder called 'buildAllJars' ====================
|
||||||
mkdir buildAllJars
|
mkdir buildAllJars
|
||||||
del buildAllJars/*
|
|
||||||
|
|
||||||
@rem Loop trough everything in the version properties folder
|
@rem Loop trough everything in the version properties folder
|
||||||
for %%f in (versionProperties\*) do (
|
for %%f in (versionProperties\*) do (
|
||||||
@@ -14,16 +13,13 @@ 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
|
call .\gradlew.bat clean -PmcVer="!version!" --no-daemon
|
||||||
|
echo ==================== Building !version! ====================
|
||||||
echo ==================== Building !version! ====================
|
call .\gradlew.bat build -PmcVer="!version!" --no-daemon
|
||||||
call .\gradlew.bat build -PmcVer="!version!"
|
echo ==================== Merging !version! ====================
|
||||||
|
call .\gradlew.bat mergeJars -PmcVer="!version!" --no-daemon
|
||||||
echo ==================== Merging !version! ====================
|
|
||||||
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
|
||||||
|
|
||||||
echo ==================== Moving jar ====================
|
echo ==================== Moving jar ====================
|
||||||
move build\merged\*.jar buildAllJars\
|
move Merged\*.jar buildAllJars\
|
||||||
)
|
)
|
||||||
|
|
||||||
endlocal
|
endlocal
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+8
-4
@@ -1,11 +1,16 @@
|
|||||||
|
buildscript {
|
||||||
|
configurations.configureEach {
|
||||||
|
resolutionStrategy {
|
||||||
|
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// temporary fix for broken spongepowered version
|
// temporary fix for broken spongepowered version
|
||||||
buildscript {
|
buildscript {
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
resolutionStrategy {
|
resolutionStrategy {
|
||||||
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
|
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
|
||||||
// newer versions can be found by going to the link:
|
|
||||||
// https://repo.spongepowered.org/#browse/browse:maven-public:org%2Fspongepowered%2Fvanillagradle%2F0.2.1-SNAPSHOT
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,5 +42,4 @@ publishing {
|
|||||||
repositories {
|
repositories {
|
||||||
// Add repositories to publish to here.
|
// Add repositories to publish to here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+164
-125
@@ -1,21 +1,30 @@
|
|||||||
package com.seibel.distanthorizons.common;
|
package com.seibel.distanthorizons.common;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
import com.mojang.brigadier.arguments.*;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||||
import com.seibel.distanthorizons.common.commands.CommandInitializer;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||||
|
import com.seibel.distanthorizons.core.config.types.AbstractConfigType;
|
||||||
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
||||||
|
import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage;
|
||||||
|
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||||
|
import com.seibel.distanthorizons.core.world.DhServerWorld;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
@@ -26,9 +35,25 @@ import net.minecraft.server.dedicated.DedicatedServer;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg;
|
||||||
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
|
import static com.seibel.distanthorizons.core.network.messages.MessageRegistry.DEBUG_ENABLE_CODEC_CRASH_MESSAGE;
|
||||||
|
import static net.minecraft.commands.Commands.argument;
|
||||||
|
import static net.minecraft.commands.Commands.literal;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_19_2
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
#else // < 1.19.2
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base for all mod loader initializers
|
* Base for all mod loader initializers
|
||||||
* and handles most setup.
|
* and handles most setup.
|
||||||
@@ -37,7 +62,7 @@ public abstract class AbstractModInitializer
|
|||||||
{
|
{
|
||||||
protected static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
protected static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
|
||||||
private CommandInitializer commandInitializer;
|
private CommandDispatcher<CommandSourceStack> commandDispatcher;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -66,22 +91,22 @@ public abstract class AbstractModInitializer
|
|||||||
{
|
{
|
||||||
DependencySetup.createClientBindings();
|
DependencySetup.createClientBindings();
|
||||||
|
|
||||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client.");
|
LOGGER.info("Initializing " + ModInfo.READABLE_NAME);
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||||
|
|
||||||
this.startup();
|
this.startup();
|
||||||
this.logBuildInfo();
|
this.printModInfo();
|
||||||
|
|
||||||
this.createClientProxy().registerEvents();
|
this.createClientProxy().registerEvents();
|
||||||
this.createServerProxy(false).registerEvents();
|
this.createServerProxy(false).registerEvents();
|
||||||
|
|
||||||
this.initializeModCompat();
|
this.initializeModCompat();
|
||||||
|
|
||||||
|
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||||
|
|
||||||
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
||||||
this.initConfig();
|
this.initConfig();
|
||||||
logModIncompatibilityWarnings(); // needs to be called after config loading
|
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
|
|
||||||
|
|
||||||
this.subscribeClientStartedEvent(this::postInit);
|
this.subscribeClientStartedEvent(this::postInit);
|
||||||
}
|
}
|
||||||
@@ -90,11 +115,11 @@ public abstract class AbstractModInitializer
|
|||||||
{
|
{
|
||||||
DependencySetup.createServerBindings();
|
DependencySetup.createServerBindings();
|
||||||
|
|
||||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server.");
|
LOGGER.info("Initializing " + ModInfo.READABLE_NAME);
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||||
|
|
||||||
this.startup();
|
this.startup();
|
||||||
this.logBuildInfo();
|
this.printModInfo();
|
||||||
|
|
||||||
// This prevents returning uninitialized Config values,
|
// This prevents returning uninitialized Config values,
|
||||||
// resulting from a circular reference mid-initialization in a static class
|
// resulting from a circular reference mid-initialization in a static class
|
||||||
@@ -105,21 +130,20 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
this.initializeModCompat();
|
this.initializeModCompat();
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
|
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||||
|
|
||||||
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); });
|
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandDispatcher = dispatcher; });
|
||||||
|
|
||||||
this.subscribeServerStartingEvent(server ->
|
this.subscribeServerStartingEvent(server ->
|
||||||
{
|
{
|
||||||
MinecraftServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer)server;
|
MinecraftDedicatedServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer)server;
|
||||||
|
|
||||||
this.initConfig();
|
this.initConfig();
|
||||||
this.postInit();
|
this.postInit();
|
||||||
this.commandInitializer.initCommands();
|
this.initCommands();
|
||||||
|
|
||||||
this.checkForUpdates();
|
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory());
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,17 +160,14 @@ public abstract class AbstractModInitializer
|
|||||||
this.createInitialBindings();
|
this.createInitialBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logBuildInfo()
|
private void printModInfo()
|
||||||
{
|
{
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||||
|
|
||||||
// if the build is stable the branch/commit/etc shouldn't be needed
|
// Useful for dev builds
|
||||||
if (ModInfo.IS_DEV_BUILD)
|
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||||
{
|
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
|
||||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends IModAccessor> void tryCreateModCompatAccessor(String modId, Class<? super T> accessorClass, Supplier<T> accessorConstructor)
|
protected <T extends IModAccessor> void tryCreateModCompatAccessor(String modId, Class<? super T> accessorClass, Supplier<T> accessorConstructor)
|
||||||
@@ -161,128 +182,146 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
private void initConfig()
|
private void initConfig()
|
||||||
{
|
{
|
||||||
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class, ModInfo.CONFIG_FILE_VERSION);
|
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class, 2);
|
||||||
Config.completeDelayedSetup();
|
Config.completeDelayedSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForUpdates()
|
|
||||||
{
|
|
||||||
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get())
|
|
||||||
{
|
|
||||||
if (Config.Client.Advanced.AutoUpdater.enableSilentUpdates.get())
|
|
||||||
{
|
|
||||||
LOGGER.info("Silent updates are not allowed for dedicated servers; force disabling.");
|
|
||||||
Config.Client.Advanced.AutoUpdater.enableSilentUpdates.set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SelfUpdater.onStart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postInit()
|
private void postInit()
|
||||||
{
|
{
|
||||||
LOGGER.info("Post-Initializing Mod");
|
LOGGER.info("Post-Initializing Mod");
|
||||||
this.runDelayedSetup();
|
this.runDelayedSetup();
|
||||||
LOGGER.info("Mod Post-Initialized");
|
LOGGER.info("Mod Post-Initialized");
|
||||||
|
|
||||||
// should be fired after all delayed setup so singletons and config can be accessed
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private void initCommands()
|
||||||
//==================================//
|
|
||||||
// mod partial compatibility checks //
|
|
||||||
//==================================//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some mods will work with a few tweaks
|
|
||||||
* or will partially work but have some known issues we can't solve.
|
|
||||||
* This method will log (and display to chat if enabled)
|
|
||||||
* these warnings and potential fixes.
|
|
||||||
*/
|
|
||||||
private static void logModIncompatibilityWarnings()
|
|
||||||
{
|
{
|
||||||
boolean showChatWarnings = Config.Common.Logging.Warning.showModCompatibilityWarningsOnStartup.get();
|
LiteralArgumentBuilder<CommandSourceStack> builder = literal("dhconfig")
|
||||||
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
.requires(source -> source.hasPermission(4));
|
||||||
|
|
||||||
String startingString = "Partially Incompatible Distant Horizons mod detected: ";
|
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Alex's caves
|
|
||||||
if (modChecker.isModLoaded("alexscaves"))
|
|
||||||
{
|
{
|
||||||
// There've been a few reports about this mod breaking DH at a few different points in time
|
if (!(type instanceof ConfigEntry))
|
||||||
// the fixes for said breakage changes depending on the version so unfortunately
|
|
||||||
// all we can do is log a warning so the user can handle it.
|
|
||||||
|
|
||||||
if (showChatWarnings)
|
|
||||||
{
|
{
|
||||||
String message =
|
continue;
|
||||||
// orange text
|
}
|
||||||
"\u00A76" + "Distant Horizons: Alex's Cave detected." + "\u00A7r\n" +
|
//noinspection PatternVariableCanBeUsed
|
||||||
"You may have to change Alex's config for DH to render. ";
|
ConfigEntry configEntry = (ConfigEntry) type;
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
if (configEntry.getServersideShortName() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.warn(startingString + "[Alex's Caves] may require some config changes in order to render Distant Horizons correctly.");
|
Function<
|
||||||
}
|
Function<CommandContext<CommandSourceStack>, Object>,
|
||||||
|
Command<CommandSourceStack>
|
||||||
// William Wythers' Overhauled Overworld (WWOO)
|
> makeConfigUpdater = getter -> c -> {
|
||||||
if (modChecker.isModLoaded("wwoo"))
|
Object value = getter.apply(c);
|
||||||
{
|
|
||||||
// WWOO has a bug with it's world gen that can't be fixed by DH or WWOO
|
c.getSource().sendSuccess(
|
||||||
// (at least that is what James learned after talking with WWOO)
|
#if MC_VER >= MC_1_20_1
|
||||||
// WWOO will cause grid lines to appear in the world when DH generates the chunks
|
() -> Component.literal("Changed the value of "+configEntry.getServersideShortName()+" to "+value),
|
||||||
// this might be due to how WWOO uses features for everything when generating
|
#elif MC_VER >= MC_1_19_2
|
||||||
// and said features don't always get to the edge of said chunks.
|
Component.literal("Changed the value of "+configEntry.getServersideShortName()+" to "+value),
|
||||||
|
#else
|
||||||
|
new TranslatableComponent("Changed the value of "+configEntry.getServersideShortName()+" to "+value),
|
||||||
|
#endif
|
||||||
|
true);
|
||||||
|
configEntry.set(value);
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
String wwooWarning = "LODs generated by DH may have grid lines between sections. Disabling either WWOO or DH's distant generator will fix the problem.";
|
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getServersideShortName())
|
||||||
|
.executes(c -> {
|
||||||
|
#if MC_VER >= MC_1_20_1
|
||||||
|
c.getSource().sendSuccess(() -> Component.literal("Current value of "+configEntry.getServersideShortName()+" is "+configEntry.get()), true);
|
||||||
|
#elif MC_VER >= MC_1_19_2
|
||||||
|
c.getSource().sendSuccess(Component.literal("Current value of "+configEntry.getServersideShortName()+" is "+configEntry.get()), true);
|
||||||
|
#else // < 1.19.2
|
||||||
|
c.getSource().sendSuccess(new TranslatableComponent("Current value of "+configEntry.getServersideShortName()+" is "+configEntry.get()), true);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
if (showChatWarnings)
|
if (Enum.class.isAssignableFrom(configEntry.getType()))
|
||||||
{
|
{
|
||||||
String message =
|
for (Object choice : configEntry.getType().getEnumConstants())
|
||||||
// orange text
|
{
|
||||||
"\u00A76" + "Distant Horizons: WWOO detected." + "\u00A7r\n" +
|
subcommand.then(
|
||||||
wwooWarning;
|
literal(choice.toString())
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
.executes(makeConfigUpdater.apply(c -> choice))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean setterAdded = false;
|
||||||
|
|
||||||
|
for (java.util.Map.Entry<Class<?>, Pair<Supplier<ArgumentType<?>>, BiFunction<CommandContext<?>, String, ?>>> pair : new HashMap<
|
||||||
|
Class<?>,
|
||||||
|
Pair<
|
||||||
|
Supplier<ArgumentType<?>>,
|
||||||
|
BiFunction<CommandContext<?>, String, ?>>
|
||||||
|
>() {{
|
||||||
|
this.put(Integer.class, new Pair<>(() -> integer((int) configEntry.getMin(), (int) configEntry.getMax()), IntegerArgumentType::getInteger));
|
||||||
|
this.put(Double.class, new Pair<>(() -> doubleArg((double) configEntry.getMin(), (double) configEntry.getMax()), DoubleArgumentType::getDouble));
|
||||||
|
this.put(Boolean.class, new Pair<>(BoolArgumentType::bool, BoolArgumentType::getBool));
|
||||||
|
this.put(String.class, new Pair<>(StringArgumentType::string, StringArgumentType::getString));
|
||||||
|
}}.entrySet())
|
||||||
|
{
|
||||||
|
if (!pair.getKey().isAssignableFrom(configEntry.getType()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
subcommand.then(argument("value", pair.getValue().first.get())
|
||||||
|
.executes(makeConfigUpdater.apply(c -> pair.getValue().second.apply(c, "value"))));
|
||||||
|
|
||||||
|
setterAdded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!setterAdded)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Config type of "+type.getName()+" is not supported: "+configEntry.getType().getSimpleName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.warn(startingString + "[WWOO] "+ wwooWarning);
|
builder.then(subcommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chunky
|
this.commandDispatcher.register(builder);
|
||||||
boolean chunkyPresent = false;
|
|
||||||
try
|
if (DEBUG_ENABLE_CODEC_CRASH_MESSAGE)
|
||||||
{
|
{
|
||||||
Class.forName("org.popcraft.chunky.api.ChunkyAPI");
|
LiteralArgumentBuilder<CommandSourceStack> dhcrash = literal("dhcrash")
|
||||||
chunkyPresent = true;
|
.requires(source -> source.hasPermission(4))
|
||||||
|
.then(literal("encode")
|
||||||
|
.executes(c -> {
|
||||||
|
assert SharedApi.getIDhServerWorld() != null;
|
||||||
|
((DhServerWorld) SharedApi.getIDhServerWorld()).remotePlayerConnectionHandler
|
||||||
|
#if MC_VER >= MC_1_19_2
|
||||||
|
.getConnectedPlayer(ServerPlayerWrapper.getWrapper(Objects.requireNonNull(c.getSource().getPlayer())))
|
||||||
|
#else
|
||||||
|
.getConnectedPlayer(ServerPlayerWrapper.getWrapper(Objects.requireNonNull(c.getSource().getPlayerOrException())))
|
||||||
|
#endif
|
||||||
|
.session.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.ENCODE));
|
||||||
|
return 1;
|
||||||
|
}))
|
||||||
|
.then(literal("decode")
|
||||||
|
.executes(c -> {
|
||||||
|
assert SharedApi.getIDhServerWorld() != null;
|
||||||
|
((DhServerWorld) SharedApi.getIDhServerWorld()).remotePlayerConnectionHandler
|
||||||
|
#if MC_VER >= MC_1_19_2
|
||||||
|
.getConnectedPlayer(ServerPlayerWrapper.getWrapper(Objects.requireNonNull(c.getSource().getPlayer())))
|
||||||
|
#else
|
||||||
|
.getConnectedPlayer(ServerPlayerWrapper.getWrapper(Objects.requireNonNull(c.getSource().getPlayerOrException())))
|
||||||
|
#endif
|
||||||
|
.session.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.DECODE));
|
||||||
|
return 1;
|
||||||
|
}));
|
||||||
|
this.commandDispatcher.register(dhcrash);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ignore) { }
|
|
||||||
|
|
||||||
if (chunkyPresent)
|
|
||||||
{
|
|
||||||
// Chunky can generate chunks faster than DH can process them,
|
|
||||||
// causing holes in the LODs.
|
|
||||||
// Generally it's better and faster to use DH's world generator.
|
|
||||||
|
|
||||||
String chunkyWarning = "Chunky can cause DH LODs to have holes " +
|
|
||||||
"since Chunky can generate chunks faster than DH can process them. \n" +
|
|
||||||
"Using DH's distant generator instead of chunky or increasing DH's CPU thread count can resolve the issue.";
|
|
||||||
|
|
||||||
if (showChatWarnings)
|
|
||||||
{
|
|
||||||
String message =
|
|
||||||
// orange text
|
|
||||||
"\u00A76" + "Distant Horizons: Chunky detected." + "\u00A7r\n" +
|
|
||||||
chunkyWarning;
|
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.warn(startingString + "[Chunky] "+ chunkyWarning);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -296,4 +335,4 @@ public abstract class AbstractModInitializer
|
|||||||
void registerEvents();
|
void registerEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+22
-39
@@ -1,12 +1,11 @@
|
|||||||
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.IncompatibleMessageEvent;
|
||||||
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorEvent;
|
||||||
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.NetworkMessage;
|
||||||
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
|
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||||
@@ -16,6 +15,7 @@ import net.minecraft.network.FriendlyByteBuf;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -23,7 +23,7 @@ import java.util.Objects;
|
|||||||
public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
||||||
{
|
{
|
||||||
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
||||||
() -> Config.Common.Logging.logNetworkEvent.get());
|
() -> Config.Client.Advanced.Logging.logNetworkEvent.get());
|
||||||
|
|
||||||
#if MC_VER >= MC_1_21_1
|
#if MC_VER >= MC_1_21_1
|
||||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||||
@@ -31,39 +31,30 @@ 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;
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public AbstractPluginPacketSender() { this(false); }
|
public final void sendPluginPacketServer(IServerPlayerWrapper serverPlayer, NetworkMessage message)
|
||||||
public AbstractPluginPacketSender(boolean forgeByteInProtocolVersion)
|
|
||||||
{
|
{
|
||||||
this.forgeByteInProtocolVersion = forgeByteInProtocolVersion;
|
this.sendPluginPacketServer((ServerPlayer) serverPlayer.getWrappedMcObject(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
public abstract void sendPluginPacketClient(NetworkMessage message);
|
||||||
{
|
public abstract void sendPluginPacketServer(ServerPlayer serverPlayer, NetworkMessage message);
|
||||||
this.sendToClient((ServerPlayer) serverPlayer.getWrappedMcObject(), message);
|
|
||||||
}
|
|
||||||
public abstract void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message);
|
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
public abstract void sendToServer(AbstractNetworkMessage message);
|
public static NetworkMessage decodeMessage(FriendlyByteBuf in)
|
||||||
|
|
||||||
public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
|
||||||
{
|
{
|
||||||
AbstractNetworkMessage message = null;
|
NetworkMessage message = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
in.markReaderIndex();
|
in.markReaderIndex();
|
||||||
|
|
||||||
int protocolVersion = this.forgeByteInProtocolVersion ? in.readByte() : in.readShort();
|
int protocolVersion = in.readShort();
|
||||||
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
return new IncompatibleMessageInternalEvent(protocolVersion);
|
return new IncompatibleMessageEvent(protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
message = MessageRegistry.INSTANCE.createMessage(in.readUnsignedShort());
|
message = MessageRegistry.INSTANCE.createMessage(in.readUnsignedShort());
|
||||||
@@ -81,10 +72,10 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
in.resetReaderIndex();
|
in.resetReaderIndex();
|
||||||
|
|
||||||
LOGGER.error("Failed to decode message", e);
|
LOGGER.error("Failed to decode message", e);
|
||||||
LOGGER.error("Buffer: ["+in+"]");
|
LOGGER.error("Buffer: {}", in);
|
||||||
LOGGER.error("Buffer contents: ["+ByteBufUtil.hexDump(in)+"]");
|
LOGGER.error("Buffer contents: [{}]", ByteBufUtil.hexDump(in));
|
||||||
|
|
||||||
return new ProtocolErrorInternalEvent(e, message, true);
|
return new ProtocolErrorEvent(e, message, true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -93,19 +84,11 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
public static void encodeMessage(FriendlyByteBuf out, NetworkMessage 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
|
||||||
{
|
{
|
||||||
@@ -116,9 +99,9 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.error("Failed to encode message", e);
|
LOGGER.error("Failed to encode message", e);
|
||||||
LOGGER.error("Message: ["+message+"]");
|
LOGGER.error("Message: {}", message);
|
||||||
|
|
||||||
message.getSession().tryHandleMessage(new ProtocolErrorInternalEvent(e, message, false));
|
message.getSession().tryHandleMessage(new ProtocolErrorEvent(e, message, false));
|
||||||
|
|
||||||
// Encode close reason message instead
|
// Encode close reason message instead
|
||||||
out.resetWriterIndex();
|
out.resetWriterIndex();
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ 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.NetworkMessage;
|
||||||
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;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
public record CommonPacketPayload(
|
||||||
|
@Nullable NetworkMessage 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
|
||||||
public Type<? extends CustomPacketPayload> type() { return TYPE; }
|
public Type<? extends CustomPacketPayload> type()
|
||||||
|
{
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class Codec implements StreamCodec<FriendlyByteBuf, CommonPacketPayload>
|
public static class Codec implements StreamCodec<FriendlyByteBuf, CommonPacketPayload>
|
||||||
@@ -26,11 +28,15 @@ 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(PACKET_SENDER.decodeMessage(in)); }
|
{
|
||||||
|
return new CommonPacketPayload(AbstractPluginPacketSender.decodeMessage(in));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
||||||
{ PACKET_SENDER.encodeMessage(out, payload.message()); }
|
{
|
||||||
|
AbstractPluginPacketSender.encodeMessage(out, payload.message());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.commands;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
#else // < 1.19.2
|
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract class providing common functionality for DH's commands.
|
|
||||||
*/
|
|
||||||
public abstract class AbstractCommand
|
|
||||||
{
|
|
||||||
public abstract LiteralArgumentBuilder<CommandSourceStack> buildCommand();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a success 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 success message.
|
|
||||||
* @return 1, indicating that the command was successful.
|
|
||||||
*/
|
|
||||||
protected int sendSuccessResponse(CommandContext<CommandSourceStack> commandContext, String text, boolean notifyAdmins)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_20_1
|
|
||||||
commandContext.getSource().sendSuccess(() -> Component.literal(text), notifyAdmins);
|
|
||||||
#elif MC_VER >= MC_1_19_2
|
|
||||||
commandContext.getSource().sendSuccess(Component.literal(text), notifyAdmins);
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the server player from a command context.
|
|
||||||
*
|
|
||||||
* @param commandContext The command context to get the server player from.
|
|
||||||
* @return The server player wrapper for the player who sent the command.
|
|
||||||
*/
|
|
||||||
protected IServerPlayerWrapper getSourcePlayer(CommandContext<CommandSourceStack> commandContext) #if MC_VER < MC_1_19_2 throws CommandSyntaxException #endif
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_19_2
|
|
||||||
return ServerPlayerWrapper.getWrapper(Objects.requireNonNull(commandContext.getSource().getPlayer()));
|
|
||||||
#else
|
|
||||||
return ServerPlayerWrapper.getWrapper(commandContext.getSource().getPlayerOrException());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the source of a command is a player.
|
|
||||||
*
|
|
||||||
* @param source The source of the command to check.
|
|
||||||
* @return True if the source is a player, false otherwise.
|
|
||||||
*/
|
|
||||||
protected boolean isPlayerSource(CommandSourceStack source)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_19_2
|
|
||||||
return source.isPlayer();
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
source.getPlayerOrException();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (CommandSyntaxException e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.commands;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
|
|
||||||
import static com.seibel.distanthorizons.core.network.messages.MessageRegistry.DEBUG_CODEC_CRASH_MESSAGE;
|
|
||||||
import static net.minecraft.commands.Commands.literal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes commands of the mod.
|
|
||||||
*/
|
|
||||||
public class CommandInitializer
|
|
||||||
{
|
|
||||||
private final CommandDispatcher<CommandSourceStack> commandDispatcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance of this class.
|
|
||||||
*
|
|
||||||
* @param commandDispatcher The dispatcher to use for registering commands.
|
|
||||||
*/
|
|
||||||
public CommandInitializer(CommandDispatcher<CommandSourceStack> commandDispatcher)
|
|
||||||
{
|
|
||||||
this.commandDispatcher = commandDispatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes all available commands.
|
|
||||||
*/
|
|
||||||
public void initCommands()
|
|
||||||
{
|
|
||||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("dh")
|
|
||||||
.requires(source -> source.hasPermission(4));
|
|
||||||
|
|
||||||
builder.then(new ConfigCommand().buildCommand());
|
|
||||||
builder.then(new DebugCommand().buildCommand());
|
|
||||||
builder.then(new PregenCommand().buildCommand());
|
|
||||||
|
|
||||||
if (DEBUG_CODEC_CRASH_MESSAGE)
|
|
||||||
{
|
|
||||||
builder.then(new CrashCommand().buildCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.commandDispatcher.register(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.commands;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.arguments.*;
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
|
||||||
import com.seibel.distanthorizons.core.config.types.AbstractConfigType;
|
|
||||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.function.ToIntBiFunction;
|
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg;
|
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
|
||||||
import static net.minecraft.commands.Commands.argument;
|
|
||||||
import static net.minecraft.commands.Commands.literal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command for managing config.
|
|
||||||
*/
|
|
||||||
public class ConfigCommand extends AbstractCommand
|
|
||||||
{
|
|
||||||
private static final List<CommandArgumentData<?>> commandArguments = Arrays.asList(
|
|
||||||
new CommandArgumentData<>(Integer.class, configEntry -> integer(configEntry.getMin(), configEntry.getMax()), IntegerArgumentType::getInteger),
|
|
||||||
new CommandArgumentData<>(Double.class, configEntry -> doubleArg(configEntry.getMin(), configEntry.getMax()), DoubleArgumentType::getDouble),
|
|
||||||
new CommandArgumentData<>(Boolean.class, BoolArgumentType::bool, BoolArgumentType::getBool),
|
|
||||||
new CommandArgumentData<>(String.class, StringArgumentType::string, StringArgumentType::getString)
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a command tree.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
|
||||||
{
|
|
||||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
|
||||||
HashSet<String> addedCommands = new HashSet<>();
|
|
||||||
|
|
||||||
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
|
||||||
{
|
|
||||||
// Skip non-config entries
|
|
||||||
if (!(type instanceof ConfigEntry))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//noinspection PatternVariableCanBeUsed
|
|
||||||
ConfigEntry configEntry = (ConfigEntry) type;
|
|
||||||
if (configEntry.getChatCommandName() == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addedCommands.add(configEntry.getChatCommandName()))
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Duplicate command name: " + configEntry.getChatCommandName());
|
|
||||||
}
|
|
||||||
|
|
||||||
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getChatCommandName())
|
|
||||||
.executes(commandContext -> this.sendSuccessResponse(commandContext,
|
|
||||||
"\n" +
|
|
||||||
"Description of §l" + configEntry.getChatCommandName() + "§r:\n" +
|
|
||||||
"§o" + configEntry.getComment().trim() + "§r\n" +
|
|
||||||
"§7Config file name: §f" + configEntry.name + "§7, category: §f" + configEntry.category + "\n" +
|
|
||||||
"\n" +
|
|
||||||
"Current value of " + configEntry.getChatCommandName() + " is §n" + configEntry.get() + "§r",
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
ToIntBiFunction<CommandContext<CommandSourceStack>, Object> updateConfigValue = (commandContext, value) -> {
|
|
||||||
configEntry.set(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
|
|
||||||
// and need literals for each individual value
|
|
||||||
if (Enum.class.isAssignableFrom(configEntry.getType()))
|
|
||||||
{
|
|
||||||
for (Object choice : configEntry.getType().getEnumConstants())
|
|
||||||
{
|
|
||||||
subcommand.then(
|
|
||||||
literal(choice.toString())
|
|
||||||
.executes(c -> updateConfigValue.applyAsInt(c, choice))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean setterAdded = false;
|
|
||||||
for (CommandArgumentData<?> commandArgumentData : commandArguments)
|
|
||||||
{
|
|
||||||
if (!commandArgumentData.argumentClass.isAssignableFrom(configEntry.getType()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
subcommand.then(argument("value", commandArgumentData.getArgumentType(configEntry))
|
|
||||||
.executes(c -> updateConfigValue.applyAsInt(c, commandArgumentData.getValue(c, "value"))));
|
|
||||||
|
|
||||||
setterAdded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!setterAdded)
|
|
||||||
{
|
|
||||||
throw new RuntimeException("Config type of " + type.getName() + " is not supported: " + configEntry.getType().getSimpleName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.then(subcommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class CommandArgumentData<T>
|
|
||||||
{
|
|
||||||
public final Class<T> argumentClass;
|
|
||||||
public final Function<ConfigEntry<T>, ArgumentType<T>> argumentTypeFunction;
|
|
||||||
private final BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter;
|
|
||||||
|
|
||||||
public CommandArgumentData(Class<T> argumentClass, Supplier<ArgumentType<T>> argumentTypeSupplier, BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter)
|
|
||||||
{
|
|
||||||
this(argumentClass, configEntry -> argumentTypeSupplier.get(), valueGetter);
|
|
||||||
}
|
|
||||||
public CommandArgumentData(Class<T> argumentClass, Function<ConfigEntry<T>, ArgumentType<T>> argumentTypeFunction, BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter)
|
|
||||||
{
|
|
||||||
this.argumentClass = argumentClass;
|
|
||||||
this.argumentTypeFunction = argumentTypeFunction;
|
|
||||||
this.valueGetter = valueGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArgumentType<T> getArgumentType(ConfigEntry<T> configEntry)
|
|
||||||
{
|
|
||||||
return this.argumentTypeFunction.apply(configEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getValue(CommandContext<CommandSourceStack> commandContext, String argumentName)
|
|
||||||
{
|
|
||||||
return this.valueGetter.apply(commandContext, argumentName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.commands;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
|
||||||
import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerState;
|
|
||||||
import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
|
|
||||||
import static net.minecraft.commands.Commands.literal;
|
|
||||||
|
|
||||||
public class CrashCommand extends AbstractCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
|
||||||
{
|
|
||||||
return literal("crash")
|
|
||||||
.requires(this::isPlayerSource)
|
|
||||||
.then(literal("encode")
|
|
||||||
.executes(c -> {
|
|
||||||
assert SharedApi.getIDhServerWorld() != null;
|
|
||||||
|
|
||||||
ServerPlayerState serverPlayerState = SharedApi.getIDhServerWorld().getServerPlayerStateManager()
|
|
||||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
|
||||||
if (serverPlayerState != null)
|
|
||||||
{
|
|
||||||
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.ENCODE));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}))
|
|
||||||
.then(literal("decode")
|
|
||||||
.executes(c -> {
|
|
||||||
assert SharedApi.getIDhServerWorld() != null;
|
|
||||||
|
|
||||||
ServerPlayerState serverPlayerState = SharedApi.getIDhServerWorld().getServerPlayerStateManager()
|
|
||||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
|
||||||
if (serverPlayerState != null)
|
|
||||||
{
|
|
||||||
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.DECODE));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.commands;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static net.minecraft.commands.Commands.literal;
|
|
||||||
|
|
||||||
public class DebugCommand extends AbstractCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
|
||||||
{
|
|
||||||
return literal("debug")
|
|
||||||
.executes(c -> {
|
|
||||||
List<String> lines = new ArrayList<>();
|
|
||||||
F3Screen.addStringToDisplay(lines);
|
|
||||||
return this.sendSuccessResponse(c, String.join("\n", lines), false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
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
@@ -77,7 +77,7 @@ public class MixinChunkMapCommon
|
|||||||
|
|
||||||
// submit the update event
|
// submit the update event
|
||||||
ServerApi.INSTANCE.serverChunkSaveEvent(
|
ServerApi.INSTANCE.serverChunkSaveEvent(
|
||||||
new ChunkWrapper(chunk, ServerLevelWrapper.getWrapper(level)),
|
new ChunkWrapper(chunk, level, ServerLevelWrapper.getWrapper(level)),
|
||||||
ServerLevelWrapper.getWrapper(level)
|
ServerLevelWrapper.getWrapper(level)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+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 James Seibel
|
* Copyright (C) 2020-2023 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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
|
|||||||
+3
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -22,8 +22,7 @@ package com.seibel.distanthorizons.common.wrappers;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.gui.ClassicConfigGUI;
|
import com.seibel.distanthorizons.common.wrappers.gui.ClassicConfigGUI;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
|
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
|
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
||||||
@@ -33,7 +32,6 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ public class DependencySetup
|
|||||||
//@Environment(EnvType.SERVER)
|
//@Environment(EnvType.SERVER)
|
||||||
public static void createServerBindings()
|
public static void createServerBindings()
|
||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftServerWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftDedicatedServerWrapper.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Environment(EnvType.CLIENT)
|
//@Environment(EnvType.CLIENT)
|
||||||
@@ -71,7 +69,6 @@ public class DependencySetup
|
|||||||
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftClientWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftGLWrapper.class, MinecraftGLWrapper.INSTANCE);
|
|
||||||
SingletonInjector.INSTANCE.bind(IConfigGui.class, ClassicConfigGUI.CONFIG_CORE_INTERFACE);
|
SingletonInjector.INSTANCE.bind(IConfigGui.class, ClassicConfigGUI.CONFIG_CORE_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-7
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -25,12 +25,7 @@ public class DependencySetupDoneCheck
|
|||||||
{
|
{
|
||||||
// TODO move to DependencySetup
|
// TODO move to DependencySetup
|
||||||
public static boolean isDone = false;
|
public static boolean isDone = false;
|
||||||
/**
|
// TODO why is this here and what is its purpose?
|
||||||
* This is used so we can override some MC logic when running
|
|
||||||
* in DH's world generator.
|
|
||||||
* Specifically so we can redirect threads to run on DH threads instead
|
|
||||||
* of MC threads.
|
|
||||||
*/
|
|
||||||
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> { return false; });
|
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> { return false; });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-7
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -49,9 +49,7 @@ public class McObjectConverter
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static Mat4f Convert(
|
public static Mat4f Convert(
|
||||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||||
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f
|
#else org.joml.Matrix4f #endif
|
||||||
#else org.joml.Matrix4fc
|
|
||||||
#endif
|
|
||||||
mcMatrix)
|
mcMatrix)
|
||||||
{
|
{
|
||||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||||
@@ -65,9 +63,7 @@ public class McObjectConverter
|
|||||||
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
||||||
private static void storeMatrix(
|
private static void storeMatrix(
|
||||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||||
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f
|
#else org.joml.Matrix4f #endif
|
||||||
#else org.joml.Matrix4fc
|
|
||||||
#endif
|
|
||||||
matrix,
|
matrix,
|
||||||
FloatBuffer buffer)
|
FloatBuffer buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
+24
-42
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,8 @@
|
|||||||
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
|
||||||
@@ -36,52 +38,32 @@ 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()
|
||||||
{
|
{
|
||||||
// these values are hard-coded to prevent an issue with Forge (specifically 1.18.2) where
|
#if MC_VER < MC_1_19_2
|
||||||
// it can't load client classes when running as a dedicated server,
|
return Minecraft.getInstance().getGame().getVersion().getId();
|
||||||
// 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";
|
|
||||||
#elif MC_VER == MC_1_21_6
|
|
||||||
return "1.21.6";
|
|
||||||
#elif MC_VER == MC_1_21_7
|
|
||||||
return "1.21.7";
|
|
||||||
#else
|
#else
|
||||||
ERROR MC version constant missing
|
return SharedConstants.getCurrentVersion().getId();
|
||||||
#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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -174,6 +174,8 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
}
|
}
|
||||||
// the level is needed for the DH level wrapper...
|
// the level is needed for the DH level wrapper...
|
||||||
Level level = (Level) objectArray[1];
|
Level level = (Level) objectArray[1];
|
||||||
|
// ...the LevelReader is needed for chunk lighting
|
||||||
|
LevelReader lightSource = level;
|
||||||
|
|
||||||
|
|
||||||
// level wrapper
|
// level wrapper
|
||||||
@@ -182,7 +184,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
: ServerLevelWrapper.getWrapper((ServerLevel)level);
|
: ServerLevelWrapper.getWrapper((ServerLevel)level);
|
||||||
|
|
||||||
|
|
||||||
return new ChunkWrapper(chunk, levelWrapper);
|
return new ChunkWrapper(chunk, lightSource, levelWrapper);
|
||||||
}
|
}
|
||||||
// incorrect number of parameters from the API
|
// incorrect number of parameters from the API
|
||||||
else
|
else
|
||||||
|
|||||||
+47
-87
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.common.wrappers.block;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
@@ -47,7 +46,6 @@ import net.minecraft.core.registries.Registries;
|
|||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
#endif
|
#endif
|
||||||
@@ -131,6 +129,14 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** should only be used to create {@link BiomeWrapper#EMPTY_WRAPPER} */
|
||||||
|
private BiomeWrapper()
|
||||||
|
{
|
||||||
|
this.biome = null;
|
||||||
|
this.serialString = EMPTY_BIOME_STRING;
|
||||||
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
//=========//
|
||||||
@@ -220,10 +226,8 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.lookupOrThrow(Registries.BIOME).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (resourceLocation == null)
|
if (resourceLocation == null)
|
||||||
@@ -279,16 +283,50 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
BiomeWrapper foundWrapper = EMPTY_WRAPPER;
|
BiomeWrapper foundWrapper = EMPTY_WRAPPER;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// parse the resource location
|
||||||
|
int separatorIndex = resourceLocationString.indexOf(":");
|
||||||
|
if (separatorIndex == -1)
|
||||||
|
{
|
||||||
|
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLocation resourceLocation;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_1
|
||||||
|
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IOException("No Resource Location found for the string: [" + resourceLocationString + "] Error: [" + e.getMessage() + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Level level = (Level) levelWrapper.getWrappedMcObject();
|
Level level = (Level) levelWrapper.getWrappedMcObject();
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
|
|
||||||
BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess);
|
boolean success;
|
||||||
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
|
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
|
success = (biome != null);
|
||||||
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
|
success = (unwrappedBiome != null);
|
||||||
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
#else
|
||||||
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
||||||
|
success = (unwrappedBiome != null);
|
||||||
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!deserializeResult.success)
|
if (!success)
|
||||||
{
|
{
|
||||||
if (!brokenResourceLocationStrings.contains(resourceLocationString))
|
if (!brokenResourceLocationStrings.contains(resourceLocationString))
|
||||||
{
|
{
|
||||||
@@ -299,7 +337,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foundWrapper = (BiomeWrapper) getBiomeWrapper(deserializeResult.biome, levelWrapper);
|
foundWrapper = (BiomeWrapper) getBiomeWrapper(biome, levelWrapper);
|
||||||
return foundWrapper;
|
return foundWrapper;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -313,82 +351,4 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BiomeDeserializeResult deserializeBiome(String resourceLocationString, net.minecraft.core.RegistryAccess registryAccess) throws IOException
|
|
||||||
{
|
|
||||||
// parse the resource location
|
|
||||||
int separatorIndex = resourceLocationString.indexOf(":");
|
|
||||||
if (separatorIndex == -1)
|
|
||||||
{
|
|
||||||
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceLocation resourceLocation;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_1
|
|
||||||
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
|
||||||
#else
|
|
||||||
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new IOException("No Resource Location found for the string: [" + resourceLocationString + "] Error: [" + e.getMessage() + "].");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
boolean success;
|
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
|
||||||
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
|
||||||
success = (biome != null);
|
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
|
||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
#else
|
|
||||||
Holder<Biome> biome;
|
|
||||||
Optional<Holder.Reference<Biome>> optionalBiomeHolder = registryAccess.lookupOrThrow(Registries.BIOME).get(resourceLocation);
|
|
||||||
if (optionalBiomeHolder.isPresent())
|
|
||||||
{
|
|
||||||
Biome unwrappedBiome = optionalBiomeHolder.get().value();
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
biome = null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new BiomeDeserializeResult(success, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper classes //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
public static class BiomeDeserializeResult
|
|
||||||
{
|
|
||||||
public final boolean success;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
public final Biome biome;
|
|
||||||
#else
|
|
||||||
public final Holder<Biome> biome;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public BiomeDeserializeResult(boolean success, #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome)
|
|
||||||
{
|
|
||||||
this.success = success;
|
|
||||||
this.biome = biome;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-133
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,8 +43,6 @@ 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;
|
||||||
@@ -60,7 +58,6 @@ import net.minecraft.world.level.Level;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class BlockStateWrapper implements IBlockStateWrapper
|
public class BlockStateWrapper implements IBlockStateWrapper
|
||||||
@@ -86,25 +83,26 @@ 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> BROKEN_RESOURCE_LOCATIONS = new HashSet<>();
|
private static final HashSet<ResourceLocation> BrokenResourceLocations = 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} */
|
/**
|
||||||
private final int opacity;
|
* Cached opacity value, -1 if not populated. <br>
|
||||||
|
* 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;
|
||||||
@@ -135,38 +133,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Can be faster than {@link BlockStateWrapper#fromBlockState(BlockState, ILevelWrapper)}
|
|
||||||
* in cases where the same block state is expected to be referenced multiple times.
|
|
||||||
*/
|
|
||||||
public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess)
|
|
||||||
{
|
|
||||||
BlockState guessBlockState = (guess == null || guess.isAir()) ? null : (BlockState) guess.getWrappedMcObject();
|
|
||||||
BlockState inputBlockState = (blockState == null || blockState.isAir()) ? null : blockState;
|
|
||||||
|
|
||||||
if (guess instanceof BlockStateWrapper
|
|
||||||
&& guessBlockState == inputBlockState)
|
|
||||||
{
|
|
||||||
return (BlockStateWrapper) guess;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return fromBlockState(blockState, levelWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockStateWrapper(BlockState blockState, ILevelWrapper levelWrapper)
|
private BlockStateWrapper(BlockState blockState, ILevelWrapper levelWrapper)
|
||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
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++)
|
||||||
{
|
{
|
||||||
@@ -202,39 +177,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -273,7 +215,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||||
baseIgnoredBlock.add(AIR_STRING);
|
baseIgnoredBlock.add(AIR_STRING);
|
||||||
rendererIgnoredBlocks = getBlockWrappers(Config.Client.Advanced.Graphics.Culling.ignoredRenderBlockCsv, baseIgnoredBlock, levelWrapper);
|
rendererIgnoredBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||||
return rendererIgnoredBlocks;
|
return rendererIgnoredBlocks;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -290,7 +232,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||||
baseIgnoredBlock.add(AIR_STRING);
|
baseIgnoredBlock.add(AIR_STRING);
|
||||||
rendererIgnoredCaveBlocks = getBlockWrappers(Config.Client.Advanced.Graphics.Culling.ignoredRenderCaveBlockCsv, baseIgnoredBlock, levelWrapper);
|
rendererIgnoredCaveBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderCaveBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||||
return rendererIgnoredCaveBlocks;
|
return rendererIgnoredCaveBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,13 +320,13 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
//=================//
|
//=================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOpacity() { return this.opacity; }
|
public int getOpacity()
|
||||||
private int calculateOpacity()
|
|
||||||
{
|
{
|
||||||
// get block properties (defaults to the values used by air)
|
// use the cached opacity value if possible
|
||||||
boolean canOcclude = this.getCanOcclude();
|
if (this.opacity != -1)
|
||||||
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
|
||||||
@@ -393,20 +335,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
{
|
{
|
||||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||||
}
|
}
|
||||||
else if (this.isLiquid() && !canOcclude)
|
else if (this.isLiquid() && !this.blockState.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;
|
||||||
}
|
}
|
||||||
else if (propagatesSkyLightDown && !canOcclude)
|
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
||||||
{
|
{
|
||||||
// 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
|
||||||
@@ -416,37 +353,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return opacity;
|
this.opacity = 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; }
|
||||||
@@ -486,11 +395,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
@Override
|
@Override
|
||||||
public boolean isSolid()
|
public boolean isSolid()
|
||||||
{
|
{
|
||||||
if (this.isAir())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
return this.blockState.getMaterial().isSolid();
|
return this.blockState.getMaterial().isSolid();
|
||||||
#else
|
#else
|
||||||
@@ -519,8 +423,6 @@ 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; }
|
||||||
@@ -559,10 +461,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -641,8 +541,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
{
|
{
|
||||||
|
|
||||||
#if MC_VER > MC_1_17_1
|
#if MC_VER > MC_1_17_1
|
||||||
LodUtil.assertTrue(levelWrapper != null && levelWrapper.getWrappedMcObject() != null);
|
Level level = (Level)Objects.requireNonNull(levelWrapper.getWrappedMcObject());
|
||||||
Level level = (Level)levelWrapper.getWrappedMcObject();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Block block;
|
Block block;
|
||||||
@@ -651,22 +550,18 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
|
||||||
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
|
|
||||||
#else
|
#else
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
Optional<Holder.Reference<Block>> optionalBlockHolder = registryAccess.lookupOrThrow(Registries.BLOCK).get(resourceLocation);
|
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
|
||||||
block = optionalBlockHolder.isPresent() ? optionalBlockHolder.get().value() : null;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
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 (!BROKEN_RESOURCE_LOCATIONS.contains(resourceLocation))
|
if (!BrokenResourceLocations.contains(resourceLocation))
|
||||||
{
|
{
|
||||||
BROKEN_RESOURCE_LOCATIONS.add(resourceLocation);
|
BrokenResourceLocations.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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,9 +591,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 (!BROKEN_RESOURCE_LOCATIONS.contains(resourceLocation))
|
if (!BrokenResourceLocations.contains(resourceLocation))
|
||||||
{
|
{
|
||||||
BROKEN_RESOURCE_LOCATIONS.add(resourceLocation);
|
BrokenResourceLocations.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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -861,4 +756,4 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+24
-81
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,18 +40,11 @@ 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
|
||||||
@@ -91,7 +84,7 @@ public class ClientBlockStateColorCache
|
|||||||
private static final RandomSource RANDOM = RandomSource.create();
|
private static final RandomSource RANDOM = RandomSource.create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private final IClientLevelWrapper clientLevelWrapper;
|
private final IClientLevelWrapper levelWrapper;
|
||||||
private final BlockState blockState;
|
private final BlockState blockState;
|
||||||
private final LevelReader level;
|
private final LevelReader level;
|
||||||
|
|
||||||
@@ -174,7 +167,7 @@ public class ClientBlockStateColorCache
|
|||||||
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
|
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
|
||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
this.clientLevelWrapper = samplingLevel;
|
this.levelWrapper = samplingLevel;
|
||||||
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
||||||
this.resolveColors();
|
this.resolveColors();
|
||||||
}
|
}
|
||||||
@@ -203,7 +196,9 @@ 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 = this.getQuadsForDirection(direction);
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
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
|
||||||
@@ -217,37 +212,19 @@ public class ClientBlockStateColorCache
|
|||||||
|
|
||||||
if (quads == null || quads.isEmpty())
|
if (quads == null || quads.isEmpty())
|
||||||
{
|
{
|
||||||
quads = this.getUnculledQuads();
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).getQuads(this.blockState, null, RANDOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quads != null
|
if (quads != null && !quads.isEmpty())
|
||||||
&& !quads.isEmpty()
|
|
||||||
&& quads.get(0) != null)
|
|
||||||
{
|
{
|
||||||
BakedQuad firstQuad = quads.get(0);
|
this.needPostTinting = quads.get(0).isTinted();
|
||||||
|
this.needShade = quads.get(0).isShade();
|
||||||
this.needPostTinting = firstQuad.isTinted();
|
this.tintIndex = quads.get(0).getTintIndex();
|
||||||
#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(
|
||||||
firstQuad.sprite,
|
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
#else quads.get(0).getSprite(), #endif
|
||||||
#elif MC_VER < MC_1_21_5
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
this.baseColor = calculateColorFromTexture(
|
|
||||||
firstQuad.getSprite(),
|
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
#else
|
|
||||||
this.baseColor = calculateColorFromTexture(
|
|
||||||
firstQuad.sprite(),
|
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -255,7 +232,8 @@ public class ClientBlockStateColorCache
|
|||||||
this.needPostTinting = false;
|
this.needPostTinting = false;
|
||||||
this.needShade = false;
|
this.needShade = false;
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = this.getParticleIconColor();
|
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -264,7 +242,8 @@ public class ClientBlockStateColorCache
|
|||||||
this.needPostTinting = true;
|
this.needPostTinting = true;
|
||||||
this.needShade = false;
|
this.needShade = false;
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = this.getParticleIconColor();
|
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isColorResolved = true;
|
this.isColorResolved = true;
|
||||||
@@ -274,35 +253,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -374,12 +324,12 @@ public class ClientBlockStateColorCache
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
// this block is entirely transparent
|
// this block is entirely transparent
|
||||||
tempColor = ColorUtil.argbToInt(0, 255, 255, 255);
|
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// determine the average color
|
// determine the average color
|
||||||
tempColor = ColorUtil.argbToInt(
|
tempColor = ColorUtil.rgbToInt(
|
||||||
alpha / count,
|
alpha / count,
|
||||||
linearToSrgb((float) (red / (double) alpha)),
|
linearToSrgb((float) (red / (double) alpha)),
|
||||||
linearToSrgb((float) (green / (double) alpha)),
|
linearToSrgb((float) (green / (double) alpha)),
|
||||||
@@ -387,10 +337,10 @@ public class ClientBlockStateColorCache
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check if not missing texture
|
//check if not missing texture
|
||||||
if (tempColor == ColorUtil.argbToInt(255, 182, 0, 182))
|
if (tempColor == ColorUtil.rgbToInt(255, 182, 0, 182))
|
||||||
{
|
{
|
||||||
//make it not render at all
|
//make it not render at all
|
||||||
tempColor = ColorUtil.argbToInt(0, 255, 255, 255);
|
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
||||||
}
|
}
|
||||||
return tempColor;
|
return tempColor;
|
||||||
}
|
}
|
||||||
@@ -433,13 +383,6 @@ 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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//===============//
|
||||||
@@ -471,7 +414,7 @@ public class ClientBlockStateColorCache
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
tintColor = Minecraft.getInstance().getBlockColors()
|
tintColor = Minecraft.getInstance().getBlockColors()
|
||||||
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.clientLevelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
|
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.levelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
{
|
{
|
||||||
|
|||||||
+12
-25
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,14 +19,8 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
#else
|
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
|
||||||
import net.minecraft.client.renderer.texture.SpriteContents;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For wrapping/utilizing around TextureAtlasSprite
|
* For wrapping/utilizing around TextureAtlasSprite
|
||||||
@@ -35,6 +29,15 @@ import net.minecraft.client.renderer.texture.SpriteContents;
|
|||||||
*/
|
*/
|
||||||
public class TextureAtlasSpriteWrapper
|
public class TextureAtlasSpriteWrapper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code is from Minecraft Forge
|
||||||
|
* Which is licensed under the terms of GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* The code has been modified to use TextureAtlasSprite
|
||||||
|
*/
|
||||||
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y)
|
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@@ -48,29 +51,13 @@ public class TextureAtlasSpriteWrapper
|
|||||||
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
|
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
|
||||||
}
|
}
|
||||||
return sprite.mainImage[0].getPixelRGBA(x, y);
|
return sprite.mainImage[0].getPixelRGBA(x, y);
|
||||||
#elif MC_VER < MC_1_21_3
|
#else
|
||||||
if (sprite.contents().animatedTexture != null)
|
if (sprite.contents().animatedTexture != null)
|
||||||
{
|
{
|
||||||
x += sprite.contents().animatedTexture.getFrameX(frameIndex) * sprite.contents().width();
|
x += sprite.contents().animatedTexture.getFrameX(frameIndex) * sprite.contents().width();
|
||||||
y += sprite.contents().animatedTexture.getFrameY(frameIndex) * sprite.contents().width();
|
y += sprite.contents().animatedTexture.getFrameY(frameIndex) * sprite.contents().width();
|
||||||
}
|
}
|
||||||
return sprite.contents().originalImage.getPixelRGBA(x, y);
|
return sprite.contents().originalImage.getPixelRGBA(x, y);
|
||||||
#else
|
|
||||||
|
|
||||||
SpriteContents content = sprite.contents(); // don't close, otherwise MC will be corrupted and you won't be able to re-access the texture
|
|
||||||
if (content.animatedTexture != null)
|
|
||||||
{
|
|
||||||
x += content.animatedTexture.getFrameX(frameIndex) * content.width();
|
|
||||||
y += content.animatedTexture.getFrameY(frameIndex) * content.width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int abgr = content.originalImage.getPixel(x, y);
|
|
||||||
// re-pack the color so we can access it normally
|
|
||||||
int a = (abgr & 0xFF000000) >>> 24;
|
|
||||||
int b = (abgr & 0x00FF0000) >>> 16;
|
|
||||||
int g = (abgr & 0x0000FF00) >>> 8;
|
|
||||||
int r = (abgr & 0x000000FF);
|
|
||||||
return ColorUtil.argbToInt(a, r, g, b);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+114
-77
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -42,24 +42,15 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
{
|
{
|
||||||
LevelReader parent;
|
LevelReader parent;
|
||||||
|
|
||||||
|
public TintGetterOverrideFast(LevelReader parent)
|
||||||
|
{
|
||||||
//=============//
|
this.parent = parent;
|
||||||
// constructor //
|
}
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintGetterOverrideFast(LevelReader parent) { this.parent = parent; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
return this.parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#else
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
@@ -72,123 +63,169 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine() { return this.parent.getLightEngine(); }
|
public LevelLightEngine getLightEngine()
|
||||||
|
{
|
||||||
|
return parent.getLightEngine();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { return this.parent.getBrightness(lightLayer, blockPos); }
|
public int getBrightness(LightLayer lightLayer, BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getBrightness(lightLayer, blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRawBrightness(BlockPos blockPos, int i) { return this.parent.getRawBrightness(blockPos, i); }
|
public int getRawBrightness(BlockPos blockPos, int i)
|
||||||
|
{
|
||||||
|
return parent.getRawBrightness(blockPos, i);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canSeeSky(BlockPos blockPos) { return this.parent.canSeeSky(blockPos); }
|
public boolean canSeeSky(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.canSeeSky(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
public BlockEntity getBlockEntity(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getBlockEntity(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
public BlockState getBlockState(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getBlockState(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FluidState getFluidState(BlockPos blockPos) { return this.parent.getFluidState(blockPos); }
|
public FluidState getFluidState(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getFluidState(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
public int getLightEmission(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getLightEmission(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLightLevel() { return parent.getMaxLightLevel(); }
|
public int getMaxLightLevel()
|
||||||
#else
|
{
|
||||||
#endif
|
return parent.getMaxLightLevel();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<BlockState> getBlockStates(AABB aABB)
|
public Stream<BlockState> getBlockStates(AABB aABB)
|
||||||
{ return this.parent.getBlockStates(aABB); }
|
{
|
||||||
|
return parent.getBlockStates(aABB);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult clip(ClipContext clipContext)
|
public BlockHitResult clip(ClipContext clipContext)
|
||||||
{ return this.parent.clip(clipContext); }
|
{
|
||||||
|
return parent.clip(clipContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
||||||
{ return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState); }
|
{
|
||||||
|
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier)
|
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier)
|
||||||
{ return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
{
|
||||||
|
return parent.getBlockFloorHeight(voxelShape, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
public double getBlockFloorHeight(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.getBlockFloorHeight(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
public int getMaxBuildHeight()
|
||||||
#else
|
{
|
||||||
@Override
|
return parent.getMaxBuildHeight();
|
||||||
public int getMaxY() { return this.parent.getMaxY(); }
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// post MC 1.17 //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
||||||
{ return this.parent.getBlockEntity(blockPos, blockEntityType); }
|
{
|
||||||
|
return parent.getBlockEntity(blockPos, blockEntityType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext)
|
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext)
|
||||||
{ return this.parent.isBlockInLine(clipBlockStateContext); }
|
{
|
||||||
|
return parent.isBlockInLine(clipBlockStateContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() { return this.parent.getHeight(); }
|
public int getHeight()
|
||||||
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
return parent.getHeight();
|
||||||
@Override
|
}
|
||||||
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinY() { return this.parent.getMinY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
public int getMinBuildHeight()
|
||||||
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
return parent.getMinBuildHeight();
|
||||||
@Override
|
}
|
||||||
public int getMinSection() { return this.parent.getMinSection(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinSectionY() { return BlockAndTintGetter.super.getMinSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMaxSection() { return this.parent.getMaxSection(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMaxSectionY() { return this.parent.getMaxSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
public int getSectionsCount()
|
||||||
|
{
|
||||||
|
return parent.getSectionsCount();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutsideBuildHeight(int i) { return this.parent.isOutsideBuildHeight(i); }
|
public int getMinSection()
|
||||||
|
{
|
||||||
|
return parent.getMinSection();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionIndex(int i) { return this.parent.getSectionIndex(i); }
|
public int getMaxSection()
|
||||||
|
{
|
||||||
|
return parent.getMaxSection();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionIndexFromSectionY(int i) { return this.parent.getSectionIndexFromSectionY(i); }
|
public boolean isOutsideBuildHeight(BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return parent.isOutsideBuildHeight(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
public boolean isOutsideBuildHeight(int i)
|
||||||
|
{
|
||||||
|
return parent.isOutsideBuildHeight(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSectionIndex(int i)
|
||||||
|
{
|
||||||
|
return parent.getSectionIndex(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSectionIndexFromSectionY(int i)
|
||||||
|
{
|
||||||
|
return parent.getSectionIndexFromSectionY(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSectionYFromSectionIndex(int i)
|
||||||
|
{
|
||||||
|
return parent.getSectionYFromSectionIndex(i);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-38
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,6 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Cursor3D;
|
import net.minecraft.core.Cursor3D;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@@ -45,28 +44,16 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
LevelReader parent;
|
LevelReader parent;
|
||||||
public int smoothingRange;
|
public int smoothingRange;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange)
|
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange)
|
||||||
{
|
{
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.smoothingRange = smoothingRange;
|
this.smoothingRange = smoothingRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
return this.parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#else
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
@@ -126,11 +113,8 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
@Override
|
@Override
|
||||||
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
||||||
@@ -151,13 +135,8 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMaxY() { return this.parent.getMaxY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
@@ -169,32 +148,17 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
@Override
|
@Override
|
||||||
public int getHeight() { return this.parent.getHeight(); }
|
public int getHeight() { return this.parent.getHeight(); }
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinY() { return this.parent.getMinY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinSection() { return this.parent.getMinSection(); }
|
public int getMinSection() { return this.parent.getMinSection(); }
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinSectionY() { return BlockAndTintGetter.super.getMinSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxSection() { return this.parent.getMaxSection(); }
|
public int getMaxSection() { return this.parent.getMaxSection(); }
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMaxSectionY() { return this.parent.getMaxSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
||||||
|
|||||||
+48
-139
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,13 +20,13 @@
|
|||||||
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.logging.DhLoggerBuilder;
|
||||||
|
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.client.Minecraft;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
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;
|
||||||
@@ -39,54 +39,55 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
/**
|
||||||
|
* This will only ever be null if there was an issue with {@link IClientLevelWrapper#getPlainsBiomeWrapper()}
|
||||||
#if MC_VER < MC_1_18_2
|
* but {@link Nullable} is there just in case.
|
||||||
public static final ConcurrentMap<String, Biome> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
|
*/
|
||||||
#else
|
@Nullable
|
||||||
public static final ConcurrentMap<String, Holder<Biome>> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
|
private final Biome biome;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final BiomeWrapper biomeWrapper;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintWithoutLevelOverrider(@NotNull BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
|
||||||
{ this.biomeWrapper = biomeWrapper; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
|
||||||
{
|
{
|
||||||
String biomeString = this.biomeWrapper.getSerialString();
|
// try to get the wrapped biome
|
||||||
if (biomeString == null
|
Biome unwrappedBiome = null;
|
||||||
|| biomeString.isEmpty()
|
if (biomeWrapper.biome != null)
|
||||||
|| biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING))
|
|
||||||
{
|
{
|
||||||
// default to "plains" for empty/invalid biomes
|
unwrappedBiome = unwrap(biomeWrapper.biome);
|
||||||
biomeString = "minecraft:plains";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(unwrappedBiome == null)
|
||||||
|
{
|
||||||
|
// we are looking at the empty biome wrapper, try using plains as a backup
|
||||||
|
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper());
|
||||||
|
if (plainsBiomeWrapper != null)
|
||||||
|
{
|
||||||
|
unwrappedBiome = unwrap(plainsBiomeWrapper.biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return colorResolver.getColor(unwrap(getClientBiome(biomeString)), blockPos.getX(), blockPos.getZ());
|
this.biome = unwrappedBiome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
|
{
|
||||||
|
if (this.biome != null)
|
||||||
|
{
|
||||||
|
return colorResolver.getColor(this.biome, blockPos.getX(), blockPos.getZ());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// hopefully unneeded debug color
|
||||||
|
return ColorUtil.CYAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
@@ -96,88 +97,6 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <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>
|
|
||||||
*/
|
|
||||||
private static #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif getClientBiome(String biomeResourceString)
|
|
||||||
{
|
|
||||||
// cache the client biomes so we don't have to re-parse the resource location every time
|
|
||||||
return BIOME_BY_RESOURCE_STRING.compute(biomeResourceString,
|
|
||||||
(resourceString, existingBiome) ->
|
|
||||||
{
|
|
||||||
if (existingBiome != null)
|
|
||||||
{
|
|
||||||
return existingBiome;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientLevel clientLevel = Minecraft.getInstance().level;
|
|
||||||
if (clientLevel == null)
|
|
||||||
{
|
|
||||||
// shouldn't happen, but just in case
|
|
||||||
throw new IllegalStateException("Attempted to get client biome when no client level was loaded.");
|
|
||||||
}
|
|
||||||
|
|
||||||
BiomeWrapper.BiomeDeserializeResult result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = BiomeWrapper.deserializeBiome(resourceString, clientLevel.registryAccess());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Unable to deserialize client biome ["+resourceString+"], using fallback...");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = BiomeWrapper.deserializeBiome("minecraft:plains", clientLevel.registryAccess());
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
// should never happen, if it does this log will explode, but just in case
|
|
||||||
LOGGER.error("Unable to deserialize fallback client biome [minecraft:plains], returning NULL.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.success)
|
|
||||||
{
|
|
||||||
existingBiome = result.biome;
|
|
||||||
}
|
|
||||||
|
|
||||||
return existingBiome;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
@@ -213,27 +132,17 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// post MC 1.17 //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
#if MC_VER < MC_1_21_3
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
{
|
||||||
#else
|
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
@Override
|
}
|
||||||
public int getMinY()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinY() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-36
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -39,24 +39,11 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
|||||||
final BiomeWrapper biome;
|
final BiomeWrapper biome;
|
||||||
public int smoothingRange;
|
public int smoothingRange;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintWithoutLevelSmoothOverrider(BiomeWrapper biome, int smoothingRange)
|
public TintWithoutLevelSmoothOverrider(BiomeWrapper biome, int smoothingRange)
|
||||||
{
|
{
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
this.smoothingRange = smoothingRange;
|
this.smoothingRange = smoothingRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||||
{
|
{
|
||||||
@@ -70,7 +57,7 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
|||||||
return biome;
|
return biome;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
//
|
||||||
// public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
// public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||||
// {
|
// {
|
||||||
// int i = smoothingRange;
|
// int i = smoothingRange;
|
||||||
@@ -102,43 +89,44 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean shade)
|
public float getShade(Direction direction, boolean shade)
|
||||||
{ throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine()
|
public LevelLightEngine getLightEngine()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(BlockPos pos)
|
public BlockEntity getBlockEntity(BlockPos pos)
|
||||||
{ throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos pos)
|
public BlockState getBlockState(BlockPos pos)
|
||||||
{ throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public FluidState getFluidState(BlockPos pos)
|
public FluidState getFluidState(BlockPos pos)
|
||||||
{ throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// post MC 1.17 //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
|
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
#if MC_VER < MC_1_21_3
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
{
|
||||||
#else
|
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
@Override
|
}
|
||||||
public int getMinY()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinY() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+212
-247
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,31 +16,37 @@
|
|||||||
* 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;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.MutableBlockPosWrapper;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.core.world.EWorldEnvironment;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import net.minecraft.client.multiplayer.ClientChunkCache;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.LightLayer;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.core.QuartPos;
|
import net.minecraft.core.QuartPos;
|
||||||
@@ -64,6 +70,8 @@ import net.minecraft.world.level.chunk.LevelChunkSection;
|
|||||||
|
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
@@ -79,28 +87,41 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
||||||
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
||||||
private static final ThreadLocal<MutableBlockPosWrapper> MUTABLE_BLOCK_POS_WRAPPER_REF = ThreadLocal.withInitial(() -> new MutableBlockPosWrapper());
|
|
||||||
|
|
||||||
|
|
||||||
private final ChunkAccess chunk;
|
private final ChunkAccess chunk;
|
||||||
private final DhChunkPos chunkPos;
|
private final DhChunkPos chunkPos;
|
||||||
|
private final LevelReader lightSource;
|
||||||
private final ILevelWrapper wrappedLevel;
|
private final ILevelWrapper wrappedLevel;
|
||||||
|
|
||||||
private boolean isDhBlockLightCorrect = false;
|
private boolean isDhLightCorrect = false;
|
||||||
private boolean isDhSkyLightCorrect = false;
|
/** only used when connected to a dedicated server */
|
||||||
|
private boolean isMcClientLightingCorrect = false;
|
||||||
|
|
||||||
private ChunkLightStorage blockLightStorage;
|
private ChunkLightStorage blockLightStorage;
|
||||||
private ChunkLightStorage skyLightStorage;
|
private ChunkLightStorage skyLightStorage;
|
||||||
|
|
||||||
private ArrayList<DhBlockPos> blockLightPosList = null;
|
private ArrayList<DhBlockPos> blockLightPosList = null;
|
||||||
|
|
||||||
|
private boolean useDhLighting;
|
||||||
|
|
||||||
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
||||||
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
||||||
|
|
||||||
/** will be null if we are using MC heightmaps */
|
private int blockBiomeHashCode = 0;
|
||||||
private final int[][] solidHeightMap;
|
|
||||||
/** will be null if we are using MC heightmaps */
|
/**
|
||||||
private final int[][] lightBlockingHeightMap;
|
* Due to vanilla `isClientLightReady()` not being designed for use by a non-render thread, it may return 'true'
|
||||||
|
* before the light engine has ticked, (right after all light changes is marked by the engine to be processed).
|
||||||
|
* To fix this, on client-only mode, we mixin-redirect the `isClientLightReady()` so that after the call, it will
|
||||||
|
* trigger a synchronous update of this flag here on all chunks that are wrapped. <br><br>
|
||||||
|
*
|
||||||
|
* Note: Using a static weak hash map to store the chunks that need to be updated, as instance of chunk wrapper
|
||||||
|
* can be duplicated, with same chunk instance. And the data stored here are all temporary, and thus will not be
|
||||||
|
* visible when a chunk is re-wrapped later. <br>
|
||||||
|
* (Also, thread safety done via a reader writer lock)
|
||||||
|
*/
|
||||||
|
private static final ConcurrentLinkedQueue<ChunkWrapper> chunksNeedingClientLightUpdating = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -108,25 +129,22 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel)
|
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource, ILevelWrapper wrappedLevel)
|
||||||
{
|
{
|
||||||
this.chunk = chunk;
|
this.chunk = chunk;
|
||||||
|
this.lightSource = lightSource;
|
||||||
this.wrappedLevel = wrappedLevel;
|
this.wrappedLevel = wrappedLevel;
|
||||||
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
|
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
|
||||||
|
|
||||||
// use DH heightmaps if requested
|
// TODO is this the best way to differentiate between when we are generating chunks and when MC gave us a chunk?
|
||||||
if (Config.Common.LodBuilding.recalculateChunkHeightmaps.get())
|
boolean isDhGeneratedChunk = (this.lightSource.getClass() == DhLitWorldGenRegion.class);
|
||||||
{
|
// MC loaded chunks should get their lighting from MC, DH generated chunks should get their lighting from DH
|
||||||
this.solidHeightMap = new int[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH];
|
this.useDhLighting = isDhGeneratedChunk;
|
||||||
this.lightBlockingHeightMap = new int[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH];
|
|
||||||
|
// FIXME +1 is to handle the fact that LodDataBuilder adds +1 to all block lighting calculations, also done in the relative position validator
|
||||||
this.recalculateDhHeightMapsIfNeeded();
|
|
||||||
}
|
if (SharedApi.getEnvironment() != EWorldEnvironment.Server_Only)
|
||||||
else
|
chunksNeedingClientLightUpdating.add(this);
|
||||||
{
|
|
||||||
this.solidHeightMap = null;
|
|
||||||
this.lightBlockingHeightMap = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,29 +165,19 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInclusiveMinBuildHeight() { return getInclusiveMinBuildHeight(this.chunk); }
|
public int getMinBuildHeight() { return getMinBuildHeight(this.chunk); }
|
||||||
public static int getInclusiveMinBuildHeight(ChunkAccess chunk)
|
public static int getMinBuildHeight(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
return chunk.getMinBuildHeight();
|
|
||||||
#else
|
#else
|
||||||
return chunk.getMinY();
|
return chunk.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getExclusiveMaxBuildHeight() { return getExclusiveMaxBuildHeight(this.chunk); }
|
public int getMaxBuildHeight() { return getMaxBuildHeight(this.chunk); }
|
||||||
public static int getExclusiveMaxBuildHeight(ChunkAccess chunk)
|
public static int getMaxBuildHeight(ChunkAccess chunk) { return chunk.getMaxBuildHeight(); }
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
return chunk.getMaxBuildHeight();
|
|
||||||
#else
|
|
||||||
// +1 since Minecraft made the max value inclusive
|
|
||||||
return chunk.getMaxY() + 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinNonEmptyHeight()
|
public int getMinNonEmptyHeight()
|
||||||
@@ -181,7 +189,7 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
// default if every section is empty or missing
|
// default if every section is empty or missing
|
||||||
this.minNonEmptyHeight = this.getInclusiveMinBuildHeight();
|
this.minNonEmptyHeight = this.getMinBuildHeight();
|
||||||
|
|
||||||
// determine the lowest empty section (bottom up)
|
// determine the lowest empty section (bottom up)
|
||||||
LevelChunkSection[] sections = this.chunk.getSections();
|
LevelChunkSection[] sections = this.chunk.getSections();
|
||||||
@@ -213,7 +221,7 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
// default if every section is empty or missing
|
// default if every section is empty or missing
|
||||||
this.maxNonEmptyHeight = this.getExclusiveMaxBuildHeight();
|
this.maxNonEmptyHeight = this.getMaxBuildHeight();
|
||||||
|
|
||||||
// determine the highest empty section (top down)
|
// determine the highest empty section (top down)
|
||||||
LevelChunkSection[] sections = this.chunk.getSections();
|
LevelChunkSection[] sections = this.chunk.getSections();
|
||||||
@@ -246,92 +254,14 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
return section.hasOnlyAir();
|
return section.hasOnlyAir();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getInclusiveMinBuildHeight(); }
|
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getMinBuildHeight(); }
|
||||||
|
|
||||||
/** Will only run if the config says the MC heightmaps shouldn't be trusted. */
|
|
||||||
public void recalculateDhHeightMapsIfNeeded()
|
|
||||||
{
|
|
||||||
// re-calculate the min/max heights for consistency (during world gen these may be wrong)
|
|
||||||
this.minNonEmptyHeight = Integer.MIN_VALUE;
|
|
||||||
this.maxNonEmptyHeight = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
|
|
||||||
// recalculate heightmaps if needed
|
|
||||||
if (this.solidHeightMap != null)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++)
|
|
||||||
{
|
|
||||||
for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++)
|
|
||||||
{
|
|
||||||
int minInclusiveBuildHeight = this.getMinNonEmptyHeight();
|
|
||||||
// if no blocks are found the height map will be at the bottom of the world
|
|
||||||
int solidHeight = minInclusiveBuildHeight;
|
|
||||||
int lightBlockingHeight = minInclusiveBuildHeight;
|
|
||||||
|
|
||||||
|
|
||||||
int y = this.getMaxNonEmptyHeight(); //this.getExclusiveMaxBuildHeight();
|
|
||||||
IBlockStateWrapper block = this.getBlockState(x, y, z);
|
|
||||||
while (// go down until we reach the minimum build height
|
|
||||||
y > minInclusiveBuildHeight
|
|
||||||
// keep going until we find both height map values
|
|
||||||
&& (solidHeight == minInclusiveBuildHeight || lightBlockingHeight == minInclusiveBuildHeight))
|
|
||||||
{
|
|
||||||
// is this block solid?
|
|
||||||
if (solidHeight == minInclusiveBuildHeight
|
|
||||||
&& block.isSolid())
|
|
||||||
{
|
|
||||||
solidHeight = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this block light blocking?
|
|
||||||
if (lightBlockingHeight == minInclusiveBuildHeight
|
|
||||||
&& block.getOpacity() != LodUtil.BLOCK_FULLY_TRANSPARENT)
|
|
||||||
{
|
|
||||||
lightBlockingHeight = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the next block down
|
|
||||||
y--;
|
|
||||||
block = this.getBlockState(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.solidHeightMap[x][z] = solidHeight;
|
|
||||||
this.lightBlockingHeightMap[x][z] = lightBlockingHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSolidHeightMapValue(int xRel, int zRel)
|
public int getSolidHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE).getFirstAvailable(xRel, zRel); }
|
||||||
{
|
|
||||||
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(xRel, zRel);
|
|
||||||
|
|
||||||
// will be null if we want to use MC heightmaps
|
|
||||||
if (this.solidHeightMap == null)
|
|
||||||
{
|
|
||||||
return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE).getFirstAvailable(xRel, zRel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.solidHeightMap[xRel][zRel];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightBlockingHeightMapValue(int xRel, int zRel)
|
public int getLightBlockingHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); }
|
||||||
{
|
|
||||||
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(xRel, zRel);
|
|
||||||
|
|
||||||
if (this.lightBlockingHeightMap == null)
|
|
||||||
{
|
|
||||||
return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.lightBlockingHeightMap[xRel][zRel];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -368,130 +298,14 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
blockPos.setY(relY);
|
blockPos.setY(relY);
|
||||||
blockPos.setZ(relZ);
|
blockPos.setZ(relZ);
|
||||||
|
|
||||||
// TODO copy into pooled array, this isn't thread safe and can cause MC to throw errors if the chunk is loaded
|
|
||||||
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ, IMutableBlockPosWrapper mcBlockPos, IBlockStateWrapper guess)
|
|
||||||
{
|
|
||||||
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
|
||||||
|
|
||||||
BlockPos.MutableBlockPos pos = (BlockPos.MutableBlockPos)mcBlockPos.getWrappedMcObject();
|
|
||||||
pos.setX(relX);
|
|
||||||
pos.setY(relY);
|
|
||||||
pos.setZ(relZ);
|
|
||||||
|
|
||||||
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
|
|
||||||
public IMutableBlockPosWrapper getMutableBlockPosWrapper() { return MUTABLE_BLOCK_POS_WRAPPER_REF.get(); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
||||||
|
|
||||||
public ChunkAccess getChunk() { return this.chunk; }
|
public ChunkAccess getChunk() { return this.chunk; }
|
||||||
|
|
||||||
public void trySetStatus(ChunkStatus status) { trySetStatus(this.getChunk(), status); }
|
|
||||||
/** does nothing if the chunk object doesn't support setting it's status */
|
|
||||||
public static void trySetStatus(ChunkAccess chunk, ChunkStatus status)
|
|
||||||
{
|
|
||||||
if (chunk instanceof ProtoChunk)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_1
|
|
||||||
((ProtoChunk) chunk).setStatus(status);
|
|
||||||
#else
|
|
||||||
((ProtoChunk) chunk).setPersistedStatus(status);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkStatus getStatus() { return getStatus(this.getChunk()); }
|
public ChunkStatus getStatus() { return getStatus(this.getChunk()); }
|
||||||
public static ChunkStatus getStatus(ChunkAccess chunk)
|
public static ChunkStatus getStatus(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
@@ -517,15 +331,45 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
// lighting //
|
// lighting //
|
||||||
//==========//
|
//==========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIsDhSkyLightCorrect(boolean isDhLightCorrect) { this.isDhSkyLightCorrect = isDhLightCorrect; }
|
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
||||||
@Override
|
|
||||||
public void setIsDhBlockLightCorrect(boolean isDhLightCorrect) { this.isDhBlockLightCorrect = isDhLightCorrect; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDhBlockLightingCorrect() { return this.isDhBlockLightCorrect; }
|
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDhSkyLightCorrect() { return this.isDhSkyLightCorrect; }
|
public boolean isLightCorrect()
|
||||||
|
{
|
||||||
|
if (this.useDhLighting)
|
||||||
|
{
|
||||||
|
return this.isDhLightCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
|
return false; // MC's lighting engine doesn't work consistently enough to trust for 1.16 or 1.17
|
||||||
|
#else
|
||||||
|
if (this.chunk instanceof LevelChunk)
|
||||||
|
{
|
||||||
|
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
||||||
|
if (levelChunk.getLevel().isClientSide())
|
||||||
|
{
|
||||||
|
// connected to a server
|
||||||
|
return this.isMcClientLightingCorrect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// in a single player world
|
||||||
|
return this.chunk.isLightCorrect() && levelChunk.loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// called when in a single player world and the chunk is a proto chunk (in world gen, and not active)
|
||||||
|
return this.chunk.isLightCorrect();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -580,6 +424,44 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
public void setSkyLightStorage(ChunkLightStorage lightStorage) { this.skyLightStorage = lightStorage; }
|
public void setSkyLightStorage(ChunkLightStorage lightStorage) { this.skyLightStorage = lightStorage; }
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int relX, int y, int relZ)
|
||||||
|
{
|
||||||
|
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, y, relZ);
|
||||||
|
|
||||||
|
// use the full lighting engine when the chunks are within render distance or the config requests it
|
||||||
|
if (this.useDhLighting)
|
||||||
|
{
|
||||||
|
// DH lighting method
|
||||||
|
return this.getBlockLightStorage().get(relX, y, relZ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// note: this returns 0 if the chunk is unload
|
||||||
|
|
||||||
|
// MC lighting method
|
||||||
|
return this.lightSource.getBrightness(LightLayer.BLOCK, new BlockPos(relX + this.getMinBlockX(), y, relZ + this.getMinBlockZ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int relX, int y, int relZ)
|
||||||
|
{
|
||||||
|
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, y, relZ);
|
||||||
|
|
||||||
|
// use the full lighting engine when the chunks are within render distance or the config requests it
|
||||||
|
if (this.useDhLighting)
|
||||||
|
{
|
||||||
|
// DH lighting method
|
||||||
|
return this.getSkyLightStorage().get(relX, y, relZ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// MC lighting method
|
||||||
|
return this.lightSource.getBrightness(LightLayer.SKY, new BlockPos(relX + this.getMinBlockX(), y, relZ + this.getMinBlockZ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME synchronized is necessary for a rare issue where this method is called from two separate threads at the same time
|
* FIXME synchronized is necessary for a rare issue where this method is called from two separate threads at the same time
|
||||||
* before the list has finished populating.
|
* before the list has finished populating.
|
||||||
@@ -615,12 +497,95 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
return this.blockLightPosList;
|
return this.blockLightPosList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void syncedUpdateClientLightStatus()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
// TODO: Check what to do in 1.18.1 and older
|
||||||
|
|
||||||
|
// since we don't currently handle this list,
|
||||||
|
// clear it to prevent memory leaks
|
||||||
|
chunksNeedingClientLightUpdating.clear();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// update the chunks client lighting
|
||||||
|
ChunkWrapper chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
||||||
|
while (chunkWrapper != null)
|
||||||
|
{
|
||||||
|
chunkWrapper.updateIsClientLightingCorrect();
|
||||||
|
chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** Should be called after client light updates are triggered. */
|
||||||
|
private void updateIsClientLightingCorrect()
|
||||||
|
{
|
||||||
|
if (this.chunk instanceof LevelChunk && ((LevelChunk) this.chunk).getLevel() instanceof ClientLevel)
|
||||||
|
{
|
||||||
|
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
||||||
|
ClientChunkCache clientChunkCache = ((ClientLevel) levelChunk.getLevel()).getChunkSource();
|
||||||
|
this.isMcClientLightingCorrect = clientChunkCache.getChunkForLighting(this.chunk.getPos().x, this.chunk.getPos().z) != null &&
|
||||||
|
#if MC_VER <= MC_1_17_1
|
||||||
|
levelChunk.isLightCorrect();
|
||||||
|
#elif MC_VER < MC_1_20_1
|
||||||
|
levelChunk.isClientLightReady();
|
||||||
|
#else
|
||||||
|
checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if MC_VER >= MC_1_20_1
|
||||||
|
private static boolean checkLightSectionsOnChunk(LevelChunk chunk, LevelLightEngine engine)
|
||||||
|
{
|
||||||
|
LevelChunkSection[] sections = chunk.getSections();
|
||||||
|
int minY = chunk.getMinSection();
|
||||||
|
int maxY = chunk.getMaxSection();
|
||||||
|
for (int y = minY; y < maxY; ++y)
|
||||||
|
{
|
||||||
|
LevelChunkSection section = sections[chunk.getSectionIndexFromSectionY(y)];
|
||||||
|
if (section.hasOnlyAir()) continue;
|
||||||
|
if (!engine.lightOnInSection(SectionPos.of(chunk.getPos(), y)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//===============//
|
||||||
// other methods //
|
// other methods //
|
||||||
//===============//
|
//===============//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doNearbyChunksExist()
|
||||||
|
{
|
||||||
|
if (this.lightSource instanceof DhLitWorldGenRegion)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int dx = -1; dx <= 1; dx++)
|
||||||
|
{
|
||||||
|
for (int dz = -1; dz <= 1; dz++)
|
||||||
|
{
|
||||||
|
if (dx == 0 && dz == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (this.lightSource.getChunk(dx + this.chunk.getPos().x, dz + this.chunk.getPos().z, ChunkStatus.BIOMES, false) == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
||||||
|
|
||||||
@@ -644,4 +609,4 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
// return this.blockBiomeHashCode;
|
// return this.blockBiomeHashCode;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
+55
-85
@@ -16,6 +16,7 @@ import java.util.regex.Pattern;
|
|||||||
// Logger (for debug stuff)
|
// Logger (for debug stuff)
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
||||||
|
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||||
import com.seibel.distanthorizons.core.config.types.*;
|
import com.seibel.distanthorizons.core.config.types.*;
|
||||||
@@ -56,20 +57,20 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translatable;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Based upon TinyConfig but is highly modified
|
* Based upon TinyConfig but is highly modified
|
||||||
* https://github.com/Minenash/TinyConfig
|
* https://github.com/Minenash/TinyConfig
|
||||||
*
|
*
|
||||||
* Note: floats don't work with this system, use doubles.
|
|
||||||
*
|
|
||||||
* Credits to Motschen
|
* Credits to Motschen
|
||||||
*
|
*
|
||||||
* @author coolGi
|
* @author coolGi
|
||||||
* @version 5-21-2022
|
* @version 5-21-2022
|
||||||
*/
|
*/
|
||||||
|
// FLOATS DONT WORK WITH THIS
|
||||||
|
|
||||||
|
/** This file is going to be removed sometime soon, please dont hook onto anything within this file until the new UI is compleated */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ClassicConfigGUI
|
public class ClassicConfigGUI
|
||||||
{
|
{
|
||||||
@@ -118,18 +119,14 @@ public class ClassicConfigGUI
|
|||||||
*/
|
*/
|
||||||
private static void textField(AbstractConfigType info, Function<String, Number> func, Pattern pattern, boolean cast)
|
private static void textField(AbstractConfigType info, Function<String, Number> func, Pattern pattern, boolean cast)
|
||||||
{
|
{
|
||||||
|
boolean isNumber = pattern != null;
|
||||||
((EntryInfo) info.guiValue).widget = (BiFunction<EditBox, Button, Predicate<String>>) (editBox, button) -> stringValue ->
|
((EntryInfo) info.guiValue).widget = (BiFunction<EditBox, Button, Predicate<String>>) (editBox, button) -> stringValue ->
|
||||||
{
|
{
|
||||||
boolean isNumber = (pattern != null);
|
|
||||||
|
|
||||||
stringValue = stringValue.trim();
|
stringValue = stringValue.trim();
|
||||||
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
|
Number value = 0;
|
||||||
Number value = info.typeIsFloatingPointNumber() ? 0.0 : 0; // different default values are needed so implicit casting works correctly (if not done casting from 0 (an int) to a double will cause an exception)
|
|
||||||
((EntryInfo) info.guiValue).error = null;
|
((EntryInfo) info.guiValue).error = null;
|
||||||
if (isNumber && !stringValue.isEmpty() && !stringValue.equals("-") && !stringValue.equals("."))
|
if (isNumber && !stringValue.isEmpty() && !stringValue.equals("-") && !stringValue.equals("."))
|
||||||
{
|
{
|
||||||
@@ -146,22 +143,18 @@ public class ClassicConfigGUI
|
|||||||
switch (isValid)
|
switch (isValid)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
((EntryInfo) info.guiValue).error = null;
|
((EntryInfo) info.guiValue).error = null; break;
|
||||||
break;
|
|
||||||
case -1:
|
case -1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry) info).getMin()));
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry) info).getMin())); break;
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry) info).getMax()));
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry) info).getMax())); break;
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid"));
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid")); break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((EntryInfo) info.guiValue).tempValue = stringValue;
|
((EntryInfo) info.guiValue).tempValue = stringValue;
|
||||||
editBox.setTextColor(((ConfigEntry) info).isValid(value) == 0 ? 0xFFFFFFFF : 0xFFFF7777); // white and red
|
editBox.setTextColor(((ConfigEntry) info).isValid(value) == 0 ? 0xFFFFFFFF : 0xFFFF7777);
|
||||||
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
||||||
|
|
||||||
|
|
||||||
@@ -178,7 +171,7 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((ConfigEntry) info).uiSetWithoutSaving(value != null ? value.intValue() : 0);
|
((ConfigEntry) info).uiSetWithoutSaving(value.intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +242,7 @@ public class ClassicConfigGUI
|
|||||||
protected void init()
|
protected void init()
|
||||||
{
|
{
|
||||||
super.init();
|
super.init();
|
||||||
if (!this.reload)
|
if (!reload)
|
||||||
{
|
{
|
||||||
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
||||||
}
|
}
|
||||||
@@ -276,7 +269,7 @@ public class ClassicConfigGUI
|
|||||||
(buttonWidget) -> {
|
(buttonWidget) -> {
|
||||||
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||||
if (changelogScreen.usable)
|
if (changelogScreen.usable)
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
|
Objects.requireNonNull(minecraft).setScreen(changelogScreen);
|
||||||
else
|
else
|
||||||
LOGGER.warn("Changelog was not able to open");
|
LOGGER.warn("Changelog was not able to open");
|
||||||
},
|
},
|
||||||
@@ -286,17 +279,17 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"),
|
addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"),
|
||||||
this.width / 2 - 154, this.height - 28,
|
this.width / 2 - 154, this.height - 28,
|
||||||
150, 20,
|
150, 20,
|
||||||
button ->
|
button ->
|
||||||
{
|
{
|
||||||
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||||
}));
|
}));
|
||||||
this.doneButton = this.addBtn(MakeBtn(Translatable("distanthorizons.general.done"), this.width / 2 + 4, this.height - 28, 150, 20, (button) -> {
|
doneButton = addBtn(MakeBtn(Translatable("distanthorizons.general.done"), this.width / 2 + 4, this.height - 28, 150, 20, (button) -> {
|
||||||
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
|
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
|
||||||
@@ -312,18 +305,15 @@ public class ClassicConfigGUI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (info.getCategory().matches(this.category) && info.getAppearance().showInGui)
|
if (info.getCategory().matches(category) && info.getAppearance().showInGui)
|
||||||
this.addMenuItem(info);
|
addMenuItem(info);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
String message = "ERROR: Failed to show [\" + info.getNameWCategory() + \"], error: ["+e.getMessage()+"]";
|
System.out.println("ERROR: Failed to show [" + info.getNameWCategory() + "]");
|
||||||
if (info.get() != null)
|
if (info.get() != null)
|
||||||
{
|
System.out.print(" with the value [" + info.get() + "] with type [" + info.getType() + "]");
|
||||||
message += " with the value [" + info.get() + "] with type [" + info.getType() + "]";
|
e.printStackTrace();
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.error(message, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +326,7 @@ public class ClassicConfigGUI
|
|||||||
private void addMenuItem(AbstractConfigType info)
|
private void addMenuItem(AbstractConfigType info)
|
||||||
{
|
{
|
||||||
initEntry(info, this.translationPrefix);
|
initEntry(info, this.translationPrefix);
|
||||||
Component name = Translatable(this.translationPrefix + info.getNameWCategory());
|
Component name = Translatable(translationPrefix + info.getNameWCategory());
|
||||||
|
|
||||||
|
|
||||||
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
||||||
@@ -345,7 +335,7 @@ public class ClassicConfigGUI
|
|||||||
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue());
|
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue());
|
||||||
((EntryInfo) info.guiValue).index = 0;
|
((EntryInfo) info.guiValue).index = 0;
|
||||||
this.reload = true;
|
this.reload = true;
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this);
|
Objects.requireNonNull(minecraft).setScreen(this);
|
||||||
};
|
};
|
||||||
int posX = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth;
|
int posX = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth;
|
||||||
int posZ = 0;
|
int posZ = 0;
|
||||||
@@ -359,17 +349,17 @@ public class ClassicConfigGUI
|
|||||||
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) ((EntryInfo) info.guiValue).widget;
|
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) ((EntryInfo) info.guiValue).widget;
|
||||||
if (info.getType().isEnum())
|
if (info.getType().isEnum())
|
||||||
{
|
{
|
||||||
widget.setValue(value -> Translatable(this.translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString()));
|
widget.setValue(value -> Translatable(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString()));
|
||||||
}
|
}
|
||||||
this.list.addButton(MakeBtn(widget.getValue().apply(info.get()), this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen, 0, 150, 20, widget.getKey()), resetButton, null, name);
|
this.list.addButton(MakeBtn(widget.getValue().apply(info.get()), this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen, 0, 150, 20, widget.getKey()), resetButton, null, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (((EntryInfo) info.guiValue).widget != null)
|
else if (((EntryInfo) info.guiValue).widget != null)
|
||||||
{
|
{
|
||||||
EditBox widget = new EditBox(this.font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, Translatable(""));
|
EditBox widget = new EditBox(font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, null);
|
||||||
widget.setMaxLength(150);
|
widget.setMaxLength(150);
|
||||||
widget.insertText(String.valueOf(info.get()));
|
widget.insertText(String.valueOf(info.get()));
|
||||||
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, this.doneButton);
|
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, doneButton);
|
||||||
widget.setFilter(processor);
|
widget.setFilter(processor);
|
||||||
this.list.addButton(widget, resetButton, null, name);
|
this.list.addButton(widget, resetButton, null, name);
|
||||||
return;
|
return;
|
||||||
@@ -379,7 +369,7 @@ public class ClassicConfigGUI
|
|||||||
{
|
{
|
||||||
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
||||||
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination()));
|
Objects.requireNonNull(minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination()));
|
||||||
}));
|
}));
|
||||||
this.list.addButton(widget, null, null, null);
|
this.list.addButton(widget, null, null, null);
|
||||||
return;
|
return;
|
||||||
@@ -397,9 +387,9 @@ public class ClassicConfigGUI
|
|||||||
this.list.addButton(null, null, null, name);
|
this.list.addButton(null, null, null, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ConfigUiLinkedEntry.class.isAssignableFrom(info.getClass()))
|
if (ConfigLinkedEntry.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
this.addMenuItem(((ConfigUiLinkedEntry) info).get());
|
this.addMenuItem(((ConfigLinkedEntry) info).get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,34 +410,16 @@ public class ClassicConfigGUI
|
|||||||
#endif
|
#endif
|
||||||
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
|
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
|
||||||
|
|
||||||
// Render title
|
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15,
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
0xFFFFFF // RGB white
|
|
||||||
#else
|
|
||||||
0xFFFFFFFF // ARGB white
|
|
||||||
#endif);
|
|
||||||
|
|
||||||
if (this.configBase.modID.equals("distanthorizons"))
|
if (this.configBase.modID.equals("distanthorizons"))
|
||||||
{
|
{
|
||||||
// Display version
|
// Display version
|
||||||
this.DhDrawString(matrices, this.font, TextOrLiteral(ModInfo.VERSION), 2, this.height - 10,
|
DhDrawString(matrices, font, TextOrLiteral(ModInfo.VERSION), 2, height - 10, 0xAAAAAA);
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
0xAAAAAA // RGB white
|
|
||||||
#else
|
|
||||||
0xFFAAAAAA // ARGB white
|
|
||||||
#endif);
|
|
||||||
|
|
||||||
// If the update is pending, display this message to inform the user that it will apply when the game restarts
|
// If the update is pending, display this message to inform the user that it will apply when the game restarts
|
||||||
if (SelfUpdater.deleteOldJarOnJvmShutdown)
|
if (SelfUpdater.deleteOldJarOnJvmShutdown)
|
||||||
{
|
DhDrawString(matrices, font, Translatable(configBase.modID + ".updater.waitingForClose"), 4, height - 38, 0xFFFFFF);
|
||||||
this.DhDrawString(matrices, this.font, Translatable(this.configBase.modID + ".updater.waitingForClose"), 4, this.height - 38,
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
0xFFFFFF // RGB white
|
|
||||||
#else
|
|
||||||
0xFFFFFFFF // ARGB white
|
|
||||||
#endif);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -466,8 +438,8 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A quick fix for tooltips on linked entries
|
// A quick fix for tooltips on linked entries
|
||||||
AbstractConfigType newInfo = ConfigUiLinkedEntry.class.isAssignableFrom(info.getClass()) ?
|
AbstractConfigType newInfo = ConfigLinkedEntry.class.isAssignableFrom(info.getClass()) ?
|
||||||
((ConfigUiLinkedEntry) info).get() :
|
((ConfigLinkedEntry) info).get() :
|
||||||
info;
|
info;
|
||||||
|
|
||||||
Component name = Translatable(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.getName());
|
Component name = Translatable(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.getName());
|
||||||
@@ -500,47 +472,47 @@ public class ClassicConfigGUI
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void initEntry(AbstractConfigType configType, String translationPrefix)
|
private static void initEntry(AbstractConfigType info, String translationPrefix)
|
||||||
{
|
{
|
||||||
configType.guiValue = new EntryInfo();
|
info.guiValue = new EntryInfo();
|
||||||
Class<?> fieldClass = configType.getType();
|
Class<?> fieldClass = info.getType();
|
||||||
|
|
||||||
if (ConfigEntry.class.isAssignableFrom(configType.getClass()))
|
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
if (fieldClass == Integer.class)
|
if (fieldClass == Integer.class)
|
||||||
{
|
{
|
||||||
// For int
|
// For int
|
||||||
textField(configType, Integer::parseInt, INTEGER_ONLY_REGEX, true);
|
textField(info, Integer::parseInt, INTEGER_ONLY_REGEX, true);
|
||||||
}
|
}
|
||||||
else if (fieldClass == Double.class)
|
else if (fieldClass == Double.class)
|
||||||
{
|
{
|
||||||
// For double
|
// For double
|
||||||
textField(configType, Double::parseDouble, DECIMAL_ONLY_REGEX, false);
|
textField(info, Double::parseDouble, DECIMAL_ONLY_REGEX, false);
|
||||||
}
|
}
|
||||||
else if (fieldClass == String.class || fieldClass == List.class)
|
else if (fieldClass == String.class || fieldClass == List.class)
|
||||||
{
|
{
|
||||||
// For string or list
|
// For string or list
|
||||||
textField(configType, String::length, null, true);
|
textField(info, String::length, null, true);
|
||||||
}
|
}
|
||||||
else if (fieldClass == Boolean.class)
|
else if (fieldClass == Boolean.class)
|
||||||
{
|
{
|
||||||
// For boolean
|
// For boolean
|
||||||
Function<Object, Component> func = value -> Translatable("distanthorizons.general."+((Boolean) value ? "true" : "false")).withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
Function<Object, Component> func = value -> Translatable("distanthorizons.general."+((Boolean) value ? "true" : "false")).withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
||||||
|
|
||||||
((EntryInfo) configType.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
((EntryInfo) info.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
||||||
((ConfigEntry) configType).uiSetWithoutSaving(!(Boolean) configType.get());
|
((ConfigEntry) info).uiSetWithoutSaving(!(Boolean) info.get());
|
||||||
button.setMessage(func.apply(configType.get()));
|
button.setMessage(func.apply(info.get()));
|
||||||
}, func);
|
}, func);
|
||||||
}
|
}
|
||||||
else if (fieldClass.isEnum())
|
else if (fieldClass.isEnum())
|
||||||
{
|
{
|
||||||
// For enum
|
// For enum
|
||||||
List<?> values = Arrays.asList(configType.getType().getEnumConstants());
|
List<?> values = Arrays.asList(info.getType().getEnumConstants());
|
||||||
Function<Object, Component> func = value -> Translatable(translationPrefix + "enum." + fieldClass.getSimpleName() + "." + configType.get().toString());
|
Function<Object, Component> func = value -> Translatable(translationPrefix + "enum." + fieldClass.getSimpleName() + "." + info.get().toString());
|
||||||
((EntryInfo) configType.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
((EntryInfo) info.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
||||||
|
|
||||||
// get the currently selected enum and enum index
|
// get the currently selected enum and enum index
|
||||||
int startingIndex = values.indexOf(configType.get());
|
int startingIndex = values.indexOf(info.get());
|
||||||
Enum<?> enumValue = (Enum<?>) values.get(startingIndex);
|
Enum<?> enumValue = (Enum<?>) values.get(startingIndex);
|
||||||
|
|
||||||
// search for the next enum that is selectable
|
// search for the next enum that is selectable
|
||||||
@@ -568,12 +540,12 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
((ConfigEntry<Enum<?>>) configType).uiSetWithoutSaving(enumValue);
|
((ConfigEntry<Enum<?>>) info).uiSetWithoutSaving(enumValue);
|
||||||
button.setMessage(func.apply(configType.get()));
|
button.setMessage(func.apply(info.get()));
|
||||||
}, func);
|
}, func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ConfigCategory.class.isAssignableFrom(configType.getClass()))
|
else if (ConfigCategory.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
// if (!info.info.getName().equals(""))
|
// if (!info.info.getName().equals(""))
|
||||||
// info.name = new TranslatableComponent(info.info.getName());
|
// info.name = new TranslatableComponent(info.info.getName());
|
||||||
@@ -677,10 +649,8 @@ public class ClassicConfigGUI
|
|||||||
if (text != null && (!text.getString().contains("spacer") || button != null))
|
if (text != null && (!text.getString().contains("spacer") || button != null))
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF);
|
|
||||||
#else
|
#else
|
||||||
matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFFFF);
|
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,27 +52,6 @@ public class DhScreen extends Screen
|
|||||||
{
|
{
|
||||||
renderTooltip(guiStack, comp, x, y);
|
renderTooltip(guiStack, comp, x, y);
|
||||||
}
|
}
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
|
||||||
{
|
|
||||||
guiStack.drawCenteredString(font, text, x, y, color);
|
|
||||||
}
|
|
||||||
protected void DhDrawString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
|
||||||
{
|
|
||||||
guiStack.drawString(font, text, x, y, color);
|
|
||||||
}
|
|
||||||
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
|
||||||
//{
|
|
||||||
// guiStack.renderTooltip(font, text, x, y);
|
|
||||||
//}
|
|
||||||
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
|
||||||
{
|
|
||||||
guiStack.renderComponentTooltip(font, comp, x, y);
|
|
||||||
}
|
|
||||||
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
|
||||||
{
|
|
||||||
guiStack.renderTooltip(font, text, x, y);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
||||||
{
|
{
|
||||||
@@ -82,20 +61,17 @@ public class DhScreen extends Screen
|
|||||||
{
|
{
|
||||||
guiStack.drawString(font, text, x, y, color);
|
guiStack.drawString(font, text, x, y, color);
|
||||||
}
|
}
|
||||||
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
||||||
//{
|
{
|
||||||
// //guiStack.renderTooltip(font, text, x, y);
|
guiStack.renderTooltip(font, text, x, y);
|
||||||
//}
|
}
|
||||||
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
||||||
{
|
{
|
||||||
guiStack.setComponentTooltipForNextFrame(font, comp, x, y);
|
guiStack.renderComponentTooltip(font, comp, x, y);
|
||||||
}
|
}
|
||||||
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
||||||
{
|
{
|
||||||
guiStack.setTooltipForNextFrame(font, text, x, y);
|
guiStack.renderTooltip(font, text, x, y);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-79
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,41 +19,31 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a button with a texture on it (and a background) that works with all mc versions
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
* @version 2023-10-03
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import net.minecraft.client.gui.components.AbstractButton;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ImageButton;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
#endif
|
#endif
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
import net.minecraft.client.gui.components.ImageButton;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
#elif MC_VER < MC_1_20_1
|
|
||||||
import net.minecraft.client.gui.components.ImageButton;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
#elif MC_VER < MC_1_20_2
|
|
||||||
import net.minecraft.client.gui.components.ImageButton;
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.RenderPipelines;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a button with a texture on it (and a background) that works with all mc versions
|
|
||||||
*
|
|
||||||
* @author coolGi
|
|
||||||
* @version 2023-10-03
|
|
||||||
*/
|
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
public class TexturedButtonWidget extends ImageButton
|
public class TexturedButtonWidget extends ImageButton
|
||||||
#else
|
#else
|
||||||
@@ -67,21 +57,20 @@ public class TexturedButtonWidget extends Button
|
|||||||
private final int v;
|
private final int v;
|
||||||
private final int hoveredVOffset;
|
private final int hoveredVOffset;
|
||||||
|
|
||||||
private final ResourceLocation textureResourceLocation;
|
private final ResourceLocation texture;
|
||||||
|
|
||||||
private final int textureWidth;
|
private final int textureWidth;
|
||||||
private final int textureHeight;
|
private final int textureHeight;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation textureResourceLocation, int textureWidth, int textureHeight, OnPress pressAction, Component text)
|
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, Component text) {
|
||||||
{
|
this(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text, true);
|
||||||
this(x, y, width, height, u, v, hoveredVOffset, textureResourceLocation, textureWidth, textureHeight, pressAction, text, true);
|
|
||||||
}
|
}
|
||||||
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation textureResourceLocation, int textureWidth, int textureHeight, OnPress pressAction, Component text, boolean renderBackground)
|
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, Component text, boolean renderBackground)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
super(x, y, width, height, u, v, hoveredVOffset, textureResourceLocation, textureWidth, textureHeight, pressAction, text);
|
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
|
||||||
#else
|
#else
|
||||||
// We don't pass on the text option as otherwise it will render (we normally pass it for narration)
|
// We don't pass on the text option as otherwise it will render (we normally pass it for narration)
|
||||||
// TODO: Find a fix for it
|
// TODO: Find a fix for it
|
||||||
@@ -91,7 +80,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
this.v = v;
|
this.v = v;
|
||||||
this.hoveredVOffset = hoveredVOffset;
|
this.hoveredVOffset = hoveredVOffset;
|
||||||
|
|
||||||
this.textureResourceLocation = textureResourceLocation;
|
this.texture = texture;
|
||||||
|
|
||||||
this.textureWidth = textureWidth;
|
this.textureWidth = textureWidth;
|
||||||
this.textureHeight = textureHeight;
|
this.textureHeight = textureHeight;
|
||||||
@@ -103,8 +92,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
@Override
|
@Override
|
||||||
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta)
|
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
{
|
|
||||||
if (this.renderBackground) // Renders the background of the button
|
if (this.renderBackground) // Renders the background of the button
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@@ -131,7 +119,6 @@ public class TexturedButtonWidget extends Button
|
|||||||
|
|
||||||
super.renderButton(matrices, mouseX, mouseY, delta);
|
super.renderButton(matrices, mouseX, mouseY, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
@Override
|
@Override
|
||||||
@@ -167,63 +154,24 @@ public class TexturedButtonWidget extends Button
|
|||||||
super.renderWidget(matrices, mouseX, mouseY, delta);
|
super.renderWidget(matrices, mouseX, mouseY, delta);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@Override
|
@Override
|
||||||
public void renderWidget(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
public void renderWidget(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
{
|
{
|
||||||
if (this.renderBackground)
|
if (this.renderBackground)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
//RenderSystem.enableBlend();
|
||||||
|
//RenderSystem.enableDepthTest();
|
||||||
matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
matrices.blitSprite(
|
|
||||||
RenderType::guiTextured,
|
|
||||||
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
|
||||||
this.getX(), this.getY(),
|
|
||||||
this.getWidth(), this.getHeight());
|
|
||||||
#else
|
|
||||||
matrices.blitSprite(
|
|
||||||
RenderPipelines.GUI_TEXTURED,
|
|
||||||
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
|
||||||
this.getX(), this.getY(),
|
|
||||||
this.getWidth(), this.getHeight());
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Renders the sprite
|
// Renders the sprite
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (!this.active)
|
if (!this.active) i = 2;
|
||||||
{
|
else if (this.isHovered) i = 1;
|
||||||
i = 2;
|
|
||||||
}
|
|
||||||
else if (this.isHovered)
|
|
||||||
{
|
|
||||||
i = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
matrices.blit(this.texture, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight);
|
||||||
matrices.blit(this.textureResourceLocation, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight);
|
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
matrices.blit(
|
|
||||||
RenderType::guiTextured,
|
|
||||||
this.textureResourceLocation,
|
|
||||||
this.getX(), this.getY(),
|
|
||||||
this.u, this.v + (this.hoveredVOffset * i),
|
|
||||||
this.width, this.height,
|
|
||||||
this.textureWidth, this.textureHeight);
|
|
||||||
#else
|
|
||||||
matrices.blit(
|
|
||||||
RenderPipelines.GUI_TEXTURED,
|
|
||||||
this.textureResourceLocation,
|
|
||||||
this.getX(), this.getY(),
|
|
||||||
this.u, this.v + (this.hoveredVOffset * i),
|
|
||||||
this.width, this.height,
|
|
||||||
this.textureWidth, this.textureHeight);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-47
@@ -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,7 +14,6 @@ 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;
|
||||||
@@ -22,7 +21,6 @@ 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
|
||||||
@@ -41,9 +39,6 @@ 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;
|
||||||
@@ -56,32 +51,24 @@ 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
|
||||||
{
|
{
|
||||||
this.setupChangelog(versionID);
|
setupChangelog(versionID);
|
||||||
this.usable = true;
|
usable = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.error("failed to setup changelog, error: ["+e.getMessage()+"].", e);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,13 +80,11 @@ public class ChangelogScreen extends DhScreen
|
|||||||
|
|
||||||
|
|
||||||
if (versionID == null)
|
if (versionID == null)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.setupChangelog(versionID);
|
setupChangelog(versionID);
|
||||||
this.usable = true;
|
usable = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -144,10 +129,8 @@ public class ChangelogScreen extends DhScreen
|
|||||||
protected void init()
|
protected void init()
|
||||||
{
|
{
|
||||||
super.init();
|
super.init();
|
||||||
if (!this.usable)
|
if (!usable)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.addBtn( // Close
|
this.addBtn( // Close
|
||||||
@@ -158,9 +141,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 < this.changelog.size(); i++)
|
for (int i = 0; i < changelog.size(); i++)
|
||||||
{
|
{
|
||||||
this.changelogArea.addButton(TextOrLiteral(this.changelog.get(i)));
|
this.changelogArea.addButton(TextOrLiteral(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,41 +161,29 @@ public class ChangelogScreen extends DhScreen
|
|||||||
#else
|
#else
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
#endif
|
#endif
|
||||||
if (!this.usable)
|
if (!usable)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
int maxScroll;
|
|
||||||
#if MC_VER <= MC_1_21_3
|
|
||||||
maxScroll = this.changelogArea.getMaxScroll();
|
|
||||||
#else
|
|
||||||
maxScroll = this.changelogArea.maxScrollAmount();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set the scroll position to the mouse height relative to the screen
|
// Set the scroll position to the mouse height relative to the screen
|
||||||
// This is a bit of a hack as we cannot scroll on this area
|
// This is a bit of a hack as we cannot scroll on this area
|
||||||
double scrollAmount = ((double) mouseY) / ((double) this.height) * 1.1 * maxScroll;
|
double scrollAmount = ((double) mouseY) / ((double) this.height) * 1.1 * this.changelogArea.getMaxScroll();
|
||||||
|
|
||||||
#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
|
||||||
this.changelogArea.setScrollAmount(scrollAmount);
|
this.changelogArea.setScrollAmount(scrollAmount);
|
||||||
#elif MC_VER <= MC_1_21_3
|
|
||||||
this.changelogArea.scrollAmount = scrollAmount;
|
|
||||||
#else
|
#else
|
||||||
this.changelogArea.setScrollAmount(scrollAmount);
|
this.changelogArea.scrollAmount = scrollAmount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// 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
|
||||||
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15, 0xFFFFFF); // Render title
|
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Goto the parent screen
|
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry>
|
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry>
|
||||||
@@ -227,7 +198,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;
|
||||||
this.textRenderer = minecraftClient.font;
|
textRenderer = minecraftClient.font;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addButton(Component text)
|
public void addButton(Component text)
|
||||||
@@ -269,20 +240,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, this.text, 12, y + 5, 0xFFFFFF);
|
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends GuiEventListener> children()
|
public List<? extends GuiEventListener> children()
|
||||||
{
|
{
|
||||||
return this.children;
|
return 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 this.children;
|
return children;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-39
@@ -4,7 +4,6 @@ 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;
|
||||||
@@ -16,7 +15,6 @@ 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.*;
|
||||||
|
|
||||||
@@ -31,9 +29,6 @@ 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;
|
||||||
|
|
||||||
@@ -41,7 +36,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
private String nextVer;
|
private String nextVer;
|
||||||
|
|
||||||
|
|
||||||
public UpdateModScreen(Screen parent, String newVersionID) throws IllegalArgumentException
|
public UpdateModScreen(Screen parent, String newVersionID)
|
||||||
{
|
{
|
||||||
super(Translatable(ModInfo.ID + ".updater.title"));
|
super(Translatable(ModInfo.ID + ".updater.title"));
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
@@ -59,13 +54,6 @@ public class UpdateModScreen extends DhScreen
|
|||||||
this.currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
this.currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
||||||
this.nextVer = this.newVersionID.substring(0,7);
|
this.nextVer = this.newVersionID.substring(0,7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// done to prevent trying to update to "null"
|
|
||||||
// (this can happen if no versions are available to check/download from modrinth/gitlab)
|
|
||||||
if (this.nextVer == null)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("No new version found with the ID ["+newVersionID+"].");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,9 +69,9 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// Logo image
|
// Logo image
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width / 2 - 95, this.height / 2 - 110,
|
this.width / 2 - 65, this.height / 2 - 110,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
195, 65,
|
130, 65,
|
||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
@@ -93,7 +81,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
#else
|
#else
|
||||||
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "logo.png"),
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "logo.png"),
|
||||||
#endif
|
#endif
|
||||||
195, 65,
|
130, 65,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// For now it goes to the client option by default
|
||||||
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
@@ -105,7 +93,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.error("Failed to setup update mod screen, error: ["+e.getMessage()+"].", e);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ModInfo.IS_DEV_BUILD)
|
if (!ModInfo.IS_DEV_BUILD)
|
||||||
@@ -169,10 +157,8 @@ public class UpdateModScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
|
||||||
#else
|
#else
|
||||||
// background blur is already being rendered, rendering again causes the game to crash
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: add the tooltips for the buttons
|
// TODO: add the tooltips for the buttons
|
||||||
@@ -180,30 +166,16 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// TODO: Add tooltips
|
// TODO: Add tooltips
|
||||||
|
|
||||||
// Render the text's
|
// Render the text's
|
||||||
this.DhDrawCenteredString(matrices, this.font,
|
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF);
|
||||||
Translatable(ModInfo.ID + ".updater.text1"),
|
DhDrawCenteredString(matrices, this.font,
|
||||||
this.width / 2, this.height / 2 - 35,
|
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer),
|
||||||
#if MC_VER < MC_1_21_6
|
this.width / 2, this.height / 2 - 20, 0x52FD52);
|
||||||
0xFFFFFF // RGB
|
|
||||||
#else
|
|
||||||
0xFFFFFFFF // ARGB
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
this.DhDrawCenteredString(matrices, this.font,
|
|
||||||
Translatable(ModInfo.ID + ".updater.text2", this.currentVer, this.nextVer),
|
|
||||||
this.width / 2, this.height / 2 - 20,
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
0x52FD52 // RGB
|
|
||||||
#else
|
|
||||||
0xFF52FD52 // ARGB
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Go to the parent screen
|
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+20
-8
@@ -13,12 +13,10 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
|
|||||||
/** This is set and managed by the ClientApi for servers with support for DH. */
|
/** This is set and managed by the ClientApi for servers with support for DH. */
|
||||||
@Nullable
|
@Nullable
|
||||||
private IServerKeyedClientLevel serverKeyedLevel = null;
|
private IServerKeyedClientLevel serverKeyedLevel = null;
|
||||||
/** Allows to keep level manager enabled between loading different keyed levels */
|
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
@@ -31,9 +29,13 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
|
|||||||
// level override logic //
|
// level override logic //
|
||||||
//======================//
|
//======================//
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public IServerKeyedClientLevel getServerKeyedLevel() { return this.serverKeyedLevel; }
|
public IServerKeyedClientLevel getServerKeyedLevel()
|
||||||
|
{
|
||||||
|
return this.serverKeyedLevel;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String levelKey)
|
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String levelKey)
|
||||||
@@ -45,11 +47,21 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearKeyedLevel() { this.serverKeyedLevel = null; }
|
public void clearServerKeyedLevel()
|
||||||
@Override
|
{
|
||||||
public boolean isEnabled() { return this.enabled; }
|
this.serverKeyedLevel = null;
|
||||||
@Override
|
}
|
||||||
public void disable() { this.enabled = false; }
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled()
|
||||||
|
{
|
||||||
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable()
|
||||||
|
{
|
||||||
|
this.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-9
@@ -2,8 +2,6 @@ package com.seibel.distanthorizons.common.wrappers.level;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
|
||||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
public class ServerKeyedClientLevel extends ClientLevelWrapper implements IServerKeyedClientLevel
|
public class ServerKeyedClientLevel extends ClientLevelWrapper implements IServerKeyedClientLevel
|
||||||
@@ -11,20 +9,20 @@ public class ServerKeyedClientLevel extends ClientLevelWrapper implements IServe
|
|||||||
/** A unique identifier (generally the level's name) for differentiating multiverse levels */
|
/** A unique identifier (generally the level's name) for differentiating multiverse levels */
|
||||||
private final String serverLevelKey;
|
private final String serverLevelKey;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ServerKeyedClientLevel(ClientLevel level, String serverLevelKey)
|
public ServerKeyedClientLevel(ClientLevel level, String serverLevelKey)
|
||||||
{
|
{
|
||||||
super(level);
|
super(level);
|
||||||
this.serverLevelKey = serverLevelKey;
|
this.serverLevelKey = serverLevelKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getServerLevelKey() { return this.serverLevelKey; }
|
public String getServerLevelKey() { return this.serverLevelKey; }
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDhIdentifier() { return this.getServerLevelKey(); }
|
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public String getDimensionName()
|
||||||
|
{
|
||||||
|
return this.getServerLevelKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+18
-68
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
@@ -54,16 +53,11 @@ import net.minecraft.core.Direction;
|
|||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
#else
|
|
||||||
import net.minecraft.util.profiling.Profiler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that wraps the Minecraft object.
|
* A singleton that wraps the Minecraft object.
|
||||||
*
|
*
|
||||||
@@ -118,7 +112,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public float getShade(EDhDirection lodDirection)
|
public float getShade(EDhDirection lodDirection)
|
||||||
{
|
{
|
||||||
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.Quality.lodShading.get();
|
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading.get();
|
||||||
switch (lodShading)
|
switch (lodShading)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@@ -208,46 +202,34 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public UUID getPlayerUUID() { return this.getPlayer().getUUID(); }
|
public UUID getPlayerUUID() { return this.getPlayer().getUUID(); }
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsername() { return MINECRAFT.getUser().getName(); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhBlockPos getPlayerBlockPos()
|
public DhBlockPos getPlayerBlockPos()
|
||||||
{
|
{
|
||||||
LocalPlayer player = this.getPlayer();
|
BlockPos playerPos = this.getPlayer().blockPosition();
|
||||||
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(player.blockPosition());
|
ChunkPos playerPos = new ChunkPos(this.getPlayer().blockPosition());
|
||||||
#else
|
#else
|
||||||
ChunkPos playerPos = player.chunkPosition();
|
ChunkPos playerPos = this.getPlayer().chunkPosition();
|
||||||
#endif
|
#endif
|
||||||
return new DhChunkPos(playerPos.x, playerPos.z);
|
return new DhChunkPos(playerPos.x, playerPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IClientLevelWrapper getWrappedClientLevel() { return this.getWrappedClientLevel(false); }
|
public IClientLevelWrapper getWrappedClientLevel()
|
||||||
|
{
|
||||||
|
return this.getWrappedClientLevel(false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public IClientLevelWrapper getWrappedClientLevel(boolean bypassLevelKeyManager)
|
public IClientLevelWrapper getWrappedClientLevel(boolean bypassMultiverse)
|
||||||
{
|
{
|
||||||
ClientLevel level = MINECRAFT.level;
|
ClientLevel level = MINECRAFT.level;
|
||||||
if (level == null)
|
if (level == null)
|
||||||
@@ -255,26 +237,19 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClientLevelWrapper.getWrapper(level, bypassLevelKeyManager);
|
return ClientLevelWrapper.getWrapper(level, bypassMultiverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IProfilerWrapper getProfiler()
|
public IProfilerWrapper getProfiler()
|
||||||
{
|
{
|
||||||
ProfilerFiller profiler;
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
profiler = MINECRAFT.getProfiler();
|
|
||||||
#else
|
|
||||||
profiler = Profiler.get();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (this.profilerWrapper == null)
|
if (this.profilerWrapper == null)
|
||||||
{
|
{
|
||||||
this.profilerWrapper = new ProfilerWrapper(profiler);
|
this.profilerWrapper = new ProfilerWrapper(MINECRAFT.getProfiler());
|
||||||
}
|
}
|
||||||
else if (profiler != this.profilerWrapper.profiler)
|
else if (MINECRAFT.getProfiler() != this.profilerWrapper.profiler)
|
||||||
{
|
{
|
||||||
this.profilerWrapper.profiler = profiler;
|
this.profilerWrapper.profiler = MINECRAFT.getProfiler();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.profilerWrapper;
|
return this.profilerWrapper;
|
||||||
@@ -305,27 +280,10 @@ 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());
|
||||||
#else
|
#else
|
||||||
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
player.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||||
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,17 +320,9 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPlayerCount()
|
public boolean isWorldInitialized()
|
||||||
{
|
{
|
||||||
// can be null if the server hasn't finished booting up yet
|
throw new NotImplementedException("TODO");
|
||||||
if (MINECRAFT.getSingleplayerServer() == null)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return MINECRAFT.getSingleplayerServer().getPlayerCount();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-22
@@ -6,34 +6,19 @@ import net.minecraft.server.dedicated.DedicatedServer;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
//@Environment(EnvType.SERVER)
|
//@Environment(EnvType.SERVER)
|
||||||
public class MinecraftServerWrapper implements IMinecraftSharedWrapper
|
public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper
|
||||||
{
|
{
|
||||||
public static final MinecraftServerWrapper INSTANCE = new MinecraftServerWrapper();
|
public static final MinecraftDedicatedServerWrapper INSTANCE = new MinecraftDedicatedServerWrapper();
|
||||||
|
private MinecraftDedicatedServerWrapper() { }
|
||||||
public DedicatedServer dedicatedServer = null;
|
public DedicatedServer dedicatedServer = null;
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
private MinecraftServerWrapper() { }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDedicatedServer() { return true; }
|
public boolean isDedicatedServer() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getInstallationDirectory()
|
public File getInstallationDirectory()
|
||||||
{
|
{
|
||||||
if (this.dedicatedServer == null)
|
if (this.dedicatedServer == null)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server completed initialization!");
|
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
@@ -44,9 +29,9 @@ public class MinecraftServerWrapper implements IMinecraftSharedWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPlayerCount()
|
public boolean isWorldInitialized()
|
||||||
{
|
{
|
||||||
return this.dedicatedServer.getPlayerCount();
|
return this.dedicatedServer.getWorldData().overworldData().isInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
-252
@@ -1,252 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.minecraft;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_5
|
|
||||||
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.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.lwjgl.opengl.GL32;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>Why does DH often call GL methods twice? </b><br>
|
|
||||||
* Once using the base {@link GL32} function and a second time using
|
|
||||||
* Minecraft's {@link GlStateManager}?<br><br>
|
|
||||||
*
|
|
||||||
* <b>Answer: </b><br>
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|
||||||
{
|
|
||||||
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
|
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
private static final StencilState STENCIL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// scissor //
|
|
||||||
|
|
||||||
/** @see GL32#GL_SCISSOR_TEST */
|
|
||||||
@Override
|
|
||||||
public void enableScissorTest()
|
|
||||||
{
|
|
||||||
GL32.glEnable(GL32.GL_SCISSOR_TEST);
|
|
||||||
GlStateManager._enableScissorTest();
|
|
||||||
}
|
|
||||||
/** @see GL32#GL_SCISSOR_TEST */
|
|
||||||
@Override
|
|
||||||
public void disableScissorTest()
|
|
||||||
{
|
|
||||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
|
||||||
GlStateManager._disableScissorTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// stencil //
|
|
||||||
//
|
|
||||||
// /** @see GL32#GL_SCISSOR_TEST */
|
|
||||||
// public void enableScissorTest() { GlStateManager._stencilFunc(); }
|
|
||||||
// /** @see GL32#GL_SCISSOR_TEST */
|
|
||||||
// public void disableScissorTest() { GlStateManager._disableScissorTest(); }
|
|
||||||
|
|
||||||
|
|
||||||
// depth //
|
|
||||||
|
|
||||||
/** @see GL32#GL_DEPTH_TEST */
|
|
||||||
@Override
|
|
||||||
public void enableDepthTest()
|
|
||||||
{
|
|
||||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
|
||||||
GlStateManager._enableDepthTest();
|
|
||||||
}
|
|
||||||
/** @see GL32#GL_DEPTH_TEST */
|
|
||||||
@Override
|
|
||||||
public void disableDepthTest()
|
|
||||||
{
|
|
||||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
|
||||||
GlStateManager._disableDepthTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see GL32#glDepthFunc(int) */
|
|
||||||
@Override
|
|
||||||
public void glDepthFunc(int func)
|
|
||||||
{
|
|
||||||
GL32.glDepthFunc(func);
|
|
||||||
GlStateManager._depthFunc(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see GL32#glDepthMask(boolean) */
|
|
||||||
@Override
|
|
||||||
public void enableDepthMask()
|
|
||||||
{
|
|
||||||
GL32.glDepthMask(true);
|
|
||||||
GlStateManager._depthMask(true);
|
|
||||||
}
|
|
||||||
/** @see GL32#glDepthMask(boolean) */
|
|
||||||
@Override
|
|
||||||
public void disableDepthMask()
|
|
||||||
{
|
|
||||||
GL32.glDepthMask(false);
|
|
||||||
GlStateManager._depthMask(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// blending //
|
|
||||||
|
|
||||||
/** @see GL32#GL_BLEND */
|
|
||||||
@Override
|
|
||||||
public void enableBlend()
|
|
||||||
{
|
|
||||||
GL32.glEnable(GL32.GL_BLEND);
|
|
||||||
GlStateManager._enableBlend();
|
|
||||||
}
|
|
||||||
/** @see GL32#GL_BLEND */
|
|
||||||
@Override
|
|
||||||
public void disableBlend()
|
|
||||||
{
|
|
||||||
GL32.glDisable(GL32.GL_BLEND);
|
|
||||||
GlStateManager._disableBlend();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see GL32#glBlendFunc */
|
|
||||||
@Override
|
|
||||||
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 */
|
|
||||||
@Override
|
|
||||||
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha)
|
|
||||||
{
|
|
||||||
GL32.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
|
|
||||||
GlStateManager._blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// frame buffers //
|
|
||||||
|
|
||||||
/** @see GL32#glBindFramebuffer */
|
|
||||||
@Override
|
|
||||||
public void glBindFramebuffer(int target, int framebuffer)
|
|
||||||
{
|
|
||||||
GL32.glBindFramebuffer(target, framebuffer);
|
|
||||||
GlStateManager._glBindFramebuffer(target, framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// buffers //
|
|
||||||
|
|
||||||
/** @see GL32#glGenBuffers() */
|
|
||||||
@Override
|
|
||||||
public int glGenBuffers()
|
|
||||||
{ return GlStateManager._glGenBuffers(); }
|
|
||||||
|
|
||||||
/** @see GL32#glDeleteBuffers(int) */
|
|
||||||
@Override
|
|
||||||
public void glDeleteBuffers(int 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 //
|
|
||||||
|
|
||||||
/** @see GL32#GL_CULL_FACE */
|
|
||||||
@Override
|
|
||||||
public void enableFaceCulling()
|
|
||||||
{
|
|
||||||
GL32.glEnable(GL32.GL_CULL_FACE);
|
|
||||||
GlStateManager._enableCull();
|
|
||||||
}
|
|
||||||
/** @see GL32#GL_CULL_FACE */
|
|
||||||
@Override
|
|
||||||
public void disableFaceCulling()
|
|
||||||
{
|
|
||||||
GL32.glDisable(GL32.GL_CULL_FACE);
|
|
||||||
GlStateManager._disableCull();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// textures //
|
|
||||||
|
|
||||||
/** @see GL32#glGenTextures() */
|
|
||||||
@Override
|
|
||||||
public int glGenTextures() { return GlStateManager._genTexture(); }
|
|
||||||
/** @see GL32#glDeleteTextures(int) */
|
|
||||||
@Override
|
|
||||||
public void glDeleteTextures(int texture) { GlStateManager._deleteTexture(texture); }
|
|
||||||
|
|
||||||
/** @see GL32#glActiveTexture(int) */
|
|
||||||
@Override
|
|
||||||
public void glActiveTexture(int textureId)
|
|
||||||
{
|
|
||||||
GL32.glActiveTexture(textureId);
|
|
||||||
GlStateManager._activeTexture(textureId);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Always binds to {@link GL32#GL_TEXTURE_2D}
|
|
||||||
* @see GL32#glBindTexture(int, int)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void glBindTexture(int texture)
|
|
||||||
{
|
|
||||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, texture);
|
|
||||||
GlStateManager._bindTexture(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
+21
-190
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -30,15 +30,11 @@ import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
|||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
#else
|
|
||||||
import net.minecraft.client.renderer.fog.FogRenderer;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
@@ -46,6 +42,9 @@ import org.joml.Matrix4f;
|
|||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
#if MC_VER >= MC_1_20_2
|
||||||
|
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
|
||||||
|
#endif
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -70,11 +69,7 @@ import net.minecraft.world.level.material.FogType;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.joml.Vector4f;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_21_5
|
|
||||||
import com.mojang.blaze3d.opengl.GlTexture;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that contains everything
|
* A singleton that contains everything
|
||||||
@@ -106,19 +101,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
*/
|
*/
|
||||||
public int finalLevelFrameBufferId = -1;
|
public int finalLevelFrameBufferId = -1;
|
||||||
|
|
||||||
public boolean colorTextureCastFailLogged = false;
|
|
||||||
public boolean depthTextureCastFailLogged = false;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
#else
|
|
||||||
private static FogRenderer mcFogRenderer = null;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3f getLookAtVector()
|
public Vec3f getLookAtVector()
|
||||||
@@ -131,22 +114,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
/** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */
|
/** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */
|
||||||
public boolean playerHasBlindingEffect()
|
public boolean playerHasBlindingEffect()
|
||||||
{
|
{
|
||||||
if (MC.player == null)
|
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (MC.player.getActiveEffectsMap() == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -164,55 +136,16 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
float[] colorValues = new float[4];
|
float[] colorValues = new float[4];
|
||||||
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
||||||
return new Color(
|
#else
|
||||||
Math.max(0f, Math.min(colorValues[0], 1f)), // r
|
|
||||||
Math.max(0f, Math.min(colorValues[1], 1f)), // g
|
|
||||||
Math.max(0f, Math.min(colorValues[2], 1f)), // b
|
|
||||||
Math.max(0f, Math.min(colorValues[3], 1f)) // a
|
|
||||||
);
|
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
FogRenderer.setupColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
FogRenderer.setupColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
||||||
float[] colorValues = RenderSystem.getShaderFogColor();
|
float[] colorValues = RenderSystem.getShaderFogColor();
|
||||||
return new Color(
|
|
||||||
Math.max(0f, Math.min(colorValues[0], 1f)), // r
|
|
||||||
Math.max(0f, Math.min(colorValues[1], 1f)), // g
|
|
||||||
Math.max(0f, Math.min(colorValues[2], 1f)), // b
|
|
||||||
Math.max(0f, Math.min(colorValues[3], 1f)) // a
|
|
||||||
);
|
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
|
||||||
return new Color(
|
|
||||||
Math.max(0f, Math.min(colorValues.x, 1f)), // r
|
|
||||||
Math.max(0f, Math.min(colorValues.y, 1f)), // g
|
|
||||||
Math.max(0f, Math.min(colorValues.z, 1f)), // b
|
|
||||||
Math.max(0f, Math.min(colorValues.w, 1f)) // a
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (mcFogRenderer == null)
|
|
||||||
{
|
|
||||||
mcFogRenderer = new FogRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MC.level == null)
|
|
||||||
{
|
|
||||||
// shouldn't happen, but just in case
|
|
||||||
return Color.white;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isFoggy =
|
|
||||||
MC.level.effects().isFoggyAt(
|
|
||||||
MC.gameRenderer.getMainCamera().getBlockPosition().getX(),
|
|
||||||
MC.gameRenderer.getMainCamera().getBlockPosition().getZ())
|
|
||||||
|| MC.gui.getBossOverlay().shouldCreateWorldFog();
|
|
||||||
Vector4f colorValues = mcFogRenderer.setupFog(MC.gameRenderer.getMainCamera(), MC.options.getEffectiveRenderDistance(), isFoggy, MC.deltaTracker, MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true)), MC.level);
|
|
||||||
return new Color(
|
|
||||||
Math.max(0f, Math.min(colorValues.x, 1f)), // r
|
|
||||||
Math.max(0f, Math.min(colorValues.y, 1f)), // g
|
|
||||||
Math.max(0f, Math.min(colorValues.z, 1f)), // b
|
|
||||||
Math.max(0f, Math.min(colorValues.w, 1f)) // a
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
return new Color(
|
||||||
|
Math.max(0f, Math.min(colorValues[0], 1f)),
|
||||||
|
Math.max(0f, Math.min(colorValues[1], 1f)),
|
||||||
|
Math.max(0f, Math.min(colorValues[2], 1f)),
|
||||||
|
Math.max(0f, Math.min(colorValues[3], 1f))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// getSpecialFogColor() is the same as getFogColor()
|
// getSpecialFogColor() is the same as getFogColor()
|
||||||
|
|
||||||
@@ -224,22 +157,16 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
float frameTime;
|
float frameTime;
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
frameTime = MC.getFrameTime();
|
frameTime = MC.getFrameTime();
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
frameTime = MC.getTimer().getRealtimeDeltaTicks();
|
|
||||||
#else
|
#else
|
||||||
frameTime = MC.deltaTracker.getGameTimeDeltaTicks();
|
frameTime = MC.getTimer().getRealtimeDeltaTicks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), frameTime);
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), frameTime);
|
||||||
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);
|
|
||||||
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
|
||||||
#else
|
#else
|
||||||
int argbColorInt = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);;
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);
|
||||||
return ColorUtil.toColorObjARGB(argbColorInt); // TODO MC changed color formats
|
|
||||||
#endif
|
#endif
|
||||||
|
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -302,26 +229,6 @@ 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()
|
||||||
{
|
{
|
||||||
@@ -331,87 +238,25 @@ 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()
|
public int getDepthTextureId() { return this.getRenderTarget().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
|
|
||||||
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 this.getRenderTarget().viewWidth;
|
return getRenderTarget().viewWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBufferViewportHeight()
|
public int getTargetFrameBufferViewportHeight()
|
||||||
{
|
{
|
||||||
return this.getRenderTarget().viewHeight;
|
return getRenderTarget().viewHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -434,10 +279,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* It's better to use {@link MinecraftRenderWrapper#setLightmapId(int, IClientLevelWrapper)} if possible,
|
|
||||||
* however old MC versions don't support it.
|
|
||||||
*/
|
|
||||||
public void updateLightmap(NativeImage lightPixels, IClientLevelWrapper level)
|
public void updateLightmap(NativeImage lightPixels, IClientLevelWrapper level)
|
||||||
{
|
{
|
||||||
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
|
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
|
||||||
@@ -448,15 +289,5 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
|
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
|
||||||
wrapper.uploadLightmap(lightPixels);
|
wrapper.uploadLightmap(lightPixels);
|
||||||
}
|
}
|
||||||
public void setLightmapId(int tetxureId, IClientLevelWrapper level)
|
|
||||||
{
|
|
||||||
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
|
|
||||||
// object for the same MC level and/or the same hash,
|
|
||||||
// so this will have to do for now
|
|
||||||
IDimensionTypeWrapper dimensionType = level.getDimensionType();
|
|
||||||
|
|
||||||
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
|
|
||||||
wrapper.setLightmapId(tetxureId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -31,19 +31,31 @@ public class ProfilerWrapper implements IProfilerWrapper
|
|||||||
{
|
{
|
||||||
public ProfilerFiller profiler;
|
public ProfilerFiller profiler;
|
||||||
|
|
||||||
public ProfilerWrapper(ProfilerFiller newProfiler) { this.profiler = newProfiler; }
|
public ProfilerWrapper(ProfilerFiller newProfiler)
|
||||||
|
{
|
||||||
|
profiler = newProfiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** starts a new section inside the currently running section */
|
/** starts a new section inside the currently running section */
|
||||||
@Override
|
@Override
|
||||||
public void push(String newSection) { this.profiler.push(newSection); }
|
public void push(String newSection)
|
||||||
|
{
|
||||||
|
profiler.push(newSection);
|
||||||
|
}
|
||||||
|
|
||||||
/** ends the currently running section and starts a new one */
|
/** ends the currently running section and starts a new one */
|
||||||
@Override
|
@Override
|
||||||
public void popPush(String newSection) { this.profiler.popPush(newSection); }
|
public void popPush(String newSection)
|
||||||
|
{
|
||||||
|
profiler.popPush(newSection);
|
||||||
|
}
|
||||||
|
|
||||||
/** ends the currently running section */
|
/** ends the currently running section */
|
||||||
@Override
|
@Override
|
||||||
public void pop() { this.profiler.pop(); }
|
public void pop()
|
||||||
|
{
|
||||||
|
profiler.pop();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -8,8 +8,4 @@ public interface IMixinServerPlayer
|
|||||||
@Nullable
|
@Nullable
|
||||||
ServerLevel distantHorizons$getDimensionChangeDestination();
|
ServerLevel distantHorizons$getDimensionChangeDestination();
|
||||||
|
|
||||||
#if MC_VER == MC_1_16_5
|
|
||||||
void distantHorizons$setDimensionChangeDestination(ServerLevel dimensionChangeDestination);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-46
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,24 +20,16 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.misc;
|
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.logging.DhLoggerBuilder;
|
|
||||||
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;
|
||||||
|
|
||||||
public class LightMapWrapper implements ILightMapWrapper
|
public class LightMapWrapper implements ILightMapWrapper
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// constructors //
|
// constructors //
|
||||||
//==============//
|
//==============//
|
||||||
@@ -46,67 +38,41 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==================//
|
//=========//
|
||||||
// lightmap syncing //
|
// methods //
|
||||||
//==================//
|
//=========//
|
||||||
|
|
||||||
public void uploadLightmap(NativeImage image)
|
public void uploadLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_5
|
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
||||||
int currentTexture = GLMC.getActiveTexture();
|
|
||||||
if (this.textureId == 0)
|
if (this.textureId == 0)
|
||||||
{
|
{
|
||||||
this.createLightmap(image);
|
this.createLightmap(image);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLMC.glBindTexture(this.textureId);
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||||
}
|
}
|
||||||
image.upload(0, 0, 0, false);
|
image.upload(0, 0, 0, false);
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
||||||
// 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 = GL32.glGenTextures();
|
||||||
this.textureId = GLMC.glGenTextures();
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 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)
|
|
||||||
{
|
|
||||||
// just use the MC texture ID
|
|
||||||
this.textureId = minecraftLightmapTetxureId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// lightmap use //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bind()
|
public void bind()
|
||||||
{
|
{
|
||||||
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
|
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||||
GLMC.glBindTexture(this.textureId);
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unbind() { GLMC.glBindTexture(0); }
|
public void unbind() { GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.misc;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
|
|
||||||
public class MutableBlockPosWrapper implements IMutableBlockPosWrapper
|
|
||||||
{
|
|
||||||
public final BlockPos.MutableBlockPos pos;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public MutableBlockPosWrapper()
|
|
||||||
{
|
|
||||||
this.pos = new BlockPos.MutableBlockPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===========//
|
|
||||||
// overrides //
|
|
||||||
//===========//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getWrappedMcObject() { return this.pos; }
|
|
||||||
|
|
||||||
}
|
|
||||||
+46
-50
@@ -15,7 +15,7 @@ import java.net.SocketAddress;
|
|||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This wrapper transparently ensures that the underlying {@link ServerPlayer} is always valid,
|
* This wrapper transparently ensures that underlying {@link ServerPlayer} is always valid,
|
||||||
* unless the player has disconnected.
|
* unless the player has disconnected.
|
||||||
*/
|
*/
|
||||||
public class ServerPlayerWrapper implements IServerPlayerWrapper
|
public class ServerPlayerWrapper implements IServerPlayerWrapper
|
||||||
@@ -23,41 +23,38 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
|||||||
private static final ConcurrentMap<ServerGamePacketListenerImpl, ServerPlayerWrapper> serverPlayerWrapperMap = new MapMaker().weakKeys().weakValues().makeMap();
|
private static final ConcurrentMap<ServerGamePacketListenerImpl, ServerPlayerWrapper> serverPlayerWrapperMap = new MapMaker().weakKeys().weakValues().makeMap();
|
||||||
|
|
||||||
private final ServerGamePacketListenerImpl connection;
|
private final ServerGamePacketListenerImpl connection;
|
||||||
|
private ServerPlayer serverPlayer()
|
||||||
|
{
|
||||||
|
return this.connection.player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServerPlayerWrapper getWrapper(ServerPlayer serverPlayer)
|
||||||
|
{
|
||||||
|
return serverPlayerWrapperMap.computeIfAbsent(serverPlayer.connection, ignored -> new ServerPlayerWrapper(serverPlayer.connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerPlayerWrapper(ServerGamePacketListenerImpl connection)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public static ServerPlayerWrapper getWrapper(ServerPlayer serverPlayer)
|
|
||||||
{ return serverPlayerWrapperMap.computeIfAbsent(serverPlayer.connection, ignored -> new ServerPlayerWrapper(serverPlayer.connection)); }
|
|
||||||
|
|
||||||
private ServerPlayerWrapper(ServerGamePacketListenerImpl connection) { this.connection = connection; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// getters //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
private ServerPlayer getServerPlayer() { return this.connection.player; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() { return this.getServerPlayer().getName().getString(); }
|
public String getName()
|
||||||
|
{
|
||||||
|
return this.serverPlayer().getName().getString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IServerLevelWrapper getLevel()
|
public IServerLevelWrapper getLevel()
|
||||||
{
|
{
|
||||||
ServerLevel level = ((IMixinServerPlayer) this.getServerPlayer()).distantHorizons$getDimensionChangeDestination();
|
ServerLevel level = ((IMixinServerPlayer) this.serverPlayer()).distantHorizons$getDimensionChangeDestination();
|
||||||
if (level == null)
|
if (level == null)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
level = this.getServerPlayer().getLevel();
|
level = this.serverPlayer().getLevel();
|
||||||
#elif MC_VER < MC_1_21_6
|
|
||||||
level = this.getServerPlayer().serverLevel();
|
|
||||||
#else
|
#else
|
||||||
level = this.getServerPlayer().level();
|
level = this.serverPlayer().serverLevel();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,58 +64,57 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Vec3d getPosition()
|
public Vec3d getPosition()
|
||||||
{
|
{
|
||||||
Vec3 position = this.getServerPlayer().position();
|
Vec3 position = this.serverPlayer().position();
|
||||||
return new Vec3d(position.x, position.y, position.z);
|
return new Vec3d(position.x, position.y, position.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getViewDistance()
|
public int getViewDistance()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_6
|
return this.serverPlayer().server.getPlayerList().getViewDistance();
|
||||||
return this.getServerPlayer().server.getPlayerList().getViewDistance();
|
|
||||||
#else
|
|
||||||
return this.getServerPlayer().getServer().getPlayerList().getViewDistance();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SocketAddress getRemoteAddress()
|
public SocketAddress getRemoteAddress()
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_19_4
|
#if MC_VER >= MC_1_19_4
|
||||||
return this.getServerPlayer().connection.getRemoteAddress();
|
return this.serverPlayer().connection.getRemoteAddress();
|
||||||
#else // < 1.19.4
|
#else // < 1.19.4
|
||||||
return this.getServerPlayer().connection.connection.getRemoteAddress();
|
return this.serverPlayer().connection.connection.getRemoteAddress();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// base overrides //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getWrappedMcObject() { return this.getServerPlayer(); }
|
public Object getWrappedMcObject()
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Wrapped{" + this.getServerPlayer() + "}"; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
{
|
||||||
if (this == obj)
|
return this.serverPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "Wrapped{" + this.serverPlayer() + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof ServerPlayerWrapper))
|
if (!(o instanceof ServerPlayerWrapper))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ServerPlayerWrapper that = (ServerPlayerWrapper) obj;
|
ServerPlayerWrapper that = (ServerPlayerWrapper) o;
|
||||||
return Objects.equal(this.connection, that.connection);
|
return Objects.equal(this.connection, that.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() { return Objects.hashCode(this.connection); }
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hashCode(this.connection);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+24
-90
@@ -25,19 +25,14 @@ 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;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
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;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@@ -45,21 +40,10 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
#else
|
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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();
|
||||||
@@ -67,10 +51,6 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
private final ClientLevel level;
|
private final ClientLevel level;
|
||||||
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/** cached method reference to reduce GC overhead */
|
|
||||||
private final Function<BlockState, ClientBlockStateColorCache> cachedBlockColorCacheFunction = (blockState) -> this.createBlockColorCache(blockState);
|
|
||||||
|
|
||||||
|
|
||||||
private BlockStateWrapper dirtBlockWrapper;
|
private BlockStateWrapper dirtBlockWrapper;
|
||||||
private BiomeWrapper plainsBiomeWrapper;
|
private BiomeWrapper plainsBiomeWrapper;
|
||||||
@Deprecated // TODO circular references are bad
|
@Deprecated // TODO circular references are bad
|
||||||
@@ -86,11 +66,14 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==================//
|
//===============//
|
||||||
// instance methods //
|
// wrapper logic //
|
||||||
//==================//
|
//===============//
|
||||||
|
|
||||||
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level) { return getWrapper(level, false); }
|
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level)
|
||||||
|
{
|
||||||
|
return getWrapper(level, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static IClientLevelWrapper getWrapper(@Nullable ClientLevel level, boolean bypassLevelKeyManager)
|
public static IClientLevelWrapper getWrapper(@Nullable ClientLevel level, boolean bypassLevelKeyManager)
|
||||||
@@ -110,31 +93,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return LEVEL_WRAPPER_BY_CLIENT_LEVEL.computeIfAbsent(level, ClientLevelWrapper::new);
|
||||||
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
|
|
||||||
if (levelRef != null)
|
|
||||||
{
|
|
||||||
ClientLevelWrapper levelWrapper = levelRef.get();
|
|
||||||
if (levelWrapper != null)
|
|
||||||
{
|
|
||||||
return levelWrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, newLevelRef) ->
|
|
||||||
{
|
|
||||||
if (newLevelRef != null)
|
|
||||||
{
|
|
||||||
ClientLevelWrapper oldLevelWrapper = newLevelRef.get();
|
|
||||||
if (oldLevelWrapper != null)
|
|
||||||
{
|
|
||||||
return newLevelRef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new WeakReference<>(new ClientLevelWrapper(newLevel));
|
|
||||||
}).get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -168,8 +127,6 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//====================//
|
//====================//
|
||||||
// base level methods //
|
// base level methods //
|
||||||
//====================//
|
//====================//
|
||||||
@@ -179,13 +136,10 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
{
|
{
|
||||||
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
|
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
|
||||||
((BlockStateWrapper) blockWrapper).blockState,
|
((BlockStateWrapper) blockWrapper).blockState,
|
||||||
this.cachedBlockColorCacheFunction);
|
(block) -> new ClientBlockStateColorCache(block, this));
|
||||||
|
|
||||||
return blockColorCache.getColor((BiomeWrapper) biome, pos);
|
return blockColorCache.getColor((BiomeWrapper) biome, pos);
|
||||||
}
|
}
|
||||||
/** used by {@link ClientLevelWrapper#cachedBlockColorCacheFunction} */
|
|
||||||
private ClientBlockStateColorCache createBlockColorCache(BlockState block) { return new ClientBlockStateColorCache(block, this); }
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDirtBlockColor()
|
public int getDirtBlockColor()
|
||||||
@@ -232,16 +186,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDimensionName() { return this.level.dimension().location().toString(); }
|
public String getDimensionName()
|
||||||
|
{
|
||||||
@Override
|
return this.level.dimension().location().toString();
|
||||||
public long getHashedSeed() { return this.level.getBiomeManager().biomeZoomSeed; }
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDhIdentifier() { return this.getHashedSeedEncoded() + "@" + this.getDimensionName(); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EDhApiLevelType getLevelType() { return EDhApiLevelType.CLIENT_LEVEL; }
|
public EDhApiLevelType getLevelType() { return EDhApiLevelType.CLIENT_LEVEL; }
|
||||||
@@ -262,10 +213,8 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
return this.level.getMinBuildHeight();
|
|
||||||
#else
|
#else
|
||||||
return this.level.getMinY();
|
return this.level.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +232,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ChunkWrapper(chunk, this);
|
return new ChunkWrapper(chunk, this.level, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -295,7 +244,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockStateWrapper getBlockState(DhBlockPos pos)
|
public IBlockStateWrapper getBlockState(DhBlockPos pos)
|
||||||
{ return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), this); }
|
{
|
||||||
|
return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper getBiome(DhBlockPos pos) { return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos)), this); }
|
public IBiomeWrapper getBiome(DhBlockPos pos) { return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos)), this); }
|
||||||
@@ -306,22 +257,10 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void onUnload()
|
public void onUnload()
|
||||||
{
|
{
|
||||||
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.remove(this.level);
|
LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level);
|
||||||
this.parentDhLevel = null;
|
this.parentDhLevel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getDhSaveFolder()
|
|
||||||
{
|
|
||||||
if (this.parentDhLevel == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.parentDhLevel.getSaveStructure().getSaveFolder(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===================//
|
//===================//
|
||||||
@@ -345,13 +284,8 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Color getCloudColor(float tickDelta)
|
public Color getCloudColor(float tickDelta)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
Vec3 colorVec3 = this.level.getCloudColor(tickDelta);
|
Vec3 colorVec3 = this.level.getCloudColor(tickDelta);
|
||||||
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
|
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
|
||||||
#else
|
|
||||||
int argbColor = this.level.getCloudColor(tickDelta);
|
|
||||||
return ColorUtil.toColorObjARGB(argbColor);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -368,7 +302,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
return "Wrapped{null}";
|
return "Wrapped{null}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Wrapped{" + this.level.toString() + "@" + this.getDhIdentifier() + "}";
|
return "Wrapped{" + this.level.toString() + "@" + this.getDimensionName() + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+45
-48
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,80 +28,78 @@ 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<String, DimensionTypeWrapper> DIMENSION_WRAPPER_BY_NAME = new ConcurrentHashMap<>();
|
private static final ConcurrentMap<DimensionType, DimensionTypeWrapper> dimensionTypeWrapperMap = 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)
|
||||||
{
|
{
|
||||||
String dimName = getName(dimensionType);
|
//first we check if the biome has already been wrapped
|
||||||
|
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 DIMENSION_WRAPPER_BY_NAME.get(dimName);
|
return dimensionTypeWrapperMap.get(dimensionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create the missing wrapper
|
//if it hasn't been created yet, we create it and save it in the map
|
||||||
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
|
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
|
||||||
DIMENSION_WRAPPER_BY_NAME.put(dimName, dimensionTypeWrapper);
|
dimensionTypeWrapperMap.put(dimensionType, dimensionTypeWrapper);
|
||||||
|
|
||||||
|
//we return the newly created wrapper
|
||||||
return dimensionTypeWrapper;
|
return dimensionTypeWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearMap() { DIMENSION_WRAPPER_BY_NAME.clear(); }
|
public static void clearMap()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=================//
|
|
||||||
// wrapper methods //
|
|
||||||
//=================//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() { return getName(this.dimensionType); }
|
|
||||||
public static String getName(DimensionType dimensionType)
|
|
||||||
{
|
{
|
||||||
#if MC_VER <= MC_1_16_5
|
dimensionTypeWrapperMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getDimensionName()
|
||||||
|
{
|
||||||
|
#if MC_VER >= MC_1_17_1
|
||||||
|
return this.dimensionType.effectsLocation().getPath();
|
||||||
|
#else // < 1.17.1
|
||||||
// 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
|
|
||||||
return dimensionType.effectsLocation().getPath();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCeiling() { return this.dimensionType.hasCeiling(); }
|
public boolean hasCeiling()
|
||||||
|
{
|
||||||
|
return this.dimensionType.hasCeiling();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSkyLight() { return this.dimensionType.hasSkyLight(); }
|
public boolean hasSkyLight()
|
||||||
|
{
|
||||||
|
return this.dimensionType.hasSkyLight();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getWrappedMcObject() { return this.dimensionType; }
|
public Object getWrappedMcObject()
|
||||||
|
{
|
||||||
|
return this.dimensionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getTeleportationScale(IDimensionTypeWrapper to)
|
||||||
|
{
|
||||||
|
return DimensionType.getTeleportationScale(this.dimensionType, (DimensionType) to.getWrappedMcObject());
|
||||||
|
}
|
||||||
|
|
||||||
// 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.getName().equalsIgnoreCase("the_end"); }
|
public boolean isTheEnd() { return this.getDimensionName().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)
|
||||||
@@ -113,10 +111,9 @@ public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DimensionTypeWrapper other = (DimensionTypeWrapper) obj;
|
DimensionTypeWrapper other = (DimensionTypeWrapper) obj;
|
||||||
return other.getName().equals(this.getName());
|
return other.getDimensionName().equals(this.getDimensionName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
||||||
+41
-84
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,10 +20,6 @@
|
|||||||
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;
|
||||||
@@ -42,7 +38,6 @@ 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;
|
||||||
|
|
||||||
@@ -52,21 +47,15 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
#else
|
|
||||||
import java.nio.file.Path;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 2022-9-16
|
||||||
|
*/
|
||||||
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
|
||||||
@@ -78,88 +67,70 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
// constructors //
|
// constructors //
|
||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
public static ServerLevelWrapper getWrapper(ServerLevel level) { return LEVEL_WRAPPER_BY_SERVER_LEVEL.computeIfAbsent(level, ServerLevelWrapper::new); }
|
||||||
|
|
||||||
|
public ServerLevelWrapper(ServerLevel level)
|
||||||
{
|
{
|
||||||
return LEVEL_WRAPPER_REF_BY_SERVER_LEVEL.compute(level, (newLevel, levelRef) ->
|
this.level = level;
|
||||||
{
|
|
||||||
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; }
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========//
|
||||||
//==================//
|
// methods //
|
||||||
// instance methods //
|
//=========//
|
||||||
//==================//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getMcSaveFolder()
|
public File getSaveFolder()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
return this.level.getChunkSource().getDataStorage().dataFolder;
|
return this.level.getChunkSource().getDataStorage().dataFolder;
|
||||||
#else
|
|
||||||
return this.level.getChunkSource().getDataStorage().dataFolder.toFile();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWorldFolderName()
|
public DimensionTypeWrapper getDimensionType()
|
||||||
{
|
{
|
||||||
// Need specifically overworld since it's the only dimension that is stored in a server root folder
|
return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType());
|
||||||
|
|
||||||
#if MC_VER >= MC_1_21_3
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDimensionName() { return this.level.dimension().location().toString(); }
|
public String getDimensionName()
|
||||||
|
{
|
||||||
@Override
|
return this.level.dimension().location().toString();
|
||||||
public long getHashedSeed() { return this.level.getBiomeManager().biomeZoomSeed; }
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDhIdentifier() { return this.getDimensionName(); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EDhApiLevelType getLevelType() { return EDhApiLevelType.SERVER_LEVEL; }
|
public EDhApiLevelType getLevelType() { return EDhApiLevelType.SERVER_LEVEL; }
|
||||||
|
|
||||||
public ServerLevel getLevel() { return this.level; }
|
public ServerLevel getLevel()
|
||||||
|
{
|
||||||
|
return this.level;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCeiling() { return this.level.dimensionType().hasCeiling(); }
|
public boolean hasCeiling()
|
||||||
|
{
|
||||||
|
return this.level.dimensionType().hasCeiling();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSkyLight() { return this.level.dimensionType().hasSkyLight(); }
|
public boolean hasSkyLight()
|
||||||
|
{
|
||||||
|
return this.level.dimensionType().hasSkyLight();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxHeight() { return this.level.getHeight(); }
|
public int getMaxHeight()
|
||||||
|
{
|
||||||
|
return this.level.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinHeight()
|
public int getMinHeight()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
return this.level.getMinBuildHeight();
|
|
||||||
#else
|
#else
|
||||||
return this.level.getMinY();
|
return this.level.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,14 +141,12 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FULL, false);
|
ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FULL, false);
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return new ChunkWrapper(chunk, this.level, this);
|
||||||
return new ChunkWrapper(chunk, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -204,7 +173,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_REF_BY_SERVER_LEVEL.remove(this.level); }
|
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,18 +190,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
return this.parentDhLevel.getGenericRenderer();
|
return this.parentDhLevel.getGenericRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getDhSaveFolder()
|
|
||||||
{
|
|
||||||
if (this.parentDhLevel == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.parentDhLevel.getSaveStructure().getSaveFolder(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
@@ -240,6 +197,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
//================//
|
//================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() { return "Wrapped{" + this.level.toString() + "@" + this.getDhIdentifier() + "}"; }
|
public String toString() { return "Wrapped{" + this.level.toString() + "@" + this.getDimensionName() + "}"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
+354
-724
File diff suppressed because it is too large
Load Diff
+17
-68
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,10 +20,11 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -45,7 +46,6 @@ public final class GenerationEvent
|
|||||||
/** the number of chunks wide this event is */
|
/** the number of chunks wide this event is */
|
||||||
public final int size;
|
public final int size;
|
||||||
public final EDhApiWorldGenerationStep targetGenerationStep;
|
public final EDhApiWorldGenerationStep targetGenerationStep;
|
||||||
public final EDhApiDistantGeneratorMode generatorMode;
|
|
||||||
public EventTimer timer = null;
|
public EventTimer timer = null;
|
||||||
public long inQueueTime;
|
public long inQueueTime;
|
||||||
public long timeoutTime = -1;
|
public long timeoutTime = -1;
|
||||||
@@ -56,13 +56,12 @@ public final class GenerationEvent
|
|||||||
|
|
||||||
public GenerationEvent(
|
public GenerationEvent(
|
||||||
DhChunkPos minPos, int size, BatchGenerationEnvironment generationGroup,
|
DhChunkPos minPos, int size, BatchGenerationEnvironment generationGroup,
|
||||||
EDhApiDistantGeneratorMode generatorMode, EDhApiWorldGenerationStep targetGenerationStep, Consumer<IChunkWrapper> resultConsumer)
|
EDhApiWorldGenerationStep targetGenerationStep, Consumer<IChunkWrapper> resultConsumer)
|
||||||
{
|
{
|
||||||
this.inQueueTime = System.nanoTime();
|
this.inQueueTime = System.nanoTime();
|
||||||
this.id = generationFutureDebugIDs++;
|
this.id = generationFutureDebugIDs++;
|
||||||
this.minPos = minPos;
|
this.minPos = minPos;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.generatorMode = generatorMode;
|
|
||||||
this.targetGenerationStep = targetGenerationStep;
|
this.targetGenerationStep = targetGenerationStep;
|
||||||
this.threadedParam = ThreadedParameters.getOrMake(generationGroup.params);
|
this.threadedParam = ThreadedParameters.getOrMake(generationGroup.params);
|
||||||
this.resultConsumer = resultConsumer;
|
this.resultConsumer = resultConsumer;
|
||||||
@@ -72,11 +71,17 @@ public final class GenerationEvent
|
|||||||
|
|
||||||
public static GenerationEvent startEvent(
|
public static GenerationEvent startEvent(
|
||||||
DhChunkPos minPos, int size, BatchGenerationEnvironment genEnvironment,
|
DhChunkPos minPos, int size, BatchGenerationEnvironment genEnvironment,
|
||||||
EDhApiDistantGeneratorMode generatorMode, EDhApiWorldGenerationStep target, Consumer<IChunkWrapper> resultConsumer,
|
EDhApiWorldGenerationStep target, Consumer<IChunkWrapper> resultConsumer,
|
||||||
ExecutorService worldGeneratorThreadPool)
|
ExecutorService worldGeneratorThreadPool)
|
||||||
{
|
{
|
||||||
GenerationEvent generationEvent = new GenerationEvent(minPos, size, genEnvironment, generatorMode, target, resultConsumer);
|
//if (size % 2 == 0)
|
||||||
generationEvent.future = CompletableFuture.supplyAsync(() ->
|
//{
|
||||||
|
// size += 1; // size must be odd for vanilla world gen regions to work
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
GenerationEvent generationEvent = new GenerationEvent(minPos, size, genEnvironment, target, resultConsumer);
|
||||||
|
generationEvent.future = CompletableFuture.runAsync(() ->
|
||||||
{
|
{
|
||||||
long runStartTime = System.nanoTime();
|
long runStartTime = System.nanoTime();
|
||||||
generationEvent.timeoutTime = runStartTime;
|
generationEvent.timeoutTime = runStartTime;
|
||||||
@@ -84,75 +89,19 @@ public final class GenerationEvent
|
|||||||
generationEvent.timer = new EventTimer("setup");
|
generationEvent.timer = new EventTimer("setup");
|
||||||
|
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
|
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
genEnvironment.generateLodFromListAsync(generationEvent, (runnable) ->
|
//LOGGER.info("generating [{}]", event.minPos);
|
||||||
{
|
genEnvironment.generateLodFromList(generationEvent);
|
||||||
worldGeneratorThreadPool.execute(() ->
|
|
||||||
{
|
|
||||||
boolean alreadyMarked = BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread();
|
|
||||||
if (!alreadyMarked)
|
|
||||||
{
|
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
catch (Throwable throwable)
|
|
||||||
{
|
|
||||||
handleWorldGenThrowable(generationEvent, throwable);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (!alreadyMarked)
|
|
||||||
{
|
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.set(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Throwable initialThrowable)
|
|
||||||
{
|
|
||||||
handleWorldGenThrowable(generationEvent, initialThrowable);
|
|
||||||
}
|
}
|
||||||
|
catch (InterruptedException ignored) { }
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}, worldGeneratorThreadPool);
|
}, worldGeneratorThreadPool);
|
||||||
return generationEvent;
|
return generationEvent;
|
||||||
}
|
}
|
||||||
/** There's probably a better way to handle this, but it'll work for now */
|
|
||||||
private static void handleWorldGenThrowable(GenerationEvent generationEvent, Throwable initialThrowable)
|
|
||||||
{
|
|
||||||
Throwable throwable = initialThrowable;
|
|
||||||
while (throwable instanceof CompletionException)
|
|
||||||
{
|
|
||||||
throwable = throwable.getCause();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (throwable instanceof InterruptedException
|
|
||||||
|| throwable instanceof UncheckedInterruptedException
|
|
||||||
|| throwable instanceof RejectedExecutionException)
|
|
||||||
{
|
|
||||||
// these exceptions can be ignored, generally they just mean
|
|
||||||
// the thread is busy so it'll need to try again later.
|
|
||||||
// FIXME this should cause the world gen task to be re-queued so we can try again later
|
|
||||||
// however, currently it can cause large gaps in the world gen instead.
|
|
||||||
// These gaps will generate correctly if the level is reloaded and the world gen is re-queued,
|
|
||||||
// however this is makes it look like the generator isn't working or skipped something.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
generationEvent.future.completeExceptionally(throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isComplete() { return this.future.isDone(); }
|
public boolean isComplete() { return this.future.isDone(); }
|
||||||
|
|
||||||
|
|||||||
+22
-30
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -50,26 +50,23 @@ import net.minecraft.world.level.storage.WorldData;
|
|||||||
public final class GlobalParameters
|
public final class GlobalParameters
|
||||||
{
|
{
|
||||||
public final ChunkGenerator generator;
|
public final ChunkGenerator generator;
|
||||||
public final IDhServerLevel lodLevel;
|
|
||||||
public final ServerLevel level;
|
|
||||||
public final Registry<Biome> biomes;
|
|
||||||
public final RegistryAccess registry;
|
|
||||||
public final long worldSeed;
|
|
||||||
public final DataFixer fixerUpper;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public final StructureManager structures;
|
public final StructureManager structures;
|
||||||
#else
|
#else
|
||||||
public final StructureTemplateManager structures;
|
public final StructureTemplateManager structures;
|
||||||
public final RandomState randomState;
|
public final RandomState randomState;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
public final WorldGenSettings worldGenSettings;
|
public final WorldGenSettings worldGenSettings;
|
||||||
#else
|
#else
|
||||||
public final WorldOptions worldOptions;
|
public final WorldOptions worldOptions;
|
||||||
#endif
|
#endif
|
||||||
|
public final IDhServerLevel lodLevel;
|
||||||
|
public final ServerLevel level;
|
||||||
|
public final Registry<Biome> biomes;
|
||||||
|
public final RegistryAccess registry;
|
||||||
|
public final long worldSeed;
|
||||||
|
public final DataFixer fixerUpper;
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
public final BiomeManager biomeManager;
|
public final BiomeManager biomeManager;
|
||||||
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
||||||
@@ -79,34 +76,29 @@ public final class GlobalParameters
|
|||||||
{
|
{
|
||||||
this.lodLevel = lodLevel;
|
this.lodLevel = lodLevel;
|
||||||
|
|
||||||
this.level = ((ServerLevelWrapper) lodLevel.getServerLevelWrapper()).getWrappedMcObject();
|
level = ((ServerLevelWrapper) lodLevel.getServerLevelWrapper()).getWrappedMcObject();
|
||||||
MinecraftServer server = this.level.getServer();
|
MinecraftServer server = level.getServer();
|
||||||
WorldData worldData = server.getWorldData();
|
WorldData worldData = server.getWorldData();
|
||||||
this.registry = server.registryAccess();
|
registry = server.registryAccess();
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
this.worldGenSettings = worldData.worldGenSettings();
|
worldGenSettings = worldData.worldGenSettings();
|
||||||
this.biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
this.worldSeed = worldGenSettings.seed();
|
worldSeed = worldGenSettings.seed();
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
this.worldOptions = worldData.worldGenOptions();
|
|
||||||
this.biomes = registry.registryOrThrow(Registries.BIOME);
|
|
||||||
this.worldSeed = worldOptions.seed();
|
|
||||||
#else
|
#else
|
||||||
this.worldOptions = worldData.worldGenOptions();
|
worldOptions = worldData.worldGenOptions();
|
||||||
this.biomes = this.registry.lookupOrThrow(Registries.BIOME);
|
biomes = registry.registryOrThrow(Registries.BIOME);
|
||||||
this.worldSeed = this.worldOptions.seed();
|
worldSeed = worldOptions.seed();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
this.biomeManager = new BiomeManager(this.level, BiomeManager.obfuscateSeed(this.worldSeed));
|
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
||||||
this.chunkScanner = this.level.getChunkSource().chunkScanner();
|
chunkScanner = level.getChunkSource().chunkScanner();
|
||||||
#endif
|
#endif
|
||||||
this.structures = server.getStructureManager();
|
structures = server.getStructureManager();
|
||||||
this.generator = this.level.getChunkSource().getGenerator();
|
generator = level.getChunkSource().getGenerator();
|
||||||
this.fixerUpper = server.getFixerUpper();
|
fixerUpper = server.getFixerUpper();
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
this.randomState = this.level.getChunkSource().randomState();
|
randomState = level.getChunkSource().randomState();
|
||||||
#endif
|
#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 James Seibel
|
* Copyright (C) 2020-2023 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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
|
|||||||
+154
-479
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Dynamic;
|
import com.mojang.serialization.Dynamic;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -26,16 +27,21 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
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 net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
#if MC_VER >= MC_1_19_4
|
#if MC_VER >= MC_1_19_4
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@@ -44,6 +50,7 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.NbtOps;
|
import net.minecraft.nbt.NbtOps;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
@@ -52,22 +59,20 @@ import net.minecraft.world.level.block.Block;
|
|||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.*;
|
import net.minecraft.world.level.chunk.*;
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
|
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||||
#endif
|
#endif
|
||||||
|
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||||
import net.minecraft.world.ticks.LevelChunkTicks;
|
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
#endif
|
#endif
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||||
#endif
|
#endif
|
||||||
@@ -86,13 +91,11 @@ 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 final AtomicBoolean ZERO_CHUNK_POS_ERROR_LOGGED_REF = new AtomicBoolean(false);
|
private static boolean zeroChunkPosErrorLogged = 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());
|
||||||
@@ -108,8 +111,6 @@ 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<>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============//
|
//============//
|
||||||
@@ -124,16 +125,19 @@ public class ChunkLoader
|
|||||||
CompoundTag tagLevel = chunkData;
|
CompoundTag tagLevel = chunkData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int chunkX = tagGetInt(tagLevel,"xPos");
|
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
||||||
int chunkZ = tagGetInt(tagLevel, "zPos");
|
|
||||||
ChunkPos actualPos = new ChunkPos(chunkX, chunkZ);
|
|
||||||
|
|
||||||
if (!Objects.equals(chunkPos, actualPos))
|
if (!Objects.equals(chunkPos, actualPos))
|
||||||
{
|
{
|
||||||
if (chunkX == 0 && chunkZ == 0)
|
#if MC_VER >= MC_1_18_2
|
||||||
|
if (actualPos.equals(ChunkPos.ZERO))
|
||||||
|
#else
|
||||||
|
if (actualPos.equals(ChunkPos.INVALID_CHUNK_POS))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (!ZERO_CHUNK_POS_ERROR_LOGGED_REF.getAndSet(true))
|
if (!zeroChunkPosErrorLogged)
|
||||||
{
|
{
|
||||||
|
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" +
|
||||||
@@ -162,7 +166,7 @@ public class ChunkLoader
|
|||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
||||||
return null;
|
return null;
|
||||||
#elif MC_VER < MC_1_21_6
|
#else
|
||||||
|
|
||||||
BlendingData blendingData = readBlendingData(tagLevel);
|
BlendingData blendingData = readBlendingData(tagLevel);
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
@@ -172,42 +176,17 @@ public class ChunkLoader
|
|||||||
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
|
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
|
||||||
return null;
|
return null;
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
|
|
||||||
// ignore blending data, there appears to be an issue with parsing it in 1.21.6
|
|
||||||
BlendingData blendingData = null;
|
|
||||||
|
|
||||||
if (chunkType == ChunkType.PROTOCHUNK)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long inhabitedTime = tagGetLong(tagLevel, "InhabitedTime");
|
long inhabitedTime = tagLevel.getLong("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;
|
||||||
|
|
||||||
UpgradeData upgradeData = UpgradeData.EMPTY;
|
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
||||||
// commented out 2025-06-04 as a test to see if the upgrade data
|
|
||||||
// is actually necessary for DH or if it can be ignored
|
|
||||||
// (if it can't be ignored we'll need to handle null responses from tagGetCompoundTag())
|
|
||||||
//
|
|
||||||
//#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 ,
|
||||||
@@ -224,21 +203,17 @@ 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);
|
||||||
#elif MC_VER < MC_1_21_4
|
#else
|
||||||
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);
|
||||||
#else
|
#endif
|
||||||
// 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);
|
||||||
@@ -248,13 +223,14 @@ 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
|
||||||
// Set some states after object creation
|
// Set some states after object creation
|
||||||
chunk.setLightCorrect(isLightOn);
|
chunk.setLightCorrect(isLightOn);
|
||||||
readHeightmaps(chunk, chunkData);
|
readHeightmaps(chunk, chunkData);
|
||||||
//readPostPocessings(chunk, chunkData);
|
readPostPocessings(chunk, chunkData);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
@@ -262,144 +238,88 @@ public class ChunkLoader
|
|||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registries.BIOME);
|
|
||||||
#else
|
#else
|
||||||
Registry<Biome> biomes = level.registryAccess().lookupOrThrow(Registries.BIOME);
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registries.BIOME);
|
||||||
#endif
|
#endif
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
||||||
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
#elif MC_VER < MC_1_19_2
|
#elif MC_VER < MC_1_19_2
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
#else
|
#else
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(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];
|
||||||
|
|
||||||
ListTag tagSections = tagGetListTag(chunkData, "Sections", 10);
|
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||||
if (tagSections == null || tagSections.isEmpty())
|
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
||||||
{
|
ListTag tagSections = chunkData.getList("Sections", 10);
|
||||||
tagSections = tagGetListTag(chunkData, "sections", 10);
|
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
||||||
}
|
|
||||||
|
|
||||||
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
if (tagSections != null)
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
CompoundTag tagSection = tagSections.getCompound(j);
|
||||||
{
|
int sectionYPos = tagSection.getByte("Y");
|
||||||
CompoundTag tagSection = tagGetCompoundTag(tagSections, j);
|
|
||||||
if (tagSection == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int sectionYPos = tagGetByte(tagSection, "Y");
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||||
|
{
|
||||||
|
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
||||||
|
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
||||||
|
tagSection.getLongArray("BlockStates"));
|
||||||
|
levelChunkSection.recalcBlockCounts();
|
||||||
|
if (!levelChunkSection.isEmpty())
|
||||||
|
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||||
|
= levelChunkSection;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
|
{
|
||||||
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
PalettedContainer<Biome> biomeContainer;
|
||||||
{
|
|
||||||
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
|
||||||
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
|
||||||
tagSection.getLongArray("BlockStates"));
|
|
||||||
levelChunkSection.recalcBlockCounts();
|
|
||||||
if (!levelChunkSection.isEmpty())
|
|
||||||
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
|
||||||
= levelChunkSection;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
|
||||||
{
|
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
PalettedContainer<Biome> biomeContainer;
|
|
||||||
#else
|
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
boolean containsBlockStates;
|
|
||||||
#if MC_VER < MC_1_21_5
|
|
||||||
containsBlockStates = tagSection.contains("block_states", 10);
|
|
||||||
#else
|
|
||||||
containsBlockStates = tagSection.contains("block_states");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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
|
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message))
|
|
||||||
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
boolean containsBiomes;
|
|
||||||
#if MC_VER < MC_1_21_5
|
|
||||||
containsBiomes = tagSection.contains("biomes", 10);
|
|
||||||
#else
|
|
||||||
containsBiomes = tagSection.contains("biomes");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (containsBiomes)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_20_6
|
|
||||||
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
|
|
||||||
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
|
||||||
.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
|
|
||||||
biomes.getHolderOrThrow(Biomes.PLAINS),
|
|
||||||
#else
|
|
||||||
biomes.getOrThrow(Biomes.PLAINS),
|
|
||||||
#endif
|
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
|
||||||
#else
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
blockStateContainer = tagSection.contains("block_states", 10)
|
||||||
|
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
||||||
|
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#else
|
||||||
|
|
||||||
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
|
#else
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
return chunkSections;
|
return chunkSections;
|
||||||
}
|
}
|
||||||
@@ -409,108 +329,48 @@ public class ChunkLoader
|
|||||||
#else ChunkType #endif
|
#else ChunkType #endif
|
||||||
readChunkType(CompoundTag tagLevel)
|
readChunkType(CompoundTag tagLevel)
|
||||||
{
|
{
|
||||||
String statusString = tagGetString(tagLevel,"Status");
|
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
||||||
if (statusString != null)
|
if (chunkStatus != null)
|
||||||
{
|
{
|
||||||
ChunkStatus chunkStatus = ChunkStatus.byName(statusString);
|
return chunkStatus.getChunkType();
|
||||||
if (chunkStatus != null)
|
|
||||||
{
|
|
||||||
return chunkStatus.getChunkType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
return
|
||||||
return ChunkStatus.ChunkType.PROTOCHUNK;
|
#if MC_VER <= MC_1_20_4 ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
#else
|
#else ChunkType.PROTOCHUNK; #endif
|
||||||
return ChunkType.PROTOCHUNK;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps");
|
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
||||||
if (tagHeightmaps != null)
|
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
||||||
{
|
{
|
||||||
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
String heightmap = type.getSerializationKey();
|
||||||
|
if (tagHeightmaps.contains(heightmap, 12))
|
||||||
|
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
||||||
|
}
|
||||||
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
|
}
|
||||||
|
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
||||||
|
for (int n = 0; n < tagPostProcessings.size(); ++n)
|
||||||
|
{
|
||||||
|
ListTag listTag3 = tagPostProcessings.getList(n);
|
||||||
|
for (int o = 0; o < listTag3.size(); ++o)
|
||||||
{
|
{
|
||||||
String heightmap = type.getSerializationKey();
|
chunk.addPackedPostProcess(listTag3.getShort(o), n);
|
||||||
#if MC_VER < MC_1_21_5
|
|
||||||
if (tagHeightmaps.contains(heightmap, 12))
|
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// commented out as a test as of 2025-06-04 to see if this is actually necessary for DH
|
|
||||||
// DH probably doesn't need any chunk post-processing data
|
|
||||||
//private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
//{
|
|
||||||
// ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
|
|
||||||
// if (tagPostProcessings != null)
|
|
||||||
// {
|
|
||||||
// for (int i = 0; i < tagPostProcessings.size(); ++i)
|
|
||||||
// {
|
|
||||||
// ListTag listTag3 = tagGetListTag(tagPostProcessings, i);
|
|
||||||
// for (int j = 0; j < listTag3.size(); ++j)
|
|
||||||
// {
|
|
||||||
// #if MC_VER < MC_1_21_3
|
|
||||||
// chunk.addPackedPostProcess(listTag3.getShort(j), i);
|
|
||||||
// #else
|
|
||||||
// chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i);
|
|
||||||
// #endif
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
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"));
|
||||||
|
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
||||||
try
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null);
|
|
||||||
#else
|
|
||||||
// blending data appears to have changed as of 1.21.6 causing a class cast exception here due to it being wrapped in a Java.Optional
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -532,7 +392,7 @@ public class ChunkLoader
|
|||||||
return null;
|
return null;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
CombinedChunkLightStorage combinedStorage = new CombinedChunkLightStorage(ChunkWrapper.getInclusiveMinBuildHeight(chunk), ChunkWrapper.getExclusiveMaxBuildHeight(chunk));
|
CombinedChunkLightStorage combinedStorage = new CombinedChunkLightStorage(ChunkWrapper.getMinBuildHeight(chunk), ChunkWrapper.getMaxBuildHeight(chunk));
|
||||||
ChunkLightStorage blockLightStorage = combinedStorage.blockLightStorage;
|
ChunkLightStorage blockLightStorage = combinedStorage.blockLightStorage;
|
||||||
ChunkLightStorage skyLightStorage = combinedStorage.skyLightStorage;
|
ChunkLightStorage skyLightStorage = combinedStorage.skyLightStorage;
|
||||||
|
|
||||||
@@ -587,37 +447,33 @@ public class ChunkLoader
|
|||||||
|
|
||||||
|
|
||||||
// if null all lights = 0
|
// if null all lights = 0
|
||||||
byte[] blockLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "BlockLight");
|
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
||||||
byte[] skyLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "SkyLight");
|
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
||||||
|
|
||||||
if (blockLightNibbleArray != null
|
// if any sky light was found then all lights above will be max brightness
|
||||||
&& skyLightNibbleArray != null)
|
if (skyLightNibbleArray.length != 0)
|
||||||
{
|
{
|
||||||
// if any sky light was found then all lights above will be max brightness
|
foundSkyLight = true;
|
||||||
if (skyLightNibbleArray.length != 0)
|
}
|
||||||
|
|
||||||
|
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||||
|
{
|
||||||
|
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||||
{
|
{
|
||||||
foundSkyLight = true;
|
// chunk sections are also 16 blocks tall
|
||||||
}
|
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
||||||
|
|
||||||
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
|
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
||||||
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
||||||
|
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
||||||
|
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
||||||
{
|
{
|
||||||
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
skyLight = LodUtil.MAX_MC_LIGHT;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getMinBuildHeight(chunk);
|
||||||
|
blockLightStorage.set(relX, y, relZ, blockLight);
|
||||||
|
skyLightStorage.set(relX, y, relZ, skyLight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,194 +495,13 @@ public class ChunkLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// logging //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||||
{
|
{
|
||||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
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.");
|
||||||
{
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
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.");
|
||||||
{
|
|
||||||
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 */
|
|
||||||
@Nullable
|
|
||||||
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 */
|
|
||||||
@Nullable
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-9
@@ -5,24 +5,19 @@ package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
|||||||
import net.minecraft.server.level.GenerationChunkHolder;
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class DhGenerationChunkHolder extends GenerationChunkHolder
|
public class DhGenerationChunkHolder extends GenerationChunkHolder
|
||||||
{
|
{
|
||||||
|
|
||||||
public DhGenerationChunkHolder(ChunkPos pos) { super(pos); }
|
public DhGenerationChunkHolder(ChunkPos pos)
|
||||||
|
{
|
||||||
|
super(pos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTicketLevel() { return 0; }
|
public int getTicketLevel() { return 0; }
|
||||||
@Override
|
@Override
|
||||||
public int getQueueLevel() { return 0; }
|
public int getQueueLevel() { return 0; }
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
protected void addSaveDependency(CompletableFuture<?> completableFuture) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+13
-53
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -68,13 +68,6 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import net.minecraft.server.level.GenerationChunkHolder;
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import net.minecraft.world.ticks.BlackholeTickAccess;
|
|
||||||
import net.minecraft.world.ticks.LevelTickAccess;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
public class DhLitWorldGenRegion extends WorldGenRegion
|
public class DhLitWorldGenRegion extends WorldGenRegion
|
||||||
{
|
{
|
||||||
@@ -83,9 +76,8 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
private static ChunkStatus debugTriggeredForStatus = null;
|
private static ChunkStatus debugTriggeredForStatus = null;
|
||||||
|
|
||||||
|
|
||||||
public final ServerLevel serverLevel;
|
|
||||||
public final DummyLightEngine lightEngine;
|
public final DummyLightEngine lightEngine;
|
||||||
public final BatchGenerationEnvironment.IEmptyChunkRetrievalFunc generator;
|
public final BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator;
|
||||||
public final int writeRadius;
|
public final int writeRadius;
|
||||||
public final int size;
|
public final int size;
|
||||||
|
|
||||||
@@ -130,7 +122,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
ChunkAccess centerChunk,
|
ChunkAccess centerChunk,
|
||||||
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
||||||
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
||||||
BatchGenerationEnvironment.IEmptyChunkRetrievalFunc generator)
|
BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator)
|
||||||
{
|
{
|
||||||
#if MC_VER == MC_1_16_5
|
#if MC_VER == MC_1_16_5
|
||||||
super(serverLevel, chunkList);
|
super(serverLevel, chunkList);
|
||||||
@@ -147,10 +139,9 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
||||||
writeRadius, (WorldGenContext var1, ChunkStep var2, StaticCache2D<GenerationChunkHolder> var3, ChunkAccess var4) -> null),
|
writeRadius, (WorldGenContext var1, ChunkStep var2, StaticCache2D<GenerationChunkHolder> var3, ChunkAccess var4) -> null),
|
||||||
centerChunk);
|
centerChunk);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
this.firstPos = chunkList.get(0).getPos();
|
this.firstPos = chunkList.get(0).getPos();
|
||||||
this.serverLevel = serverLevel;
|
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.lightEngine = lightEngine;
|
this.lightEngine = lightEngine;
|
||||||
this.writeRadius = writeRadius;
|
this.writeRadius = writeRadius;
|
||||||
@@ -179,18 +170,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
if (center.isUpgrading())
|
if (center.isUpgrading())
|
||||||
{
|
{
|
||||||
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
||||||
|
if (blockPos.getY() < levelHeightAccessor.getMinBuildHeight() || blockPos.getY() >= levelHeightAccessor.getMaxBuildHeight())
|
||||||
int minY;
|
|
||||||
int maxY;
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
minY = levelHeightAccessor.getMinBuildHeight();
|
|
||||||
maxY = levelHeightAccessor.getMaxBuildHeight();
|
|
||||||
#else
|
|
||||||
minY = levelHeightAccessor.getMinY();
|
|
||||||
maxY = levelHeightAccessor.getMaxY();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (blockPos.getY() < minY || blockPos.getY() >= maxY)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -200,22 +180,6 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public LevelTickAccess<Block> getBlockTicks()
|
|
||||||
{
|
|
||||||
// DH world gen doesn't need ticking, so return the BlackholeTickAccess list (which causes all ticks to be ignored).
|
|
||||||
// If this isn't done the server may attempt to tick chunks outside the vanilla render distance,
|
|
||||||
// which can throw warnings or cause other issues
|
|
||||||
return BlackholeTickAccess.emptyLevelList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public LevelTickAccess<Fluid> getFluidTicks() { return BlackholeTickAccess.emptyLevelList(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO Check this
|
// TODO Check this
|
||||||
// @Override
|
// @Override
|
||||||
// public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
// public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
||||||
@@ -229,16 +193,8 @@ 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;
|
||||||
}
|
chunkAccess.setBlockState(blockPos, blockState, false);
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_5
|
|
||||||
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))
|
||||||
@@ -383,7 +339,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
{
|
{
|
||||||
// chunk isn't in memory, generate a new one
|
// chunk isn't in memory, generate a new one
|
||||||
chunk = this.generator.getChunk(chunkX, chunkZ);
|
chunk = this.generator.generate(chunkX, chunkZ);
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("The provided generator should not return null!");
|
throw new NullPointerException("The provided generator should not return null!");
|
||||||
@@ -434,10 +390,14 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
/** Overriding allows us to use our own lighting engine */
|
/** Overriding allows us to use our own lighting engine */
|
||||||
@Override
|
@Override
|
||||||
public boolean canSeeSky(@NotNull BlockPos blockPos)
|
public boolean canSeeSky(@NotNull BlockPos blockPos)
|
||||||
{ return (this.getBrightness(LightLayer.SKY, blockPos) >= LodUtil.MAX_MC_LIGHT); }
|
{
|
||||||
|
return (this.getBrightness(LightLayer.SKY, blockPos) >= this.getMaxLightLevel());
|
||||||
|
}
|
||||||
|
|
||||||
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
{ return this.calculateBlockTint(blockPos, colorResolver); }
|
{
|
||||||
|
return this.calculateBlockTint(blockPos, colorResolver);
|
||||||
|
}
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
|
|||||||
+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 James Seibel
|
* Copyright (C) 2020-2023 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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
|
|||||||
+18
-25
@@ -22,11 +22,11 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shouldn't be used when the C2ME mod is present,
|
* @deprecated should be replaced with net.minecraft.world.level.chunk.storage.IOWorker to
|
||||||
* otherwise there may be potential file corruption.
|
* prevent potential file corruption and issues with the C2ME mod.
|
||||||
* When C2ME is present use (via MC ServerLevel) level.getChunkSource().chunkMap.worker#loadAsync()
|
* Generally this would be done via (MC ServerLevel) level.getChunkSource().chunkMap.worker#loadAsync()
|
||||||
* instead.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class RegionFileStorageExternalCache implements AutoCloseable
|
public class RegionFileStorageExternalCache implements AutoCloseable
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
@@ -46,11 +46,22 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static class RegionFileCache
|
||||||
|
{
|
||||||
|
public final long pos;
|
||||||
|
public final RegionFile file;
|
||||||
|
|
||||||
|
public RegionFileCache(long pos, RegionFile file)
|
||||||
|
{
|
||||||
|
this.pos = pos;
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private final ConcurrentLinkedQueue<RegionFileCache> regionFileCache = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
|
|
||||||
|
public ConcurrentLinkedQueue<RegionFileCache> regionFileCache = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
public RegionFileStorageExternalCache(RegionFileStorage storage) { this.storage = storage; }
|
public RegionFileStorageExternalCache(RegionFileStorage storage) { this.storage = storage; }
|
||||||
|
|
||||||
@@ -139,7 +150,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
|
|
||||||
if (retryCount >= maxRetryCount)
|
if (retryCount >= maxRetryCount)
|
||||||
{
|
{
|
||||||
BatchGenerationEnvironment.LOAD_LOGGER.warn("Concurrency issue detected when getting region file for chunk at [" + pos + "].");
|
BatchGenerationEnvironment.LOAD_LOGGER.warn("Concurrency issue detected when getting region file for chunk at " + pos + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -226,22 +237,4 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper classes //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
private static class RegionFileCache
|
|
||||||
{
|
|
||||||
public final long pos;
|
|
||||||
public final RegionFile file;
|
|
||||||
|
|
||||||
public RegionFileCache(long pos, RegionFile file)
|
|
||||||
{
|
|
||||||
this.pos = pos;
|
|
||||||
this.file = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+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 James Seibel
|
* Copyright (C) 2020-2023 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
-33
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -68,50 +68,33 @@ public final class StepBiomes
|
|||||||
}
|
}
|
||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
|
// System.out.println("StepBiomes: "+chunk.getPos());
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
this.environment.params.generator.createBiomes(this.environment.params.biomes, chunk);
|
this.environment.params.generator.createBiomes(this.environment.params.biomes, chunk);
|
||||||
#elif MC_VER < MC_1_19_2
|
#elif MC_VER < MC_1_19_2
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
||||||
this.environment.params.generator.createBiomes(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
this.environment.params.biomes,
|
|
||||||
Runnable::run,
|
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk)
|
|
||||||
);
|
|
||||||
#elif MC_VER < MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
this.environment.params.generator.createBiomes(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
this.environment.params.biomes,
|
|
||||||
Runnable::run,
|
|
||||||
this.environment.params.randomState, Blender.of(worldGenRegion),
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk)
|
|
||||||
);
|
|
||||||
#elif MC_VER < MC_1_21_1
|
#elif MC_VER < MC_1_21_1
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
this.environment.params.generator.createBiomes(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
Runnable::run,
|
|
||||||
this.environment.params.randomState,
|
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk)
|
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
this.environment.params.generator.createBiomes(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
this.environment.params.randomState,
|
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk)
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -66,7 +66,11 @@ public final class StepFeatures
|
|||||||
}
|
}
|
||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -87,6 +91,7 @@ public final class StepFeatures
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||||
|
BatchGenerationEnvironment.clearDistantGenerationMixinData();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
+16
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -67,42 +67,32 @@ public final class StepNoise
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
|
||||||
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
|
// System.out.println("StepNoise: "+chunk.getPos());
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
this.environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
this.environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
||||||
#elif MC_VER < MC_1_18_2
|
#elif MC_VER < MC_1_18_2
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run,
|
||||||
this.environment.params.generator.fillFromNoise(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
Runnable::run,
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk));
|
|
||||||
#elif MC_VER < MC_1_19_2
|
#elif MC_VER < MC_1_19_2
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
||||||
this.environment.params.generator.fillFromNoise(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
Runnable::run,
|
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk));
|
|
||||||
#elif MC_VER < MC_1_21_1
|
#elif MC_VER < MC_1_21_1
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
this.environment.params.generator.fillFromNoise(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
Runnable::run,
|
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
this.environment.params.randomState,
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk));
|
|
||||||
#else
|
#else
|
||||||
chunk = this.environment.confirmFutureWasRunSynchronously(
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
this.environment.params.generator.fillFromNoise(
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
Blender.of(worldGenRegion),
|
|
||||||
this.environment.params.randomState,
|
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
|
||||||
chunk));
|
|
||||||
#endif
|
#endif
|
||||||
UncheckedInterruptedException.throwIfInterrupted();
|
UncheckedInterruptedException.throwIfInterrupted();
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -66,7 +66,12 @@ public final class StepStructureReference
|
|||||||
}
|
}
|
||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-18
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,9 +28,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
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.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -85,7 +83,12 @@ public final class StepStructureStart
|
|||||||
}
|
}
|
||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +96,7 @@ public final class StepStructureStart
|
|||||||
if (this.environment.params.worldGenSettings.generateFeatures())
|
if (this.environment.params.worldGenSettings.generateFeatures())
|
||||||
{
|
{
|
||||||
#elif MC_VER < MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
if (this.environment.params.worldGenSettings.generateStructures())
|
if (this.environment.params.worldGenSettings.generateStructures()) {
|
||||||
{
|
|
||||||
#else
|
#else
|
||||||
if (this.environment.params.worldOptions.generateStructures())
|
if (this.environment.params.worldOptions.generateStructures())
|
||||||
{
|
{
|
||||||
@@ -112,20 +114,15 @@ public final class StepStructureStart
|
|||||||
STRUCTURE_PLACEMENT_LOCK.lock();
|
STRUCTURE_PLACEMENT_LOCK.lock();
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
this.environment.params.generator.createStructures(this.environment.params.registry, tParams.structFeat, chunk, this.environment.params.structures,
|
environment.params.generator.createStructures(environment.params.registry, tParams.structFeat, chunk, environment.params.structures,
|
||||||
this.environment.params.worldSeed);
|
environment.params.worldSeed);
|
||||||
#elif MC_VER < MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
this.environment.params.generator.createStructures(this.environment.params.registry, this.environment.params.randomState, tParams.structFeat, chunk, this.environment.params.structures,
|
environment.params.generator.createStructures(environment.params.registry, environment.params.randomState, tParams.structFeat, chunk, environment.params.structures,
|
||||||
this.environment.params.worldSeed);
|
environment.params.worldSeed);
|
||||||
#elif MC_VER <= MC_1_21_3
|
|
||||||
this.environment.params.generator.createStructures(this.environment.params.registry,
|
|
||||||
this.environment.params.level.getChunkSource().getGeneratorState(),
|
|
||||||
tParams.structFeat, chunk, this.environment.params.structures);
|
|
||||||
#else
|
#else
|
||||||
this.environment.params.generator.createStructures(this.environment.params.registry,
|
environment.params.generator.createStructures(environment.params.registry,
|
||||||
this.environment.params.level.getChunkSource().getGeneratorState(),
|
environment.params.level.getChunkSource().getGeneratorState(),
|
||||||
tParams.structFeat, chunk, this.environment.params.structures,
|
tParams.structFeat, chunk, environment.params.structures);
|
||||||
this.environment.params.level.dimension());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
|
|||||||
+7
-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 James Seibel
|
* Copyright (C) 2020-2023 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
|
||||||
@@ -65,7 +65,12 @@ public final class StepSurface
|
|||||||
}
|
}
|
||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
#if MC_VER < MC_1_21_1
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible field com/mojang/blaze3d/vertex/VertexBuffer vertexCount I
|
accessible field com/mojang/blaze3d/vertex/VertexBuffer vertexCount I
|
||||||
@@ -33,9 +31,6 @@ accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecr
|
|||||||
#accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
#accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
||||||
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
accessWidener v1 named
|
accessWidener v1 named
|
||||||
|
|
||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible field com/mojang/blaze3d/vertex/VertexBuffer indexCount I
|
accessible field com/mojang/blaze3d/vertex/VertexBuffer indexCount I
|
||||||
@@ -32,11 +31,6 @@ accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecr
|
|||||||
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
||||||
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -17,11 +15,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
|
|||||||
# world generation
|
# world generation
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -17,11 +15,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
|
|||||||
# world generation
|
# world generation
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -17,11 +15,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
|
|||||||
# world generation
|
# world generation
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel iss
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -19,11 +17,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
|
|||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -18,11 +16,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
|
|||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ accessWidener v1 named
|
|||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
# used when rendering
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
@@ -18,11 +16,6 @@ accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit
|
|||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
accessWidener v1 named
|
|
||||||
|
|
||||||
# used when determining where to save files to
|
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/nio/file/Path;
|
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F
|
|
||||||
accessible field net/minecraft/client/Minecraft deltaTracker Lnet/minecraft/client/DeltaTracker$Timer;
|
|
||||||
|
|
||||||
|
|
||||||
# used for grabbing vanilla rendered chunks
|
|
||||||
accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
|
|
||||||
|
|
||||||
# world generation
|
|
||||||
# accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
|
||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
|
||||||
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage regionCache Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/nio/file/Path;
|
|
||||||
|
|
||||||
# grabbing textures
|
|
||||||
accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture
|
|
||||||
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameX (I)I
|
|
||||||
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameY (I)I
|
|
||||||
accessible field net/minecraft/client/renderer/texture/SpriteContents animatedTexture Lnet/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture;
|
|
||||||
accessible field net/minecraft/client/renderer/texture/SpriteContents originalImage Lcom/mojang/blaze3d/platform/NativeImage;
|
|
||||||
|
|
||||||
# UI stuff
|
|
||||||
accessible field net/minecraft/client/gui/components/AbstractButton SPRITES Lnet/minecraft/client/gui/components/WidgetSprites;
|
|
||||||
# Handles inserting the config button
|
|
||||||
accessible field net/minecraft/client/gui/layouts/HeaderAndFooterLayout headerFrame Lnet/minecraft/client/gui/layouts/FrameLayout;
|
|
||||||
accessible field net/minecraft/client/gui/layouts/FrameLayout children Ljava/util/List;
|
|
||||||
accessible class net/minecraft/client/gui/layouts/FrameLayout$ChildContainer
|
|
||||||
accessible field net/minecraft/client/gui/layouts/LinearLayout wrapped Lnet/minecraft/client/gui/layouts/GridLayout;
|
|
||||||
|
|
||||||
# hacky stuff
|
|
||||||
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
|
||||||
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
|
||||||
accessible field net/minecraft/client/gui/components/AbstractSelectionList scrollAmount D # Hack to bypass vanilla's setScrollAmount's clamp
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
accessWidener v1 named
|
|
||||||
|
|
||||||
# used when determining where to save files to
|
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/nio/file/Path;
|
|
||||||
# used to help determine what folder a clientLevel is
|
|
||||||
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
|
||||||
|
|
||||||
# used when rendering
|
|
||||||
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F
|
|
||||||
accessible field net/minecraft/client/Minecraft deltaTracker Lnet/minecraft/client/DeltaTracker$Timer;
|
|
||||||
|
|
||||||
|
|
||||||
# used for grabbing vanilla rendered chunks
|
|
||||||
accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
|
|
||||||
|
|
||||||
# world generation
|
|
||||||
# accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
|
||||||
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
|
||||||
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
|
||||||
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
|
||||||
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
|
||||||
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
|
||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
|
||||||
|
|
||||||
# lod generation from save file
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage regionCache Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
|
||||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/nio/file/Path;
|
|
||||||
|
|
||||||
# grabbing textures
|
|
||||||
accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture
|
|
||||||
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameX (I)I
|
|
||||||
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameY (I)I
|
|
||||||
accessible field net/minecraft/client/renderer/texture/SpriteContents animatedTexture Lnet/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture;
|
|
||||||
accessible field net/minecraft/client/renderer/texture/SpriteContents originalImage Lcom/mojang/blaze3d/platform/NativeImage;
|
|
||||||
|
|
||||||
# UI stuff
|
|
||||||
accessible field net/minecraft/client/gui/components/AbstractButton SPRITES Lnet/minecraft/client/gui/components/WidgetSprites;
|
|
||||||
# Handles inserting the config button
|
|
||||||
accessible field net/minecraft/client/gui/layouts/HeaderAndFooterLayout headerFrame Lnet/minecraft/client/gui/layouts/FrameLayout;
|
|
||||||
accessible field net/minecraft/client/gui/layouts/FrameLayout children Ljava/util/List;
|
|
||||||
accessible class net/minecraft/client/gui/layouts/FrameLayout$ChildContainer
|
|
||||||
accessible field net/minecraft/client/gui/layouts/LinearLayout wrapped Lnet/minecraft/client/gui/layouts/GridLayout;
|
|
||||||
|
|
||||||
# hacky stuff
|
|
||||||
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
|
||||||
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
|
||||||
|
|
||||||
|
|
||||||
+1
-1
Submodule coreSubProjects updated: a588070ce1...7cd1a37914
+7
-12
@@ -1,26 +1,21 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "fabric-loom" version "1.10-SNAPSHOT"
|
id "fabric-loom" version "1.6-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
|
|
||||||
|
// Custom logging
|
||||||
|
log4jConfigs.from(file("log4j-dev.xml"))
|
||||||
|
|
||||||
// "runs" isn't required, but when we do need it then it can be useful
|
// "runs" isn't required, but when we do need it then it can be useful
|
||||||
runs {
|
runs {
|
||||||
client {
|
client {
|
||||||
client()
|
client()
|
||||||
setConfigName("Fabric Client")
|
setConfigName("Fabric Client")
|
||||||
ideConfigGenerated(true) // When true a run configuration file will be generated for IDE's. By default only set to true for the root project.
|
ideConfigGenerated(true)
|
||||||
runDir("../run/client")
|
runDir("../run/client")
|
||||||
vmArgs(
|
vmArgs("-Dio.netty.leakDetection.level=advanced")
|
||||||
// https://github.com/FabricMC/fabric-loom/issues/915#issuecomment-1609154390
|
|
||||||
"-Dminecraft.api.auth.host=https://nope.invalid",
|
|
||||||
"-Dminecraft.api.account.host=https://nope.invalid",
|
|
||||||
"-Dminecraft.api.session.host=https://nope.invalid",
|
|
||||||
"-Dminecraft.api.services.host=https://nope.invalid",
|
|
||||||
// https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
|
|
||||||
"-Dio.netty.leakDetection.level=advanced"
|
|
||||||
)
|
|
||||||
programArgs("--username", "Dev")
|
programArgs("--username", "Dev")
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
@@ -165,4 +160,4 @@ sourcesJar {
|
|||||||
def commonSources = project(":common").sourcesJar
|
def commonSources = project(":common").sourcesJar
|
||||||
dependsOn commonSources
|
dependsOn commonSources
|
||||||
from commonSources.archiveFile.map { zipTree(it) }
|
from commonSources.archiveFile.map { zipTree(it) }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration name="Dev" monitorInterval="10">
|
||||||
|
<Loggers>
|
||||||
|
<Logger name="com.seibel.distanthorizons.core.network" level="trace" additivity="false">
|
||||||
|
<AppenderRef ref="DebugFile" level="${sys:fabric.log.debug.level:-debug}" />
|
||||||
|
<AppenderRef ref="SysOut" />
|
||||||
|
<AppenderRef ref="LatestFile" level="${sys:fabric.log.level:-info}" />
|
||||||
|
<AppenderRef ref="ServerGuiConsole" />
|
||||||
|
</Logger>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,7 +33,6 @@ 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;
|
||||||
@@ -53,14 +52,13 @@ import net.minecraft.client.gui.screens.TitleScreen;
|
|||||||
import com.seibel.distanthorizons.common.CommonPacketPayload;
|
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.NetworkMessage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
#endif
|
#endif
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.AbstractExecutorService;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
@@ -83,7 +81,6 @@ 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
|
||||||
@@ -129,7 +126,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
if (MC.clientConnectedToDedicatedServer())
|
if (MC.clientConnectedToDedicatedServer())
|
||||||
{
|
{
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
||||||
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
|
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, level, wrappedLevel), wrappedLevel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -145,7 +142,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
// if the getChunk() takes longer than expected
|
||||||
// (which can be caused by certain mods)
|
// (which can be caused by certain mods)
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
executor.execute(() ->
|
executor.execute(() ->
|
||||||
@@ -157,7 +154,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||||
new ChunkWrapper(chunk, wrappedLevel),
|
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||||
wrappedLevel
|
wrappedLevel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -185,7 +182,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
// if the getChunk() takes longer than expected
|
||||||
// (which can be caused by certain mods)
|
// (which can be caused by certain mods)
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
executor.execute(() ->
|
executor.execute(() ->
|
||||||
@@ -197,7 +194,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||||
new ChunkWrapper(chunk, wrappedLevel),
|
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||||
wrappedLevel
|
wrappedLevel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -228,14 +225,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//LOGGER.info("\n\n" +
|
|
||||||
// "Level Render\n" +
|
|
||||||
// "Mc MVM: \n" + modelViewMatrix.toString() + "\n" +
|
|
||||||
// "Mc Proj: \n" + projectionMatrix.toString()
|
|
||||||
//);
|
|
||||||
|
|
||||||
|
|
||||||
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
@@ -247,67 +236,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// TODO add to forge and neo
|
|
||||||
WorldRenderEvents.AFTER_ENTITIES.register((renderContext) ->
|
|
||||||
{
|
|
||||||
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
|
||||||
|
|
||||||
Mat4f modelViewMatrix;
|
|
||||||
#if MC_VER < MC_1_20_6
|
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
|
||||||
#else
|
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this.clientApi.renderFadeOpaque(
|
|
||||||
modelViewMatrix,
|
|
||||||
projectionMatrix,
|
|
||||||
#if MC_VER < MC_1_21_1
|
|
||||||
renderContext.tickDelta(),
|
|
||||||
#else
|
|
||||||
renderContext.tickCounter().getGameTimeDeltaTicks(),
|
|
||||||
#endif
|
|
||||||
ClientLevelWrapper.getWrapper(renderContext.world())
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO add to forge and neo
|
|
||||||
WorldRenderEvents.AFTER_TRANSLUCENT.register((renderContext) ->
|
|
||||||
{
|
|
||||||
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
|
||||||
|
|
||||||
Mat4f modelViewMatrix;
|
|
||||||
#if MC_VER < MC_1_20_6
|
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
|
||||||
#else
|
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
// rendered in MixinLevelRenderer
|
|
||||||
#else
|
|
||||||
ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(renderContext.world()),
|
|
||||||
ClientApi.RENDER_STATE.mcModelViewMatrix,
|
|
||||||
ClientApi.RENDER_STATE.mcProjectionMatrix,
|
|
||||||
ClientApi.RENDER_STATE.frameTime
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this.clientApi.renderFade(
|
|
||||||
modelViewMatrix,
|
|
||||||
projectionMatrix,
|
|
||||||
#if MC_VER < MC_1_21_1
|
|
||||||
renderContext.tickDelta(),
|
|
||||||
#else
|
|
||||||
renderContext.tickCounter().getGameTimeDeltaTicks(),
|
|
||||||
#endif
|
|
||||||
ClientLevelWrapper.getWrapper(renderContext.world())
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Debug keyboard event
|
// Debug keyboard event
|
||||||
// FIXME: Use better hooks so it doesn't trigger key press events in text boxes
|
// FIXME: Use better hooks so it doesn't trigger key press events in text boxes
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(client ->
|
ClientTickEvents.END_CLIENT_TICK.register(client ->
|
||||||
@@ -325,6 +253,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
//==================//
|
//==================//
|
||||||
|
|
||||||
#if MC_VER >= MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
|
PayloadTypeRegistry.playC2S().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
|
||||||
PayloadTypeRegistry.playS2C().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
|
PayloadTypeRegistry.playS2C().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
|
||||||
ClientPlayNetworking.registerGlobalReceiver(CommonPacketPayload.TYPE, (payload, context) ->
|
ClientPlayNetworking.registerGlobalReceiver(CommonPacketPayload.TYPE, (payload, context) ->
|
||||||
{
|
{
|
||||||
@@ -337,7 +266,9 @@ 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) ->
|
||||||
{
|
{
|
||||||
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
|
// Forge packet ID
|
||||||
|
buffer.readByte();
|
||||||
|
NetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
|
||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.pluginMessageReceived(message);
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
@@ -382,4 +313,4 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
this.previouslyPressKeyCodes = currentKeyDown;
|
this.previouslyPressKeyCodes = currentKeyDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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 James Seibel
|
* Copyright (C) 2020-2023 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,7 +20,6 @@
|
|||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
|
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||||
@@ -41,7 +40,6 @@ import net.minecraft.commands.CommandSourceStack;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
@@ -91,13 +89,16 @@ 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 for versions 0.5 and less in order to use the Fabric rendering API
|
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
||||||
if (!modChecker.isModLoaded("indium") && SodiumAccessor.isSodiumV5OrLess)
|
if (!modChecker.isModLoaded("indium"))
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
TinyFileDialogs.tinyfd_messageBox(ModInfo.READABLE_NAME, indiumMissingMessage, "ok", "error", false);
|
if (!GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
JOptionPane.showMessageDialog(null, indiumMissingMessage, ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
||||||
@@ -118,12 +119,9 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
@Override
|
@Override
|
||||||
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
||||||
{
|
{
|
||||||
CommandRegistrationCallback.EVENT.register(
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess #if MC_VER >= MC_1_19_2 , environment #endif ) -> {
|
||||||
(dispatcher, registryAccess #if MC_VER >= MC_1_19_2 , environment #endif ) ->
|
eventHandler.accept(dispatcher);
|
||||||
{
|
});
|
||||||
eventHandler.accept(dispatcher);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -141,7 +139,7 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.runDelayedSetup();
|
SingletonInjector.INSTANCE.runDelayedSetup();
|
||||||
|
|
||||||
if (!Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get() && SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
if (Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get() && SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
||||||
{
|
{
|
||||||
ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).setRenderCustomFog(false); // Remove BCLib's fog
|
ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).setRenderCustomFog(false); // Remove BCLib's fog
|
||||||
}
|
}
|
||||||
@@ -159,4 +157,4 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user