Fixed Font Cache in <= 1.12.2

This commit is contained in:
FlorianMichael 2023-04-19 19:57:51 +02:00
parent c4cb0c52c2
commit 2dd154203c
10 changed files with 305 additions and 0 deletions

View File

@ -20,6 +20,7 @@ package de.florianmichael.viafabricplus;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import de.florianmichael.viafabricplus.definition.ChatLengthCalculation;
import de.florianmichael.viafabricplus.definition.v1_12_2.FontCacheFix;
import de.florianmichael.viafabricplus.mappings.ItemReleaseVersionMappings;
import de.florianmichael.viafabricplus.mappings.PackFormatsMappings;
import de.florianmichael.viafabricplus.definition.bedrock.BedrockAccountHandler;
@ -62,6 +63,7 @@ public class ViaFabricPlus {
// Protocol Translator
ChatLengthCalculation.create();
FontCacheFix.init();
ProtocolHack.init();
FinishMinecraftLoadCallback.EVENT.register(() -> {

View File

@ -0,0 +1,122 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.definition.v1_12_2;
import com.mojang.blaze3d.systems.RenderSystem;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.injection.access.IFontStorage;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.groups.ExperimentalSettings;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.Glyph;
import net.minecraft.client.font.GlyphRenderer;
import net.minecraft.client.font.RenderableGlyph;
import net.minecraft.client.texture.NativeImage;
import java.util.function.Function;
import java.util.function.Supplier;
public class FontCacheFix {
public final static boolean DASH_LOADER = FabricLoader.getInstance().isModLoaded("dashloader");
public static void init() {
if (DASH_LOADER) return;
ChangeProtocolVersionCallback.EVENT.register(protocolVersion -> MinecraftClient.getInstance().fontManager.fontStorages.values().forEach(fontStorage -> {
RenderSystem.recordRenderCall(() -> {
((IFontStorage) fontStorage).viafabricplus_clearCaches();
});
}));
}
public static boolean shouldReplaceFontRenderer() {
if (ViaLoadingBase.getInstance() == null || DASH_LOADER) return false;
return ExperimentalSettings.INSTANCE.fixFontCache.getValue() && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(ProtocolVersion.v1_12_2);
}
public enum BuiltinEmptyGlyph1_12_2 implements Glyph {
VERY_MISSING(() -> BuiltinEmptyGlyph1_12_2.createRectImage((x, y) -> {
boolean bl = x == 0 || x + 1 == 5 || y == 0 || y + 1 == 8;
return bl ? -1 : 0;
}));
final NativeImage image;
BuiltinEmptyGlyph1_12_2(Supplier<NativeImage> imageSupplier) {
this.image = imageSupplier.get();
}
private static NativeImage createRectImage(BuiltinEmptyGlyph1_12_2.ColorSupplier colorSupplier) {
final NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, 5, 8, false);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 5; ++j) {
nativeImage.setColor(j, i, colorSupplier.getColor(j, i));
}
}
nativeImage.untrack();
return nativeImage;
}
@Override
public float getAdvance() {
return this.image.getWidth() + 1;
}
@Override
public GlyphRenderer bake(Function<RenderableGlyph, GlyphRenderer> function) {
return function.apply(new RenderableGlyph() {
@Override
public int getWidth() {
return BuiltinEmptyGlyph1_12_2.this.image.getWidth();
}
@Override
public int getHeight() {
return BuiltinEmptyGlyph1_12_2.this.image.getHeight();
}
@Override
public float getOversample() {
return 1.0f;
}
@Override
public void upload(int x, int y) {
BuiltinEmptyGlyph1_12_2.this.image.upload(0, x, y, false);
}
@Override
public boolean hasColor() {
return true;
}
});
}
@FunctionalInterface
interface ColorSupplier {
int getColor(int var1, int var2);
}
}
}

View File

@ -0,0 +1,23 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.access;
public interface IFontStorage {
void viafabricplus_clearCaches();
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.font;
import de.florianmichael.viafabricplus.definition.v1_12_2.FontCacheFix;
import net.minecraft.client.font.BuiltinEmptyGlyph;
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.CallbackInfoReturnable;
@Mixin(BuiltinEmptyGlyph.class)
public class MixinBuiltinEmptyGlyph {
@Inject(method = "getAdvance", at = @At("HEAD"), cancellable = true)
public void resetAdvance(CallbackInfoReturnable<Float> cir) {
if (FontCacheFix.shouldReplaceFontRenderer()) {
cir.setReturnValue(0F);
}
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.font;
import de.florianmichael.viafabricplus.definition.v1_12_2.FontCacheFix;
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.CallbackInfoReturnable;
@Mixin(targets = "net/minecraft/client/font/BuiltinEmptyGlyph$1")
public class MixinBuiltinEmptyGlyph_1 {
@Inject(method = {"getWidth", "getHeight"}, at = @At("HEAD"), cancellable = true)
public void resetDimension(CallbackInfoReturnable<Integer> cir) {
if (FontCacheFix.shouldReplaceFontRenderer()) {
cir.setReturnValue(0);
}
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.font;
import de.florianmichael.viafabricplus.definition.v1_12_2.FontCacheFix;
import de.florianmichael.viafabricplus.injection.access.IFontStorage;
import net.minecraft.client.font.Font;
import net.minecraft.client.font.FontStorage;
import net.minecraft.client.font.GlyphRenderer;
import net.minecraft.client.font.RenderableGlyph;
import org.spongepowered.asm.mixin.Final;
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.List;
@Mixin(FontStorage.class)
public abstract class MixinFontStorage implements IFontStorage {
@Shadow protected abstract GlyphRenderer getGlyphRenderer(RenderableGlyph c);
@Shadow @Final private List<Font> fonts;
@Shadow public abstract void setFonts(List<Font> fonts);
@Unique
private GlyphRenderer unknownGlyphRenderer;
@Unique
private List<Font> viafabricplus_fontCache;
@Inject(method = "setFonts", at = @At("HEAD"))
public void cacheFonts(List<Font> fonts, CallbackInfo ci) {
if (viafabricplus_fontCache == fonts) return;
viafabricplus_fontCache = fonts;
}
@Inject(method = "setFonts", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/BuiltinEmptyGlyph;bake(Ljava/util/function/Function;)Lnet/minecraft/client/font/GlyphRenderer;", ordinal = 0, shift = At.Shift.AFTER))
public void injectSetFonts(List<Font> fonts, CallbackInfo ci) {
this.unknownGlyphRenderer = FontCacheFix.BuiltinEmptyGlyph1_12_2.VERY_MISSING.bake(this::getGlyphRenderer);
}
@Inject(method = "getRectangleRenderer", at = @At("HEAD"), cancellable = true)
public void setCustomRenderer(CallbackInfoReturnable<GlyphRenderer> cir) {
if (FontCacheFix.shouldReplaceFontRenderer()) {
cir.setReturnValue(this.unknownGlyphRenderer);
}
}
@Override
public void viafabricplus_clearCaches() {
if (fonts != null) {
fonts.clear();
if (viafabricplus_fontCache != null) {
setFonts(viafabricplus_fontCache);
}
}
}
}

View File

@ -26,6 +26,7 @@ public class ExperimentalSettings extends SettingGroup {
public final BooleanSetting fixChunkBorders = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.chunkborderfix"), true);
public final BooleanSetting waterMovementEdgeDetection = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.watermovement"), true);
public final BooleanSetting fixFontCache = new BooleanSetting(this, Text.translatable("experimental.viafabricplus.fontcachefix"), true);
public ExperimentalSettings() {
super("Experimental");

View File

@ -23,6 +23,7 @@
"experimental.viafabricplus.chunkborderfix": "Fix Chunk borders",
"experimental.viafabricplus.watermovement": "Water movement edge detection",
"experimental.viafabricplus.fontcachefix": "Fix Font Cache",
"debug.viafabricplus.sequence": "Disable sequencing",
"debug.viafabricplus.merchant": "Smooth out merchant screens",

View File

@ -6,5 +6,7 @@ accessible field net/minecraft/client/gui/screen/ConnectScreen connection Lnet/m
accessible field net/minecraft/network/ClientConnection channel Lio/netty/channel/Channel;
accessible field net/minecraft/client/network/ServerAddress INVALID Lnet/minecraft/client/network/ServerAddress;
accessible field net/minecraft/client/network/ServerAddress hostAndPort Lcom/google/common/net/HostAndPort;
accessible field net/minecraft/client/MinecraftClient fontManager Lnet/minecraft/client/font/FontManager;
accessible field net/minecraft/client/font/FontManager fontStorages Ljava/util/Map;
accessible class net/minecraft/client/gui/screen/GameModeSelectionScreen$GameModeSelection

View File

@ -76,6 +76,9 @@
"fixes.minecraft.entity.MixinSquidEntity",
"fixes.minecraft.entity.MixinVexEntity",
"fixes.minecraft.entity.MixinWolfEntity",
"fixes.minecraft.font.MixinBuiltinEmptyGlyph",
"fixes.minecraft.font.MixinBuiltinEmptyGlyph_1",
"fixes.minecraft.font.MixinFontStorage",
"fixes.minecraft.input.MixinKeyboard",
"fixes.minecraft.input.MixinKeyboardInput",
"fixes.minecraft.input.MixinMouse",