Compare commits

..

87 Commits

Author SHA1 Message Date
James Seibel d09ddf57d3 remove dev from version number 2025-07-19 14:57:19 -05:00
James Seibel 486edac1d8 replace 1.21.7 with 1.21.8 in gitlab CI 2025-07-19 14:56:32 -05:00
James Seibel 3b3731a137 Replace 1.21.7 support with 1.21.8 2025-07-19 13:29:29 -05:00
s809 563ec70154 Load level on player add if missing 2025-07-19 19:05:59 +05:00
James Seibel 175f5ed6d6 Improve logging for initial DH startup 2025-07-16 07:28:15 -05:00
James Seibel 1e63607233 Fix AfterDhInitEvent not firing on Neo
Fixes some Iris shader compile issues
2025-07-16 07:18:23 -05:00
James Seibel 4dd8be23fa Merge !81 (forge AfterInit API Event not firing on clients) 2025-07-16 06:56:38 -05:00
James Seibel 7fac5b4c6e Remove chunky incompatibility
I'm still a bit annoyed that problems can arise, but if people are able to configure DH/Chunky to work well together, I won't stop them from running together.

Note that a warning will be printed to the chat/log, if chunky is detected.
2025-07-15 07:49:44 -05:00
James Seibel f2ec1ecf3f Update all neoforge references to latest
Hopefully will fix some shader issues #1087
2025-07-15 07:41:19 -05:00
James Seibel 2674e6b2e9 up the version number 2.3.3 -> 2.3.4 2025-07-12 09:35:52 -05:00
James Seibel bcbe3f0fb7 remove dev from the version number 2025-07-12 09:35:24 -05:00
James Seibel f85108ed11 Fix API config renderingEnabled() changing the user value
Fixes #1083
2025-07-12 08:16:40 -05:00
James Seibel 2bc5169ce5 Closes #1084 (AfterDhInitEvent firing before DH config setup) 2025-07-12 08:02:08 -05:00
James Seibel 1edd809708 Fix config UI not showing DH version for MC 1.21.6+ 2025-07-11 07:29:46 -05:00
James Seibel 475111b38b full data DTO close data source if corrupted 2025-07-10 22:25:41 -05:00
James Seibel b44a967e56 Fix monoliths when connected to a server 2025-07-10 07:29:52 -05:00
James Seibel acea685e75 fix some neo running issues with dependency ranges 2025-07-09 07:28:54 -05:00
James Seibel 20f15a6b39 Fixes !1078 (lag due to beacon updating on server) 2025-07-09 07:28:37 -05:00
James Seibel debf52418c Potentially fix an issue with AMD GPU shader compiling
Fix from Cortex and the Canvas mod
2025-07-08 07:22:41 -05:00
James Seibel cf71491381 Disable vanilla fading when shaders are active 2025-07-07 07:49:46 -05:00
James Seibel 0a4a8466cf Add comments to MixinFogRenderer 2025-07-04 09:21:02 -05:00
James Seibel 31fac60d34 Increment default dev MC version 1.21.6 -> 1.21.7 2025-07-04 09:12:36 -05:00
James Seibel c335020c2f Fix sodium fog for MC 1.21.7 2025-07-04 09:05:42 -05:00
James Seibel 4db4f2fbc6 Fix Neoforge 1.21.7 packet registration changes 2025-07-04 09:05:23 -05:00
James Seibel f9f4a208e7 Fix 1.21.7 compiling 2025-07-03 07:52:17 -05:00
James Seibel b5fa5936b3 Add 1.21.7 version (may not compile) 2025-07-02 07:52:07 -05:00
James Seibel 6ceabe7895 Force vanilla fading and overdraw prevention with Sodium 2025-07-02 07:42:55 -05:00
s809 ec3d8afbfc Disable enableAdaptiveTransferSpeed bby default 2025-07-01 22:03:16 +05:00
James Seibel e9a0c6d097 Fix config UI changes not always saving 2025-07-01 07:45:31 -05:00
James Seibel 0238568370 Fix neo config crashing and fix some warnings 2025-07-01 07:22:43 -05:00
James Seibel 74be00e025 Fix neoforge vanilla fade for MC 1.21.6 2025-07-01 07:11:08 -05:00
James Seibel c10af6dd04 fix build-all scripts 2025-06-30 07:46:18 -05:00
James Seibel 85ee5ac833 fix forge compiling 2025-06-30 07:46:12 -05:00
James Seibel 21877d67a5 Add neo version dependency and roll back 6.20 -> 6.19
6.20 had some issue preventing running in dev
2025-06-30 07:38:37 -05:00
James Seibel ae33a79d6e update to Neo 21.6.20 2025-06-30 06:56:08 -05:00
James Seibel 9204b357d8 comment out Z_STD compression
comment out Z_STD compression
2025-06-30 06:55:47 -05:00
James Seibel 78b1b74036 Mark Chunky as incompatible
Done as a test
2025-06-28 13:58:12 -05:00
James Seibel 864c5b5f86 Re-Add Z_STD compression for testing 2025-06-28 11:37:17 -05:00
James Seibel b271c8e119 Fix MinecraftGLWrapper.getActiveTexture() 2025-06-28 10:10:03 -05:00
James Seibel 79bdae5b8b Fix auto-updater for MC 1.21.6 2025-06-28 09:56:51 -05:00
James Seibel d5dc9f6b79 Fix multiplayer null pointer 2025-06-28 09:22:32 -05:00
James Seibel a50f13caa0 Mostly fix Iris transparent rendering for 1.21.6 2025-06-28 08:37:18 -05:00
James Seibel 75b3649a97 Fix world-gen progress not showing in release builds 2025-06-27 07:29:43 -05:00
James Seibel 69adb54b91 disable blending data parsing in chunk loading for MC 1.21.6
There appears to be a parsing issue and since it doesn't appear to change how the chunks load I'm going to ignore it for now
2025-06-27 07:18:01 -05:00
James Seibel 458c1ae7e0 re-add LevelTicks mixin for MC 1.21.4+ 2025-06-27 07:10:12 -05:00
James Seibel a647551d26 Move RenderState to core 2025-06-26 07:50:59 -05:00
James Seibel 3a45bdd2a2 remove broken var in NeoClientProxy 2025-06-26 07:29:51 -05:00
James Seibel 4806cd2445 Move RenderState object into ClientApi 2025-06-26 07:21:33 -05:00
James Seibel af7f90f128 add 1.21.6 to the CI script 2025-06-26 07:10:39 -05:00
James Seibel f72ad60f58 Fix old MC version compiling 2025-06-26 07:10:32 -05:00
James Seibel 6015afbf4c Fix neo rendering and fabric shader rendering 2025-06-25 07:48:04 -05:00
James Seibel 0369ae63f3 fix neo fox mixin 2025-06-21 09:22:39 -05:00
James Seibel 278d5063fb up neoforge version 2025-06-21 09:21:47 -05:00
James Seibel a64e72034e Fix UI text rendering 2025-06-21 09:21:40 -05:00
James Seibel fcdb56660c fix fog renderer again 2025-06-20 07:39:50 -05:00
James Seibel 0c26261cd5 Update gradle.properties 2025-06-19 07:32:43 -05:00
James Seibel b50525fff9 Update ServerPlayerWrapper.java 2025-06-19 07:32:35 -05:00
James Seibel 92e403823b fix gui button rendering 2025-06-19 07:32:21 -05:00
James Seibel e02f56f4ef Update VersionConstants.java 2025-06-19 06:52:32 -05:00
James Seibel aa4681e044 update MC GL Wrapper 2025-06-18 17:36:46 -05:00
James Seibel 1c9130c3f1 update McObjectConverter for matricies 2025-06-18 17:36:22 -05:00
James Seibel c3597cd843 update fog mixin 2025-06-18 17:36:02 -05:00
James Seibel d4a52ac5a3 update version properties 2025-06-18 17:34:14 -05:00
James Seibel 1b9d14e7b4 Disable cave culling for medium quality and higher 2025-06-17 07:15:36 -05:00
James Seibel 0ea27b676e Optimize ClientLevelWrapper.GetWrapper()
Should speed up initial LOD loading a bit
2025-06-17 07:15:15 -05:00
James Seibel cd73608b07 Reduce stuttering with fast world gen 2025-06-14 16:17:33 -05:00
James Seibel 03fc22f611 Reduce allocations in getBlockColor by using a cached method reference
Currently there is a large number of allocations of `java.lang.invoke.invokers$Holder:linkToTargetMethod` -- this prevents that
2025-06-11 07:09:40 -05:00
James Seibel cc251e46b0 Add Api Before/After Text Create events 2025-06-09 07:50:25 -05:00
James Seibel 7aa0bfefec Fix hash collisions in FullDataPointIdMap 2025-06-06 07:43:44 -05:00
James Seibel 9bdad5e4f1 Fix 1.21.5 compiling 2025-06-06 07:36:00 -05:00
James Seibel baebb7323d Close #776 (fix Polytone client biome colors) 2025-06-05 07:53:23 -05:00
James Seibel 8a3175f345 Mark Polytone as incompatible 2025-06-04 07:49:15 -05:00
James Seibel dc58efb301 Handle nulls in ChunkLoader
Should fix WorldPainter worlds
2025-06-04 07:28:51 -05:00
James Seibel c9ac4b2ada Fix GLMC.glDeleteTextures() calls 2025-06-04 07:07:51 -05:00
s809 6e1ec476ed Check LOD timestamps in file handler threads 2025-06-03 23:41:51 +05:00
James Seibel d1aa5a524b Remove line ending from editorconfig
Done to fix some issues with some devs on linux
2025-05-17 11:47:06 -05:00
James Seibel 5c661a3a76 yaml indent 2 -> 4
for consistency
2025-05-17 11:25:37 -05:00
s809 d29e9085a1 Fix getWorldFolderName crash 2025-05-03 13:44:54 +05:00
Ran d392de3c0d Update Forgix
fixes a critical bug
2025-05-03 17:40:58 +10:00
Ran 7209193f8f Fix gradle versioning 2025-05-03 11:21:17 +10:00
s809 ed4f644a3f Bump protocol version 2025-05-03 00:08:12 +05:00
Ran 34038684a7 Fix gradle versioning for core application 2025-05-02 12:45:18 +10:00
s809 6fe6694c82 Merge branch 'feature/adaptive-data-rate' 2025-04-27 21:57:47 +05:00
s809 8e52f1aca5 Merge branch 'refactor/remove-python-dependency' 2025-04-27 21:48:53 +05:00
s809 5ce3dda2d5 Clear up the comment a bit 2025-04-27 21:48:28 +05:00
s809 f4f81f4d7f Account for forge byte when encoding protocol version instead of shifting the entire packet on pre-1.20.6 2025-04-27 21:40:50 +05:00
s809 2ddeaf50eb test builds 2025-04-21 00:00:01 +05:00
62 changed files with 1434 additions and 576 deletions
+1 -2
View File
@@ -5,7 +5,6 @@ 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
@@ -688,7 +687,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 = 2 indent_size = 4
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
+2 -2
View File
@@ -35,13 +35,13 @@ 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"] - 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.8"]
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/* ./Merged/* . || true - 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:
+8 -49
View File
@@ -13,7 +13,7 @@ plugins {
id "com.github.johnrengelman.shadow" version '8.1.1' apply false id "com.github.johnrengelman.shadow" version '8.1.1' apply false
// Plugin to create merged jars // Plugin to create merged jars
id "io.github.pacifistmc.forgix" version "1.2.9" id "io.github.pacifistmc.forgix" version "1.3.4"
// 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"
@@ -67,43 +67,8 @@ project.gradle.ext.getProperties().each { prop ->
// Sets up manifold stuff // Sets up manifold stuff
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex) writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
// Sets up the version string (the name we use for our jar) // Sets up the version string (the name we use for our jar)
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm") rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
// Forgix settings (used for merging jars)
forgix {
String loaderHyphenSeparatedList = ((String)gradle.builds_for).replaceAll(",", "-");
group = "com.seibel.distanthorizons"
mergedJarName = "DistantHorizons-${loaderHyphenSeparatedList}-${rootProject.versionStr}.jar"
if (findProject(":forge"))
forge {
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
}
if (findProject(":neoforge"))
custom {
projectName = "neoforge"
jarLocation = "build/libs/DistantHorizons-neoforge-${rootProject.versionStr}.jar"
}
if (findProject(":fabric"))
fabric {
jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar"
}
if (findProject(":quilt"))
quilt {
jarLocation = "build/libs/DistantHorizons-quilt-${rootProject.versionStr}.jar"
}
removeDuplicate "com.seibel.distanthorizons"
}
class NativeTransformer implements Transformer { class NativeTransformer implements Transformer {
private final HashMap<String, String> replacements = new HashMap() private final HashMap<String, String> replacements = new HashMap()
@@ -280,7 +245,9 @@ subprojects { p ->
// Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12 // Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12
// 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
@@ -480,6 +447,8 @@ subprojects { p ->
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
@@ -560,8 +529,9 @@ allprojects { p ->
apply plugin: "java" apply plugin: "java"
apply plugin: "maven-publish" apply plugin: "maven-publish"
// Sets the name of the jar, the version will contain the name of the project if it isn't the root project
archivesBaseName = rootProject.mod_name archivesBaseName = rootProject.mod_name
version = project.name + "-" + rootProject.versionStr version = (project == rootProject ? "" : project.name + "-") + rootProject.versionStr
group = rootProject.maven_group group = rootProject.maven_group
// this is the text that appears at the top of the overview (home) page // this is the text that appears at the top of the overview (home) page
@@ -726,14 +696,3 @@ allprojects { p ->
withSourcesJar() withSourcesJar()
} }
} }
// Delete the merged folder when running clean
task cleanMergedJars() {
def mergedFolder = file("Merged")
if (mergedFolder.exists()) {
delete(mergedFolder)
}
}
// add cleanMergedJars to the end of the "clean" task
tasks["clean"].finalizedBy(cleanMergedJars)
+2 -2
View File
@@ -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 Merged/*.jar buildAllJars/ mv build/merged/*.jar buildAllJars/
done done
+6 -3
View File
@@ -15,12 +15,15 @@ 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
echo ==================== Building !version! ====================
echo ==================== Building !version! ====================
call .\gradlew.bat build -PmcVer="!version!" call .\gradlew.bat build -PmcVer="!version!"
echo ==================== Merging !version! ====================
echo ==================== Merging !version! ====================
call .\gradlew.bat mergeJars -PmcVer="!version!" call .\gradlew.bat mergeJars -PmcVer="!version!"
echo ==================== Moving jar ==================== echo ==================== Moving jar ====================
move Merged\*.jar buildAllJars\ move build\merged\*.jar buildAllJars\
) )
endlocal endlocal
@@ -66,7 +66,7 @@ public abstract class AbstractModInitializer
{ {
DependencySetup.createClientBindings(); DependencySetup.createClientBindings();
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client."); LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client, firing DhApiBeforeDhInitEvent...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
this.startup(); this.startup();
@@ -77,13 +77,12 @@ public abstract class AbstractModInitializer
this.initializeModCompat(); this.initializeModCompat();
LOGGER.info(ModInfo.READABLE_NAME + " client 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 logModIncompatibilityWarnings(); // needs to be called after config loading
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
this.subscribeClientStartedEvent(this::postInit); this.subscribeClientStartedEvent(this::postInit);
} }
@@ -91,7 +90,7 @@ public abstract class AbstractModInitializer
{ {
DependencySetup.createServerBindings(); DependencySetup.createServerBindings();
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server."); LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server, firing DhApiBeforeDhInitEvent event...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
this.startup(); this.startup();
@@ -106,8 +105,7 @@ public abstract class AbstractModInitializer
this.initializeModCompat(); this.initializeModCompat();
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized."); LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); }); this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); });
@@ -121,7 +119,7 @@ public abstract class AbstractModInitializer
this.checkForUpdates(); this.checkForUpdates();
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory()); LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory());
}); });
} }
@@ -183,9 +181,12 @@ public abstract class AbstractModInitializer
private void postInit() private void postInit()
{ {
LOGGER.info("Post-Initializing Mod"); LOGGER.info("Running Delayed setup...");
this.runDelayedSetup(); this.runDelayedSetup();
LOGGER.info("Mod Post-Initialized"); LOGGER.info("Delayed setup complete, firing DhApiAfterDhInitEvent event...");
// should be fired after all delayed setup so singletons and config can be accessed
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
} }
@@ -1,6 +1,7 @@
package com.seibel.distanthorizons.common; package com.seibel.distanthorizons.common;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger; import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent; import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent; import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
@@ -30,6 +31,16 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH); public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
#endif #endif
// "Forge byte" is an unused packet ID. We have our own system which works with all mod loaders,
// so we're just accounting for it by reading the protocol version as a byte instead of a short in Forge, to keep cross-loader compatibility
private final boolean forgeByteInProtocolVersion;
public AbstractPluginPacketSender() { this(false); }
public AbstractPluginPacketSender(boolean forgeByteInProtocolVersion)
{
this.forgeByteInProtocolVersion = forgeByteInProtocolVersion;
}
@Override @Override
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message) public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
@@ -41,7 +52,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
@Override @Override
public abstract void sendToServer(AbstractNetworkMessage message); public abstract void sendToServer(AbstractNetworkMessage message);
public static AbstractNetworkMessage decodeMessage(FriendlyByteBuf in) public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
{ {
AbstractNetworkMessage message = null; AbstractNetworkMessage message = null;
@@ -49,7 +60,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
{ {
in.markReaderIndex(); in.markReaderIndex();
int protocolVersion = in.readShort(); int protocolVersion = this.forgeByteInProtocolVersion ? in.readByte() : in.readShort();
if (protocolVersion != ModInfo.PROTOCOL_VERSION) if (protocolVersion != ModInfo.PROTOCOL_VERSION)
{ {
return new IncompatibleMessageInternalEvent(protocolVersion); return new IncompatibleMessageInternalEvent(protocolVersion);
@@ -82,11 +93,19 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
} }
} }
public static void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message) public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
{ {
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild // This is intentionally unhandled, because errors related to this are unlikely to appear in wild
Objects.requireNonNull(message); Objects.requireNonNull(message);
out.writeShort(ModInfo.PROTOCOL_VERSION);
if (this.forgeByteInProtocolVersion)
{
out.writeByte(ModInfo.PROTOCOL_VERSION);
}
else
{
out.writeShort(ModInfo.PROTOCOL_VERSION);
}
try try
{ {
@@ -2,7 +2,9 @@ package com.seibel.distanthorizons.common;
#if MC_VER >= MC_1_20_6 #if MC_VER >= MC_1_20_6
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
@@ -12,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
{ {
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE); public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
@NotNull @NotNull
@Override @Override
@@ -23,11 +26,11 @@ public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) impl
@NotNull @NotNull
@Override @Override
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in) public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
{ return new CommonPacketPayload(AbstractPluginPacketSender.decodeMessage(in)); } { return new CommonPacketPayload(PACKET_SENDER.decodeMessage(in)); }
@Override @Override
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload) public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
{ AbstractPluginPacketSender.encodeMessage(out, payload.message()); } { PACKET_SENDER.encodeMessage(out, payload.message()); }
} }
@@ -49,7 +49,9 @@ 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
#else org.joml.Matrix4f #endif #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc
#endif
mcMatrix) mcMatrix)
{ {
FloatBuffer buffer = FloatBuffer.allocate(16); FloatBuffer buffer = FloatBuffer.allocate(16);
@@ -63,7 +65,9 @@ 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
#else org.joml.Matrix4f #endif #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc
#endif
matrix, matrix,
FloatBuffer buffer) FloatBuffer buffer)
{ {
@@ -74,6 +74,10 @@ public class VersionConstants implements IVersionConstants
return "1.21.4"; return "1.21.4";
#elif MC_VER == MC_1_21_5 #elif MC_VER == MC_1_21_5
return "1.21.5"; return "1.21.5";
#elif MC_VER == MC_1_21_6
return "1.21.6";
#elif MC_VER == MC_1_21_8
return "1.21.8";
#else #else
ERROR MC version constant missing ERROR MC version constant missing
#endif #endif
@@ -47,6 +47,7 @@ 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
@@ -130,14 +131,6 @@ 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);
}
//=========// //=========//
@@ -286,64 +279,16 @@ 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();
boolean success; BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess);
#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
if (!success) if (!deserializeResult.success)
{ {
if (!brokenResourceLocationStrings.contains(resourceLocationString)) if (!brokenResourceLocationStrings.contains(resourceLocationString))
{ {
@@ -354,7 +299,7 @@ public class BiomeWrapper implements IBiomeWrapper
} }
foundWrapper = (BiomeWrapper) getBiomeWrapper(biome, levelWrapper); foundWrapper = (BiomeWrapper) getBiomeWrapper(deserializeResult.biome, levelWrapper);
return foundWrapper; return foundWrapper;
} }
catch (Exception e) catch (Exception e)
@@ -368,4 +313,82 @@ 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;
}
}
} }
@@ -91,7 +91,7 @@ public class ClientBlockStateColorCache
private static final RandomSource RANDOM = RandomSource.create(); private static final RandomSource RANDOM = RandomSource.create();
#endif #endif
private final IClientLevelWrapper levelWrapper; private final IClientLevelWrapper clientLevelWrapper;
private final BlockState blockState; private final BlockState blockState;
private final LevelReader level; private final LevelReader level;
@@ -174,7 +174,7 @@ public class ClientBlockStateColorCache
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel) public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
{ {
this.blockState = blockState; this.blockState = blockState;
this.levelWrapper = samplingLevel; this.clientLevelWrapper = samplingLevel;
this.level = (LevelReader) samplingLevel.getWrappedMcObject(); this.level = (LevelReader) samplingLevel.getWrappedMcObject();
this.resolveColors(); this.resolveColors();
} }
@@ -471,7 +471,7 @@ public class ClientBlockStateColorCache
try try
{ {
tintColor = Minecraft.getInstance().getBlockColors() tintColor = Minecraft.getInstance().getBlockColors()
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.levelWrapper), McObjectConverter.Convert(pos), this.tintIndex); .getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.clientLevelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
} }
catch (UnsupportedOperationException e) catch (UnsupportedOperationException e)
{ {
@@ -19,8 +19,10 @@
package com.seibel.distanthorizons.common.wrappers.block; package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
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.*;
@@ -29,6 +31,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -36,22 +39,64 @@ 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()}
* but {@link Nullable} is there just in case. #if MC_VER < MC_1_18_2
*/ public static final ConcurrentMap<String, Biome> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
@Nullable
#if MC_VER >= MC_1_18_2
public final Holder<Biome> biome;
#else #else
public final Biome biome; public static final ConcurrentMap<String, Holder<Biome>> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
#endif #endif
@NotNull
private final BiomeWrapper biomeWrapper;
//=============//
// 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();
if (biomeString == null
|| biomeString.isEmpty()
|| biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING))
{
// default to "plains" for empty/invalid biomes
biomeString = "minecraft:plains";
}
return colorResolver.getColor(unwrap(getClientBiome(biomeString)), blockPos.getX(), blockPos.getZ());
}
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
{
#if MC_VER >= MC_1_18_2
return biome.value();
#else
return biome;
#endif
}
/** /**
* Constructs the TintWithoutLevelOverrider, storing the provided Biome Holder for late-binding access.
*
* <p>Previously, this class might have immediately unwrapped the Holder like this:</p> * <p>Previously, this class might have immediately unwrapped the Holder like this:</p>
* <pre>{@code * <pre>{@code
* // Inside constructor (OLD WAY - PROBLEMATIC): * // Inside constructor (OLD WAY - PROBLEMATIC):
@@ -85,41 +130,52 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
* whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome} * whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome}
* instance associated with the holder at that time.</p> * instance associated with the holder at that time.</p>
*/ */
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper) private static #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif getClientBiome(String biomeResourceString)
{ {
#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome = biomeWrapper.biome; // cache the client biomes so we don't have to re-parse the resource location every time
if (biome == null) // We are looking at the empty biome wrapper return BIOME_BY_RESOURCE_STRING.compute(biomeResourceString,
{ (resourceString, existingBiome) ->
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper()); {
if (plainsBiomeWrapper != null) if (existingBiome != null)
{ {
biome = plainsBiomeWrapper.biome; return existingBiome;
} }
}
ClientLevel clientLevel = Minecraft.getInstance().level;
this.biome = biome; if (clientLevel == null)
} {
// shouldn't happen, but just in case
throw new IllegalStateException("Attempted to get client biome when no client level was loaded.");
}
@Override
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver) BiomeWrapper.BiomeDeserializeResult result;
{ try
if (this.biome == null) {
{ result = BiomeWrapper.deserializeBiome(resourceString, clientLevel.registryAccess());
// hopefully unneeded debug color }
return ColorUtil.CYAN; catch (Exception e)
} {
return colorResolver.getColor(unwrap(biome), blockPos.getX(), blockPos.getZ()); LOGGER.warn("Unable to deserialize client biome ["+resourceString+"], using fallback...");
}
try
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome) {
{ result = BiomeWrapper.deserializeBiome("minecraft:plains", clientLevel.registryAccess());
#if MC_VER >= MC_1_18_2 }
return biome.value(); catch (IOException ex)
#else {
return biome; // should never happen, if it does this log will explode, but just in case
#endif LOGGER.error("Unable to deserialize fallback client biome [minecraft:plains], returning NULL.");
return null;
}
}
if (result.success)
{
existingBiome = result.biome;
}
return existingBiome;
});
} }
@@ -56,20 +56,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
{ {
@@ -178,7 +178,7 @@ public class ClassicConfigGUI
} }
else else
{ {
((ConfigEntry) info).uiSetWithoutSaving(value.intValue()); ((ConfigEntry) info).uiSetWithoutSaving(value != null ? value.intValue() : 0);
} }
} }
@@ -249,7 +249,7 @@ public class ClassicConfigGUI
protected void init() protected void init()
{ {
super.init(); super.init();
if (!reload) if (!this.reload)
{ {
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile(); ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
} }
@@ -276,7 +276,7 @@ public class ClassicConfigGUI
(buttonWidget) -> { (buttonWidget) -> {
ChangelogScreen changelogScreen = new ChangelogScreen(this); ChangelogScreen changelogScreen = new ChangelogScreen(this);
if (changelogScreen.usable) if (changelogScreen.usable)
Objects.requireNonNull(minecraft).setScreen(changelogScreen); Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
else else
LOGGER.warn("Changelog was not able to open"); LOGGER.warn("Changelog was not able to open");
}, },
@@ -286,17 +286,17 @@ public class ClassicConfigGUI
} }
addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"), this.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(minecraft).setScreen(parent); Objects.requireNonNull(this.minecraft).setScreen(this.parent);
})); }));
doneButton = addBtn(MakeBtn(Translatable("distanthorizons.general.done"), this.width / 2 + 4, this.height - 28, 150, 20, (button) -> { this.doneButton = this.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(minecraft).setScreen(parent); Objects.requireNonNull(this.minecraft).setScreen(this.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,8 +312,8 @@ public class ClassicConfigGUI
{ {
try try
{ {
if (info.getCategory().matches(category) && info.getAppearance().showInGui) if (info.getCategory().matches(this.category) && info.getAppearance().showInGui)
addMenuItem(info); this.addMenuItem(info);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -336,7 +336,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(translationPrefix + info.getNameWCategory()); Component name = Translatable(this.translationPrefix + info.getNameWCategory());
if (ConfigEntry.class.isAssignableFrom(info.getClass())) if (ConfigEntry.class.isAssignableFrom(info.getClass()))
@@ -345,7 +345,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(minecraft).setScreen(this); Objects.requireNonNull(this.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 +359,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(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString())); widget.setValue(value -> Translatable(this.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(font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, null); EditBox widget = new EditBox(this.font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, Translatable(""));
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, doneButton); Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, this.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 +379,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(minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination())); Objects.requireNonNull(this.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;
@@ -420,16 +420,34 @@ public class ClassicConfigGUI
#endif #endif
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title // 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
DhDrawString(matrices, font, TextOrLiteral(ModInfo.VERSION), 2, height - 10, 0xAAAAAA); this.DhDrawString(matrices, this.font, TextOrLiteral(ModInfo.VERSION), 2, this.height - 10,
#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);
}
} }
@@ -659,8 +677,10 @@ 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, text, 12, y + 5, 0xFFFFFF); matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFFFF);
#endif #endif
} }
@@ -52,6 +52,27 @@ 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)
{ {
@@ -61,17 +82,20 @@ 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.renderComponentTooltip(font, comp, x, y); guiStack.setComponentTooltipForNextFrame(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.renderTooltip(font, text, x, y); guiStack.setTooltipForNextFrame(font, text, x, y);
} }
#endif #endif
} }
@@ -39,9 +39,13 @@ import net.minecraft.client.renderer.GameRenderer;
#elif MC_VER < MC_1_20_2 #elif MC_VER < MC_1_20_2
import net.minecraft.client.gui.components.ImageButton; import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.gui.GuiGraphics; 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.RenderType;
import net.minecraft.client.renderer.RenderPipelines;
#endif #endif
/** /**
@@ -172,9 +176,15 @@ public class TexturedButtonWidget extends Button
{ {
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
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 #else
matrices.blitSprite( matrices.blitSprite(
RenderType::guiTextured, RenderPipelines.GUI_TEXTURED,
SPRITES.get(this.active, this.isHoveredOrFocused()), SPRITES.get(this.active, this.isHoveredOrFocused()),
this.getX(), this.getY(), this.getX(), this.getY(),
this.getWidth(), this.getHeight()); this.getWidth(), this.getHeight());
@@ -196,7 +206,7 @@ public class TexturedButtonWidget extends Button
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
matrices.blit(this.textureResourceLocation, 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);
#else #elif MC_VER < MC_1_21_6
matrices.blit( matrices.blit(
RenderType::guiTextured, RenderType::guiTextured,
this.textureResourceLocation, this.textureResourceLocation,
@@ -204,6 +214,14 @@ public class TexturedButtonWidget extends Button
this.u, this.v + (this.hoveredVOffset * i), this.u, this.v + (this.hoveredVOffset * i),
this.width, this.height, this.width, this.height,
this.textureWidth, this.textureHeight); 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
} }
@@ -169,8 +169,10 @@ 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
#else #elif MC_VER < MC_1_21_6
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
#else
// background blur is already being rendered, rendering again causes the game to crash
#endif #endif
// TODO: add the tooltips for the buttons // TODO: add the tooltips for the buttons
@@ -178,16 +180,30 @@ public class UpdateModScreen extends DhScreen
// TODO: Add tooltips // TODO: Add tooltips
// Render the text's // Render the text's
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF); this.DhDrawCenteredString(matrices, this.font,
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"),
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer), this.width / 2, this.height / 2 - 35,
this.width / 2, this.height / 2 - 20, 0x52FD52); #if MC_VER < MC_1_21_6
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(minecraft).setScreen(this.parent); // Goto the parent screen Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Go to the parent screen
} }
} }
@@ -21,7 +21,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
#elif MC_VER == MC_1_21_5 #elif MC_VER >= MC_1_21_5
import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.opengl.GlStateManager;
#endif #endif
@@ -233,7 +233,7 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
GlStateManager._activeTexture(textureId); GlStateManager._activeTexture(textureId);
} }
@Override @Override
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); } public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); }
/** /**
* Always binds to {@link GL32#GL_TEXTURE_2D} * Always binds to {@link GL32#GL_TEXTURE_2D}
@@ -33,9 +33,12 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.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
@@ -43,8 +46,6 @@ import org.joml.Matrix4f;
import org.joml.Vector3f; import org.joml.Vector3f;
#else #else
#endif #endif
#if MC_VER >= MC_1_20_2
#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;
@@ -73,7 +74,6 @@ import org.joml.Vector4f;
#if MC_VER >= MC_1_21_5 #if MC_VER >= MC_1_21_5
import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.opengl.GlTexture;
import org.lwjgl.opengl.GL32;
#endif #endif
/** /**
@@ -109,6 +109,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
public boolean colorTextureCastFailLogged = false; public boolean colorTextureCastFailLogged = false;
public boolean depthTextureCastFailLogged = false; public boolean depthTextureCastFailLogged = false;
#if MC_VER < MC_1_21_6
#else
private static FogRenderer mcFogRenderer = null;
#endif
//=========// //=========//
@@ -126,11 +131,22 @@ 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()
{ {
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null if (MC.player == 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
@@ -163,7 +179,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
Math.max(0f, Math.min(colorValues[2], 1f)), // b Math.max(0f, Math.min(colorValues[2], 1f)), // b
Math.max(0f, Math.min(colorValues[3], 1f)) // a Math.max(0f, Math.min(colorValues[3], 1f)) // a
); );
#else #elif MC_VER < MC_1_21_6
Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks)); Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
return new Color( return new Color(
Math.max(0f, Math.min(colorValues.x, 1f)), // r Math.max(0f, Math.min(colorValues.x, 1f)), // r
@@ -171,6 +187,31 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
Math.max(0f, Math.min(colorValues.z, 1f)), // b Math.max(0f, Math.min(colorValues.z, 1f)), // b
Math.max(0f, Math.min(colorValues.w, 1f)) // a 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
} }
// getSpecialFogColor() is the same as getFogColor() // getSpecialFogColor() is the same as getFogColor()
@@ -54,8 +54,10 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
{ {
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
level = this.getServerPlayer().getLevel(); level = this.getServerPlayer().getLevel();
#else #elif MC_VER < MC_1_21_6
level = this.getServerPlayer().serverLevel(); level = this.getServerPlayer().serverLevel();
#else
level = this.getServerPlayer().level();
#endif #endif
} }
@@ -70,7 +72,14 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
} }
@Override @Override
public int getViewDistance() { return this.getServerPlayer().server.getPlayerList().getViewDistance(); } public int getViewDistance()
{
#if MC_VER < MC_1_21_6
return this.getServerPlayer().server.getPlayerList().getViewDistance();
#else
return this.getServerPlayer().getServer().getPlayerList().getViewDistance();
#endif
}
@Override @Override
public SocketAddress getRemoteAddress() public SocketAddress getRemoteAddress()
@@ -37,6 +37,7 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; 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;
@@ -66,6 +67,10 @@ 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
@@ -105,14 +110,26 @@ public class ClientLevelWrapper implements IClientLevelWrapper
} }
} }
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, levelRef) ->
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
if (levelRef != null)
{ {
if (levelRef != null) ClientLevelWrapper levelWrapper = levelRef.get();
if (levelWrapper != null)
{ {
ClientLevelWrapper oldLevelWrapper = levelRef.get(); return levelWrapper;
}
}
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, newLevelRef) ->
{
if (newLevelRef != null)
{
ClientLevelWrapper oldLevelWrapper = newLevelRef.get();
if (oldLevelWrapper != null) if (oldLevelWrapper != null)
{ {
return levelRef; return newLevelRef;
} }
} }
@@ -162,10 +179,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
{ {
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent( ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
((BlockStateWrapper) blockWrapper).blockState, ((BlockStateWrapper) blockWrapper).blockState,
(block) -> new ClientBlockStateColorCache(block, this)); this.cachedBlockColorCacheFunction);
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()
@@ -42,6 +42,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkSource; import net.minecraft.world.level.chunk.ChunkSource;
@@ -115,12 +116,12 @@ public class ServerLevelWrapper implements IServerLevelWrapper
@Override @Override
public String getWorldFolderName() public String getWorldFolderName()
{ {
// TODO can we just replace this with getMcSaveFolder()? Why are we using the screenshot file anyway? // Need specifically overworld since it's the only dimension that is stored in a server root folder
// this can have issues when the screenshot file is null/missing
#if MC_VER >= MC_1_17_1 #if MC_VER >= MC_1_21_3
return this.level.getServer().getWorldScreenshotFile().get().getParent().getFileName().toString(); return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParent().getFileName().toString();
#else // <= 1.16.5 #else // <= 1.21.3
return this.level.getServer().getWorldScreenshotFile().getParentFile().getName(); return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParentFile().getName();
#endif #endif
} }
@@ -162,7 +162,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;
#else #elif MC_VER < MC_1_21_6
BlendingData blendingData = readBlendingData(tagLevel); BlendingData blendingData = readBlendingData(tagLevel);
#if MC_VER < MC_1_19_2 #if MC_VER < MC_1_19_2
@@ -172,27 +172,39 @@ 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 = tagGetLong(tagLevel, "InhabitedTime");
//================== Read params for making the LevelChunk ================== //================== Read params for making the LevelChunk ==================
UpgradeData upgradeData; UpgradeData upgradeData = UpgradeData.EMPTY;
#if MC_VER < MC_1_17_1 // commented out 2025-06-04 as a test to see if the upgrade data
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10) // is actually necessary for DH or if it can be ignored
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA)) // (if it can't be ignored we'll need to handle null responses from tagGetCompoundTag())
: UpgradeData.EMPTY; //
#elif MC_VER < MC_1_21_5 //#if MC_VER < MC_1_17_1
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10) //upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level) // ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA))
: UpgradeData.EMPTY; // : UpgradeData.EMPTY;
#else //#elif MC_VER < MC_1_21_5
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA) //upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level) // ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
: UpgradeData.EMPTY; // : UpgradeData.EMPTY;
#endif //#else
//upgradeData = tagLevel.contains(TAG_UPGRADE_DATA)
// ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
// : UpgradeData.EMPTY;
//#endif
boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn"); boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn");
@@ -242,7 +254,7 @@ public class ChunkLoader
// 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)
@@ -285,48 +297,54 @@ public class ChunkLoader
for (int j = 0; j < tagSections.size(); ++j) for (int j = 0; j < tagSections.size(); ++j)
{ {
CompoundTag tagSection = tagGetCompoundTag(tagSections, j); CompoundTag tagSection = tagGetCompoundTag(tagSections, j);
int sectionYPos = tagGetByte(tagSection, "Y"); if (tagSection == null)
{
continue;
}
final int sectionYPos = tagGetByte(tagSection, "Y");
#if MC_VER < MC_1_18_2 #if MC_VER < MC_1_18_2
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12)) if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
{ {
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4); LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
levelChunkSection.getStates().read(tagSection.getList("Palette", 10), levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
tagSection.getLongArray("BlockStates")); tagSection.getLongArray("BlockStates"));
levelChunkSection.recalcBlockCounts(); levelChunkSection.recalcBlockCounts();
if (!levelChunkSection.isEmpty()) if (!levelChunkSection.isEmpty())
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ] chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
= levelChunkSection; = levelChunkSection;
} }
#else #else
int sectionId = level.getSectionIndexFromSectionY(sectionYPos); int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
if (sectionId >= 0 && sectionId < chunkSections.length) if (sectionId >= 0 && sectionId < chunkSections.length)
{ {
PalettedContainer<BlockState> blockStateContainer; PalettedContainer<BlockState> blockStateContainer;
#if MC_VER < MC_1_18_2 #if MC_VER < MC_1_18_2
PalettedContainer<Biome> biomeContainer; PalettedContainer<Biome> biomeContainer;
#else #else
PalettedContainer<Holder<Biome>> biomeContainer; PalettedContainer<Holder<Biome>> biomeContainer;
#endif #endif
boolean containsBlockStates; boolean containsBlockStates;
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
containsBlockStates = tagSection.contains("block_states", 10); containsBlockStates = tagSection.contains("block_states", 10);
#else #else
containsBlockStates = tagSection.contains("block_states"); containsBlockStates = tagSection.contains("block_states");
#endif #endif
if (containsBlockStates) if (containsBlockStates)
{ {
#if MC_VER < MC_1_20_6 #if MC_VER < MC_1_20_6
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states")) blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string)) .promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
.getOrThrow(false, (message) -> logParsingWarningOnce(message)); .getOrThrow(false, (message) -> logParsingWarningOnce(message));
#else #else
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states")) blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string)) .promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
.getOrThrow((message) -> logErrorAndReturnException(message)); .getOrThrow((message) -> logErrorAndReturnException(message));
#endif #endif
} }
else else
{ {
@@ -334,31 +352,31 @@ public class ChunkLoader
} }
#if MC_VER < MC_1_18_2 #if MC_VER < MC_1_18_2
biomeContainer = tagSection.contains("biomes", 10) biomeContainer = tagSection.contains("biomes", 10)
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message)) ? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message))
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); : new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
#else #else
boolean containsBiomes; boolean containsBiomes;
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
containsBiomes = tagSection.contains("biomes", 10); containsBiomes = tagSection.contains("biomes", 10);
#else #else
containsBiomes = tagSection.contains("biomes"); containsBiomes = tagSection.contains("biomes");
#endif #endif
if (containsBiomes) if (containsBiomes)
{ {
#if MC_VER < MC_1_20_6 #if MC_VER < MC_1_20_6
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes")) biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string)) .promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
.getOrThrow(false, (message) -> logParsingWarningOnce(message)); .getOrThrow(false, (message) -> logParsingWarningOnce(message));
#else #else
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes")) biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string)) .promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
.getOrThrow((message) -> logErrorAndReturnException(message)); .getOrThrow((message) -> logErrorAndReturnException(message));
#endif #endif
} }
else else
{ {
@@ -371,15 +389,15 @@ public class ChunkLoader
PalettedContainer.Strategy.SECTION_BIOMES); PalettedContainer.Strategy.SECTION_BIOMES);
} }
#endif #endif
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer); chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
#else #else
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer); chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
#endif #endif
} }
#endif #endif
} }
} }
@@ -391,10 +409,14 @@ public class ChunkLoader
#else ChunkType #endif #else ChunkType #endif
readChunkType(CompoundTag tagLevel) readChunkType(CompoundTag tagLevel)
{ {
ChunkStatus chunkStatus = ChunkStatus.byName(tagGetString(tagLevel,"Status")); String statusString = tagGetString(tagLevel,"Status");
if (chunkStatus != null) if (statusString != null)
{ {
return chunkStatus.getChunkType(); ChunkStatus chunkStatus = ChunkStatus.byName(statusString);
if (chunkStatus != null)
{
return chunkStatus.getChunkType();
}
} }
#if MC_VER <= MC_1_20_4 #if MC_VER <= MC_1_20_4
@@ -406,43 +428,52 @@ public class ChunkLoader
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData) private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
{ {
CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps"); CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps");
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter()) if (tagHeightmaps != null)
{ {
String heightmap = type.getSerializationKey(); for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
#if MC_VER < MC_1_21_5
if (tagHeightmaps.contains(heightmap, 12))
{ {
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap)); String heightmap = type.getSerializationKey();
} #if MC_VER < MC_1_21_5
#else if (tagHeightmaps.contains(heightmap, 12))
if (tagHeightmaps.contains(heightmap))
{
Optional<long[]> optionalHeightmap = tagHeightmaps.getLongArray(heightmap);
if (optionalHeightmap.isPresent())
{ {
chunk.setHeightmap(type, optionalHeightmap.get()); chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
} }
}
#endif
}
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
}
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
{
ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
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 #else
chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i); if (tagHeightmaps.contains(heightmap))
{
Optional<long[]> optionalHeightmap = tagHeightmaps.getLongArray(heightmap);
if (optionalHeightmap.isPresent())
{
chunk.setHeightmap(type, optionalHeightmap.get());
}
}
#endif #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)
{ {
@@ -466,6 +497,7 @@ public class ChunkLoader
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null); blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null);
#else #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)); blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null));
#endif #endif
} }
@@ -728,6 +760,7 @@ public class ChunkLoader
/** defaults to null if the tag isn't present */ /** defaults to null if the tag isn't present */
@Nullable
private static String tagGetString(CompoundTag tag, String key) private static String tagGetString(CompoundTag tag, String key)
{ {
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
@@ -738,6 +771,7 @@ public class ChunkLoader
} }
/** defaults to null if the tag isn't present */ /** defaults to null if the tag isn't present */
@Nullable
private static byte[] tagGetByteArray(CompoundTag tag, String key) private static byte[] tagGetByteArray(CompoundTag tag, String key)
{ {
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
@@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Mat4f;
@@ -82,6 +83,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
{ {
private final ClientApi clientApi = ClientApi.INSTANCE; private final ClientApi clientApi = ClientApi.INSTANCE;
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final Logger LOGGER = DhLoggerBuilder.getLogger();
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi // TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
@@ -226,6 +228,14 @@ 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,
@@ -274,6 +284,17 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix()); modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
#endif #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( this.clientApi.renderFade(
modelViewMatrix, modelViewMatrix,
projectionMatrix, projectionMatrix,
@@ -316,9 +337,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
#else #else
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) -> ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
{ {
// Forge packet ID AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
buffer.readByte();
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
if (message != null) if (message != null)
{ {
ClientApi.INSTANCE.pluginMessageReceived(message); ClientApi.INSTANCE.pluginMessageReceived(message);
@@ -20,6 +20,7 @@
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;
@@ -126,7 +127,8 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
} }
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) { ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); } protected void subscribeClientStartedEvent(Runnable eventHandler)
{ ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
@Override @Override
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler) protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
@@ -22,9 +22,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
ClientPlayNetworking.send(new CommonPacketPayload(message)); ClientPlayNetworking.send(new CommonPacketPayload(message));
#else // < 1.20.6 #else // < 1.20.6
FriendlyByteBuf buffer = PacketByteBufs.create(); FriendlyByteBuf buffer = PacketByteBufs.create();
// Forge packet ID this.encodeMessage(buffer, message);
buffer.writeByte(0);
AbstractPluginPacketSender.encodeMessage(buffer, message);
ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer); ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer);
#endif #endif
} }
@@ -36,9 +34,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message)); ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message));
#else // < 1.20.6 #else // < 1.20.6
FriendlyByteBuf buffer = PacketByteBufs.create(); FriendlyByteBuf buffer = PacketByteBufs.create();
// Forge packet ID this.encodeMessage(buffer, message);
buffer.writeByte(0);
AbstractPluginPacketSender.encodeMessage(buffer, message);
ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer); ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer);
#endif #endif
} }
@@ -9,7 +9,10 @@ import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.distanthorizons.core.api.internal.ServerApi; import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent; import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
@@ -32,7 +35,6 @@ import com.seibel.distanthorizons.common.CommonPacketPayload;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
#else #else
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
#endif #endif
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -48,6 +50,8 @@ import java.util.function.Supplier;
public class FabricServerProxy implements AbstractModInitializer.IEventProxy public class FabricServerProxy implements AbstractModInitializer.IEventProxy
{ {
private static final ServerApi SERVER_API = ServerApi.INSTANCE; private static final ServerApi SERVER_API = ServerApi.INSTANCE;
@SuppressWarnings("unused")
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private final boolean isDedicatedServer; private final boolean isDedicatedServer;
@@ -192,9 +196,7 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
#else #else
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) -> ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
{ {
// Forge packet ID AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
buffer.readByte();
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
if (message != null) if (message != null)
{ {
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message); ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
@@ -22,31 +22,51 @@ package com.seibel.distanthorizons.fabric.mixins.client;
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.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
#else import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.shaders.FogShape; import com.mojang.blaze3d.shaders.FogShape;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogParameters;
import org.joml.Vector4f; import org.joml.Vector4f;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.fog.FogRenderer;
import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
@Mixin(FogRenderer.class) @Mixin(FogRenderer.class)
@@ -66,18 +86,23 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
@Inject(at = @At("RETURN"), method = "setupFog") @Inject(at = @At("RETURN"), method = "setupFog")
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback) private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
#else #elif MC_VER < MC_1_21_6
@Inject(at = @At("RETURN"), method = "setupFog", cancellable = true) @Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback) private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
#else
@Unique
private static void unused()
#endif #endif
{ {
boolean cameraNotInFluid = cameraNotInFluid(camera); #if MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera);
#else
boolean cancelFog = cancelFog();
#endif
Entity entity = camera.getEntity(); if (cancelFog)
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
&& !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get())
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -85,10 +110,74 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE); RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#else #elif MC_VER < MC_1_21_6
callback.setReturnValue(FogParameters.NO_FOG); callback.setReturnValue(FogParameters.NO_FOG);
#else
#endif #endif
} }
}
#if MC_VER < MC_1_21_6
#else
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
// which prevents us from disabling the vanilla fog.
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
@WrapOperation(
method = "setupFog",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
opcode = org.objectweb.asm.Opcodes.PUTFIELD
)
)
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
{
if (cancelFog())
{
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
}
// Always call the original with the modified or original value
original.call(instance, value);
}
#endif
@Unique
#if MC_VER < MC_1_21_6
private static boolean cancelFog(Camera camera, FogMode fogMode)
#else
private static boolean cancelFog()
#endif
{
#if MC_VER < MC_1_21_6
Entity entity = camera.getEntity();
#else
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.getEntity();
#endif
boolean cameraNotInFluid = cameraNotInFluid(camera);
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
boolean cancelFog = !isSpecialFog;
cancelFog = cancelFog && cameraNotInFluid;
#if MC_VER < MC_1_21_6
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
#endif
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
return cancelFog;
} }
@Unique @Unique
@@ -105,4 +194,6 @@ public class MixinFogRenderer
return cameraNotInFluid; return cameraNotInFluid;
} }
} }
@@ -19,51 +19,54 @@
package com.seibel.distanthorizons.fabric.mixins.client; package com.seibel.distanthorizons.fabric.mixins.client;
import com.mojang.blaze3d.vertex.PoseStack;
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f; import com.mojang.math.Matrix4f;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
#else import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import org.joml.Matrix4fc;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#endif #endif
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter; import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.fabric.FabricClientProxy;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Mat4f;
import net.minecraft.client.Camera; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/** import org.apache.logging.log4j.Logger;
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
* If this wasn't done, and we used Forge's
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi
* @author James Seibel
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class) @Mixin(LevelRenderer.class)
public class MixinLevelRenderer public class MixinLevelRenderer
{ {
@Shadow @Shadow
private ClientLevel level; private ClientLevel level;
@Unique
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V", method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
@@ -84,51 +87,65 @@ public class MixinLevelRenderer
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V", method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true) cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
#else #elif MC_VER < MC_1_21_6
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"),
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
cancellable = true) cancellable = true)
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders", cancellable = true)
private void prepareChunkRenders(Matrix4fc projectionMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
#endif #endif
{ {
#if MC_VER == MC_1_16_5 #if MC_VER == MC_1_16_5
// get the matrices from the OpenGL fixed pipeline // get the matrices from the OpenGL fixed pipeline
float[] mcProjMatrixRaw = new float[16]; float[] mcProjMatrixRaw = new float[16];
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw); GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw); ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
mcProjectionMatrix.transpose(); ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose()); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
#elif MC_VER <= MC_1_20_4 #elif MC_VER <= MC_1_20_4
// get the matrices directly from MC // get the matrices directly from MC
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose()); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix); ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
#else #else
// MC combined the model view and projection matricies // MC combined the model view and projection matricies
Mat4f mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
Mat4f mcProjectionMatrix = new Mat4f(); ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f();
mcProjectionMatrix.setIdentity(); ClientApi.RENDER_STATE.mcProjectionMatrix.setIdentity();
#endif #endif
// TODO move this into a common place // TODO move this into a common place
float frameTime;
#if MC_VER < MC_1_21_1 #if MC_VER < MC_1_21_1
frameTime = Minecraft.getInstance().getFrameTime(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
#else #else
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
#endif #endif
//LOGGER.info("\n\n" +
// "Level Mixin\n" +
// "Mc MVM: \n" + mcModelViewMatrix.toString() + "\n" +
// "Mc Proj: \n" + mcProjectionMatrix.toString()
//);
#if MC_VER < MC_1_21_6
if (renderType.equals(RenderType.translucent())) if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level),
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime ClientApi.RENDER_STATE.frameTime
); );
} }
#else
// rendering handled via Fabric Api render event
#endif
// FIXME completely disables rendering when sodium is installed // FIXME completely disables rendering when sodium is installed
if (Config.Client.Advanced.Debugging.lodOnlyMode.get()) if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
@@ -137,4 +154,6 @@ public class MixinLevelRenderer
} }
} }
} }
@@ -0,0 +1,48 @@
package com.seibel.distanthorizons.fabric.mixins.server;
#if MC_VER < MC_1_21_4
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public class MixinLevelTicks<T>
{
// dummy mixin to make the loader happy
}
#else
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import net.minecraft.world.ticks.LevelTicks;
import net.minecraft.world.ticks.ScheduledTick;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
public class MixinLevelTicks<T>
{
// TODO put in a common location
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
{
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
if (isWorldGenThread())
{
ci.cancel();
}
}
}
#endif
@@ -8,7 +8,8 @@
"server.MixinEntity", "server.MixinEntity",
"server.MixinServerPlayer", "server.MixinServerPlayer",
"server.MixinTracingExecutor", "server.MixinTracingExecutor",
"server.MixinUtilBackgroundThread" "server.MixinUtilBackgroundThread",
"server.MixinLevelTicks"
], ],
"client": [ "client": [
"client.MixinClientLevel", "client.MixinClientLevel",
@@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
@@ -79,6 +80,7 @@ import java.util.concurrent.ThreadPoolExecutor;
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
{ {
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final Logger LOGGER = DhLoggerBuilder.getLogger();
@@ -96,7 +98,7 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
// handles singleplayer, LAN, and connecting to a server // handles singleplayer, LAN, and connecting to a server
ForgePluginPacketSender.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) -> PACKET_SENDER.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
{ {
ClientApi.INSTANCE.pluginMessageReceived(message); ClientApi.INSTANCE.pluginMessageReceived(message);
ServerApi.INSTANCE.pluginMessageReceived(player, message); ServerApi.INSTANCE.pluginMessageReceived(player, message);
@@ -118,14 +118,14 @@ public class ForgeMain extends AbstractModInitializer
@Override @Override
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler) protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
{ { MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); }); }
MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); });
}
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) protected void subscribeClientStartedEvent(Runnable eventHandler)
{ {
// FIXME What event is this? // Just run the event handler, since there are no proper ClientLifecycleEvent for the client
// to signify readiness other than FmlClientSetupEvent
eventHandler.run();
} }
@Override @Override
@@ -45,16 +45,18 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
); );
#endif #endif
public static void setPacketHandler(Consumer<AbstractNetworkMessage> consumer) public ForgePluginPacketSender() { super(true); }
public void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
{ {
setPacketHandler((player, message) -> consumer.accept(message)); this.setPacketHandler((player, message) -> consumer.accept(message));
} }
public static void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer) public void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
{ {
#if MC_VER >= MC_1_20_2 #if MC_VER >= MC_1_20_2
PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0) PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0)
.encoder((wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message)) .encoder((wrapper, out) -> this.encodeMessage(out, wrapper.message))
.decoder(in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in))) .decoder(in -> new MessageWrapper(this.decodeMessage(in)))
.consumerNetworkThread((wrapper, context) -> .consumerNetworkThread((wrapper, context) ->
{ {
if (wrapper.message != null) if (wrapper.message != null)
@@ -73,8 +75,8 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
.add(); .add();
#else // < 1.20.2 #else // < 1.20.2
PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class, PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class,
(wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message), (wrapper, out) -> this.encodeMessage(out, wrapper.message),
in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in)), in -> new MessageWrapper(this.decodeMessage(in)),
(wrapper, context) -> (wrapper, context) ->
{ {
if (wrapper.message != null) if (wrapper.message != null)
@@ -7,7 +7,9 @@ import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.distanthorizons.core.api.internal.ServerApi; import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
@@ -51,6 +53,8 @@ import java.util.function.Supplier;
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
{ {
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
#if MC_VER < MC_1_19_2 #if MC_VER < MC_1_19_2
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); } private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
#else #else
@@ -68,7 +72,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
if (this.isDedicated) if (this.isDedicated)
{ {
ForgePluginPacketSender.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived); PACKET_SENDER.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
} }
} }
@@ -156,7 +156,7 @@ public class MixinLevelRenderer
} }
else if (renderType.equals(RenderType.translucent())) else if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
} }
// render fade // render fade
+3 -3
View File
@@ -5,7 +5,7 @@ org.gradle.caching=true
# Mod Info # Mod Info
mod_name=DistantHorizons mod_name=DistantHorizons
mod_version=2.3.3-b-dev mod_version=2.3.4-b
api_version=4.0.0 api_version=4.0.0
maven_group=com.seibel.distanthorizons maven_group=com.seibel.distanthorizons
mod_readable_name=Distant Horizons mod_readable_name=Distant Horizons
@@ -18,7 +18,7 @@ mod_issues=https://gitlab.com/jeseibel/distant-horizons/-/issues
mod_discord=https://discord.gg/xAB8G4cENx mod_discord=https://discord.gg/xAB8G4cENx
# Global Plugin Versions # Global Plugin Versions
manifold_version=2024.1.37 manifold_version=2025.1.20
# 2023.1.17 can be used if there are mystery Java compiler issues # 2023.1.17 can be used if there are mystery Java compiler issues
nightconfig_version=3.6.6 nightconfig_version=3.6.6
lz4_version=1.8.0 lz4_version=1.8.0
@@ -51,7 +51,7 @@ versionStr=
# This defines what MC version Intellij will use for the preprocessor # This defines what MC version Intellij will use for the preprocessor
# and what version is used automatically by build and run commands # and what version is used automatically by build and run commands
mcVer=1.21.5 mcVer=1.21.8
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment # Defines the maximum amount of memory Minecraft is allowed when run in a development environment
#minecraftMemoryJavaArg="-Xmx4G" #minecraftMemoryJavaArg="-Xmx4G"
@@ -78,13 +78,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final Logger LOGGER = DhLoggerBuilder.getLogger();
// private static SimpleChannel multiversePluginChannel;
// Not the cleanest way of passing this to the LOD renderer, but it'll have to do for now
public static Mat4f currentModelViewMatrix = new Mat4f();
public static Mat4f currentProjectionMatrix = new Mat4f();
@Override @Override
@@ -244,16 +237,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
// rendering // // rendering //
//===========// //===========//
@SubscribeEvent #if MC_VER < MC_1_21_6
public void beforeLevelRenderEvent(RenderLevelStageEvent event)
{
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_SKY)
{
currentModelViewMatrix = McObjectConverter.Convert(event.getModelViewMatrix());
currentProjectionMatrix = McObjectConverter.Convert(event.getProjectionMatrix());
}
}
@SubscribeEvent @SubscribeEvent
public void afterLevelRenderEvent(RenderLevelStageEvent event) public void afterLevelRenderEvent(RenderLevelStageEvent event)
{ {
@@ -272,6 +256,56 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
} }
} }
} }
#else
@SubscribeEvent
public void afterLevelEntityRenderEvent(RenderLevelStageEvent.AfterEntities event)
{
ClientApi.INSTANCE.renderFade(
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel())
);
}
@SubscribeEvent
public void afterLevelTranslucentRenderEvent(RenderLevelStageEvent.AfterTranslucentBlocks event)
{
ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel()),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime
);
}
@SubscribeEvent
public void afterLevelRenderEvent(RenderLevelStageEvent.AfterLevel event)
{
try
{
// should generally only need to be set once per game session
// allows DH to render directly to Optifine's level frame buffer,
// allowing better shader support
MinecraftRenderWrapper.INSTANCE.finalLevelFrameBufferId = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING);
}
catch (Exception | Error e)
{
LOGGER.error("Unexpected error in afterLevelRenderEvent: "+e.getMessage(), e);
}
ClientApi.INSTANCE.renderFadeOpaque(
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel())
);
}
#endif
@@ -282,4 +316,5 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); } private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
} }
@@ -23,7 +23,6 @@ import com.mojang.brigadier.CommandDispatcher;
import com.seibel.distanthorizons.common.AbstractModInitializer; import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen; import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.api.internal.ServerApi; import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
@@ -51,9 +50,13 @@ import java.util.function.Consumer;
#if MC_VER < MC_1_20_6 #if MC_VER < MC_1_20_6
import net.neoforged.neoforge.client.ConfigScreenHandler; import net.neoforged.neoforge.client.ConfigScreenHandler;
#elif MC_VER < MC_1_21_8
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import org.jetbrains.annotations.NotNull;
#else #else
import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
#endif #endif
/** /**
@@ -72,6 +75,11 @@ public class NeoforgeMain extends AbstractModInitializer
{ {
this.onInitializeClient(); this.onInitializeClient();
eventBus.addListener(this::registerNetworkingClientServer); eventBus.addListener(this::registerNetworkingClientServer);
#if MC_VER < MC_1_21_8
#else
eventBus.addListener(this::registerClientPayloadEvent);
#endif
}); });
// handles dedicated servers // handles dedicated servers
@@ -99,6 +107,12 @@ public class NeoforgeMain extends AbstractModInitializer
public void registerNetworkingServer(RegisterPayloadHandlersEvent event) public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); } { NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
#if MC_VER < MC_1_21_8
#else
public void registerClientPayloadEvent(RegisterClientPayloadHandlersEvent event)
{ NeoforgePluginPacketSender.registerClientPacketHandler(event); }
#endif
@@ -141,7 +155,9 @@ public class NeoforgeMain extends AbstractModInitializer
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) protected void subscribeClientStartedEvent(Runnable eventHandler)
{ {
// FIXME What event is this? // Just run the event handler, since there are no proper ClientLifecycleEvent for the client
// to signify readiness other than FmlClientSetupEvent
eventHandler.run();
} }
@Override @Override
@@ -14,10 +14,19 @@ import java.util.Optional;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
#if MC_VER < MC_1_21_8
#else
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
#endif
public class NeoforgePluginPacketSender extends AbstractPluginPacketSender public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
{ {
private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer; private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer;
public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer) public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer)
{ setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); } { setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); }
public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer) public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
@@ -39,9 +48,31 @@ public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
}); });
} }
#if MC_VER < MC_1_21_8
#else
public static void registerClientPacketHandler(RegisterClientPayloadHandlersEvent event)
{
// as of MC 1.21.7 Neo added a separate client network register
// https://github.com/neoforged/NeoForge/pull/2272
event.register(CommonPacketPayload.TYPE, (payload, context) ->
{
if (payload.message() != null)
{
packetConsumer.accept(null, payload.message());
}
});
}
#endif
@Override @Override
public void sendToServer(AbstractNetworkMessage message) public void sendToServer(AbstractNetworkMessage message)
{ PacketDistributor.sendToServer(new CommonPacketPayload(message)); } {
#if MC_VER < MC_1_21_8
PacketDistributor.sendToServer(new CommonPacketPayload(message));
#else
ClientPacketDistributor.sendToServer(new CommonPacketPayload(message));
#endif
}
@Override @Override
public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message) public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message)
@@ -22,67 +22,87 @@ package com.seibel.distanthorizons.neoforge.mixins.client;
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.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.world.level.material.FogType;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.shaders.FogShape;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.client.renderer.FogParameters;
import org.joml.Vector4f;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else #else
import net.minecraft.client.renderer.FogParameters;
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import org.joml.Vector4f; import net.minecraft.client.renderer.fog.FogRenderer;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
@Mixin(FogRenderer.class) @Mixin(FogRenderer.class)
public class MixinFogRenderer public class MixinFogRenderer
{ {
// Using this instead of Float.MAX_VALUE because Sodium don't like it. // Using this instead of Float.MAX_VALUE because Sodium don't like it.
@Unique
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F; private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
@Unique
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F; private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
#if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 #if MC_VER < MC_1_19_2
@Inject(at = @At("RETURN"), @Inject(at = @At("RETURN"), method = "setupFog")
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback)
remap = false)
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
@Inject(at = @At("RETURN"), @Inject(at = @At("RETURN"), method = "setupFog")
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
remap = true) #elif MC_VER < MC_1_21_6
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback) @Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
#else #else
@Inject(at = @At("RETURN"), @Unique
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;Lorg/joml/Vector4f;FZF)Lnet/minecraft/client/renderer/FogParameters;", private static void unused()
remap = true, cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float partTick, CallbackInfoReturnable<FogParameters> callback)
#endif #endif
{ {
boolean cameraNotInFluid = cameraNotInFluid(camera); #if MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera);
#else
boolean cancelFog = cancelFog();
#endif
Entity entity = camera.getEntity(); if (cancelFog)
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
&& !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get())
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -90,12 +110,77 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE); RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#else #elif MC_VER < MC_1_21_6
callback.setReturnValue(FogParameters.NO_FOG); callback.setReturnValue(FogParameters.NO_FOG);
#else
#endif #endif
} }
} }
#if MC_VER < MC_1_21_6
#else
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
// which prevents us from disabling the vanilla fog.
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
@WrapOperation(
method = "setupFog",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
opcode = org.objectweb.asm.Opcodes.PUTFIELD
)
)
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
{
if (cancelFog())
{
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
}
// Always call the original with the modified or original value
original.call(instance, value);
}
#endif
@Unique
#if MC_VER < MC_1_21_6
private static boolean cancelFog(Camera camera, FogMode fogMode)
#else
private static boolean cancelFog()
#endif
{
#if MC_VER < MC_1_21_6
Entity entity = camera.getEntity();
#else
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.getEntity();
#endif
boolean cameraNotInFluid = cameraNotInFluid(camera);
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
boolean cancelFog = !isSpecialFog;
cancelFog = cancelFog && cameraNotInFluid;
#if MC_VER < MC_1_21_6
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
#endif
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
return cancelFog;
}
@Unique
private static boolean cameraNotInFluid(Camera camera) private static boolean cameraNotInFluid(Camera camera)
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
@@ -110,4 +195,5 @@ public class MixinFogRenderer
} }
} }
@@ -19,39 +19,53 @@
package com.seibel.distanthorizons.neoforge.mixins.client; package com.seibel.distanthorizons.neoforge.mixins.client;
import com.mojang.blaze3d.systems.RenderSystem; #if MC_VER < MC_1_21_6
import com.mojang.blaze3d.vertex.PoseStack;
#if MC_VER < MC_1_19_4
import com.mojang.math.Matrix4f;
#else
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import org.joml.Matrix4f;
#endif
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import org.joml.Matrix4f;
#else
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#endif
import org.apache.logging.log4j.Logger;
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#if MC_VER < MC_1_17_1
import org.lwjgl.opengl.GL15;
#endif
/** /**
* This class is used to mix in DH's rendering code * This class is used to mix in DH's rendering code
* before Minecraft starts rendering blocks. * before Minecraft starts rendering blocks.
@@ -70,73 +84,66 @@ public class MixinLevelRenderer
#endif #endif
private ClientLevel level; private ClientLevel level;
@Unique
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
#if MC_VER < MC_1_17_1
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V", #if MC_VER < MC_1_21_6
cancellable = true) @Inject(at = @At("HEAD"), method = "renderSectionLayer", cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_19_4
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_20_2
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_20_6
@Inject(at = @At("HEAD"),
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
#else #else
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"), method = "renderLevel", cancellable = true)
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", private void onRenderLevel(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, Matrix4f positionMatrix, Matrix4f projectionMatrix, GpuBufferSlice gpuBufferSlice, Vector4f skyColor, boolean thinFog, CallbackInfo callback)
cancellable = true) #endif
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
#endif
{ {
#if MC_VER == MC_1_16_5 #if MC_VER < MC_1_21_6
// get the matrices from the OpenGL fixed pipeline // MC combined the model view and projection matricies
float[] mcProjMatrixRaw = new float[16]; ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw); ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
#elif MC_VER <= MC_1_20_4
// get the matrices directly from MC
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
#else #else
// get the matrices from neoForge's render event. ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
// We can't call the renderer there because we don't have access to the level that's being rendered
Mat4f mcModelViewMatrix = NeoforgeClientProxy.currentModelViewMatrix;
Mat4f mcProjectionMatrix = NeoforgeClientProxy.currentProjectionMatrix;
#endif #endif
//LOGGER.info("\n\n" +
// "Level Mixin\n" +
// "Mc MVM: \n" + ClientApi.RENDER_STATE.mcModelViewMatrix.toString() + "\n" +
// "Mc Proj: \n" + ClientApi.RENDER_STATE.mcProjectionMatrix.toString()
//);
float frameTime;
#if MC_VER < MC_1_21_1 #if MC_VER < MC_1_21_1
frameTime = Minecraft.getInstance().getFrameTime(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
#else #else
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
#endif #endif
#if MC_VER < MC_1_21_6
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
// render LODs // render LODs
if (renderType.equals(RenderType.solid())) if (renderType.equals(RenderType.solid()))
{ {
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
} }
else if (renderType.equals(RenderType.translucent())) else if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
} }
// render fade // render fade
@@ -146,21 +153,22 @@ public class MixinLevelRenderer
if (renderType.equals(RenderType.cutout())) if (renderType.equals(RenderType.cutout()))
{ {
ClientApi.INSTANCE.renderFadeOpaque( ClientApi.INSTANCE.renderFadeOpaque(
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime, ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper(this.level) ClientLevelWrapper.getWrapper(this.level)
); );
} }
else if (renderType.equals(RenderType.tripwire())) else if (renderType.equals(RenderType.tripwire()))
{ {
ClientApi.INSTANCE.renderFade( ClientApi.INSTANCE.renderFade(
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime, ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper(this.level) ClientLevelWrapper.getWrapper(this.level)
); );
} }
#endif
if (Config.Client.Advanced.Debugging.lodOnlyMode.get()) if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
{ {
@@ -169,4 +177,30 @@ public class MixinLevelRenderer
} }
#if MC_VER < MC_1_21_6
// formerly handled in renderChunkLayer()
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders", cancellable = true)
private void renderChunkLayer(Matrix4fc modelViewMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
{
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
}
#endif
} }
@@ -0,0 +1,46 @@
package com.seibel.distanthorizons.neoforge.mixins.server;
#if MC_VER < MC_1_21_4
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public class MixinLevelTicks<T>
{
// dummy mixin to make the loader happy
}
#else
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import net.minecraft.world.ticks.LevelTicks;
import net.minecraft.world.ticks.ScheduledTick;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
public class MixinLevelTicks<T>
{
// TODO put in a common location
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
{
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
if (isWorldGenThread())
{
ci.cancel();
}
}
}
#endif
@@ -8,7 +8,8 @@
"server.MixinServerPlayer", "server.MixinServerPlayer",
"server.MixinTFChunkGenerator", "server.MixinTFChunkGenerator",
"server.MixinTracingExecutor", "server.MixinTracingExecutor",
"server.MixinUtilBackgroundThread" "server.MixinUtilBackgroundThread",
"server.MixinLevelTicks"
], ],
"client": [ "client": [
"client.MixinClientPacketListener", "client.MixinClientPacketListener",
@@ -3,6 +3,8 @@ loaderVersion = "*" # // mandatory. Allow all forge versions as we are definding
license = "LGPL" license = "LGPL"
issueTrackerURL = "${issues}" issueTrackerURL = "${issues}"
# https://docs.neoforged.net/docs/gettingstarted/modfiles/#neoforgemodstoml
[[mods]] #//mandatory [[mods]] #//mandatory
modId = "distanthorizons" #//mandatory modId = "distanthorizons" #//mandatory
@@ -32,4 +34,11 @@ issueTrackerURL = "${issues}"
type = "required" type = "required"
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
ordering = "NONE" ordering = "NONE"
side = "BOTH" side = "BOTH"
[[dependencies.distanthorizons]]
modId = "neoforge"
type = "required"
versionRange = "${neoforge_version_range}"
ordering = "NONE"
side = "BOTH"
+1 -1
View File
@@ -6,7 +6,7 @@ How to add a library's natives:
1. In `build.gradle`: 1. In `build.gradle`:
- Make sure the target package is the same length or shorter (untested) than the source package. Underscores in native methods will take 2 characters so account for that as well. - Make sure the target package is the same length or shorter (untested) than the source package. Underscores in native methods will be mapped to `_1` so account for that as well.
- Exclude the native files and add them as `relocateNative` (see example). - Exclude the native files and add them as `relocateNative` (see example).
Example: Example:
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.42.0+1.16
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -43,6 +44,9 @@ fabric_api_version=0.42.0+1.16
# Forge loader # Forge loader
forge_version=36.2.39 forge_version=36.2.39
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version=4044290 terraforged_version=4044290
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.46.1+1.17
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,6 +43,9 @@ fabric_api_version=0.46.1+1.17
# Forge loader # Forge loader
forge_version=37.1.1 forge_version=37.1.1
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge=3457784 starlight_version_forge=3457784
terraforged_version= terraforged_version=
+4
View File
@@ -25,6 +25,7 @@ fabric_api_version=0.76.0+1.18.2
immersive_portals_version=v1.4.11-1.18 immersive_portals_version=v1.4.11-1.18
canvas_version=mc118:1.0.2616 canvas_version=mc118:1.0.2616
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -51,6 +52,9 @@ quilted_api_version=1.0.0-beta.28+0.67.0-1.18.2
# Forge loader # Forge loader
forge_version=40.2.10 forge_version=40.2.10
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.76.1+1.19.2
immersive_portals_version= immersive_portals_version=
canvas_version=mc119-1.0.2480 canvas_version=mc119-1.0.2480
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,6 +43,9 @@ fabric_api_version=0.76.1+1.19.2
# Forge loader # Forge loader
forge_version=43.3.2 forge_version=43.3.2
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -1
View File
@@ -22,7 +22,8 @@ fabric_api_version=0.87.1+1.19.4
bclib_version=2.3.3 bclib_version=2.3.3
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.87.1+1.19.4
# Forge loader # Forge loader
forge_version=45.2.4 forge_version=45.2.4
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -1
View File
@@ -22,7 +22,8 @@ fabric_api_version=0.90.4+1.20.1
bclib_version=3.0.13 bclib_version=3.0.13
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.90.4+1.20.1
# Forge loader # Forge loader
forge_version=47.2.1 forge_version=47.2.1
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -1
View File
@@ -22,7 +22,8 @@ fabric_api_version=0.90.4+1.20.2
bclib_version=3.0.13 bclib_version=3.0.13
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.90.4+1.20.2
# Forge loader # Forge loader
forge_version=48.0.13 forge_version=48.0.13
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -2
View File
@@ -23,7 +23,8 @@ fabric_api_version=0.91.2+1.20.4
bclib_version= bclib_version=
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.91.2+1.20.4
# (Neo)Forge loader # (Neo)Forge loader
forge_version=49.1.13 forge_version=49.1.13
neoforge_version=20.4.233 neoforge_version=20.4.246
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -2
View File
@@ -23,7 +23,8 @@ fabric_api_version=0.97.8+1.20.6
bclib_version= bclib_version=
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.97.8+1.20.6
# (Neo)Forge loader # (Neo)Forge loader
forge_version=50.0.19 forge_version=50.0.19
neoforge_version=20.6.70-beta neoforge_version=20.6.136
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -2
View File
@@ -23,7 +23,8 @@ fabric_api_version=0.115.0+1.21.1
bclib_version= bclib_version=
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.115.0+1.21.1
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.1.92 neoforge_version=21.1.192
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+3 -1
View File
@@ -43,7 +43,9 @@ fabric_api_version=0.110.0+1.21.3
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.3.11-beta neoforge_version=21.3.86
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -2
View File
@@ -23,7 +23,7 @@ fabric_api_version=0.110.5+1.21.4
bclib_version= bclib_version=
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +42,10 @@ fabric_api_version=0.110.5+1.21.4
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.4.3-beta neoforge_version=21.4.147
# version range may not be necessary, but having compiled DH for an older version caused issues with shaders
neoforge_version_range=[21.4.147,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -3
View File
@@ -1,4 +1,4 @@
# 1.21.4 version # 1.21.5 version
java_version=21 java_version=21
minecraft_version=1.21.5 minecraft_version=1.21.5
parchment_version=1.21:2024.07.28 parchment_version=1.21:2024.07.28
@@ -23,7 +23,7 @@ fabric_api_version=0.119.5+1.21.5
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should # Iris - some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should
fabric_incompatibility_list={ "iris": "<=1.8.10" } fabric_incompatibility_list={ "iris": "<=1.8.10" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +42,9 @@ fabric_api_version=0.119.5+1.21.5
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.5.0-beta neoforge_version=21.5.87
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+58
View File
@@ -0,0 +1,58 @@
# 1.21.6 version
java_version=21
minecraft_version=1.21.6
parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.6"]
accessWidenerVersion=1_21_4
builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues
# Netty
netty_version=4.1.97.Final
# Fabric loader
fabric_loader_version=0.16.13
fabric_api_version=0.127.0+1.21.6
modmenu_version=15.0.0-beta.2
starlight_version_fabric=
phosphor_version_fabric=
lithium_version=
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.0+1.21.6-fabric
bclib_version=
immersive_portals_version=
canvas_version=
fabric_incompatibility_list={ }
fabric_recommend_list={}
# Fabric mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# (Neo)Forge loader
forge_version=
neoforge_version=21.6.20-beta
# around 6.19 neo changed how their render API works, failing to meet this causes the game to crash
neoforge_version_range=[21.6.19-beta,)
# (Neo)Forge mod versions
starlight_version_forge=
terraforged_version=
# (Neo)Forge mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight_forge=0
enable_terraforged=0
enable_terrafirmacraft=0
+58
View File
@@ -0,0 +1,58 @@
# 1.21.7 version
java_version=21
minecraft_version=1.21.8
parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.8"]
accessWidenerVersion=1_21_4
builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues
# Netty
netty_version=4.1.97.Final
# Fabric loader
fabric_loader_version=0.16.13
fabric_api_version=0.129.0+1.21.8
modmenu_version=15.0.0-beta.3
starlight_version_fabric=
phosphor_version_fabric=
lithium_version=
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.1+1.21.7-fabric
bclib_version=
immersive_portals_version=
canvas_version=
fabric_incompatibility_list={ }
fabric_recommend_list={}
# Fabric mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# (Neo)Forge loader
forge_version=
neoforge_version=21.8.2-beta
# around 6.19 neo changed how their render API works, failing to meet this causes the game to crash
neoforge_version_range=[*,)
# (Neo)Forge mod versions
starlight_version_forge=
terraforged_version=
# (Neo)Forge mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight_forge=0
enable_terraforged=0
enable_terrafirmacraft=0