ReflectionUtils.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package me.km.utils;
  2. import cpw.mods.modlauncher.api.INameMappingService;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.util.Set;
  7. import net.minecraft.block.Block;
  8. import net.minecraft.block.Blocks;
  9. import net.minecraft.block.FireBlock;
  10. import net.minecraft.command.Commands;
  11. import net.minecraft.entity.ai.goal.GoalSelector;
  12. import net.minecraft.entity.ai.goal.PrioritizedGoal;
  13. import net.minecraft.entity.player.PlayerEntity;
  14. import net.minecraft.entity.player.ServerPlayerEntity;
  15. import net.minecraft.inventory.IInventory;
  16. import net.minecraft.inventory.container.Container;
  17. import net.minecraft.inventory.container.Slot;
  18. import net.minecraft.item.ItemStack;
  19. import net.minecraft.resources.DataPackRegistries;
  20. import net.minecraft.server.MinecraftServer;
  21. import net.minecraft.server.management.PlayerInteractionManager;
  22. import net.minecraft.server.management.PlayerList;
  23. import net.minecraft.tileentity.SignTileEntity;
  24. import net.minecraft.util.FoodStats;
  25. import net.minecraft.util.IIntArray;
  26. import net.minecraft.util.IntReferenceHolder;
  27. import net.minecraft.util.text.ITextComponent;
  28. import net.minecraft.world.Explosion;
  29. import net.minecraft.world.GameRules;
  30. import net.minecraft.world.GameType;
  31. import net.minecraft.world.World;
  32. import net.minecraft.world.server.ServerWorld;
  33. import net.minecraft.world.storage.DerivedWorldInfo;
  34. import net.minecraft.world.storage.IServerConfiguration;
  35. import net.minecraft.world.storage.IServerWorldInfo;
  36. import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
  37. import static net.minecraftforge.fml.common.ObfuscationReflectionHelper.remapName;
  38. import org.apache.logging.log4j.LogManager;
  39. public class ReflectionUtils {
  40. public static Method getMethod(Class<?> c, String name, Class<?>... pars) {
  41. try {
  42. return ObfuscationReflectionHelper.findMethod(c, name, pars);
  43. } catch(Exception ex) {
  44. LogManager.getLogger().warn(name + " - " + ex);
  45. }
  46. return null;
  47. }
  48. public static Field getField(Class<?> c, String field) {
  49. try {
  50. Field f = c.getDeclaredField(remapName(INameMappingService.Domain.FIELD, field));
  51. f.setAccessible(true);
  52. return f;
  53. } catch(Exception ex) {
  54. LogManager.getLogger().warn(field + " - " + ex);
  55. }
  56. return null;
  57. }
  58. private static <T> void setInt(T t, Field f, int i) {
  59. try {
  60. f.setInt(t, i);
  61. } catch(Exception ex) {
  62. LogManager.getLogger().warn(f + " - " + ex);
  63. }
  64. }
  65. private static <T> void setFloat(T t, Field f, float fl) {
  66. try {
  67. f.setFloat(t, fl);
  68. } catch(Exception ex) {
  69. LogManager.getLogger().warn(f + " - " + ex);
  70. }
  71. }
  72. private static <T> float getFloat(T t, Field f, float error) {
  73. try {
  74. return f.getFloat(t);
  75. } catch(Exception ex) {
  76. LogManager.getLogger().warn(f + " - " + ex);
  77. return error;
  78. }
  79. }
  80. public static <T> T getFieldValue(Class<T> cast, Object o, Field f) {
  81. try {
  82. return cast.cast(f.get(o));
  83. } catch(Exception ex) {
  84. LogManager.getLogger().warn(f + " - " + ex);
  85. return null;
  86. }
  87. }
  88. public static void setFieldValue(Object instance, Field f, Object value) {
  89. try {
  90. f.set(instance, value);
  91. } catch(Exception ex) {
  92. LogManager.getLogger().warn(f + " - " + ex);
  93. }
  94. }
  95. public static <T> T getFieldValue(Class<T> cast, Class<?> c, Object instance, String field) {
  96. Field f = getField(c, field);
  97. if(f == null) {
  98. return null;
  99. }
  100. return getFieldValue(cast, instance, f);
  101. }
  102. private final static Field FOOD_EXHAUSTION_LEVEL = getField(FoodStats.class, "field_75126_c"); // foodExhaustionLevel
  103. public static void setExhaustion(FoodStats stats, float f) {
  104. setFloat(stats, FOOD_EXHAUSTION_LEVEL, f);
  105. }
  106. public static float getExhaustion(FoodStats stats) {
  107. return getFloat(stats, FOOD_EXHAUSTION_LEVEL, 0);
  108. }
  109. private final static Field FOOD_SATURATION_LEVEL = getField(FoodStats.class, "field_75125_b"); // foodSaturationLevel
  110. public static void setSaturation(FoodStats stats, float f) {
  111. setFloat(stats, FOOD_SATURATION_LEVEL, f);
  112. }
  113. private final static Method SET_GAMETYPE = getMethod(PlayerList.class, "func_72381_a",
  114. ServerPlayerEntity.class, ServerPlayerEntity.class, ServerWorld.class); // setPlayerGameTypeBasedOnOther
  115. public static void setPlayerGameTypeBasedOnOther(PlayerList pl, ServerPlayerEntity target,
  116. ServerPlayerEntity source, ServerWorld sw) {
  117. try {
  118. SET_GAMETYPE.invoke(pl, target, source, sw);
  119. } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
  120. LogManager.getLogger().warn("setPlayerGameTypeBasedOnOther - " + ex);
  121. }
  122. }
  123. private final static Field COMMAND_MANAGER =
  124. getField(DataPackRegistries.class, "field_240953_c_"); // commands
  125. public static void setCommandManager(MinecraftServer server, Commands manager) {
  126. setFieldValue(server.getDataPackRegistries(), COMMAND_MANAGER, manager);
  127. }
  128. private final static Field MODE = getField(Explosion.class, "field_222260_b"); // mode
  129. public static void setNoBreakMode(Explosion ex) {
  130. Explosion.Mode mode = getFieldValue(Explosion.Mode.class, ex, MODE);
  131. if(mode == Explosion.Mode.DESTROY) {
  132. setFieldValue(ex, MODE, Explosion.Mode.BREAK);
  133. }
  134. }
  135. private final static Field INTEGER_VALUE =
  136. getField(GameRules.IntegerValue.class, "field_223566_a"); // value
  137. public static void setIntegerValue(GameRules.IntegerValue rule, int value) {
  138. setInt(rule, INTEGER_VALUE, value);
  139. }
  140. // -----------------------------------------------------------------------------------
  141. // game type setter without update for dirty hack
  142. // -----------------------------------------------------------------------------------
  143. private final static Field GAME_TYPE =
  144. getField(PlayerInteractionManager.class, "field_73091_c");
  145. public static void setGameType(PlayerInteractionManager m, GameType type) {
  146. setFieldValue(m, GAME_TYPE, type);
  147. }
  148. // -----------------------------------------------------------------------------------
  149. // for clearing ai
  150. // -----------------------------------------------------------------------------------
  151. private final static Field GOALS = getField(GoalSelector.class, "field_220892_d");
  152. @SuppressWarnings("unchecked")
  153. public static Set<PrioritizedGoal> getGoals(GoalSelector gs) {
  154. return getFieldValue(Set.class, gs, GOALS);
  155. }
  156. private final static Method SET_FIRE_INFO =
  157. getMethod(FireBlock.class, "func_180686_a", Block.class, int.class, int.class);
  158. public static void setFireInfo(Block b, int encouragement, int flammability) {
  159. FireBlock fireblock = (FireBlock) Blocks.FIRE;
  160. try {
  161. SET_FIRE_INFO.invoke(fireblock, b, encouragement, flammability);
  162. } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
  163. LogManager.getLogger().warn("setFireInfo - " + ex);
  164. }
  165. }
  166. private final static Field SIGN_TEXT = getField(SignTileEntity.class, "field_145915_a");
  167. public static ITextComponent getSignText(SignTileEntity ent, int index) {
  168. return getFieldValue(ITextComponent[].class, ent, SIGN_TEXT)[index];
  169. }
  170. private final static Field WORLD_INFO = getField(World.class, "field_72986_A"); // worldInfo
  171. private final static Field SERVER_WORLD_INFO = getField(ServerWorld.class, "field_241103_E_"); // worldInfo
  172. public static void setWorldInfo(ServerWorld w, IServerWorldInfo info) {
  173. setFieldValue(w, WORLD_INFO, info);
  174. setFieldValue(w, SERVER_WORLD_INFO, info);
  175. }
  176. private final static Field DERIVED_WORLD_INFO_DELEGATE =
  177. getField(DerivedWorldInfo.class, "field_76115_a");
  178. public static IServerWorldInfo getDerivedWorldInfoDelegate(DerivedWorldInfo info) {
  179. return getFieldValue(IServerWorldInfo.class, info, DERIVED_WORLD_INFO_DELEGATE);
  180. }
  181. private final static Field DERIVED_WORLD_INFO_CONFIGURATION =
  182. getField(DerivedWorldInfo.class, "field_237244_a_");
  183. public static IServerConfiguration getDerivedWorldInfoConfiguration(DerivedWorldInfo info) {
  184. return getFieldValue(IServerConfiguration.class, info, DERIVED_WORLD_INFO_CONFIGURATION);
  185. }
  186. private final static Method ADD_SLOT = getMethod(Container.class, "func_75146_a", Slot.class); // addSlot
  187. private final static Method TRACK_INT =
  188. getMethod(Container.class, "func_216958_a", IntReferenceHolder.class); // trackInt
  189. private final static Method TRACK_INT_ARRAY =
  190. getMethod(Container.class, "func_216961_a", IIntArray.class); // trackIntArray
  191. private final static Method CLEAR_CONTAINER = getMethod(Container.class, "func_193327_a",
  192. PlayerEntity.class, World.class, IInventory.class); // clearContainer
  193. private final static Method MERGE_ITEM_STACK = getMethod(Container.class, "func_75135_a",
  194. ItemStack.class, int.class, int.class, boolean.class); // mergeItemStack
  195. private final static Method RESET_DRAG = getMethod(Container.class, "func_94533_d"); // resetDrag
  196. public static Slot addSlot(Container c, Slot slot) {
  197. try {
  198. return (Slot) ADD_SLOT.invoke(c, slot);
  199. } catch(Exception ex) {
  200. LogManager.getLogger().warn("addSlot - " + ex);
  201. }
  202. return null;
  203. }
  204. public static IntReferenceHolder trackInt(Container c, IntReferenceHolder i) {
  205. try {
  206. return (IntReferenceHolder) TRACK_INT.invoke(c, i);
  207. } catch(Exception ex) {
  208. LogManager.getLogger().warn("trackInt - " + ex);
  209. }
  210. return null;
  211. }
  212. public static void trackIntArray(Container c, IIntArray array) {
  213. try {
  214. TRACK_INT_ARRAY.invoke(c, array);
  215. } catch(Exception ex) {
  216. LogManager.getLogger().warn("trackIntArray - " + ex);
  217. }
  218. }
  219. public static void clearContainer(Container c, PlayerEntity p, World w, IInventory i) {
  220. try {
  221. CLEAR_CONTAINER.invoke(c, p, w, i);
  222. } catch(Exception ex) {
  223. LogManager.getLogger().warn("clearContainer - " + ex);
  224. }
  225. }
  226. public static boolean mergeItemStack(Container c, ItemStack stack, int startIndex, int endIndex,
  227. boolean reverseDirection) {
  228. try {
  229. return (boolean) MERGE_ITEM_STACK.invoke(c, stack, startIndex, endIndex,
  230. reverseDirection);
  231. } catch(Exception ex) {
  232. LogManager.getLogger().warn("mergeItemStack - " + ex);
  233. }
  234. return false;
  235. }
  236. public static void resetDrag(Container c) {
  237. try {
  238. RESET_DRAG.invoke(c);
  239. } catch(Exception ex) {
  240. LogManager.getLogger().warn("resetDrag - " + ex);
  241. }
  242. }
  243. }