From 5808bab08eeaed01a322f5336f01cd5a58d7887c Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 20 Aug 2021 01:57:27 +0200 Subject: [PATCH] ModMenu Integration --- .../modmenu/util/ModMenuApiMarker.java | 11 ++ .../bclib/gui/screens/ModMenu/MainScreen.java | 28 +++++ .../bclib/integration/ModMenuIntegration.java | 106 ++++++++++++++++++ .../resources/assets/bclib/lang/en_us.json | 4 +- src/main/resources/fabric.mod.json | 12 +- 5 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/terraformersmc/modmenu/util/ModMenuApiMarker.java create mode 100644 src/main/java/ru/bclib/gui/screens/ModMenu/MainScreen.java create mode 100644 src/main/java/ru/bclib/integration/ModMenuIntegration.java diff --git a/src/main/java/com/terraformersmc/modmenu/util/ModMenuApiMarker.java b/src/main/java/com/terraformersmc/modmenu/util/ModMenuApiMarker.java new file mode 100644 index 00000000..54a17f17 --- /dev/null +++ b/src/main/java/com/terraformersmc/modmenu/util/ModMenuApiMarker.java @@ -0,0 +1,11 @@ +package com.terraformersmc.modmenu.util; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +//This File was included from TerraformersMC/ModMenu +// to enable a ModMenu-Integration without having to +// compile against the actual plugin + +@Environment(EnvType.CLIENT) +public interface ModMenuApiMarker {} diff --git a/src/main/java/ru/bclib/gui/screens/ModMenu/MainScreen.java b/src/main/java/ru/bclib/gui/screens/ModMenu/MainScreen.java new file mode 100644 index 00000000..e56f2f3c --- /dev/null +++ b/src/main/java/ru/bclib/gui/screens/ModMenu/MainScreen.java @@ -0,0 +1,28 @@ +package ru.bclib.gui.screens.ModMenu; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.TranslatableComponent; +import org.jetbrains.annotations.Nullable; +import ru.bclib.gui.gridlayout.GridRow; +import ru.bclib.gui.gridlayout.GridScreen; + +public class MainScreen extends GridScreen{ + + public MainScreen(@Nullable Screen parent) { + super(parent, new TranslatableComponent("title.bclib.modmenu.main")); + } + + @Override + protected void initLayout() { + final int BUTTON_HEIGHT = 20; + grid.addSpacerRow(20); + GridRow row = grid.addRow(); + + row.addFiller(); + row.addButton(CommonComponents.GUI_BACK, BUTTON_HEIGHT, font, (button)->{ + onClose(); + }); + row.addFiller(); + } +} diff --git a/src/main/java/ru/bclib/integration/ModMenuIntegration.java b/src/main/java/ru/bclib/integration/ModMenuIntegration.java new file mode 100644 index 00000000..e05b3afb --- /dev/null +++ b/src/main/java/ru/bclib/integration/ModMenuIntegration.java @@ -0,0 +1,106 @@ +package ru.bclib.integration; + +import com.google.common.collect.ImmutableMap; +import com.terraformersmc.modmenu.util.ModMenuApiMarker; +import net.minecraft.client.gui.screens.Screen; +import ru.bclib.gui.screens.ModMenu.MainScreen; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +@FunctionalInterface +interface IModMenuScreenFactory { + S create(Screen parent); +} + +class ModMenuScreenFactory { + static class ScreenFactoryInvocationHandler implements InvocationHandler { + private final IModMenuScreenFactory act; + + public ScreenFactoryInvocationHandler(IModMenuScreenFactory act) { + this.act = act; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return act.create((Screen)args[0]); + } + } + + public static IModMenuScreenFactory create(IModMenuScreenFactory act) { + Class iConfigScreenFactory = null; + try { + iConfigScreenFactory = Class.forName("com.terraformersmc.modmenu.api.ConfigScreenFactory"); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + Object o = Proxy.newProxyInstance( + ModMenuIntegration.class.getClassLoader(), + new Class[] {iConfigScreenFactory, IModMenuScreenFactory.class}, + new ScreenFactoryInvocationHandler(act)); + + return (IModMenuScreenFactory)o; + } +} + +public class ModMenuIntegration { + static class BCLibModMenuInvocationHandler implements InvocationHandler { + private final ModMenuIntegration target; + + public BCLibModMenuInvocationHandler(ModMenuIntegration target) { + this.target = target; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if ("getModConfigScreenFactory".equals(method.getName())){ + return target.getModConfigScreenFactory(); + } else if ("getProvidedConfigScreenFactories".equals(method.getName())){ + return target.getProvidedConfigScreenFactories(); + } else if ("toString".equals(method.getName())){ + return target.toString(); + } else { + return null; + } + } + } + + public static final ModMenuApiMarker entrypointObject = create(); + + public static ModMenuApiMarker create() { + Class iModMenuAPI = null; + //Class iModMenuAPIMarker = null; + try { + iModMenuAPI = Class.forName("com.terraformersmc.modmenu.api.ModMenuApi"); + //iModMenuAPIMarker = Class.forName("com.terraformersmc.modmenu.util.ModMenuApiMarker"); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + return (ModMenuApiMarker)new Object(); + } + + Object o = Proxy.newProxyInstance( + ModMenuIntegration.class.getClassLoader(), + new Class[] {iModMenuAPI}, + new BCLibModMenuInvocationHandler(new ModMenuIntegration())); + + return (ModMenuApiMarker)o; + } + + IModMenuScreenFactory getModConfigScreenFactory() { + return ModMenuScreenFactory.create( MainScreen::new ); + } + + Map> getProvidedConfigScreenFactories() { + return ImmutableMap.of(); + } + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/src/main/resources/assets/bclib/lang/en_us.json b/src/main/resources/assets/bclib/lang/en_us.json index 0a734d75..cc591dd7 100644 --- a/src/main/resources/assets/bclib/lang/en_us.json +++ b/src/main/resources/assets/bclib/lang/en_us.json @@ -14,5 +14,7 @@ "message.bclib.syncfiles.folders": "Synchronize Folders and Files", "message.bclib.syncfiles.delete": "Delete unneeded", "title.bclib.confirmrestart": "Restart Required", - "message.bclib.confirmrestart": "The requested files were processed. You need o restart Minecraft now." + "message.bclib.confirmrestart": "The requested content was synchronized. You need to restart Minecraft now.", + "title.link.bclib.discord": "Discord", + "title.bclib.modmenu.main": "BCLib Settings" } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 2a83ad36..0a193be3 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -25,7 +25,8 @@ ], "server": [ "ru.bclib.server.BCLibServer" - ] + ], + "modmenu": [ "ru.bclib.integration.ModMenuIntegration::entrypointObject" ] }, "mixins": [ "bclib.mixins.common.json", @@ -35,5 +36,12 @@ "fabricloader": ">=0.11.6", "fabric": ">=0.36.0", "minecraft": ">=1.17.1" - } + }, + "custom":{ + "modmenu":{ + "links":{ + "title.link.bclib.discord":"https://discord.gg/kYuATbYbKW" + } + } + } }