aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub <53441451+kuba6000@users.noreply.github.com>2023-06-15 17:53:16 +0200
committerGitHub <noreply@github.com>2023-06-15 17:53:16 +0200
commitcb383c824c3f799e678fb98f29661d79b5a13836 (patch)
treec27ec3672eb0cb1726565bf28ae2655404496231
parentb2c2a6dfe91696d4ecada95e5e43806ddb144ece (diff)
downloadGT5-Unofficial-cb383c824c3f799e678fb98f29661d79b5a13836.tar.gz
GT5-Unofficial-cb383c824c3f799e678fb98f29661d79b5a13836.tar.bz2
GT5-Unofficial-cb383c824c3f799e678fb98f29661d79b5a13836.zip
Use mixins accessors + some misc fixes (#77)
* Change reflections to mixins * Wrap witchery checking * Remove more repeating code * hmm * test generation * test * client sided * Update CommandCustomDrops.java * Update MobRecipeLoader.java * Save to static variable * Imports * Log message * Convert InfernalHelper to mixin accessors * Update build.gradle * One more * Return class nodes to optimize * Translations mixin * Automatically add commands * Fixes * Fix https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12021 * Update kubatech.java * Update CommonProxy.java * Unnecessary qualified reference * Simplify ItemUtils * Check if single player diffrently * Remove accessor for infernal-mobs
-rw-r--r--build.gradle1
-rw-r--r--dependencies.gradle38
-rw-r--r--src/main/java/kubatech/CommonProxy.java8
-rw-r--r--src/main/java/kubatech/api/helpers/InfernalHelper.java231
-rw-r--r--src/main/java/kubatech/api/helpers/ReflectionHelper.java63
-rw-r--r--src/main/java/kubatech/api/network/CustomTileEntityPacket.java2
-rw-r--r--src/main/java/kubatech/api/utils/ItemUtils.java26
-rw-r--r--src/main/java/kubatech/api/utils/MobUtils.java16
-rw-r--r--src/main/java/kubatech/api/utils/ModUtils.java14
-rw-r--r--src/main/java/kubatech/commands/CommandBees.java6
-rw-r--r--src/main/java/kubatech/commands/CommandConfig.java1
-rw-r--r--src/main/java/kubatech/commands/CommandCustomDrops.java67
-rw-r--r--src/main/java/kubatech/commands/CommandHandler.java30
-rw-r--r--src/main/java/kubatech/commands/CommandHelp.java1
-rw-r--r--src/main/java/kubatech/commands/CommandTea.java1
-rw-r--r--src/main/java/kubatech/kubatech.java19
-rw-r--r--src/main/java/kubatech/loaders/MobRecipeLoader.java922
-rw-r--r--src/main/java/kubatech/mixin/Mixin.java12
-rw-r--r--src/main/java/kubatech/mixin/MixinsVariablesHelper.java6
-rw-r--r--src/main/java/kubatech/mixin/TargetedMod.java4
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/EntityAccessor.java15
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/EntityLivingAccessor.java16
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/EntityLivingBaseAccessor.java16
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/EntitySlimeAccessor.java13
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/LanguageRegistryMixin.java27
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/LocaleMixin.java47
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/RendererLivingEntityAccessor.java15
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/StringTranslateMixin.java33
-rw-r--r--src/main/java/kubatech/mixin/mixins/minecraft/WorldMixin.java12
-rw-r--r--src/main/java/kubatech/nei/Mob_Handler.java25
-rw-r--r--src/main/java/kubatech/standalone.java15
-rw-r--r--src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java34
-rw-r--r--src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java10
33 files changed, 980 insertions, 766 deletions
diff --git a/build.gradle b/build.gradle
index 3930990407..f56a438f84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -879,6 +879,7 @@ def getManifestAttributes() {
"ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean()
]
}
+ manifestAttributes += ["Main-class": "kubatech.standalone"]
return manifestAttributes
}
diff --git a/dependencies.gradle b/dependencies.gradle
index 54717f7e1f..67de402103 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -1,12 +1,46 @@
-// Add your dependencies here
+/*
+ * Add your dependencies here. Supported configurations:
+ * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod
+ * Available at runtime and compiletime for mods depending on this mod
+ * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API
+ * Available at runtime but not compiletime for mods depending on this mod
+ * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods
+ * Not available at all for mods depending on this mod, only visible at compiletime for this mod
+ * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod
+ * Available at compiletime but not runtime for mods depending on this mod
+ * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency
+ * Not available at all for mods depending on this mod, only visible at runtime for this mod
+ * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime,
+ * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing
+ * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime
+ * Available at runtime for mods depending on this mod
+ * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
+ * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main
+ *
+ * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name
+ * Requires you to enable usesShadowedDependencies in gradle.properties
+ *
+ * - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient)
+ *
+ * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed,
+ * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful.
+ *
+ * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven,
+ * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file.
+ *
+ * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not.
+ * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published.
+ *
+ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
+ */
dependencies {
api('com.github.GTNewHorizons:GT5-Unofficial:5.09.43.82:dev')
api("com.github.GTNewHorizons:EnderCore:0.2.16:dev")
api("com.github.GTNewHorizons:EnderIO:2.4.18:dev")
- api("com.github.GTNewHorizons:Infernal-Mobs:1.7.8-GTNH:dev")
api("com.github.GTNewHorizons:ForestryMC:4.6.7:dev")
api("com.github.GTNewHorizons:ModularUI:1.1.10:dev")
+ devOnlyNonPublishable("com.github.GTNewHorizons:Infernal-Mobs:1.7.9-GTNH:dev")
//compileOnly("curse.maven:extrautilities-225561:2264384") {
// transitive = false
//}
diff --git a/src/main/java/kubatech/CommonProxy.java b/src/main/java/kubatech/CommonProxy.java
index b0d8446211..267efdab21 100644
--- a/src/main/java/kubatech/CommonProxy.java
+++ b/src/main/java/kubatech/CommonProxy.java
@@ -36,11 +36,7 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppedEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import kubatech.api.LoaderReference;
-import kubatech.commands.CommandBees;
-import kubatech.commands.CommandConfig;
import kubatech.commands.CommandHandler;
-import kubatech.commands.CommandHelp;
-import kubatech.commands.CommandTea;
import kubatech.config.Config;
import kubatech.loaders.MTLoader;
import kubatech.loaders.RecipeLoader;
@@ -76,10 +72,6 @@ public class CommonProxy {
public void serverStarting(FMLServerStartingEvent event) {
RecipeLoader.addRecipesLate();
CommandHandler cmd = new CommandHandler();
- cmd.addCommand(new CommandHelp());
- cmd.addCommand(new CommandConfig());
- cmd.addCommand(new CommandBees());
- cmd.addCommand(new CommandTea());
event.registerServerCommand(cmd);
}
diff --git a/src/main/java/kubatech/api/helpers/InfernalHelper.java b/src/main/java/kubatech/api/helpers/InfernalHelper.java
deleted file mode 100644
index e3c0db456b..0000000000
--- a/src/main/java/kubatech/api/helpers/InfernalHelper.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * spotless:off
- * KubaTech - Gregtech Addon
- * Copyright (C) 2022 - 2023 kuba6000
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <https://www.gnu.org/licenses/>.
- * spotless:on
- */
-
-package kubatech.api.helpers;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.item.ItemStack;
-
-import atomicstryker.infernalmobs.common.InfernalMobsCore;
-import atomicstryker.infernalmobs.common.mods.api.ModifierLoader;
-
-@SuppressWarnings("unchecked")
-public class InfernalHelper {
-
- private static Method isClassAllowed = null;
-
- public static boolean isClassAllowed(EntityLivingBase e) {
- try {
- if (isClassAllowed == null) {
- isClassAllowed = InfernalMobsCore.class.getDeclaredMethod("isClassAllowed", EntityLivingBase.class);
- isClassAllowed.setAccessible(true);
- }
- return (boolean) isClassAllowed.invoke(InfernalMobsCore.instance(), e);
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return false;
- }
-
- private static Method checkEntityClassForced = null;
-
- public static boolean checkEntityClassForced(EntityLivingBase e) {
- try {
- if (checkEntityClassForced == null) {
- checkEntityClassForced = InfernalMobsCore.class
- .getDeclaredMethod("checkEntityClassForced", EntityLivingBase.class);
- checkEntityClassForced.setAccessible(true);
- }
- return (boolean) checkEntityClassForced.invoke(InfernalMobsCore.instance(), e);
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return false;
- }
-
- private static Field modifierLoaders = null;
-
- public static ArrayList<ModifierLoader<?>> getModifierLoaders() {
- try {
- if (modifierLoaders == null) {
- modifierLoaders = InfernalMobsCore.class.getDeclaredField("modifierLoaders");
- modifierLoaders.setAccessible(true);
- }
- return (ArrayList<ModifierLoader<?>>) modifierLoaders.get(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return new ArrayList<>();
- }
-
- private static Field eliteRarity;
-
- public static int getEliteRarity() {
- try {
- if (eliteRarity == null) {
- eliteRarity = InfernalMobsCore.class.getDeclaredField("eliteRarity");
- eliteRarity.setAccessible(true);
- }
- return eliteRarity.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field ultraRarity;
-
- public static int getUltraRarity() {
- try {
- if (ultraRarity == null) {
- ultraRarity = InfernalMobsCore.class.getDeclaredField("ultraRarity");
- ultraRarity.setAccessible(true);
- }
- return ultraRarity.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field infernoRarity;
-
- public static int getInfernoRarity() {
- try {
- if (infernoRarity == null) {
- infernoRarity = InfernalMobsCore.class.getDeclaredField("infernoRarity");
- infernoRarity.setAccessible(true);
- }
- return infernoRarity.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field minEliteModifiers;
-
- public static int getMinEliteModifiers() {
- try {
- if (minEliteModifiers == null) {
- minEliteModifiers = InfernalMobsCore.class.getDeclaredField("minEliteModifiers");
- minEliteModifiers.setAccessible(true);
- }
- return minEliteModifiers.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field minUltraModifiers;
-
- public static int getMinUltraModifiers() {
- try {
- if (minUltraModifiers == null) {
- minUltraModifiers = InfernalMobsCore.class.getDeclaredField("minUltraModifiers");
- minUltraModifiers.setAccessible(true);
- }
- return minUltraModifiers.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field minInfernoModifiers;
-
- public static int getMinInfernoModifiers() {
- try {
- if (minInfernoModifiers == null) {
- minInfernoModifiers = InfernalMobsCore.class.getDeclaredField("minInfernoModifiers");
- minInfernoModifiers.setAccessible(true);
- }
- return minInfernoModifiers.getInt(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return 15;
- }
-
- private static Field dimensionBlackList;
-
- public static ArrayList<Integer> getDimensionBlackList() {
- try {
- if (dimensionBlackList == null) {
- dimensionBlackList = InfernalMobsCore.class.getDeclaredField("dimensionBlackList");
- dimensionBlackList.setAccessible(true);
- }
- return (ArrayList<Integer>) dimensionBlackList.get(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return new ArrayList<>();
- }
-
- private static Field dropIdListElite;
-
- public static ArrayList<ItemStack> getDropIdListElite() {
- try {
- if (dropIdListElite == null) {
- dropIdListElite = InfernalMobsCore.class.getDeclaredField("dropIdListElite");
- dropIdListElite.setAccessible(true);
- }
- return (ArrayList<ItemStack>) dropIdListElite.get(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return new ArrayList<>();
- }
-
- private static Field dropIdListUltra;
-
- public static ArrayList<ItemStack> getDropIdListUltra() {
- try {
- if (dropIdListUltra == null) {
- dropIdListUltra = InfernalMobsCore.class.getDeclaredField("dropIdListUltra");
- dropIdListUltra.setAccessible(true);
- }
- return (ArrayList<ItemStack>) dropIdListUltra.get(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return new ArrayList<>();
- }
-
- private static Field dropIdListInfernal;
-
- public static ArrayList<ItemStack> getDropIdListInfernal() {
- try {
- if (dropIdListInfernal == null) {
- dropIdListInfernal = InfernalMobsCore.class.getDeclaredField("dropIdListInfernal");
- dropIdListInfernal.setAccessible(true);
- }
- return (ArrayList<ItemStack>) dropIdListInfernal.get(InfernalMobsCore.instance());
- } catch (Throwable exception) {
- exception.printStackTrace();
- }
- return new ArrayList<>();
- }
-}
diff --git a/src/main/java/kubatech/api/helpers/ReflectionHelper.java b/src/main/java/kubatech/api/helpers/ReflectionHelper.java
index 63fd6bd633..8f2234f052 100644
--- a/src/main/java/kubatech/api/helpers/ReflectionHelper.java
+++ b/src/main/java/kubatech/api/helpers/ReflectionHelper.java
@@ -20,9 +20,23 @@
package kubatech.api.helpers;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Objects;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+
+import net.minecraft.launchwrapper.Launch;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.tree.ClassNode;
public class ReflectionHelper {
@@ -140,4 +154,53 @@ public class ReflectionHelper {
return defaultValue;
}
}
+
+ /**
+ * Gets all classes in a specific package path, works only for jar files.
+ *
+ * @param packageName The package name
+ * @return The class nodes
+ */
+ public static Collection<ClassNode> getClasses(String packageName) throws IOException, SecurityException {
+ ClassLoader classLoader = Thread.currentThread()
+ .getContextClassLoader();
+ assert classLoader != null;
+ String packagePath = packageName.replace('.', '/');
+ URL resource = classLoader.getResource(packagePath);
+ if (resource == null) throw new FileNotFoundException();
+ if (!resource.getProtocol()
+ .equals("jar")) return Collections.emptySet();
+ String jarPath = resource.getPath();
+
+ try (JarFile jar = new JarFile(jarPath.substring(5, jarPath.indexOf('!')))) {
+ return jar.stream()
+ .filter(
+ j -> !j.isDirectory() && j.getName()
+ .startsWith(packagePath)
+ && j.getName()
+ .endsWith(".class"))
+ .map(j -> {
+ try {
+ String name = j.getName();
+ URL jarResource = Launch.classLoader.getResource(name);
+ if (jarResource == null) return null;
+ byte[] bytes;
+ try (InputStream is = jarResource.openStream()) {
+ bytes = new byte[(int) j.getSize()];
+ if (is.read(bytes) != bytes.length) return null;
+ if (is.available() > 0) return null;
+ }
+
+ ClassNode cn = new ClassNode();
+ ClassReader cr = new ClassReader(bytes);
+ cr.accept(cn, 0);
+
+ return cn;
+ } catch (IOException ignored) {}
+ return null;
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ }
+ }
}
diff --git a/src/main/java/kubatech/api/network/CustomTileEntityPacket.java b/src/main/java/kubatech/api/network/CustomTileEntityPacket.java
index cd65d08d57..67a310ecf5 100644
--- a/src/main/java/kubatech/api/network/CustomTileEntityPacket.java
+++ b/src/main/java/kubatech/api/network/CustomTileEntityPacket.java
@@ -132,7 +132,7 @@ public class CustomTileEntityPacket implements IMessage {
@Override
public IMessage onMessage(CustomTileEntityPacket message, MessageContext ctx) {
- if (!ModUtils.isClientSided) return null;
+ if (!ModUtils.isClientThreaded()) return null;
Minecraft mc = Minecraft.getMinecraft();
if (mc == null) return null;
if (mc.thePlayer == null) return null;
diff --git a/src/main/java/kubatech/api/utils/ItemUtils.java b/src/main/java/kubatech/api/utils/ItemUtils.java
new file mode 100644
index 0000000000..2fc34057c3
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/ItemUtils.java
@@ -0,0 +1,26 @@
+package kubatech.api.utils;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class ItemUtils {
+
+ public static NBTTagCompound writeItemStackToNBT(ItemStack stack) {
+ NBTTagCompound compound = new NBTTagCompound();
+
+ stack.writeToNBT(compound);
+ compound.setInteger("IntCount", stack.stackSize);
+
+ return compound;
+ }
+
+ public static ItemStack readItemStackFromNBT(NBTTagCompound compound) {
+ ItemStack stack = ItemStack.loadItemStackFromNBT(compound);
+
+ if (stack == null) return null;
+
+ if (compound.hasKey("IntCount")) stack.stackSize = compound.getInteger("IntCount");
+
+ return stack;
+ }
+}
diff --git a/src/main/java/kubatech/api/utils/MobUtils.java b/src/main/java/kubatech/api/utils/MobUtils.java
index ad48c51cbf..d3ec59757a 100644
--- a/src/main/java/kubatech/api/utils/MobUtils.java
+++ b/src/main/java/kubatech/api/utils/MobUtils.java
@@ -20,8 +20,6 @@
package kubatech.api.utils;
-import java.lang.reflect.Field;
-
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBox;
import net.minecraft.client.model.ModelRenderer;
@@ -32,11 +30,10 @@ import net.minecraft.entity.EntityLiving;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
+import kubatech.mixin.mixins.minecraft.RendererLivingEntityAccessor;
public class MobUtils {
- private static Field mainmodelfield = null;
-
@SideOnly(Side.CLIENT)
public static float getDesiredScale(EntityLiving e, float desiredHeight) {
return getDesiredScale(getMobHeight(e), desiredHeight);
@@ -50,17 +47,12 @@ public class MobUtils {
@SideOnly(Side.CLIENT)
public static float getMobHeight(EntityLiving e) {
try {
- if (mainmodelfield == null) {
- mainmodelfield = RendererLivingEntity.class
- .getDeclaredField(ModUtils.isDeobfuscatedEnvironment ? "mainModel" : "field_77045_g");
- mainmodelfield.setAccessible(true);
- }
float eheight = e.height;
float ewidth = e.width;
Render r = RenderManager.instance.getEntityRenderObject(e);
- if (r instanceof RendererLivingEntity && mainmodelfield != null) {
- ModelBase mainmodel = (ModelBase) mainmodelfield.get(r);
- for (Object box : mainmodel.boxList) {
+ if (r instanceof RendererLivingEntity) {
+ ModelBase mainModel = ((RendererLivingEntityAccessor) r).getMainModel();
+ for (Object box : mainModel.boxList) {
if (box instanceof ModelRenderer) {
float minY = 999f;
float minX = 999f;
diff --git a/src/main/java/kubatech/api/utils/ModUtils.java b/src/main/java/kubatech/api/utils/ModUtils.java
index cd02d28dba..61352cce9d 100644
--- a/src/main/java/kubatech/api/utils/ModUtils.java
+++ b/src/main/java/kubatech/api/utils/ModUtils.java
@@ -32,6 +32,7 @@ import javax.xml.bind.DatatypeConverter;
import net.minecraft.launchwrapper.Launch;
+import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import kubatech.kubatech;
@@ -41,6 +42,19 @@ public class ModUtils {
public static final boolean isDeobfuscatedEnvironment = (boolean) Launch.blackboard
.get("fml.deobfuscatedEnvironment");
public static boolean isClientSided = false;
+
+ public static boolean isClientThreaded() {
+ return FMLCommonHandler.instance()
+ .getEffectiveSide()
+ .isClient();
+ }
+
+ @FunctionalInterface
+ public interface TriConsumer<T, U, V> {
+
+ void accept(T t, U u, V v);
+ }
+
private static final HashMap<String, String> classNamesToModIDs = new HashMap<>();
private static final Map.Entry<String, String> emptyEntry = new AbstractMap.SimpleEntry<>("", "");
diff --git a/src/main/java/kubatech/commands/CommandBees.java b/src/main/java/kubatech/commands/CommandBees.java
index 8d01080500..edf3b04ce6 100644
--- a/src/main/java/kubatech/commands/CommandBees.java
+++ b/src/main/java/kubatech/commands/CommandBees.java
@@ -28,7 +28,6 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
-import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender;
import net.minecraft.item.ItemStack;
@@ -40,7 +39,9 @@ import com.google.common.io.Files;
import forestry.api.apiculture.IAlleleBeeSpecies;
import forestry.api.apiculture.IBee;
import forestry.api.apiculture.IBeeGenome;
+import kubatech.api.utils.ModUtils;
+@CommandHandler.ChildCommand
public class CommandBees extends CommandBase {
@Override
@@ -62,8 +63,7 @@ public class CommandBees extends CommandBase {
@Override
public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) {
- if (!Minecraft.getMinecraft()
- .isSingleplayer()) {
+ if (!ModUtils.isClientSided) {
p_71515_1_
.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This command is single-player only!"));
return;
diff --git a/src/main/java/kubatech/commands/CommandConfig.java b/src/main/java/kubatech/commands/CommandConfig.java
index e4ffe9753d..cf43bc88ba 100644
--- a/src/main/java/kubatech/commands/CommandConfig.java
+++ b/src/main/java/kubatech/commands/CommandConfig.java
@@ -36,6 +36,7 @@ import kubatech.config.Config;
import kubatech.kubatech;
import kubatech.loaders.MobRecipeLoader;
+@CommandHandler.ChildCommand
public class CommandConfig extends CommandBase {
enum Translations {
diff --git a/src/main/java/kubatech/commands/CommandCustomDrops.java b/src/main/java/kubatech/commands/CommandCustomDrops.java
new file mode 100644
index 0000000000..80148eb796
--- /dev/null
+++ b/src/main/java/kubatech/commands/CommandCustomDrops.java
@@ -0,0 +1,67 @@
+/*
+ * spotless:off
+ * KubaTech - Gregtech Addon
+ * Copyright (C) 2022 - 2023 kuba6000
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <https://www.gnu.org/licenses/>.
+ * spotless:on
+ */
+
+package kubatech.commands;
+
+import java.io.File;
+
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+
+import kubatech.api.utils.ModUtils;
+import kubatech.loaders.MobRecipeLoader;
+
+@CommandHandler.ChildCommand
+public class CommandCustomDrops extends CommandBase {
+
+ @Override
+ public String getCommandName() {
+ return "customdrops";
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender p_71518_1_) {
+ return "customdrops";
+ }
+
+ @Override
+ public int getRequiredPermissionLevel() {
+ return 4;
+ }
+
+ @Override
+ public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) {
+
+ if (!ModUtils.isClientSided) {
+ p_71515_1_
+ .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This command is single-player only!"));
+ return;
+ }
+
+ File f = MobRecipeLoader.make