diff --git a/README.md b/README.md index 6f2fbf29..f79baa26 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ See [List of all available settings](https://github.com/fxmorin/carpet-fixes/wik This mod works for both Singleplayer & Multiplayer. This mod now supports fixing some client-side bugs! Run `/carpet-fixes list client` to see a list of all available client-side fixes. -These fixes may not be client-side only +Any fix marked as Client, means it affects the client-side, although it might also affect the server-side! --- diff --git a/build.gradle b/build.gradle index 07470a1b..29db5a9c 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation "carpet:fabric-carpet:${project.minecraft_version}-${project.carpet_core_version}" + modImplementation "carpet:fabric-carpet:${project.carpet_minecraft_version}-${project.carpet_core_version}" modImplementation 'com.github.astei:lazydfu:0.1.2' // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. diff --git a/gradle.properties b/gradle.properties index c4d7d7be..58efb11d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,10 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use or https://modmuss50.me/fabric.html - minecraft_version=1.18 - yarn_mappings=1.18+build.1 - loader_version=0.11.3 + minecraft_version=1.18.1 + yarn_mappings=1.18.1+build.1 + loader_version=0.12.11 + carpet_minecraft_version=1.18 # check available versions on maven for the given minecraft version you are using carpet_core_version=1.4.56+v211130 diff --git a/src/main/java/carpetfixes/CarpetFixesSettings.java b/src/main/java/carpetfixes/CarpetFixesSettings.java index 511d40c7..ec59a3c0 100644 --- a/src/main/java/carpetfixes/CarpetFixesSettings.java +++ b/src/main/java/carpetfixes/CarpetFixesSettings.java @@ -900,6 +900,35 @@ public class CarpetFixesSettings { ) public static boolean optimizedBiomeAccess = false; + //by FX - PR0CESS + @Rule( + desc = "Fixes lava being able to damage entity client-side leading to de-sync", + extra = {"Fixes [MC-246465](https://bugs.mojang.com/browse/MC-246465)", + "This is client-side only"}, + category = {BUGFIX,EXPERIMENTAL,CLIENT} + ) + public static boolean lavaDamageDesyncFix = false; + + //by FX - PR0CESS + @Rule( + desc = "Fixes the client-side being able to apply damage to item entities & experience orbs, causing de-sync", + extra = {"Fixes [MC-53850](https://bugs.mojang.com/browse/MC-53850)", + "This is client-side only"}, + category = {BUGFIX,EXPERIMENTAL,CLIENT} + ) + public static boolean clientSideDamageDesyncFix = false; + + //by FX - PR0CESS + @Rule( + desc = "Fixes chat causing subtle freezing after no activity in chat", + extra = {"Fixes [MC-247973](https://bugs.mojang.com/browse/MC-247973)", + "unlike other fixes, we dont just put it in a thread since that might change the order of the messages", + "Instead we allow the first message to go through, then async load the blockList", + "Although this should never happen since the list will not continuously be updated due to them setting it to null"}, + category = {BUGFIX,OPTIMIZATION,CLIENT} + ) + public static boolean chatLagFix = false; + /* DUPE BUGS diff --git a/src/main/java/carpetfixes/mixins/coreSystemFixes/YggdrasilUserApiService_syncBlockListMixin.java b/src/main/java/carpetfixes/mixins/coreSystemFixes/YggdrasilUserApiService_syncBlockListMixin.java new file mode 100644 index 00000000..6491f4c9 --- /dev/null +++ b/src/main/java/carpetfixes/mixins/coreSystemFixes/YggdrasilUserApiService_syncBlockListMixin.java @@ -0,0 +1,57 @@ +package carpetfixes.mixins.coreSystemFixes; + +import carpetfixes.CarpetFixesSettings; +import com.mojang.authlib.yggdrasil.YggdrasilUserApiService; +import com.mojang.authlib.yggdrasil.response.BlockListResponse; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Environment(EnvType.CLIENT) +@Mixin(YggdrasilUserApiService.class) +public abstract class YggdrasilUserApiService_syncBlockListMixin { + + @Shadow protected abstract Set fetchBlockList(); + + @Shadow private Set blockList; + + + @Redirect( + method = "isBlockedPlayer(Ljava/util/UUID;)Z", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/authlib/yggdrasil/YggdrasilUserApiService;fetchBlockList()Ljava/util/Set;" + ) + ) + public Set isBlockedPlayerFetchAsync(YggdrasilUserApiService instance) { + if (CarpetFixesSettings.chatLagFix) { + CompletableFuture.runAsync(() -> this.blockList = this.fetchBlockList()); + return null; //Skip first laggy check. Although load the blocklist async for the next messages + } + return this.fetchBlockList(); + } + + + @Redirect( + method = "forceFetchBlockList()Ljava/util/Set;", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/authlib/yggdrasil/response/BlockListResponse;getBlockedProfiles()Ljava/util/Set;" + ) + ) + private Set forceFetchBlockListDontReturnNull(BlockListResponse instance) { + if (CarpetFixesSettings.chatLagFix) { //Do not return null or else the system will think the blockList is not loaded + Set uuids = instance.getBlockedProfiles(); + return uuids == null ? new HashSet() : uuids; + } + return instance.getBlockedProfiles(); + } +} diff --git a/src/main/java/carpetfixes/mixins/entityFixes/Entity_clientDamageMixin.java b/src/main/java/carpetfixes/mixins/entityFixes/Entity_clientDamageMixin.java new file mode 100644 index 00000000..046249cf --- /dev/null +++ b/src/main/java/carpetfixes/mixins/entityFixes/Entity_clientDamageMixin.java @@ -0,0 +1,36 @@ +package carpetfixes.mixins.entityFixes; + +import carpetfixes.CarpetFixesSettings; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.ExperienceOrbEntity; +import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Environment(EnvType.CLIENT) +@Mixin(Entity.class) +public class Entity_clientDamageMixin { + + @Shadow public World world; + + private final Entity self = (Entity) (Object) this; + + + @Inject( + method = "isInvulnerableTo(Lnet/minecraft/entity/damage/DamageSource;)Z", + at = @At("HEAD"), + cancellable = true + ) + public void isInvulnerableToAndClient(DamageSource damageSource, CallbackInfoReturnable cir) { + if (CarpetFixesSettings.clientSideDamageDesyncFix && (self instanceof ItemEntity || self instanceof ExperienceOrbEntity)) { + cir.setReturnValue(true); + } + } +} diff --git a/src/main/java/carpetfixes/mixins/entityFixes/Entity_lavaDamageMixin.java b/src/main/java/carpetfixes/mixins/entityFixes/Entity_lavaDamageMixin.java new file mode 100644 index 00000000..af72aa1e --- /dev/null +++ b/src/main/java/carpetfixes/mixins/entityFixes/Entity_lavaDamageMixin.java @@ -0,0 +1,29 @@ +package carpetfixes.mixins.entityFixes; + +import carpetfixes.CarpetFixesSettings; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Environment(EnvType.CLIENT) +@Mixin(Entity.class) +public class Entity_lavaDamageMixin { + + @Shadow public World world; + + + @Inject( + method = "isFireImmune()Z", + at = @At("HEAD"), + cancellable = true + ) + public void isFireImmuneAndServerSide(CallbackInfoReturnable cir) { + if (CarpetFixesSettings.lavaDamageDesyncFix && this.world.isClient()) cir.setReturnValue(true); + } +} diff --git a/src/main/resources/carpet-fixes.mixins.json b/src/main/resources/carpet-fixes.mixins.json index 02e27514..0d2b706b 100644 --- a/src/main/resources/carpet-fixes.mixins.json +++ b/src/main/resources/carpet-fixes.mixins.json @@ -172,6 +172,11 @@ "reIntroduced.ThreadedAnvilChunkStorage_oldSavingMixin", "screenHandlerFixes.EnchantmentScreenHandler_transparentBlocksMixin" ], + "client": [ + "coreSystemFixes.YggdrasilUserApiService_syncBlockListMixin", + "entityFixes.Entity_clientDamageMixin", + "entityFixes.Entity_lavaDamageMixin" + ], "injectors": { "defaultRequire": 1 }