Reorganized Imports/Packages
This commit is contained in:
parent
cb9459f176
commit
3ee10482ab
721 changed files with 34873 additions and 33558 deletions
213
src/main/java/org/betterx/bclib/integration/ModIntegration.java
Normal file
213
src/main/java/org/betterx/bclib/integration/ModIntegration.java
Normal file
|
@ -0,0 +1,213 @@
|
|||
package org.betterx.bclib.integration;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.tag.TagAPI;
|
||||
import org.betterx.bclib.world.features.BCLFeature;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public abstract class ModIntegration {
|
||||
private final String modID;
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public ModIntegration(String modID) {
|
||||
this.modID = modID;
|
||||
}
|
||||
|
||||
public ResourceLocation getID(String name) {
|
||||
return new ResourceLocation(modID, name);
|
||||
}
|
||||
|
||||
public ResourceKey<PlacedFeature> getFeatureKey(String name) {
|
||||
return ResourceKey.create(Registry.PLACED_FEATURE_REGISTRY, getID(name));
|
||||
}
|
||||
|
||||
public Block getBlock(String name) {
|
||||
return Registry.BLOCK.get(getID(name));
|
||||
}
|
||||
|
||||
public Item getItem(String name) {
|
||||
return Registry.ITEM.get(getID(name));
|
||||
}
|
||||
|
||||
public BlockState getDefaultState(String name) {
|
||||
return getBlock(name).defaultBlockState();
|
||||
}
|
||||
|
||||
public ResourceKey<Biome> getKey(String name) {
|
||||
return ResourceKey.create(Registry.BIOME_REGISTRY, getID(name));
|
||||
}
|
||||
|
||||
public boolean modIsInstalled() {
|
||||
return FabricLoader.getInstance().isModLoaded(modID);
|
||||
}
|
||||
|
||||
public BCLFeature getFeature(String featureID, String placedFeatureID, GenerationStep.Decoration featureStep) {
|
||||
ResourceLocation id = getID(featureID);
|
||||
Feature<?> feature = Registry.FEATURE.get(id);
|
||||
Holder<PlacedFeature> featurePlaced = BuiltinRegistries.PLACED_FEATURE.getHolder(getFeatureKey(placedFeatureID))
|
||||
.orElse(null);
|
||||
return new BCLFeature(id, feature, featureStep, featurePlaced);
|
||||
}
|
||||
|
||||
public BCLFeature getFeature(String name, GenerationStep.Decoration featureStep) {
|
||||
return getFeature(name, name, featureStep);
|
||||
}
|
||||
|
||||
public ConfiguredFeature<?, ?> getConfiguredFeature(String name) {
|
||||
return BuiltinRegistries.CONFIGURED_FEATURE.get(getID(name));
|
||||
}
|
||||
|
||||
public Holder<Biome> getBiome(String name) {
|
||||
return BuiltinRegistries.BIOME.getHolder(getKey(name)).orElseThrow();
|
||||
}
|
||||
|
||||
public Class<?> getClass(String path) {
|
||||
Class<?> cl = null;
|
||||
try {
|
||||
cl = Class.forName(path);
|
||||
} catch (ClassNotFoundException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Object> T getStaticFieldValue(Class<?> cl, String name) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
Field field = cl.getDeclaredField(name);
|
||||
if (field != null) {
|
||||
return (T) field.get(null);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getFieldValue(Class<?> cl, String name, Object classInstance) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
Field field = cl.getDeclaredField(name);
|
||||
if (field != null) {
|
||||
return field.get(classInstance);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method getMethod(Class<?> cl, String functionName, Class<?>... args) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
return cl.getMethod(functionName, args);
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object executeMethod(Object instance, Method method, Object... args) {
|
||||
if (method != null) {
|
||||
try {
|
||||
return method.invoke(instance, args);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getAndExecuteStatic(Class<?> cl, String functionName, Object... args) {
|
||||
if (cl != null) {
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = args[i].getClass();
|
||||
}
|
||||
Method method = getMethod(cl, functionName, classes);
|
||||
return executeMethod(null, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Object> T getAndExecuteRuntime(Class<?> cl,
|
||||
Object instance,
|
||||
String functionName,
|
||||
Object... args) {
|
||||
if (instance != null) {
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = args[i].getClass();
|
||||
}
|
||||
Method method = getMethod(cl, functionName, classes);
|
||||
return (T) executeMethod(instance, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object newInstance(Class<?> cl, Object... args) {
|
||||
if (cl != null) {
|
||||
for (Constructor<?> constructor : cl.getConstructors()) {
|
||||
if (constructor.getParameterCount() == args.length) {
|
||||
try {
|
||||
return constructor.newInstance(args);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
|
||||
InvocationTargetException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TagKey<Item> getItemTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
return TagAPI.makeItemTag(id);
|
||||
}
|
||||
|
||||
public TagKey<Block> getBlockTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
return TagAPI.makeBlockTag(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.betterx.bclib.integration.modmenu;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Integration, to provide a custom Screen for ModMenu.
|
||||
* <p>
|
||||
* This integration allows you to use ModMenu without adding a dependency to your project. If the
|
||||
* Mod is installed on the Client.
|
||||
* <p>
|
||||
* You can add a screen for your mod by calling {@link #addModMenuScreen(String, Function)}
|
||||
*/
|
||||
public class ModMenu {
|
||||
static final Map<String, Function<Screen, Screen>> screen = new HashMap<>();
|
||||
|
||||
/**
|
||||
* registers a ModMenu entrypoint for another Mod. For Example {@code addModMenuScreen("myMod", (parent)->new Screen(parent));}
|
||||
*
|
||||
* @param modID The ID of your Mod
|
||||
* @param scr a function that takes a parent {@link Screen} and provides the main Screen you want
|
||||
* to show with ModMenu for your Mod.
|
||||
*/
|
||||
public static void addModMenuScreen(String modID, Function<Screen, Screen> scr) {
|
||||
screen.put(modID, scr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.betterx.bclib.integration.modmenu;
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import org.betterx.bclib.gui.modmenu.MainScreen;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
/**
|
||||
* Internal class to hook into ModMenu, you should not need to use this class. If you want to register a
|
||||
* ModMenu Screen for a Mod using BCLib, use {@link ModMenu#addModMenuScreen(String, Function)}
|
||||
*/
|
||||
public class ModMenuEntryPoint implements ModMenuApi {
|
||||
@Override
|
||||
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
|
||||
Map<String, ConfigScreenFactory<?>> copy = new HashMap<>();
|
||||
for (var entry : ModMenu.screen.entrySet()) {
|
||||
copy.put(entry.getKey(), (parent) -> entry.getValue().apply(parent));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return (parent) -> new MainScreen(parent);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
package org.betterx.bclib.integration.modmenu;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import org.betterx.bclib.integration.modmenu.ModMenuIntegration.ModMenuScreenFactory;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
|
||||
@Deprecated
|
||||
class ModMenuScreenFactoryImpl {
|
||||
record ScreenFactoryInvocationHandler(ModMenuScreenFactory act) implements InvocationHandler {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
return switch (method.getName()) {
|
||||
case "toString" -> "";
|
||||
case "equals" -> false;
|
||||
case "hashCode" -> 0;
|
||||
default -> act.create((Screen) args[0]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static ModMenuScreenFactory create(ModMenuScreenFactory act) {
|
||||
Class<?> iConfigScreenFactory = null;
|
||||
try {
|
||||
iConfigScreenFactory = Class.forName("com.terraformersmc.modmenu.api.ConfigScreenFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
Object o = Proxy.newProxyInstance(
|
||||
ModMenuIntegration.class.getClassLoader(),
|
||||
new Class[]{iConfigScreenFactory, ModMenuScreenFactory.class},
|
||||
new ScreenFactoryInvocationHandler(act));
|
||||
|
||||
return (ModMenuScreenFactory) o;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* Integration, to provide a custom Screen for ModMenu.
|
||||
* <p>
|
||||
* This integration allows you to use ModMenu without adding a dependency to your project. If the
|
||||
* Mod is installed on the Client, and the correct ModMenu-EntryPoint is registered in your <i>fabric.mod.json</i>
|
||||
* the screen will show up.
|
||||
* <p>
|
||||
* You only need to subclass this class, and initialize a static Field of Type {@link ModMenuApi} using
|
||||
* the {@link #createEntrypoint(ModMenuIntegration)}-Method.
|
||||
* <p>
|
||||
* Example:
|
||||
* <pre>{@code public class ModMenu extends ModMenuIntegration {
|
||||
* public static final ModMenuApiMarker entrypointObject = createEntrypoint(new EntryPoint());
|
||||
*
|
||||
* public EntryPoint() {
|
||||
* super(GridScreen::new);
|
||||
* }
|
||||
* }}</pre>
|
||||
* You'd also need to add the ModMenu-Entrypoint to your <i>fabric.mod.json</i>:
|
||||
* <pre>"entrypoints": {
|
||||
* ...
|
||||
* "modmenu": [ "your.mod.ModMenu::entrypointObject" ]
|
||||
* }</pre>
|
||||
*/
|
||||
public abstract class ModMenuIntegration {
|
||||
/**
|
||||
* Creates a new EntryPoint Object that is accepted by ModMenu
|
||||
*
|
||||
* @param target The delegate Object that will receive calls from ModMenu
|
||||
* @return A Proxy that conforms to the ModMenu spec
|
||||
*/
|
||||
public static ModMenuApi createEntrypoint(ModMenuIntegration target) {
|
||||
Class<?> iModMenuAPI;
|
||||
//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 null;
|
||||
}
|
||||
|
||||
Object o = Proxy.newProxyInstance(
|
||||
ModMenuIntegration.class.getClassLoader(),
|
||||
new Class[]{iModMenuAPI},
|
||||
new BCLibModMenuInvocationHandler(target));
|
||||
|
||||
return (ModMenuApi) o;
|
||||
}
|
||||
|
||||
/**
|
||||
* The factory passed to {@link #ModMenuIntegration(ModMenuScreenFactory)}
|
||||
*/
|
||||
protected final ModMenuScreenFactory screenFactory;
|
||||
|
||||
/**
|
||||
* Create a new ModMenu delegate
|
||||
*
|
||||
* @param screenFactory A Factory. The Factory receives the currently visible {@code parent}-Screen
|
||||
* and must return a new Screen Object.
|
||||
*/
|
||||
public ModMenuIntegration(ModMenuScreenFactory screenFactory) {
|
||||
this.screenFactory = screenFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper class to make a BCLib-Factory conform to the ModMenu-Factory Interface.
|
||||
*
|
||||
* @param factory A BCLib-Type Factory, ie. {@code GridScreen::new }
|
||||
* @return A ModMenu Factory for a Screen
|
||||
*/
|
||||
final protected ModMenuScreenFactory createFactory(ModMenuScreenFactory factory) {
|
||||
return ModMenuScreenFactoryImpl.create(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to construct a new config screen instance when your mod's
|
||||
* configuration button is selected on the mod menu screen. The
|
||||
* screen instance parameter is the active mod menu screen.
|
||||
* (Text copied from ModMenu)
|
||||
*
|
||||
* @return A factory for constructing config screen instances.
|
||||
*/
|
||||
public ModMenuScreenFactory getModConfigScreenFactory() {
|
||||
return createFactory(screenFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to provide config screen factories for other mods. This takes second
|
||||
* priority to a mod's own config screen factory provider. For example, if
|
||||
* mod `xyz` supplies a config screen factory, mod `abc` providing a config
|
||||
* screen to `xyz` will be pointless, as the one provided by `xyz` will be
|
||||
* used.
|
||||
* <p>
|
||||
* This method is NOT meant to be used to add a config screen factory to
|
||||
* your own mod.
|
||||
* (Text copied from ModMenu)
|
||||
*
|
||||
* @return a map of mod ids to screen factories.
|
||||
*/
|
||||
public Map<String, ModMenuScreenFactory> getProvidedConfigScreenFactories() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A Factory Interface for ModMenu-Screens
|
||||
* <p>
|
||||
* The Interface matches {@code com.terraformersmc.modmenu.api.ConfigScreenFactory}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ModMenuScreenFactory extends ConfigScreenFactory {
|
||||
}
|
||||
|
||||
record BCLibModMenuInvocationHandler(ModMenuIntegration target) implements InvocationHandler {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
return switch (method.getName()) {
|
||||
case "getModConfigScreenFactory" -> target.getModConfigScreenFactory();
|
||||
case "getProvidedConfigScreenFactories" -> target.getProvidedConfigScreenFactories();
|
||||
case "toString" -> target.toString();
|
||||
case "equals" -> target.equals(args[0]);
|
||||
case "hashCode" -> target.hashCode();
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue