From d4bb5a94308d4379ef3d6cc7b9221ea0d98ff051 Mon Sep 17 00:00:00 2001
From: Wyvest <45589059+Wyvest@users.noreply.github.com>
Date: Sat, 2 Jul 2022 06:12:23 +0700
Subject: Separate Minecraft dependant and non-dependant code
---
.../cc/polyfrost/oneconfig/internal/OneConfig.java | 93 +++++++++++++++
.../internal/gui/impl/BlurHandlerImpl.java | 132 +++++++++++++++++++++
.../internal/mixin/GuiIngameForgeMixin.java | 19 +++
.../oneconfig/internal/mixin/MinecraftMixin.java | 100 ++++++++++++++++
.../internal/mixin/NetHandlerPlayClientMixin.java | 38 ++++++
.../internal/mixin/NetworkManagerMixin.java | 25 ++++
.../internal/mixin/OptifineConfigMixin.java | 23 ++++
.../internal/mixin/ShaderGroupAccessor.java | 16 +++
.../oneconfig/internal/mixin/VigilantMixin.java | 10 ++
.../oneconfig/internal/mixin/WorldClientMixin.java | 23 ++++
.../internal/plugin/asm/ClassTransformer.java | 102 ++++++++++++++++
.../internal/plugin/asm/ITransformer.java | 24 ++++
.../internal/plugin/asm/OneConfigTweaker.java | 117 ++++++++++++++++++
.../asm/tweakers/NanoVGGLConfigTransformer.java | 47 ++++++++
.../plugin/asm/tweakers/VigilantTransformer.java | 89 ++++++++++++++
.../plugin/hooks/Lwjgl2FunctionProvider.java | 47 ++++++++
.../internal/plugin/hooks/OptifineConfigHook.java | 22 ++++
.../internal/plugin/hooks/VigilantHook.java | 26 ++++
18 files changed, 953 insertions(+)
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/OneConfig.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/gui/impl/BlurHandlerImpl.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/OptifineConfigMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ShaderGroupAccessor.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/VigilantMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/OneConfigTweaker.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/OptifineConfigHook.java
create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/VigilantHook.java
(limited to 'versions/src/main/java/cc/polyfrost/oneconfig/internal')
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/OneConfig.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/OneConfig.java
new file mode 100644
index 0000000..7ecfe98
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/OneConfig.java
@@ -0,0 +1,93 @@
+package cc.polyfrost.oneconfig.internal;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ShutdownEvent;
+import cc.polyfrost.oneconfig.internal.command.OneConfigCommand;
+import cc.polyfrost.oneconfig.internal.config.OneConfigConfig;
+import cc.polyfrost.oneconfig.internal.config.Preferences;
+import cc.polyfrost.oneconfig.internal.config.core.ConfigCore;
+import cc.polyfrost.oneconfig.internal.config.core.KeyBindHandler;
+import cc.polyfrost.oneconfig.internal.gui.BlurHandler;
+import cc.polyfrost.oneconfig.internal.hud.HudCore;
+import cc.polyfrost.oneconfig.libs.eventbus.Subscribe;
+import cc.polyfrost.oneconfig.utils.commands.CommandManager;
+import cc.polyfrost.oneconfig.utils.gui.GuiUtils;
+import cc.polyfrost.oneconfig.utils.hypixel.HypixelUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.util.ServiceLoader;
+
+/**
+ * The main class of OneConfig.
+ */
+@net.minecraftforge.fml.common.Mod(modid = "@ID@", name = "@NAME@", version = "@VER@")
+public class OneConfig {
+
+ public OneConfig() {
+ EventManager.INSTANCE.register(this);
+ }
+
+ public static final File oneConfigDir = new File("./OneConfig");
+ public static final Logger LOGGER = LogManager.getLogger("@NAME@");
+ private static boolean preLaunched = false;
+ private static boolean initialized = false;
+ private static boolean isObfuscated = true;
+
+ /**
+ * Called before mods are loaded.
+ *
SHOULD NOT BE CALLED!
+ */
+ public static void preLaunch() {
+ if (preLaunched) return;
+ try {
+ Class.forName("net.minecraft.world.World");
+ LOGGER.warn("OneConfig is NOT obfuscated!");
+ isObfuscated = false;
+ } catch (Exception ignored) {
+ }
+ oneConfigDir.mkdirs();
+ new File(oneConfigDir, "profiles").mkdirs();
+ if (OneConfigConfig.getInstance() == null) {
+ OneConfigConfig.getInstance();
+ }
+ if (Preferences.getInstance() == null) {
+ Preferences.getInstance();
+ }
+ preLaunched = true;
+ }
+
+ /**
+ * Called after mods are loaded.
+ * SHOULD NOT BE CALLED!
+ */
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public static void init() {
+ if (initialized) return;
+ GuiUtils.getDeltaTime(); // called to make sure static initializer is called
+ try {
+ EventManager.INSTANCE.register(BlurHandler.INSTANCE);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ CommandManager.INSTANCE.registerCommand(OneConfigCommand.class);
+ EventManager.INSTANCE.register(new HudCore());
+ HypixelUtils.INSTANCE.initialize();
+ EventManager.INSTANCE.register(KeyBindHandler.INSTANCE);
+ ConfigCore.sortMods();
+
+ initialized = true;
+ }
+
+ /** Returns weather this is an obfuscated environment, using a check for obfuscated name of net.minecraft.world.World.class.
+ * @return true if this is an obfuscated environment, which is normal for Minecraft or false if not. */
+ public static boolean isObfuscated() {
+ return isObfuscated;
+ }
+
+ @Subscribe
+ private void onShutdown(ShutdownEvent event) {
+ ConfigCore.saveAll();
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/gui/impl/BlurHandlerImpl.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/gui/impl/BlurHandlerImpl.java
new file mode 100644
index 0000000..0ef5f2b
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/gui/impl/BlurHandlerImpl.java
@@ -0,0 +1,132 @@
+package cc.polyfrost.oneconfig.internal.gui.impl;
+
+import cc.polyfrost.oneconfig.events.event.RenderEvent;
+import cc.polyfrost.oneconfig.events.event.ScreenOpenEvent;
+import cc.polyfrost.oneconfig.events.event.Stage;
+import cc.polyfrost.oneconfig.gui.OneConfigGui;
+import cc.polyfrost.oneconfig.internal.config.Preferences;
+import cc.polyfrost.oneconfig.internal.gui.BlurHandler;
+import cc.polyfrost.oneconfig.internal.mixin.ShaderGroupAccessor;
+import cc.polyfrost.oneconfig.libs.eventbus.Subscribe;
+import cc.polyfrost.oneconfig.libs.universal.UMinecraft;
+import cc.polyfrost.oneconfig.libs.universal.UScreen;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.shader.Shader;
+import net.minecraft.client.shader.ShaderUniform;
+import net.minecraft.util.ResourceLocation;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+
+/**
+ * An implementation of the BlurMC mod by tterrag1098.
+ *
+ * For the original source see ...
+ * For the public license, see ...
+ *
+ * License available under ...
+ *
+ * @author tterrag1098, boomboompower
+ *
+ * Taken from ToggleChat
+ * ...
+ */
+public class BlurHandlerImpl implements BlurHandler {
+ private final ResourceLocation blurShader = new ResourceLocation("shaders/post/fade_in_blur.json");
+ private final Logger logger = LogManager.getLogger("OneConfig - Blur");
+ private long start;
+ private float progress = 0;
+
+ @Subscribe
+ private void onGuiChange(ScreenOpenEvent event) {
+ reloadBlur(event.screen);
+ }
+
+ @Subscribe
+ private void onRenderTick(RenderEvent event) {
+ if (event.stage != Stage.END) {
+ return;
+ }
+
+ // Only blur on our own menus
+ if (UScreen.getCurrentScreen() == null) {
+ return;
+ }
+
+ // Only update the shader if one is active
+ if (!UMinecraft.getMinecraft().entityRenderer.isShaderActive()) {
+ return;
+ }
+ if (progress >= 5) return;
+ progress = getBlurStrengthProgress();
+
+ // This is hilariously bad, and could cause frame issues on low-end computers.
+ // Why is this being computed every tick? Surely there is a better way?
+ // This needs to be optimized.
+ try {
+ final List listShaders = ((ShaderGroupAccessor) Minecraft.getMinecraft().entityRenderer.getShaderGroup()).getListShaders();
+
+ // Should not happen. Something bad happened.
+ if (listShaders == null) {
+ return;
+ }
+
+ // Iterate through the list of shaders.
+ for (Shader shader : listShaders) {
+ ShaderUniform su = shader.getShaderManager().getShaderUniform("Progress");
+
+ if (su == null) {
+ continue;
+ }
+
+ // All this for this.
+ su.set(progress);
+ }
+ } catch (IllegalArgumentException ex) {
+ this.logger.error("An error.png occurred while updating OneConfig's blur. Please report this!", ex);
+ }
+ }
+
+ /**
+ * Activates/deactivates the blur in the current world if
+ * one of many conditions are met, such as no current other shader
+ * is being used, we actually have the blur setting enabled
+ */
+ public void reloadBlur(Object gui) {
+ // Don't do anything if no world is loaded
+ if (UMinecraft.getWorld() == null) {
+ return;
+ }
+
+ // If a shader is not already active and the UI is
+ // a one of ours, we should load our own blur!
+
+ if (!UMinecraft.getMinecraft().entityRenderer.isShaderActive() && gui instanceof OneConfigGui && Preferences.enableBlur) {
+ UMinecraft.getMinecraft().entityRenderer.loadShader(this.blurShader);
+
+ this.start = System.currentTimeMillis();
+ this.progress = 0;
+
+ // If a shader is active and the incoming UI is null or we have blur disabled, stop using the shader.
+ } else if (UMinecraft.getMinecraft().entityRenderer.isShaderActive() && (gui == null || !Preferences.enableBlur)) {
+ String name = UMinecraft.getMinecraft().entityRenderer.getShaderGroup().getShaderGroupName();
+
+ // Only stop our specific blur ;)
+ if (!name.endsWith("fade_in_blur.json")) {
+ return;
+ }
+
+ UMinecraft.getMinecraft().entityRenderer.stopUseShader();
+ }
+ }
+
+ /**
+ * Returns the strength of the blur as determined by the duration the effect of the blur.
+ *
+ * The strength of the blur does not go below 5.0F.
+ */
+ private float getBlurStrengthProgress() {
+ return Math.min((System.currentTimeMillis() - this.start) / 50F, 5.0F);
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java
new file mode 100644
index 0000000..2a89972
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/GuiIngameForgeMixin.java
@@ -0,0 +1,19 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.HudRenderEvent;
+import net.minecraftforge.client.GuiIngameForge;
+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 = GuiIngameForge.class, remap = false)
+public class GuiIngameForgeMixin {
+ @Inject(method = "renderGameOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/GuiIngameForge;post(Lnet/minecraftforge/client/event/RenderGameOverlayEvent$ElementType;)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderGameOverlay(float partialTicks, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new HudRenderEvent(partialTicks));
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java
new file mode 100644
index 0000000..0603d12
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/MinecraftMixin.java
@@ -0,0 +1,100 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.internal.OneConfig;
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.*;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.Timer;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.Event;
+import org.objectweb.asm.Opcodes;
+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.ModifyArg;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(Minecraft.class)
+public class MinecraftMixin {
+ @Shadow
+ private Timer timer;
+
+ @Inject(method = "shutdownMinecraftApplet", at = @At("HEAD"))
+ private void onShutdown(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new PreShutdownEvent());
+ }
+
+ @Inject(method = "startGame", at = @At("HEAD"))
+ private void onStart(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new StartEvent());
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> EventManager.INSTANCE.post(new ShutdownEvent())));
+ }
+
+ @Inject(method = "startGame", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/FMLClientHandler;beginMinecraftLoading(Lnet/minecraft/client/Minecraft;Ljava/util/List;Lnet/minecraft/client/resources/IReloadableResourceManager;)V", remap = false), remap = true)
+ private void onPreLaunch(CallbackInfo ci) {
+ OneConfig.preLaunch();
+ }
+
+ @Inject(method = "startGame", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/FMLClientHandler;onInitializationComplete()V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onInit(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new InitializationEvent());
+ OneConfig.init();
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;onRenderTickStart(F)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderTickStart(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new RenderEvent(Stage.START, timer.renderPartialTicks));
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;onRenderTickEnd(F)V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onRenderTickEnd(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new RenderEvent(Stage.END, timer.renderPartialTicks));
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;onPreClientTick()V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onClientTickStart(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TickEvent(Stage.START));
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;onPostClientTick()V", shift = At.Shift.AFTER, remap = false), remap = true)
+ private void onClientTickEnd(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TickEvent(Stage.END));
+ }
+
+ @ModifyArg(method = "displayGuiScreen", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/eventhandler/EventBus;post(Lnet/minecraftforge/fml/common/eventhandler/Event;)Z", remap = false), remap = true)
+ private Event onGuiOpenEvent(Event a) {
+ if (a instanceof GuiOpenEvent) {
+ GuiOpenEvent forgeEvent = (GuiOpenEvent) a;
+ ScreenOpenEvent event = new ScreenOpenEvent(forgeEvent.gui);
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ forgeEvent.setCanceled(true);
+ }
+ return forgeEvent;
+ }
+ return a;
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "FIELD", target = "Lnet/minecraft/util/Timer;renderPartialTicks:F", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER))
+ private void onNonDeltaTickTimerUpdate(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TimerUpdateEvent(timer, false));
+ }
+
+ @Inject(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Timer;updateTimer()V", shift = At.Shift.AFTER, ordinal = 1))
+ private void onDeltaTickTimerUpdate(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new TimerUpdateEvent(timer, true));
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;fireKeyInput()V"))
+ private void onKeyEvent(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new KeyInputEvent());
+ }
+
+ @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;fireMouseInput()V"))
+ private void onMouseEvent(CallbackInfo ci) {
+ EventManager.INSTANCE.post(new MouseInputEvent());
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java
new file mode 100644
index 0000000..7a446c7
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetHandlerPlayClientMixin.java
@@ -0,0 +1,38 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ChatReceiveEvent;
+import cc.polyfrost.oneconfig.events.event.SendPacketEvent;
+import net.minecraft.client.network.NetHandlerPlayClient;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S02PacketChat;
+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 = NetHandlerPlayClient.class, priority = Integer.MAX_VALUE)
+public class NetHandlerPlayClientMixin {
+
+ @Inject(method = "addToSendQueue", at = @At("HEAD"), cancellable = true)
+ private void onSendPacket(Packet> p_147297_1_, CallbackInfo ci) {
+ SendPacketEvent event = new SendPacketEvent(p_147297_1_);
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+
+ @Inject(method = "handleChat", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;onClientChat(BLnet/minecraft/util/IChatComponent;)Lnet/minecraft/util/IChatComponent;", remap = false), cancellable = true, remap = true)
+ private void onClientChat(S02PacketChat packetIn, CallbackInfo ci) {
+ if (packetIn.getType() == 0) {
+ ChatReceiveEvent event = new ChatReceiveEvent(packetIn.getChatComponent());
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java
new file mode 100644
index 0000000..3da0c91
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/NetworkManagerMixin.java
@@ -0,0 +1,25 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.ReceivePacketEvent;
+import io.netty.channel.ChannelHandlerContext;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+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 = NetworkManager.class, priority = Integer.MAX_VALUE)
+public class NetworkManagerMixin {
+ @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/Packet;)V", at = @At("HEAD"), cancellable = true)
+ private void onReceivePacket(ChannelHandlerContext p_channelRead0_1_, Packet> p_channelRead0_2_, CallbackInfo ci) {
+ ReceivePacketEvent event = new ReceivePacketEvent(p_channelRead0_2_);
+ EventManager.INSTANCE.post(event);
+ if (event.isCancelled) {
+ ci.cancel();
+ }
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/OptifineConfigMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/OptifineConfigMixin.java
new file mode 100644
index 0000000..9012091
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/OptifineConfigMixin.java
@@ -0,0 +1,23 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.internal.plugin.hooks.OptifineConfigHook;
+import org.spongepowered.asm.mixin.Dynamic;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Pseudo
+@Mixin(targets = "Config", remap = false)
+public class OptifineConfigMixin {
+ @Dynamic("OptiFine")
+ @Inject(method = "isFastRender", at = @At("HEAD"), cancellable = true)
+ private static void cancelFastRender(CallbackInfoReturnable cir) {
+ if (OptifineConfigHook.shouldNotApplyFastRender()) {
+ cir.setReturnValue(false);
+ }
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ShaderGroupAccessor.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ShaderGroupAccessor.java
new file mode 100644
index 0000000..588da19
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/ShaderGroupAccessor.java
@@ -0,0 +1,16 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import net.minecraft.client.shader.Shader;
+import net.minecraft.client.shader.ShaderGroup;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+
+@Mixin(ShaderGroup.class)
+public interface ShaderGroupAccessor {
+ @Accessor("listShaders")
+ List getListShaders();
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/VigilantMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/VigilantMixin.java
new file mode 100644
index 0000000..6b474ab
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/VigilantMixin.java
@@ -0,0 +1,10 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import gg.essential.vigilance.Vigilant;
+import org.spongepowered.asm.mixin.Mixin;
+
+@Mixin(Vigilant.class)
+public class VigilantMixin {
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java
new file mode 100644
index 0000000..05c6920
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/mixin/WorldClientMixin.java
@@ -0,0 +1,23 @@
+//#if MC==10809
+package cc.polyfrost.oneconfig.internal.mixin;
+
+import cc.polyfrost.oneconfig.events.EventManager;
+import cc.polyfrost.oneconfig.events.event.WorldLoadEvent;
+import net.minecraft.client.multiplayer.WorldClient;
+import net.minecraft.client.network.NetHandlerPlayClient;
+import net.minecraft.profiler.Profiler;
+import net.minecraft.world.EnumDifficulty;
+import net.minecraft.world.WorldSettings;
+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(WorldClient.class)
+public class WorldClientMixin {
+ @Inject(method = "", at = @At("RETURN"))
+ private void onWorldLoad(NetHandlerPlayClient p_i45063_1_, WorldSettings p_i45063_2_, int p_i45063_3_, EnumDifficulty p_i45063_4_, Profiler p_i45063_5_, CallbackInfo ci) {
+ EventManager.INSTANCE.post(new WorldLoadEvent());
+ }
+}
+//#endif
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java
new file mode 100644
index 0000000..52256ca
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java
@@ -0,0 +1,102 @@
+package cc.polyfrost.oneconfig.internal.plugin.asm;
+
+import cc.polyfrost.oneconfig.internal.plugin.asm.tweakers.NanoVGGLConfigTransformer;
+import cc.polyfrost.oneconfig.internal.plugin.asm.tweakers.VigilantTransformer;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import net.minecraft.launchwrapper.IClassTransformer;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.tree.ClassNode;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ * also half taken from asmworkspace by asbyth ty
+ */
+@SuppressWarnings("unused")
+public class ClassTransformer implements IClassTransformer {
+ private static final Logger logger = LogManager.getLogger("OneConfig ASM");
+ private final Multimap transformerMap = ArrayListMultimap.create();
+ private static final boolean outputBytecode = Boolean.parseBoolean(System.getProperty("debugBytecode", "false"));
+
+ public ClassTransformer() {
+ registerTransformer(new NanoVGGLConfigTransformer());
+ registerTransformer(new VigilantTransformer());
+ }
+
+ private void registerTransformer(ITransformer transformer) {
+ // loop through names of classes
+ for (String cls : transformer.getClassName()) {
+ // put the classes into the transformer map
+ transformerMap.put(cls, transformer);
+ }
+ }
+
+ @Override
+ public byte[] transform(String name, String transformedName, byte[] bytes) {
+ if (bytes == null) return null;
+
+ Collection transformers = transformerMap.get(transformedName);
+ if (transformers.isEmpty()) return bytes;
+
+ ClassReader reader = new ClassReader(bytes);
+ ClassNode node = new ClassNode();
+ reader.accept(node, ClassReader.EXPAND_FRAMES);
+
+ for (ITransformer transformer : transformers) {
+ transformer.transform(transformedName, node);
+ }
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ try {
+ node.accept(cw);
+ } catch (Throwable t) {
+ logger.error("Exception when transforming " + transformedName + " : " + t.getClass().getSimpleName());
+ t.printStackTrace();
+ }
+
+ if (outputBytecode) {
+ File bytecodeDirectory = new File("bytecode");
+ String transformedClassName;
+
+ // anonymous classes
+ if (transformedName.contains("$")) {
+ transformedClassName = transformedName.replace('$', '.') + ".class";
+ } else {
+ transformedClassName = transformedName + ".class";
+ }
+
+ if (!bytecodeDirectory.exists()) {
+ bytecodeDirectory.mkdirs();
+ }
+
+ File bytecodeOutput = new File(bytecodeDirectory, transformedClassName);
+
+ try {
+ if (!bytecodeOutput.exists()) {
+ bytecodeOutput.createNewFile();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ try (FileOutputStream os = new FileOutputStream(bytecodeOutput)) {
+ // write to the generated class to /run/bytecode/classfile.class
+ // with the class bytes from transforming
+ os.write(cw.toByteArray());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return cw.toByteArray();
+ }
+}
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java
new file mode 100644
index 0000000..1bc50d1
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java
@@ -0,0 +1,24 @@
+package cc.polyfrost.oneconfig.internal.plugin.asm;
+
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+
+public interface ITransformer {
+ String[] getClassName();
+
+ void transform(String transformedName, ClassNode node);
+
+ default void clearInstructions(MethodNode methodNode) {
+ methodNode.instructions.clear();
+
+ // dont waste time clearing local variables if they're empty
+ if (!methodNode.localVariables.isEmpty()) {
+ methodNode.localVariables.clear();
+ }
+
+ // dont waste time clearing try-catches if they're empty
+ if (!methodNode.tryCatchBlocks.isEmpty()) {
+ methodNode.tryCatchBlocks.clear();
+ }
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/OneConfigTweaker.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/OneConfigTweaker.java
new file mode 100644
index 0000000..d302b9d
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/OneConfigTweaker.java
@@ -0,0 +1,117 @@
+package cc.polyfrost.oneconfig.internal.plugin.asm;
+
+import cc.polyfrost.oneconfig.internal.init.OneConfigInit;
+import net.minecraft.launchwrapper.ITweaker;
+import net.minecraft.launchwrapper.Launch;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+import net.minecraftforge.fml.relauncher.CoreModManager;
+import org.spongepowered.asm.launch.MixinBootstrap;
+import org.spongepowered.asm.launch.MixinTweaker;
+import org.spongepowered.asm.mixin.Mixins;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+
+public class OneConfigTweaker implements ITweaker {
+
+ public OneConfigTweaker() {
+ for (URL url : Launch.classLoader.getSources()) {
+ doMagicMixinStuff(url);
+ }
+ }
+
+ private void doMagicMixinStuff(URL url) {
+ try {
+ URI uri = url.toURI();
+ if (Objects.equals(uri.getScheme(), "file")) {
+ File file = new File(uri);
+ if (file.exists() && file.isFile()) {
+ try (JarFile jarFile = new JarFile(file)) {
+ if (jarFile.getManifest() != null) {
+ Attributes attributes = jarFile.getManifest().getMainAttributes();
+ String tweakerClass = attributes.getValue("TweakClass");
+ if (Objects.equals(tweakerClass, "cc.polyfrost.oneconfigwrapper.OneConfigWrapper")) {
+ CoreModManager.getIgnoredMods().remove(file.getName());
+ CoreModManager.getReparseableCoremods().add(file.getName());
+ String mixinConfig = attributes.getValue("MixinConfigs");
+ if (mixinConfig != null) {
+ try {
+ try {
+ List tweakClasses = (List) Launch.blackboard.get("TweakClasses"); // tweak classes before other mod trolling
+ if (tweakClasses.contains("org.spongepowered.asm.launch.MixinTweaker")) { // if there's already a mixin tweaker, we'll just load it like "usual"
+ new MixinTweaker(); // also we might not need to make a new mixin tweawker all the time but im just making sure
+ } else if (!Launch.blackboard.containsKey("mixin.initialised")) { // if there isnt, we do our own trolling
+ List tweaks = (List) Launch.blackboard.get("Tweaks");
+ tweaks.add(new MixinTweaker());
+ }
+ } catch (Exception ignored) {
+ // if it fails i *think* we can just ignore it
+ }
+ MixinBootstrap.getPlatform().addContainer(uri);
+ } catch (Exception ignored) {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception ignored) {
+
+ }
+ }
+
+ @Override
+ public void acceptOptions(List args, File gameDir, File assetsDir, String profile) {
+ MixinBootstrap.init();
+ boolean captureNext = false;
+ for (String arg : args) {
+ if (captureNext) {
+ Mixins.addConfiguration(arg);
+ }
+ captureNext = "--mixin".equals(arg);
+ }
+ }
+
+ @Override
+ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
+ removeLWJGLException();
+ Launch.classLoader.registerTransformer(ClassTransformer.class.getName());
+ OneConfigInit.initialize(new String[]{});
+ Launch.blackboard.put("oneconfig.init.initialized", true);
+ Launch.classLoader.addClassLoaderExclusion("cc.polyfrost.oneconfig.internal.plugin.asm.");
+ }
+
+ /**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+ private void removeLWJGLException() {
+ try {
+ Field f_exceptions = LaunchClassLoader.class.getDeclaredField("classLoaderExceptions");
+ f_exceptions.setAccessible(true);
+ Set exceptions = (Set) f_exceptions.get(Launch.classLoader);
+ exceptions.remove("org.lwjgl.");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getLaunchTarget() {
+ return null;
+ }
+
+ @Override
+ public String[] getLaunchArguments() {
+ return new String[0];
+ }
+}
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java
new file mode 100644
index 0000000..bbbf4a1
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java
@@ -0,0 +1,47 @@
+package cc.polyfrost.oneconfig.internal.plugin.asm.tweakers;
+
+import cc.polyfrost.oneconfig.internal.plugin.asm.ITransformer;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.*;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+public class NanoVGGLConfigTransformer implements ITransformer {
+ @Override
+ public String[] getClassName() {
+ return new String[]{"org.lwjgl.nanovg.NanoVGGLConfig"};
+ }
+
+ @Override
+ public void transform(String transformedName, ClassNode node) {
+ for (MethodNode method : node.methods) {
+ if (method.name.equals("configGL")) {
+ InsnList list = new InsnList();
+
+ list.add(new VarInsnNode(Opcodes.LLOAD, 0));
+ list.add(new TypeInsnNode(Opcodes.NEW, "cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider"));
+ list.add(new InsnNode(Opcodes.DUP));
+ list.add(new MethodInsnNode(
+ Opcodes.INVOKESPECIAL,
+ "cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider",
+ "",
+ "()V",
+ false
+ ));
+ list.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ "org/lwjgl/nanovg/NanoVGGLConfig",
+ "config",
+ "(JLorg/lwjgl/system/FunctionProvider;)V",
+ false
+ ));
+ list.add(new InsnNode(Opcodes.RETURN));
+
+ clearInstructions(method);
+ method.instructions.insert(list);
+ }
+ }
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java
new file mode 100644
index 0000000..8dd60cf
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java
@@ -0,0 +1,89 @@
+package cc.polyfrost.oneconfig.internal.plugin.asm.tweakers;
+
+import cc.polyfrost.oneconfig.internal.plugin.asm.ITransformer;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.*;
+
+import java.io.File;
+
+public class VigilantTransformer implements ITransformer {
+
+ @Override
+ public String[] getClassName() {
+ return new String[]{"gg.essential.vigilance.Vigilant"};
+ }
+
+ /**
+ * If anything here is changed, edit the corresponding method in OneConfigMixinPlugin!
+ */
+ @Override
+ public void transform(String transformedName, ClassNode node) {
+ if (!node.interfaces.contains("cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor")) {
+ node.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "oneconfig$config", "Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;", null, null));
+ node.fields.add(new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "oneconfig$file", Type.getDescriptor(File.class), null, null));
+
+ node.interfaces.add("cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor");
+ MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "getPropertyCollector", "()Lgg/essential/vigilance/data/PropertyCollector;", null, null);
+ LabelNode labelNode = new LabelNode();
+ methodNode.instructions.add(labelNode);
+ methodNode.instructions.add(new LineNumberNode(421421, labelNode));
+ methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ methodNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "propertyCollector", "Lgg/essential/vigilance/data/PropertyCollector;"));
+ methodNode.instructions.add(new InsnNode(Opcodes.ARETURN));
+ node.methods.add(methodNode);
+
+ MethodNode methodNode2 = new MethodNode(Opcodes.ACC_PUBLIC, "handleOneConfigDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", null, null);
+ LabelNode labelNode2 = new LabelNode();
+ LabelNode labelNode3 = new LabelNode();
+ LabelNode labelNode4 = new LabelNode();
+ methodNode2.instructions.add(labelNode2);
+ methodNode2.instructions.add(new LineNumberNode(15636436, labelNode2));
+ methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ methodNode2.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", "Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;"));
+
+ methodNode2.instructions.add(new JumpInsnNode(Opcodes.IFNULL, labelNode4));
+
+ methodNode2.instructions.add(labelNode3);
+ methodNode2.instructions.add(new LineNumberNode(15636437, labelNode3));
+ methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ methodNode2.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", "Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;"));
+ methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
+ methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2));
+ methodNode2.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig", "addDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", false));
+
+ methodNode2.instructions.add(labelNode4);
+ methodNode2.instructions.add(new LineNumberNode(15636438, labelNode4));
+ methodNode2.instructions.add(new InsnNode(Opcodes.RETURN));
+ node.methods.add(methodNode2);
+
+ for (MethodNode method : node.methods) {
+ if (method.name.equals("initialize")) {
+ InsnList list = new InsnList();
+ list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ list.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$file", Type.getDescriptor(File.class)));
+ list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "cc/polyfrost/oneconfig/internal/plugin/hooks/VigilantHook", "returnNewConfig", "(Lgg/essential/vigilance/Vigilant;Ljava/io/File;)Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;", false));
+ list.add(new FieldInsnNode(Opcodes.PUTFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", "Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;"));
+ method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list);
+ } else if (method.name.equals("addDependency") && method.desc.equals("(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V")) {
+ InsnList list = new InsnList();
+
+ list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ list.add(new VarInsnNode(Opcodes.ALOAD, 1));
+ list.add(new VarInsnNode(Opcodes.ALOAD, 2));
+ list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "gg/essential/vigilance/Vigilant", "handleOneConfigDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", false));
+
+ method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list);
+ } else if (method.name.equals("") && method.desc.equals("(Ljava/io/File;Ljava/lang/String;Lgg/essential/vigilance/data/PropertyCollector;Lgg/essential/vigilance/data/SortingBehavior;)V")) {
+ InsnList list = new InsnList();
+ list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+ list.add(new VarInsnNode(Opcodes.ALOAD, 1));
+ list.add(new FieldInsnNode(Opcodes.PUTFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$file", Type.getDescriptor(File.class)));
+ method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list);
+ }
+ }
+ }
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider.java
new file mode 100644
index 0000000..297c84d
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/Lwjgl2FunctionProvider.java
@@ -0,0 +1,47 @@
+package cc.polyfrost.oneconfig.internal.plugin.hooks;
+
+import org.lwjgl.system.FunctionProvider;
+
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+public class Lwjgl2FunctionProvider implements FunctionProvider {
+
+ private static final Class> GLContext;
+ private final Method m_getFunctionAddress;
+
+ static {
+ try {
+ GLContext = Class.forName("org.lwjgl.opengl.GLContext");
+ } catch (Throwable t) {
+ throw new RuntimeException("Unable to initialize LWJGL2FunctionProvider", t);
+ }
+ }
+
+ public Lwjgl2FunctionProvider() {
+ try {
+ m_getFunctionAddress = GLContext.getDeclaredMethod("getFunctionAddress", String.class);
+ m_getFunctionAddress.setAccessible(true);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public long getFunctionAddress(CharSequence functionName) {
+ try {
+ return (long) m_getFunctionAddress.invoke(null, functionName.toString());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public long getFunctionAddress(ByteBuffer byteBuffer) {
+ throw new UnsupportedOperationException();
+ }
+}
\ No newline at end of file
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/OptifineConfigHook.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/OptifineConfigHook.java
new file mode 100644
index 0000000..dea68cf
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/OptifineConfigHook.java
@@ -0,0 +1,22 @@
+package cc.polyfrost.oneconfig.internal.plugin.hooks;
+
+import cc.polyfrost.oneconfig.gui.OneConfigGui;
+import cc.polyfrost.oneconfig.platform.Platform;
+import cc.polyfrost.oneconfig.utils.gui.GuiUtils;
+
+import java.util.Optional;
+
+public class OptifineConfigHook {
+
+ public static boolean shouldNotApplyFastRender() {
+ if (Platform.getGuiPlatform().getCurrentScreen() instanceof OneConfigGui) {
+ return true;
+ }
+ for (Optional screen : GuiUtils.getScreenQueue()) {
+ if (screen.isPresent() && screen.get() instanceof OneConfigGui) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/VigilantHook.java b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/VigilantHook.java
new file mode 100644
index 0000000..a012773
--- /dev/null
+++ b/versions/src/main/java/cc/polyfrost/oneconfig/internal/plugin/hooks/VigilantHook.java
@@ -0,0 +1,26 @@
+package cc.polyfrost.oneconfig.internal.plugin.hooks;
+
+import cc.polyfrost.oneconfig.config.compatibility.vigilance.VigilanceConfig;
+import cc.polyfrost.oneconfig.config.data.Mod;
+import cc.polyfrost.oneconfig.config.data.ModType;
+import cc.polyfrost.oneconfig.internal.config.core.ConfigCore;
+import cc.polyfrost.oneconfig.platform.Platform;
+import gg.essential.vigilance.Vigilant;
+
+import java.io.File;
+
+@SuppressWarnings("unused")
+public class VigilantHook {
+ public static VigilanceConfig returnNewConfig(Vigilant vigilant, File file) {
+ if (vigilant != null && Platform.getInstance().isCallingFromMinecraftThread()) {
+ String name = !vigilant.getGuiTitle().equals("Settings") ? vigilant.getGuiTitle() : !Platform.getLoaderPlatform().hasActiveModContainer() ? "Unknown" : Platform.getLoaderPlatform().getActiveModContainer().name;
+ if (name.equals("OneConfig")) name = "Essential";
+ String finalName = name;
+ // duplicate fix
+ if (ConfigCore.mods.stream().anyMatch(mod -> mod.name.equals(finalName))) return null;
+ return new VigilanceConfig(new Mod(name, ModType.THIRD_PARTY), file.getAbsolutePath(), vigilant);
+ } else {
+ return null;
+ }
+ }
+}
--
cgit