ReflectionUtils.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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.ServerPlayerEntity;
  14. import net.minecraft.resources.DataPackRegistries;
  15. import net.minecraft.server.MinecraftServer;
  16. import net.minecraft.server.management.PlayerInteractionManager;
  17. import net.minecraft.server.management.PlayerList;
  18. import net.minecraft.tileentity.SignTileEntity;
  19. import net.minecraft.util.FoodStats;
  20. import net.minecraft.util.text.ITextComponent;
  21. import net.minecraft.world.Explosion;
  22. import net.minecraft.world.GameRules;
  23. import net.minecraft.world.GameType;
  24. import net.minecraft.world.World;
  25. import net.minecraft.world.server.ServerWorld;
  26. import net.minecraft.world.storage.IServerWorldInfo;
  27. import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
  28. import static net.minecraftforge.fml.common.ObfuscationReflectionHelper.remapName;
  29. import org.apache.logging.log4j.LogManager;
  30. public class ReflectionUtils {
  31. // -----------------------------------------------------------------------------------
  32. // helper stuff
  33. // -----------------------------------------------------------------------------------
  34. public static Method getMethod(Class c, String name, Class... pars) {
  35. try {
  36. return ObfuscationReflectionHelper.findMethod(c, name, pars);
  37. } catch(Exception ex) {
  38. LogManager.getLogger().warn(name + " - " + ex);
  39. }
  40. return null;
  41. }
  42. public static Field getField(Class c, String field) {
  43. try {
  44. Field f = c.getDeclaredField(remapName(INameMappingService.Domain.FIELD, field));
  45. f.setAccessible(true);
  46. return f;
  47. } catch(Exception ex) {
  48. LogManager.getLogger().warn(field + " - " + ex);
  49. }
  50. return null;
  51. }
  52. private static <T> void setInt(T t, Field f, int i) {
  53. try {
  54. f.setInt(t, i);
  55. } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) {
  56. LogManager.getLogger().warn(f + " - " + ex);
  57. }
  58. }
  59. private static <T> int getInt(T t, Field f, int error) {
  60. try {
  61. return f.getInt(t);
  62. } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) {
  63. LogManager.getLogger().warn(f + " - " + ex);
  64. return error;
  65. }
  66. }
  67. private static <T> void setFloat(T t, Field f, float fl) {
  68. try {
  69. f.setFloat(t, fl);
  70. } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) {
  71. LogManager.getLogger().warn(f + " - " + ex);
  72. }
  73. }
  74. private static <T> float getFloat(T t, Field f, float error) {
  75. try {
  76. return f.getFloat(t);
  77. } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) {
  78. LogManager.getLogger().warn(f + " - " + ex);
  79. return error;
  80. }
  81. }
  82. private static <T> boolean getBoolean(T t, Field f, boolean error) {
  83. try {
  84. return f.getBoolean(t);
  85. } catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex) {
  86. LogManager.getLogger().warn(f + " - " + ex);
  87. return error;
  88. }
  89. }
  90. public static <T> T getFieldValue(Class<T> cast, Object o, Field f) {
  91. try {
  92. return (T) f.get(o);
  93. } catch(SecurityException | IllegalAccessException | IllegalArgumentException ex) {
  94. LogManager.getLogger().warn(f + " - " + ex);
  95. return null;
  96. }
  97. }
  98. public static void setFieldValue(Object instance, Field f, Object value) {
  99. try {
  100. f.set(instance, value);
  101. } catch(SecurityException | IllegalAccessException | IllegalArgumentException ex) {
  102. LogManager.getLogger().warn(f + " - " + ex);
  103. }
  104. }
  105. public static <T> T getFieldValue(Class<T> cast, Class c, Object instance, String field) {
  106. Field f = getField(c, field);
  107. if(f == null) {
  108. return null;
  109. }
  110. return getFieldValue(cast, instance, f);
  111. }
  112. // -----------------------------------------------------------------------------------
  113. // food stats
  114. // -----------------------------------------------------------------------------------
  115. private final static Field FOOD_EXHAUSTION_LEVEL = getField(FoodStats.class, "field_75126_c"); // foodExhaustionLevel
  116. public static void setExhaustion(FoodStats stats, float f) {
  117. setFloat(stats, FOOD_EXHAUSTION_LEVEL, f);
  118. }
  119. public static float getExhaustion(FoodStats stats) {
  120. return getFloat(stats, FOOD_EXHAUSTION_LEVEL, 0);
  121. }
  122. private final static Field FOOD_SATURATION_LEVEL = getField(FoodStats.class, "field_75125_b"); // foodSaturationLevel
  123. public static void setSaturation(FoodStats stats, float f) {
  124. setFloat(stats, FOOD_SATURATION_LEVEL, f);
  125. }
  126. // -----------------------------------------------------------------------------------
  127. // PlayerList
  128. // -----------------------------------------------------------------------------------
  129. private final static Method SET_GAMETYPE = getMethod(PlayerList.class, "func_72381_a",
  130. ServerPlayerEntity.class, ServerPlayerEntity.class, ServerWorld.class); // setPlayerGameTypeBasedOnOther
  131. public static void setPlayerGameTypeBasedOnOther(PlayerList pl, ServerPlayerEntity target, ServerPlayerEntity source, ServerWorld sw) {
  132. try {
  133. SET_GAMETYPE.invoke(pl, target, source, sw);
  134. } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
  135. LogManager.getLogger().warn("setPlayerGameTypeBasedOnOther - " + ex);
  136. }
  137. }
  138. // -----------------------------------------------------------------------------------
  139. // minecraft server
  140. // -----------------------------------------------------------------------------------
  141. private final static Field COMMAND_MANAGER = getField(DataPackRegistries.class, "field_240953_c_"); // commands
  142. public static void setCommandManager(MinecraftServer server, Commands manager) {
  143. setFieldValue(server.getDataPackRegistries(), COMMAND_MANAGER, manager);
  144. }
  145. private final static Field MODE = getField(Explosion.class, "field_222260_b"); // mode
  146. public static void setNoBreakMode(Explosion ex) {
  147. Explosion.Mode mode = getFieldValue(Explosion.Mode.class, ex, MODE);
  148. if(mode == Explosion.Mode.DESTROY) {
  149. setFieldValue(ex, MODE, Explosion.Mode.BREAK);
  150. }
  151. }
  152. private final static Field INTEGER_VALUE = getField(GameRules.IntegerValue.class, "field_223566_a"); // value
  153. public static void setIntegerValue(GameRules.IntegerValue rule, int value) {
  154. setInt(rule, INTEGER_VALUE, value);
  155. }
  156. // -----------------------------------------------------------------------------------
  157. // game type setter without update for dirty hack
  158. // -----------------------------------------------------------------------------------
  159. private final static Field GAME_TYPE = getField(PlayerInteractionManager.class, "field_73091_c");
  160. public static void setGameType(PlayerInteractionManager m, GameType type) {
  161. setFieldValue(m, GAME_TYPE, type);
  162. }
  163. // -----------------------------------------------------------------------------------
  164. // for clearing ai
  165. // -----------------------------------------------------------------------------------
  166. private final static Field GOALS = getField(GoalSelector.class, "field_220892_d");
  167. public static Set<PrioritizedGoal> getGoals(GoalSelector gs) {
  168. return getFieldValue(Set.class, gs, GOALS);
  169. }
  170. private final static Method SET_FIRE_INFO = getMethod(FireBlock.class, "func_180686_a", Block.class, int.class, int.class);
  171. public static void setFireInfo(Block b, int encouragement, int flammability) {
  172. FireBlock fireblock = (FireBlock) Blocks.FIRE;
  173. try {
  174. SET_FIRE_INFO.invoke(fireblock, b, encouragement, flammability);
  175. } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
  176. LogManager.getLogger().warn("setFireInfo - " + ex);
  177. }
  178. }
  179. private final static Field SIGN_TEXT = getField(SignTileEntity.class, "field_145915_a");
  180. public static ITextComponent getSignText(SignTileEntity ent, int index) {
  181. return getFieldValue(ITextComponent[].class, ent, SIGN_TEXT)[index];
  182. }
  183. private final static Field WORLD_INFO = getField(World.class, "field_72986_A"); // worldInfo
  184. private final static Field SERVER_WORLD_INFO = getField(ServerWorld.class, "field_241103_E_"); // worldInfo
  185. public static void setWorldInfo(ServerWorld w, IServerWorldInfo info) {
  186. setFieldValue(w, WORLD_INFO, info);
  187. setFieldValue(w, SERVER_WORLD_INFO, info);
  188. }
  189. }