aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/firmament
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/moe/nea/firmament')
-rw-r--r--src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java36
-rw-r--r--src/main/java/moe/nea/firmament/init/MixinPlugin.java103
-rw-r--r--src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java183
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java44
-rw-r--r--src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java17
-rw-r--r--src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java7
-rw-r--r--src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java13
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java26
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java16
-rw-r--r--src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java2
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java8
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java30
-rw-r--r--src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java6
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java10
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java2
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java31
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java25
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java43
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java23
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java19
20 files changed, 462 insertions, 182 deletions
diff --git a/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java b/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
index 0713068..a9db7f9 100644
--- a/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
+++ b/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
@@ -1,6 +1,9 @@
package moe.nea.firmament.init;
+import moe.nea.firmament.util.ErrorUtil;
+import moe.nea.firmament.util.compatloader.ICompatMeta;
+
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -94,7 +97,7 @@ public class AutoDiscoveryPlugin {
String norm = (className.substring(0, className.length() - ".class".length()))
.replace("\\", "/")
.replace("/", ".");
- if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
+ if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".") && ICompatMeta.Companion.shouldLoad(norm)) {
mixins.add(norm.substring(getMixinPackage().length() + 1));
}
}
@@ -125,24 +128,25 @@ public class AutoDiscoveryPlugin {
*/
public List<String> getMixins() {
if (mixins != null) return mixins;
- System.out.println("Trying to discover mixins");
- mixins = new ArrayList<>();
- URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
- System.out.println("Found classes at " + classUrl);
- tryDiscoverFromContentFile(classUrl);
- var classRoots = System.getProperty("firmament.classroots");
- if (classRoots != null && !classRoots.isBlank()) {
- System.out.println("Found firmament class roots: " + classRoots);
- for (String s : classRoots.split(File.pathSeparator)) {
- if (s.isBlank()) {
- continue;
- }
- try {
+ try {
+ System.out.println("Trying to discover mixins");
+ mixins = new ArrayList<>();
+ URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
+ System.out.println("Found classes at " + classUrl);
+ tryDiscoverFromContentFile(classUrl);
+ var classRoots = System.getProperty("firmament.classroots");
+ if (classRoots != null && !classRoots.isBlank()) {
+ System.out.println("Found firmament class roots: " + classRoots);
+ for (String s : classRoots.split(File.pathSeparator)) {
+ if (s.isBlank()) {
+ continue;
+ }
tryDiscoverFromContentFile(new File(s).toURI().toURL());
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
}
}
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
}
return mixins;
}
diff --git a/src/main/java/moe/nea/firmament/init/MixinPlugin.java b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
index 61e8f14..d48139b 100644
--- a/src/main/java/moe/nea/firmament/init/MixinPlugin.java
+++ b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
@@ -8,54 +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();
- public static String mixinPackage;
- @Override
- public void onLoad(String mixinPackage) {
- MixinExtrasBootstrap.init();
- MixinPlugin.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 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) {
-
- }
-
- public static List<String> appliedMixins = new ArrayList<>();
-
- @Override
- public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- appliedMixins.add(mixinClassName);
- }
+ AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin();
+ public static List<MixinPlugin> instances = new ArrayList<>();
+ public String mixinPackage;
+
+ @Override
+ public void onLoad(String mixinPackage) {
+ MixinExtrasBootstrap.init();
+ instances.add(this);
+ 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 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) {
+
+ }
+
+ 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<>();
+
+ @Override
+ public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+ appliedMixins.add(mixinClassName);
+ }
}
diff --git a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
index f2c6c53..8b65946 100644
--- a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
+++ b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
@@ -3,10 +3,9 @@ package moe.nea.firmament.init;
import me.shedaniel.mm.api.ClassTinkerers;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.BlockState;
-import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.chunk.SectionBuilder;
-import net.minecraft.client.render.model.BakedModel;
+import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.util.math.BlockPos;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@@ -20,98 +19,100 @@ import org.objectweb.asm.tree.VarInsnNode;
public class SectionBuilderRiser extends RiserUtils {
- @IntermediaryName(SectionBuilder.class)
- String SectionBuilder;
- @IntermediaryName(BlockPos.class)
- String BlockPos;
- @IntermediaryName(BlockRenderManager.class)
- String BlockRenderManager;
- @IntermediaryName(BlockState.class)
- String BlockState;
- @IntermediaryName(BakedModel.class)
- String BakedModel;
- String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
+ @IntermediaryName(SectionBuilder.class)
+ String SectionBuilder;
+ @IntermediaryName(BlockPos.class)
+ String BlockPos;
+ @IntermediaryName(BlockRenderManager.class)
+ String BlockRenderManager;
+ @IntermediaryName(BlockState.class)
+ String BlockState;
+ @IntermediaryName(BlockStateModel.class)
+ String BlockStateModel;
+ String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
- Type getModelDesc = Type.getMethodType(
- getTypeForClassName(BlockRenderManager),
- getTypeForClassName(BlockState)
- );
- String getModel = remapper.mapMethodName(
- "intermediary",
- Intermediary.<BlockRenderManager>className(),
- Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
- Type.getMethodDescriptor(
- getTypeForClassName(Intermediary.<BakedModel>className()),
- getTypeForClassName(Intermediary.<BlockState>className())
- )
- );
+ Type getModelDesc = Type.getMethodType(
+ getTypeForClassName(BlockRenderManager),
+ getTypeForClassName(BlockState)
+ );
+ String getModel = remapper.mapMethodName(
+ "intermediary",
+ Intermediary.<BlockRenderManager>className(),
+ Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
+ Type.getMethodDescriptor(
+ getTypeForClassName(Intermediary.<BlockStateModel>className()),
+ getTypeForClassName(Intermediary.<BlockState>className())
+ )
+ );
- @Override
- public void addTinkerers() {
- if (FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
- ClassTinkerers.addTransformation(SectionBuilder, this::handle, true);
- }
+ @Override
+ public void addTinkerers() {
+ if (FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
+ ClassTinkerers.addTransformation(SectionBuilder, this::handle, true);
+ }
- private void handle(ClassNode classNode) {
- for (MethodNode method : classNode.methods) {
- if ((method.name.endsWith("$fabric-renderer-indigo$hookBuildRenderBlock")
- || method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate")) &&
- method.name.startsWith("redirect$")) {
- handleIndigo(method);
- return;
- }
- }
- System.err.println("Could not inject indigo rendering hook. Is a custom renderer installed (e.g. sodium)?");
- }
+ private void handle(ClassNode classNode) {
+ System.out.println("AVAST! "+ getModel);
+ for (MethodNode method : classNode.methods) {
+ if ((method.name.endsWith("$fabric-renderer-indigo$hookBuildRenderBlock")
+ || method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate")) &&
+ method.name.startsWith("redirect$")) {
+ handleIndigo(method);
+ return;
+ }
+ }
+ System.err.println("Could not inject indigo rendering hook. Is a custom renderer installed (e.g. sodium)?");
+ }
- private void handleIndigo(MethodNode method) {
- LocalVariableNode blockPosVar = null, blockStateVar = null;
- for (LocalVariableNode localVariable : method.localVariables) {
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockPos))) {
- blockPosVar = localVariable;
- }
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockState))) {
- blockStateVar = localVariable;
- }
- }
- if (blockPosVar == null || blockStateVar == null) {
- System.err.println("Firmament could inject into indigo: missing either block pos or blockstate");
- return;
- }
- for (AbstractInsnNode instruction : method.instructions) {
- if (instruction.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
- var methodInsn = (MethodInsnNode) instruction;
- if (!(methodInsn.name.equals(getModel) && Type.getObjectType(methodInsn.owner).equals(getTypeForClassName(BlockRenderManager))))
- continue;
- method.instructions.insertBefore(
- methodInsn,
- new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "enterFallbackCall",
- Type.getMethodDescriptor(Type.VOID_TYPE)
- ));
+ private void handleIndigo(MethodNode method) {
+ LocalVariableNode blockPosVar = null, blockStateVar = null;
+ for (LocalVariableNode localVariable : method.localVariables) {
+ if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockPos))) {
+ blockPosVar = localVariable;
+ }
+ if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockState))) {
+ blockStateVar = localVariable;
+ }
+ }
+ if (blockPosVar == null || blockStateVar == null) {
+ System.err.println("Firmament could inject into indigo: missing either block pos or blockstate");
+ return;
+ }
+ for (AbstractInsnNode instruction : method.instructions) {
+ if (instruction.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
+ var methodInsn = (MethodInsnNode) instruction;
+ if (!(methodInsn.name.equals(getModel) && Type.getObjectType(methodInsn.owner).equals(getTypeForClassName(BlockRenderManager))))
+ continue;
+ method.instructions.insertBefore(
+ methodInsn,
+ new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "enterFallbackCall",
+ Type.getMethodDescriptor(Type.VOID_TYPE)
+ ));
- var insnList = new InsnList();
- insnList.add(new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "exitFallbackCall",
- Type.getMethodDescriptor(Type.VOID_TYPE)
- ));
- insnList.add(new VarInsnNode(Opcodes.ALOAD, blockPosVar.index));
- insnList.add(new VarInsnNode(Opcodes.ALOAD, blockStateVar.index));
- insnList.add(new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "patchIndigo",
- Type.getMethodDescriptor(getTypeForClassName(BakedModel),
- getTypeForClassName(BakedModel),
- getTypeForClassName(BlockPos),
- getTypeForClassName(BlockState)),
- false
- ));
- method.instructions.insert(methodInsn, insnList);
- }
- }
+ var insnList = new InsnList();
+ insnList.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "exitFallbackCall",
+ Type.getMethodDescriptor(Type.VOID_TYPE)
+ ));
+ insnList.add(new VarInsnNode(Opcodes.ALOAD, blockPosVar.index));
+ insnList.add(new VarInsnNode(Opcodes.ALOAD, blockStateVar.index));
+ insnList.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "patchIndigo",
+ Type.getMethodDescriptor(
+ getTypeForClassName(BlockStateModel),
+ getTypeForClassName(BlockStateModel),
+ getTypeForClassName(BlockPos),
+ getTypeForClassName(BlockState)),
+ false
+ ));
+ method.instructions.insert(methodInsn, insnList);
+ }
+ }
}
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/PlayerDropEventPatch.java b/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
index b20c223..f07604e 100644
--- a/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
@@ -20,7 +20,7 @@ public abstract class PlayerDropEventPatch extends PlayerEntity {
@Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true)
public void onDropSelectedItem(boolean entireStack, CallbackInfoReturnable<Boolean> cir) {
- Slot fakeSlot = new Slot(getInventory(), getInventory().selectedSlot, 0, 0);
+ Slot fakeSlot = new Slot(getInventory(), getInventory().getSelectedSlot(), 0, 0);
if (IsSlotProtectedEvent.shouldBlockInteraction(fakeSlot, SlotActionType.THROW, IsSlotProtectedEvent.MoveOrigin.DROP_FROM_HOTBAR)) {
cir.setReturnValue(false);
}
diff --git a/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
index 06ecbd4..a4ae931 100644
--- a/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
+++ b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
@@ -43,11 +43,11 @@ public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
var player = this.client.player;
assert player != null;
- if (packet.getSyncId() == 0) {
- PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.getContents()));
- } else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
+ if (packet.syncId() == 0) {
+ PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.contents()));
+ } else if (packet.syncId() == player.currentScreenHandler.syncId) {
ChestInventoryUpdateEvent.Companion.publish(
- new ChestInventoryUpdateEvent.Multi(packet.getContents())
+ new ChestInventoryUpdateEvent.Multi(packet.contents())
);
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java b/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
index 5c52d70..b8cba80 100644
--- a/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
@@ -1,30 +1,32 @@
package moe.nea.firmament.mixins;
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import moe.nea.firmament.events.SoundReceiveEvent;
import net.minecraft.client.network.ClientPlayNetworkHandler;
-import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.Entity;
+import net.minecraft.registry.entry.RegistryEntry;
+import net.minecraft.sound.SoundCategory;
+import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.Vec3d;
+import org.jetbrains.annotations.Nullable;
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(ClientPlayNetworkHandler.class)
public class SoundReceiveEventPatch {
- @Inject(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/player/PlayerEntity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"), cancellable = true)
- private void postEventWhenSoundIsPlayed(PlaySoundS2CPacket packet, CallbackInfo ci) {
+ @WrapWithCondition(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/Entity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"))
+ private boolean postEventWhenSoundIsPlayed(ClientWorld instance, @Nullable Entity source, double x, double y, double z, RegistryEntry<SoundEvent> sound, SoundCategory category, float volume, float pitch, long seed) {
var event = new SoundReceiveEvent(
- packet.getSound(),
- packet.getCategory(),
- new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
- packet.getPitch(),
- packet.getVolume(),
- packet.getSeed()
+ sound,
+ category,
+ new Vec3d(x,y,z),
+ pitch,
+ volume,
+ seed
);
SoundReceiveEvent.Companion.publish(event);
- if (event.getCancelled()) {
- ci.cancel();
- }
+ return !event.getCancelled();
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java b/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
index 847fb4d..3ed8c1b 100644
--- a/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
@@ -2,11 +2,9 @@
package moe.nea.firmament.mixins;
-import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.events.WorldRenderLastEvent;
import net.minecraft.client.render.*;
import net.minecraft.client.util.Handle;
-import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.profiler.Profiler;
import org.joml.Matrix4f;
@@ -31,12 +29,12 @@ public abstract class WorldRenderLastEventPatch {
protected abstract void checkEmpty(MatrixStack matrices);
@Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;pop()V", shift = At.Shift.AFTER))
- public void onWorldRenderLast(Fog fog, RenderTickCounter tickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, Handle handle3, Handle handle4, boolean bl, Frustum frustum, Handle handle5, CallbackInfo ci) {
+ public void onWorldRenderLast(Fog fog, RenderTickCounter renderTickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, boolean bl, Frustum frustum, Handle handle3, Handle handle4, CallbackInfo ci) {
var imm = this.bufferBuilders.getEntityVertexConsumers();
var stack = new MatrixStack();
// TODO: pre-cancel this event if F1 is active
var event = new WorldRenderLastEvent(
- stack, tickCounter,
+ stack, renderTickCounter,
camera,
imm
);
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);
+ }
+}