Skip to content

Commit

Permalink
add missing mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
Luna0x01 committed Jan 31, 2025
1 parent a39c22d commit 869bb5d
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package net.coderbot.iris.mixin;

import net.coderbot.iris.Iris;
import net.coderbot.iris.shaderpack.LanguageMap;
import net.coderbot.iris.shaderpack.ShaderPack;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.resource.ResourceManager;
import org.spongepowered.asm.mixin.Mixin;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
* Allows shader packs to provide extra usable language entries outside of resource packs.
*
* <p>We "sideload" the language entries with an override system to avoid having to reload the
* resource manager on shader pack changes, since reloading the resource manager is very slow.</p>
*
* Uses a lower priority to inject before Incubus-Core to prevent translations from breaking
* @see <a href="https://github.com/devs-immortal/Incubus-Core/blob/4edfff0f088bc1b7ea77a1d475f76801a03179a4/src/main/java/net/id/incubus_core/mixin/devel/client/TranslationStorageMixin.java">Incubus-Core translation mixin</a>
*/
@Mixin(value = TranslationStorage.class, priority = 990)
public class MixinClientLanguage {
// storage
@Shadow Map<String, String> translations;

@Unique
private static final List<String> languageCodes = new ArrayList<>();

@Inject(method = "translate", at = @At("HEAD"), cancellable = true)
private void iris$overrideLanguageEntries(String key, CallbackInfoReturnable<String> cir) {
final String override = iris$lookupOverriddenEntry(key);

if (override != null) {
cir.setReturnValue(override);
}
}

@Unique
private String iris$lookupOverriddenEntry(String key) {
final ShaderPack pack = Iris.getCurrentPack().orElse(null);

if (pack == null) {
// If no shaderpack is loaded, do not try to process language overrides.
//
// This prevents a cryptic NullPointerException when shaderpack loading fails for some reason.
return null;
}

// Minecraft loads the "en_US" language code by default, and any other code will be right after it.
//
// So we also check if the user is loading a special language, and if the shaderpack has support for that
// language. If they do, we load that, but if they do not, we load "en_US" instead.
final LanguageMap languageMap = pack.getLanguageMap();

if (translations.containsKey(key)) {
return null;
}

for (String code : languageCodes) {
final Map<String, String> translations = languageMap.getTranslations(code);

if (translations != null) {
final String translation = translations.get(key);

if (translation != null) {
return translation;
}
}
}

return null;
}

@Inject(method = "load(Lnet/minecraft/resource/ResourceManager;Ljava/util/List;)V", at = @At("HEAD"))
private void iris$addLanguageCodes(ResourceManager resourceManager, List<String> definitions, CallbackInfo ci) {
languageCodes.clear();

// Reverse order due to how minecraft has English and then the primary language in the language definitions list
new LinkedList<>(definitions).descendingIterator().forEachRemaining(languageCodes::add);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.coderbot.iris.mixin;

import net.caffeinemc.mods.sodium.mixin.features.options.MinecraftClientMixin;
import net.coderbot.iris.Iris;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.profiler.Profiler;
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.CallbackInfo;

/**
* Small hook giving Iris a chance to check for keyboard input for its keybindings.
*
* <p>This is equivalent to the END_CLIENT_TICK event in Fabric API, but since it's a super simple mixin and we
* only need this event (out of the many events provided by Fabric API) I've just implemented it myself. This
* alone shaves over 60kB off the released JAR size.</p>
*/
@Mixin(MinecraftClient.class)
public class MixinMinecraft_Keybinds {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.coderbot.iris.mixin;

import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.caffeinemc.mods.sodium.mixin.features.options.MinecraftClientMixin;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
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;

/**
* Suppresses Minecraft's authentication check in development environments. It's unnecessary log spam, and there's no
* need to send off a network request to Microsoft telling them that we're using Fabric/Quilt every time we launch the
* game in the development environment.
*/
@Mixin(MinecraftClient.class)
public class MixinMinecraft_NoAuthInDev {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package net.coderbot.iris.mixin.vertices.block_rendering;

import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.coderbot.iris.vertices.BlockSensitiveBufferBuilder;
import net.coderbot.iris.vertices.ExtendedDataHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import java.util.Iterator;
import java.util.Random;
import java.util.Set;

/**
* Captures and tracks the current block being rendered.
*
* Uses a priority of 999 so that we apply before Indigo's mixins.
*/
@Mixin(BlockModelRenderer.class)
public class MixinChunkRebuildTask {
@Unique
private BlockSensitiveBufferBuilder lastBufferBuilder;

// Resolve the ID map on the main thread to avoid thread safety issues
@Unique
private final Object2IntMap<BlockState> blockStateIds = getBlockStateIds();

@Unique
private Object2IntMap<BlockState> getBlockStateIds() {
return BlockRenderingSettings.INSTANCE.getBlockStateIds();
}

@Unique
private short resolveBlockId(BlockState state) {
if (blockStateIds == null) {
return -1;
}

return (short) blockStateIds.getOrDefault(state, -1);
}

@Inject(method = "render(Lnet/minecraft/world/BlockView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/render/BufferBuilder;Z)Z", at = @At(value = "HEAD"))
private void iris$onRenderBlock(BlockView world, BakedModel model, BlockState state, BlockPos pos, BufferBuilder buffer, boolean cull, CallbackInfoReturnable<Boolean> cir) {
try {
if (buffer instanceof BlockSensitiveBufferBuilder) {
lastBufferBuilder = ((BlockSensitiveBufferBuilder) buffer);
lastBufferBuilder.beginBlock(resolveBlockId(state), ExtendedDataHelper.BLOCK_RENDER_TYPE, pos.getX() & 0xF, pos.getY() & 0xF, pos.getZ() & 0xF);
}
} catch (Throwable e) {}
}

@Inject(method = "render(Lnet/minecraft/world/BlockView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/render/BufferBuilder;Z)Z", at = @At(value = "RETURN"))
private void iris$finishRenderingBlock(BlockView world, BakedModel model, BlockState state, BlockPos pos, BufferBuilder buffer, boolean cull, CallbackInfoReturnable<Boolean> cir) {
if (lastBufferBuilder != null) {
lastBufferBuilder.endBlock();
lastBufferBuilder = null;
}
}
}

0 comments on commit 869bb5d

Please sign in to comment.