package me.km.utils; import cpw.mods.modlauncher.api.INameMappingService; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.function.Function; import net.minecraft.command.Commands; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerAbilities; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.PlayerList; import net.minecraft.util.FoodStats; import net.minecraft.util.ResourceLocation; import net.minecraft.world.Explosion; import net.minecraft.world.GameRules; import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.biome.provider.BiomeProvider; import net.minecraft.world.biome.provider.BiomeProviderType; import net.minecraft.world.biome.provider.IBiomeProviderSettings; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import static net.minecraftforge.fml.common.ObfuscationReflectionHelper.remapName; import org.apache.logging.log4j.LogManager; public class ReflectionUtils { // ----------------------------------------------------------------------------------- // helper stuff // ----------------------------------------------------------------------------------- public static Method getMethod(Class c, String name, Class... pars) { try { return ObfuscationReflectionHelper.findMethod(c, name, pars); } catch(Exception ex) { LogManager.getLogger().warn(name + " - " + ex); } return null; } public static Field getField(Class c, String field) { try { Field f = c.getDeclaredField(remapName(INameMappingService.Domain.FIELD, field)); f.setAccessible(true); return f; } catch(Exception ex) { LogManager.getLogger().warn(field + " - " + ex); } return null; } private static void setInt(T t, Field f, int i) { try { f.setInt(t, i); } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) { LogManager.getLogger().warn(f + " - " + ex); } } private static int getInt(T t, Field f, int error) { try { return f.getInt(t); } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) { LogManager.getLogger().warn(f + " - " + ex); return error; } } private static void setFloat(T t, Field f, float fl) { try { f.setFloat(t, fl); } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) { LogManager.getLogger().warn(f + " - " + ex); } } private static float getFloat(T t, Field f, float error) { try { return f.getFloat(t); } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) { LogManager.getLogger().warn(f + " - " + ex); return error; } } private static boolean getBoolean(T t, Field f, boolean error) { try { return f.getBoolean(t); } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) { LogManager.getLogger().warn(f + " - " + ex); return error; } } public static T getFieldValue(Class cast, Object o, Field f) { try { return (T) f.get(o); } catch(SecurityException | IllegalAccessException | IllegalArgumentException ex) { LogManager.getLogger().warn(f + " - " + ex); return null; } } public static void setFieldValue(Object instance, Field f, Object value) { try { f.set(instance, value); } catch(SecurityException | IllegalAccessException | IllegalArgumentException ex) { LogManager.getLogger().warn(f + " - " + ex); } } public static T getFieldValue(Class cast, Class c, Object instance, String field) { Field f = getField(c, field); if(f == null) { return null; } return getFieldValue(cast, instance, f); } // ----------------------------------------------------------------------------------- // food stats // ----------------------------------------------------------------------------------- private final static Field FOOD_EXHAUSTION_LEVEL = getField(FoodStats.class, "field_75126_c"); // foodExhaustionLevel public static void setExhaustion(FoodStats stats, float f) { setFloat(stats, FOOD_EXHAUSTION_LEVEL, f); } public static float getExhaustion(FoodStats stats) { return getFloat(stats, FOOD_EXHAUSTION_LEVEL, 0); } private final static Field FOOD_SATURATION_LEVEL = getField(FoodStats.class, "field_75125_b"); // foodSaturationLevel public static void setSaturation(FoodStats stats, float f) { setFloat(stats, FOOD_SATURATION_LEVEL, f); } // ----------------------------------------------------------------------------------- // player stats // ----------------------------------------------------------------------------------- private final static Field FLY_SPEED = getField(PlayerAbilities.class, "field_75096_f"); // flySpeed public static void setFlySpeed(PlayerAbilities cap, float f) { setFloat(cap, FLY_SPEED, f); } private final static Field WALK_SPEED = getField(PlayerAbilities.class, "field_75097_g"); // walkSpeed public static void setWalkSpeed(PlayerAbilities cap, float f) { setFloat(cap, WALK_SPEED, f); } // ----------------------------------------------------------------------------------- // PlayerList // ----------------------------------------------------------------------------------- private final static Method SET_GAMETYPE = getMethod(PlayerList.class, "func_72381_a", ServerPlayerEntity.class, ServerPlayerEntity.class, IWorld.class); // setPlayerGameTypeBasedOnOther public static void setPlayerGameTypeBasedOnOther(PlayerList pl, ServerPlayerEntity target, ServerPlayerEntity source, IWorld worldIn) { try { SET_GAMETYPE.invoke(pl, target, source, worldIn); } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { LogManager.getLogger().warn("setPlayerGameTypeBasedOnOther - " + ex); } } // ----------------------------------------------------------------------------------- // random field gets // ----------------------------------------------------------------------------------- private final static Field ENTITY_ITEM_AGE = getField(ItemEntity.class, "field_70292_b"); // age public static int getAge(ItemEntity item) { return getInt(item, ENTITY_ITEM_AGE, 0); } public static void setAge(ItemEntity item, int age) { setInt(item, ENTITY_ITEM_AGE, age); } // ----------------------------------------------------------------------------------- // minecraft server // ----------------------------------------------------------------------------------- private final static Field COMMAND_MANAGER = getField(MinecraftServer.class, "field_195579_af"); // commandManager public static void setCommandManager(MinecraftServer server, Commands manager) { setFieldValue(server, COMMAND_MANAGER, manager); } // ----------------------------------------------------------------------------------- // DimensionManager // ----------------------------------------------------------------------------------- private final static Field SAVED_ENTRIES = getField(DimensionManager.class, "savedEntries"); // forge name public static void removeDimensionSaveEntry(ResourceLocation rl) { // the map seems to be always empty ... getFieldValue(Map.class, null, SAVED_ENTRIES).remove(rl); } // ----------------------------------------------------------------------------------- // explosion stuff // ----------------------------------------------------------------------------------- private final static Field MODE = getField(Explosion.class, "field_222260_b"); // mode private final static Field EXPLODER = getField(Explosion.class, "field_77283_e"); // exploder private final static Field SIZE = getField(Explosion.class, "field_77280_f"); // size public static void setNoBreakMode(Explosion ex) { Explosion.Mode mode = getFieldValue(Explosion.Mode.class, ex, MODE); if(mode == Explosion.Mode.DESTROY) { setFieldValue(ex, MODE, Explosion.Mode.BREAK); } } public static Entity getExploder(Explosion ex) { return getFieldValue(Entity.class, ex, EXPLODER); } public static float getSize(Explosion ex) { return getFloat(ex, SIZE, 1); } // ----------------------------------------------------------------------------------- // world info // ----------------------------------------------------------------------------------- private final static Field WORLD_INFO = getField(World.class, "field_72986_A"); // worldInfo public static void setWorldInfo(World w, WorldInfo info) { setFieldValue(w, WORLD_INFO, info); } // ----------------------------------------------------------------------------------- // gamerule integer value // ----------------------------------------------------------------------------------- private final static Field INTEGER_VALUE = getField(GameRules.IntegerValue.class, "field_223566_a"); // value public static void setIntegerValue(GameRules.IntegerValue rule, int value) { setInt(rule, INTEGER_VALUE, value); } public static BiomeProviderType newBiomeProviderType(Function factory, Function settingsFactory) { try { Constructor con = (Constructor) BiomeProviderType.class.getDeclaredConstructors()[0]; con.setAccessible(true); return con.newInstance(factory, settingsFactory); } catch(Exception ex) { return null; } } }