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 --- .../oneconfig/events/event/ChatReceiveEvent.java | 22 ++ .../oneconfig/events/event/ReceivePacketEvent.java | 11 + .../oneconfig/events/event/ScreenOpenEvent.java | 17 ++ .../oneconfig/events/event/SendPacketEvent.java | 11 + .../oneconfig/events/event/TimerUpdateEvent.java | 24 ++ .../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 ++ .../oneconfig/platform/impl/GLPlatformImpl.java | 67 +++++ .../oneconfig/platform/impl/GuiPlatformImpl.java | 31 ++ .../oneconfig/platform/impl/I18nPlatformImpl.java | 13 + .../platform/impl/LoaderPlatformImpl.java | 26 ++ .../oneconfig/platform/impl/MousePlatformImpl.java | 53 ++++ .../oneconfig/platform/impl/PlatformImpl.java | 12 + .../platform/impl/ServerPlatformImpl.java | 22 ++ .../utils/commands/PlatformCommandManagerImpl.java | 330 +++++++++++++++++++++ .../cc/polyfrost/oneconfig/utils/gui/GuiUtils.java | 100 +++++++ .../cc/polyfrost/oneconfig/utils/dsl/DSLs.kt | 9 + .../polyfrost/oneconfig/utils/dsl/GuiUtilsDSL.kt | 11 + ...cc.polyfrost.oneconfig.internal.gui.BlurHandler | 1 + .../cc.polyfrost.oneconfig.platform.GLPlatform | 1 + .../cc.polyfrost.oneconfig.platform.GuiPlatform | 1 + .../cc.polyfrost.oneconfig.platform.I18nPlatform | 1 + .../cc.polyfrost.oneconfig.platform.LoaderPlatform | 1 + .../cc.polyfrost.oneconfig.platform.MousePlatform | 1 + .../cc.polyfrost.oneconfig.platform.Platform | 1 + .../cc.polyfrost.oneconfig.platform.ServerPlatform | 1 + ...oneconfig.utils.commands.PlatformCommandManager | 1 + versions/src/main/resources/mixins.oneconfig.json | 21 ++ 44 files changed, 1742 insertions(+) create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/events/event/ChatReceiveEvent.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/events/event/ReceivePacketEvent.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/events/event/ScreenOpenEvent.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/events/event/SendPacketEvent.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/events/event/TimerUpdateEvent.java 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 create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GLPlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GuiPlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/I18nPlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/LoaderPlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/MousePlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/PlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/ServerPlatformImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManagerImpl.java create mode 100644 versions/src/main/java/cc/polyfrost/oneconfig/utils/gui/GuiUtils.java create mode 100644 versions/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/DSLs.kt create mode 100644 versions/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/GuiUtilsDSL.kt create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.internal.gui.BlurHandler create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.GLPlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.GuiPlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.I18nPlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.LoaderPlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.MousePlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.Platform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.platform.ServerPlatform create mode 100644 versions/src/main/resources/META-INF/services/cc.polyfrost.oneconfig.utils.commands.PlatformCommandManager create mode 100644 versions/src/main/resources/mixins.oneconfig.json (limited to 'versions/src') diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ChatReceiveEvent.java b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ChatReceiveEvent.java new file mode 100644 index 0000000..6585729 --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ChatReceiveEvent.java @@ -0,0 +1,22 @@ +package cc.polyfrost.oneconfig.events.event; + +import cc.polyfrost.oneconfig.libs.universal.wrappers.message.UTextComponent; +import net.minecraft.util.IChatComponent; + +/** + * Called when a chat message is received. + */ +public class ChatReceiveEvent extends CancellableEvent { + /** + * The message that was received. + */ + public final IChatComponent message; + + public ChatReceiveEvent(IChatComponent message) { + this.message = message; + } + + public String getFullyUnformattedMessage() { + return UTextComponent.Companion.stripFormatting(message.getUnformattedText()); + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ReceivePacketEvent.java b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ReceivePacketEvent.java new file mode 100644 index 0000000..17bc16d --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ReceivePacketEvent.java @@ -0,0 +1,11 @@ +package cc.polyfrost.oneconfig.events.event; + +import net.minecraft.network.Packet; + +public class ReceivePacketEvent extends CancellableEvent { + public final Packet packet; + + public ReceivePacketEvent(Packet packet) { + this.packet = packet; + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ScreenOpenEvent.java b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ScreenOpenEvent.java new file mode 100644 index 0000000..4593638 --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/ScreenOpenEvent.java @@ -0,0 +1,17 @@ +package cc.polyfrost.oneconfig.events.event; + +import net.minecraft.client.gui.GuiScreen; +import org.jetbrains.annotations.Nullable; + +/** + * Called when a screen is opened or closed. + * If the screen is closed, {@link ScreenOpenEvent#screen} will be null. + */ +public class ScreenOpenEvent extends CancellableEvent { + @Nullable + public final GuiScreen screen; + + public ScreenOpenEvent(@Nullable GuiScreen screen) { + this.screen = screen; + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/events/event/SendPacketEvent.java b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/SendPacketEvent.java new file mode 100644 index 0000000..3cee784 --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/SendPacketEvent.java @@ -0,0 +1,11 @@ +package cc.polyfrost.oneconfig.events.event; + +import net.minecraft.network.Packet; + +public class SendPacketEvent extends CancellableEvent { + public final Packet packet; + + public SendPacketEvent(Packet packet) { + this.packet = packet; + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/events/event/TimerUpdateEvent.java b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/TimerUpdateEvent.java new file mode 100644 index 0000000..a8b88dc --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/events/event/TimerUpdateEvent.java @@ -0,0 +1,24 @@ +package cc.polyfrost.oneconfig.events.event; + +import net.minecraft.util.Timer; + +/** + * Called when the {@link Timer} is updated. + * Can be used as an alternative to getting instances of {@link Timer} + * via Mixin or Access Wideners / Transformers + */ +public class TimerUpdateEvent { + /** + * Whether the deltaTicks / renderPartialTicks was updated + */ + public final boolean updatedDeltaTicks; + /** + * The {@link Timer} instance + */ + public final Timer timer; + + public TimerUpdateEvent(Timer timer, boolean updatedDeltaTicks) { + this.timer = timer; + this.updatedDeltaTicks = updatedDeltaTicks; + } +} \ No newline at end of file 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; + } + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GLPlatformImpl.java b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GLPlatformImpl.java new file mode 100644 index 0000000..3ee962b --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GLPlatformImpl.java @@ -0,0 +1,67 @@ +package cc.polyfrost.oneconfig.platform.impl; + +import cc.polyfrost.oneconfig.libs.universal.UMatrixStack; +import cc.polyfrost.oneconfig.libs.universal.UMinecraft; +import cc.polyfrost.oneconfig.platform.GLPlatform; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.shader.Framebuffer; + +@SuppressWarnings("unused") +public class GLPlatformImpl implements GLPlatform { + + @Override + public void drawRect(float x, float y, float x2, float y2, int color) { + if (x < x2) { + float i = x; + x = x2; + x2 = i; + } + + if (y < y2) { + float i = y; + y = y2; + y2 = i; + } + + float f = (float)(color >> 24 & 0xFF) / 255.0F; + float g = (float)(color >> 16 & 0xFF) / 255.0F; + float h = (float)(color >> 8 & 0xFF) / 255.0F; + float j = (float)(color & 0xFF) / 255.0F; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRenderer = tessellator.getWorldRenderer(); + GlStateManager.enableBlend(); + GlStateManager.disableTexture2D(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.color(g, h, j, f); + worldRenderer.begin(7, DefaultVertexFormats.POSITION); + worldRenderer.pos(x, y2, 0.0).endVertex(); + worldRenderer.pos(x2, y2, 0.0).endVertex(); + worldRenderer.pos(x2, y, 0.0).endVertex(); + worldRenderer.pos(x, y, 0.0).endVertex(); + tessellator.draw(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } + + @Override + public void enableStencil() { + Framebuffer framebuffer = Minecraft.getMinecraft().getFramebuffer(); + if (!framebuffer.isStencilEnabled()) { + framebuffer.enableStencil(); + } + } + + @Override + public float drawText(UMatrixStack matrixStack, String text, float x, float y, int color, boolean shadow) { + return UMinecraft.getFontRenderer().drawString(text, x, y, color, shadow); + } + + @Override + public int getStringWidth(String text) { + return UMinecraft.getFontRenderer().getStringWidth(text); + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GuiPlatformImpl.java b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GuiPlatformImpl.java new file mode 100644 index 0000000..6ea3c03 --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/GuiPlatformImpl.java @@ -0,0 +1,31 @@ +package cc.polyfrost.oneconfig.platform.impl; + +import cc.polyfrost.oneconfig.libs.universal.UMinecraft; +import cc.polyfrost.oneconfig.libs.universal.UScreen; +import cc.polyfrost.oneconfig.platform.GuiPlatform; +import net.minecraft.client.gui.GuiChat; +import net.minecraft.client.gui.GuiScreen; + +@SuppressWarnings("unused") +public class GuiPlatformImpl implements GuiPlatform { + + @Override + public Object getCurrentScreen() { + return UScreen.getCurrentScreen(); + } + + @Override + public void setCurrentScreen(Object screen) { + UScreen.displayScreen((GuiScreen) screen); + } + + @Override + public boolean isInChat() { + return getCurrentScreen() instanceof GuiChat; + } + + @Override + public boolean isInDebug() { + return UMinecraft.getSettings().showDebugInfo; + } +} diff --git a/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/I18nPlatformImpl.java b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/I18nPlatformImpl.java new file mode 100644 index 0000000..1913238 --- /dev/null +++ b/versions/src/main/java/cc/polyfrost/oneconfig/platform/impl/I18nPlatformImpl.java @@ -0,0 +1,13 @@ +package cc.polyfrost.oneconfig.platform.impl; + +import cc.polyfrost.oneconfig.platform.I18nPlatform; +import net.minecraft.client.resources.I18n; + +@SuppressWarnings("unused") +public class I18nPlatformImpl implements I18nPlatform { + + @Override + public String format(String key, Object... args) { + return I18n.format(key, args); + } +} diff --git a/versions/src/main/java/cc/polyfros