diff options
Diffstat (limited to 'src/main/java')
14 files changed, 315 insertions, 42 deletions
diff --git a/src/main/java/moe/nea/firmament/init/MixinPlugin.java b/src/main/java/moe/nea/firmament/init/MixinPlugin.java index 513efef..d48139b 100644 --- a/src/main/java/moe/nea/firmament/init/MixinPlugin.java +++ b/src/main/java/moe/nea/firmament/init/MixinPlugin.java @@ -8,56 +8,69 @@ import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class MixinPlugin implements IMixinConfigPlugin { - AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin(); + AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin(); public static List<MixinPlugin> instances = new ArrayList<>(); public String mixinPackage; - @Override - public void onLoad(String mixinPackage) { - MixinExtrasBootstrap.init(); + + @Override + public void onLoad(String mixinPackage) { + MixinExtrasBootstrap.init(); instances.add(this); - this.mixinPackage = mixinPackage; - autoDiscoveryPlugin.setMixinPackage(mixinPackage); - } + this.mixinPackage = mixinPackage; + autoDiscoveryPlugin.setMixinPackage(mixinPackage); + } + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + if (!Boolean.getBoolean("firmament.debug") && mixinClassName.contains("devenv.")) { + return false; + } + return true; + } - @Override - public String getRefMapperConfig() { - return null; - } + @Override + public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - if (!Boolean.getBoolean("firmament.debug") && mixinClassName.contains("devenv.")) { - return false; - } - return true; - } + } - @Override - public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { + @Override + public List<String> getMixins() { + return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it)) + .toList(); + } - } + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - @Override - public List<String> getMixins() { - return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it)) - .toList(); - } + } - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + public Set<String> getAppliedFullPathMixins() { + return new HashSet<>(appliedMixins); + } - } + public Set<String> getExpectedFullPathMixins() { + return getMixins() + .stream() + .map(it -> mixinPackage + "." + it) + .collect(Collectors.toSet()); + } - public List<String> appliedMixins = new ArrayList<>(); + public List<String> appliedMixins = new ArrayList<>(); - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - appliedMixins.add(mixinClassName); - } + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + appliedMixins.add(mixinClassName); + } } diff --git a/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java b/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java new file mode 100644 index 0000000..6996818 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java @@ -0,0 +1,44 @@ +package moe.nea.firmament.mixins; + +import moe.nea.firmament.features.chat.CopyChat; +import moe.nea.firmament.mixins.accessor.AccessorChatHud; +import moe.nea.firmament.util.ClipboardUtils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.client.gui.hud.ChatHudLine; +import net.minecraft.client.gui.screen.ChatScreen; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.MathHelper; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.List; + +@Mixin(ChatScreen.class) +public class CopyChatPatch { + @Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true) + private void onRightClick(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) throws NoSuchFieldException, IllegalAccessException { + if (button != 1 || !CopyChat.TConfig.INSTANCE.getCopyChat()) return; + MinecraftClient client = MinecraftClient.getInstance(); + ChatHud chatHud = client.inGameHud.getChatHud(); + int lineIndex = getChatLineIndex(chatHud, mouseY); + if (lineIndex < 0) return; + List<ChatHudLine.Visible> visible = ((AccessorChatHud) chatHud).getVisibleMessages_firmament(); + if (lineIndex >= visible.size()) return; + ChatHudLine.Visible line = visible.get(lineIndex); + String text = CopyChat.INSTANCE.orderedTextToString(line.content()); + ClipboardUtils.INSTANCE.setTextContent(text); + chatHud.addMessage(Text.literal("Copied: ").append(text).formatted(Formatting.GRAY)); + cir.setReturnValue(true); + cir.cancel(); + } + + @Unique + private int getChatLineIndex(ChatHud chatHud, double mouseY) { + double chatLineY = ((AccessorChatHud) chatHud).toChatLineY_firmament(mouseY); + return MathHelper.floor(chatLineY + ((AccessorChatHud) chatHud).getScrolledLines_firmament()); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java b/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java new file mode 100644 index 0000000..f1b07bb --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java @@ -0,0 +1,17 @@ +package moe.nea.firmament.mixins; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import moe.nea.firmament.events.WorldMouseMoveEvent; +import net.minecraft.client.Mouse; +import net.minecraft.client.network.ClientPlayerEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Mouse.class) +public class DispatchMouseInputEventsPatch { + @WrapWithCondition(method = "updateMouse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;changeLookDirection(DD)V")) + public boolean onRotatePlayer(ClientPlayerEntity instance, double deltaX, double deltaY) { + var event = WorldMouseMoveEvent.Companion.publish(new WorldMouseMoveEvent(deltaX, deltaY)); + return !event.getCancelled(); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java b/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java index 85c0462..49e86fb 100644 --- a/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java +++ b/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java @@ -4,6 +4,7 @@ package moe.nea.firmament.mixins; import moe.nea.firmament.events.HotbarItemRenderEvent; import moe.nea.firmament.events.HudRenderEvent; +import moe.nea.firmament.features.fixes.Fixes; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.render.RenderTickCounter; @@ -26,4 +27,10 @@ public class HudRenderEventsPatch { if (stack != null && !stack.isEmpty()) HotbarItemRenderEvent.Companion.publish(new HotbarItemRenderEvent(stack, context, x, y, tickCounter)); } + + @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"), cancellable = true) + public void hideStatusEffects(CallbackInfo ci) { + if (Fixes.TConfig.INSTANCE.getHidePotionEffectsHud()) ci.cancel(); + } + } diff --git a/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java b/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java index 48f3c23..d2b3f91 100644 --- a/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java +++ b/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java @@ -2,18 +2,19 @@ package moe.nea.firmament.mixins; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import moe.nea.firmament.events.WorldKeyboardEvent; import net.minecraft.client.Keyboard; +import net.minecraft.client.util.InputUtil; 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(Keyboard.class) public class KeyPressInWorldEventPatch { - @Inject(method = "onKey", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V")) - public void onKeyBoardInWorld(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { - WorldKeyboardEvent.Companion.publish(new WorldKeyboardEvent(key, scancode, modifiers)); - } + @WrapWithCondition(method = "onKey", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V")) + public boolean onKeyBoardInWorld(InputUtil.Key key, long window, int _key, int scancode, int action, int modifiers) { + var event = WorldKeyboardEvent.Companion.publish(new WorldKeyboardEvent(_key, scancode, modifiers)); + return !event.getCancelled(); + } } diff --git a/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java b/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java new file mode 100644 index 0000000..1673987 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java @@ -0,0 +1,26 @@ +package moe.nea.firmament.mixins; + +import moe.nea.firmament.util.mc.InitLevel; +import net.minecraft.client.MinecraftClient; +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(MinecraftClient.class) +public class MinecraftInitLevelListener { + @Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;initBackendSystem()Lnet/minecraft/util/TimeSupplier$Nanoseconds;")) + private void onInitRenderBackend(CallbackInfo ci) { + InitLevel.bump(InitLevel.RENDER_INIT); + } + + @Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;initRenderer(JIZLjava/util/function/BiFunction;Z)V")) + private void onInitRender(CallbackInfo ci) { + InitLevel.bump(InitLevel.RENDER); + } + + @Inject(method = "<init>", at = @At(value = "TAIL")) + private void onFinishedLoading(CallbackInfo ci) { + InitLevel.bump(InitLevel.MAIN_MENU); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java b/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java new file mode 100644 index 0000000..2dbe738 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java @@ -0,0 +1,16 @@ +package moe.nea.firmament.mixins; + +import moe.nea.firmament.features.fixes.Fixes; +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; +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(value = RecipeBookScreen.class, priority = 999) +public class MixinRecipeBookScreen { + @Inject(method = "addRecipeBook", at = @At("HEAD"), cancellable = true) + public void addRecipeBook(CallbackInfo ci) { + if (Fixes.TConfig.INSTANCE.getHideRecipeBook()) ci.cancel(); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java index 72a72f0..d164aac 100644 --- a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java +++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java @@ -4,6 +4,7 @@ import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.ChatHudLine; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; import java.util.List; @@ -11,4 +12,13 @@ import java.util.List; public interface AccessorChatHud { @Accessor("messages") List<ChatHudLine> getMessages_firmament(); + + @Accessor("visibleMessages") + List<ChatHudLine.Visible> getVisibleMessages_firmament(); + + @Accessor("scrolledLines") + int getScrolledLines_firmament(); + + @Invoker("toChatLineY") + double toChatLineY_firmament(double y); } diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java index 7ed04b1..f55ef4f 100644 --- a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java +++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java @@ -1,5 +1,3 @@ - - package moe.nea.firmament.mixins.accessor; import net.minecraft.client.gui.screen.ingame.HandledScreen; diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java new file mode 100644 index 0000000..81ea0fd --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java @@ -0,0 +1,31 @@ +package moe.nea.firmament.mixins.accessor; + +import net.minecraft.client.gui.hud.PlayerListHud; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.Comparator; +import java.util.List; + +@Mixin(PlayerListHud.class) +public interface AccessorPlayerListHud { + + @Accessor("ENTRY_ORDERING") + static Comparator<PlayerListEntry> getEntryOrdering() { + throw new AssertionError(); + } + + @Invoker("collectPlayerEntries") + List<PlayerListEntry> collectPlayerEntries_firmament(); + + @Accessor("footer") + @Nullable Text getFooter_firmament(); + + @Accessor("header") + @Nullable Text getHeader_firmament(); + +} diff --git a/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java b/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java new file mode 100644 index 0000000..0abed22 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java @@ -0,0 +1,25 @@ +package moe.nea.firmament.mixins.feature; + +import moe.nea.firmament.features.fixes.Fixes; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; +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; + +@Mixin(Slot.class) +public abstract class DisableSlotHighlights { + @Shadow + public abstract ItemStack getStack(); + + @Inject(method = "canBeHighlighted", at = @At("HEAD"), cancellable = true) + private void dontHighlight(CallbackInfoReturnable<Boolean> cir) { + if (!Fixes.TConfig.INSTANCE.getHideSlotHighlights()) return; + var display = getStack().get(DataComponentTypes.TOOLTIP_DISPLAY); + if (display != null && display.hideTooltip()) + cir.setReturnValue(false); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java new file mode 100644 index 0000000..5a92f89 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java @@ -0,0 +1,43 @@ +package moe.nea.firmament.mixins.feature.devcosmetics; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import kotlin.Unit; +import moe.nea.firmament.features.misc.CustomCapes; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.feature.CapeFeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.entity.model.PlayerEntityModel; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +import net.minecraft.client.util.SkinTextures; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(CapeFeatureRenderer.class) +public abstract class CustomCapeFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState, PlayerEntityModel> { + public CustomCapeFeatureRenderer(FeatureRendererContext<PlayerEntityRenderState, PlayerEntityModel> context) { + super(context); + } + + @WrapOperation( + method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/PlayerEntityRenderState;FF)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/model/BipedEntityModel;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;II)V") + ) + private void onRender(BipedEntityModel instance, MatrixStack matrixStack, VertexConsumer vertexConsumer, int light, int overlay, Operation<Void> original, @Local PlayerEntityRenderState playerEntityRenderState, @Local SkinTextures skinTextures, @Local VertexConsumerProvider vertexConsumerProvider) { + CustomCapes.render( + playerEntityRenderState, + vertexConsumer, + RenderLayer.getEntitySolid(skinTextures.capeTexture()), + vertexConsumerProvider, + updatedConsumer -> { + original.call(instance, matrixStack, updatedConsumer, light, overlay); + return Unit.INSTANCE; + }); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java new file mode 100644 index 0000000..428d7ec --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java @@ -0,0 +1,23 @@ +package moe.nea.firmament.mixins.feature.devcosmetics; + +import moe.nea.firmament.features.misc.CustomCapes; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(PlayerEntityRenderState.class) +public class CustomCapeStorage implements CustomCapes.CapeStorage { + @Unique + CustomCapes.CustomCape customCape; + + @Override + public CustomCapes.@Nullable CustomCape getCape_firmament() { + return customCape; + } + + @Override + public void setCape_firmament(CustomCapes.@Nullable CustomCape customCape) { + this.customCape = customCape; + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java new file mode 100644 index 0000000..ae9c743 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java @@ -0,0 +1,19 @@ +package moe.nea.firmament.mixins.feature.devcosmetics; + +import moe.nea.firmament.features.misc.CustomCapes; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.entity.PlayerEntityRenderer; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +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(PlayerEntityRenderer.class) +public class SaveCapeToPlayerEntityRenderState { + @Inject(method = "updateRenderState(Lnet/minecraft/client/network/AbstractClientPlayerEntity;Lnet/minecraft/client/render/entity/state/PlayerEntityRenderState;F)V", + at = @At("TAIL")) + private void addCustomCape(AbstractClientPlayerEntity abstractClientPlayerEntity, PlayerEntityRenderState playerEntityRenderState, float f, CallbackInfo ci) { + CustomCapes.addCapeData(abstractClientPlayerEntity, playerEntityRenderState); + } +} |