ReflectionUtils.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. package me.km.utils;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.lang.reflect.Method;
  5. import java.util.Map;
  6. import java.util.Random;
  7. import java.util.UUID;
  8. import net.minecraft.block.Block;
  9. import net.minecraft.block.material.Material;
  10. import net.minecraft.entity.Entity;
  11. import net.minecraft.entity.EntityLivingBase;
  12. import net.minecraft.entity.item.EntityItem;
  13. import net.minecraft.entity.passive.EntityVillager;
  14. import net.minecraft.entity.player.EntityPlayerMP;
  15. import net.minecraft.entity.player.PlayerCapabilities;
  16. import net.minecraft.entity.projectile.EntityArrow;
  17. import net.minecraft.server.management.PlayerList;
  18. import net.minecraft.util.DamageSource;
  19. import net.minecraft.util.FoodStats;
  20. import net.minecraft.world.Explosion;
  21. import net.minecraftforge.fml.relauncher.ReflectionHelper;
  22. public class ReflectionUtils
  23. {
  24. // -----------------------------------------------------------------------------------
  25. // helper stuff
  26. // -----------------------------------------------------------------------------------
  27. private static Method getMethod(Class c, String name, String obfusName, Class... pars)
  28. {
  29. try
  30. {
  31. return ReflectionHelper.findMethod(c, name, obfusName, pars);
  32. }
  33. catch(SecurityException | ReflectionHelper.UnableToFindMethodException ex)
  34. {
  35. System.out.println(name + ", " + obfusName + " - " + ex);
  36. }
  37. return null;
  38. }
  39. public static Field getField(Class c, String... field)
  40. {
  41. try
  42. {
  43. return ReflectionHelper.findField(c, field);
  44. }
  45. catch(SecurityException | ReflectionHelper.UnableToFindFieldException ex)
  46. {
  47. System.out.println(String.join(", ", field) + " - " + ex);
  48. }
  49. return null;
  50. }
  51. private static <T> void setInt(T t, Field f, int i)
  52. {
  53. try
  54. {
  55. f.setInt(t, i);
  56. }
  57. catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
  58. {
  59. System.out.println(f + " - " + ex);
  60. }
  61. }
  62. private static <T> int getInt(T t, Field f, int error)
  63. {
  64. try
  65. {
  66. return f.getInt(t);
  67. }
  68. catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
  69. {
  70. System.out.println(f + " - " + ex);
  71. return error;
  72. }
  73. }
  74. private static <T> void setFloat(T t, Field f, float fl)
  75. {
  76. try
  77. {
  78. f.setFloat(t, fl);
  79. }
  80. catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
  81. {
  82. System.out.println(f + " - " + ex);
  83. }
  84. }
  85. private static <T> float getFloat(T t, Field f, float error)
  86. {
  87. try
  88. {
  89. return f.getFloat(t);
  90. }
  91. catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
  92. {
  93. System.out.println(f + " - " + ex);
  94. return error;
  95. }
  96. }
  97. private static <T> boolean getBoolean(T t, Field f, boolean error)
  98. {
  99. try
  100. {
  101. return f.getBoolean(t);
  102. }
  103. catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
  104. {
  105. System.out.println(f + " - " + ex);
  106. return error;
  107. }
  108. }
  109. private static <T> T getFieldValue(Class<T> cast, Object o, Field f)
  110. {
  111. try
  112. {
  113. return (T) f.get(o);
  114. }
  115. catch(SecurityException | IllegalAccessException | IllegalArgumentException ex)
  116. {
  117. System.out.println(f + " - " + ex);
  118. return null;
  119. }
  120. }
  121. public static void setFieldValue(Object o, Field f, Object value)
  122. {
  123. try
  124. {
  125. f.set(o, value);
  126. }
  127. catch(SecurityException | IllegalAccessException | IllegalArgumentException ex)
  128. {
  129. System.out.println(f + " - " + ex);
  130. }
  131. }
  132. // -----------------------------------------------------------------------------------
  133. // villager stuff
  134. // -----------------------------------------------------------------------------------
  135. private final static Field CARRER_LEVEL = getField(EntityVillager.class, "field_175562_bw", "careerLevel");
  136. public static void setCareerLevel(EntityVillager v, int level)
  137. {
  138. setInt(v, CARRER_LEVEL, level);
  139. }
  140. // -----------------------------------------------------------------------------------
  141. // food stats
  142. // -----------------------------------------------------------------------------------
  143. private final static Field FOOD_EXHAUSTION_LEVEL = getField(FoodStats.class, "field_75126_c", "foodExhaustionLevel");
  144. public static void setExhaustion(FoodStats stats, float f)
  145. {
  146. setFloat(stats, FOOD_EXHAUSTION_LEVEL, f);
  147. }
  148. public static float getExhaustion(FoodStats stats)
  149. {
  150. return getFloat(stats, FOOD_EXHAUSTION_LEVEL, 0);
  151. }
  152. private final static Field FOOD_SATURATION_LEVEL = getField(FoodStats.class, "field_75125_b", "foodSaturationLevel");
  153. public static void setSaturation(FoodStats stats, float f)
  154. {
  155. setFloat(stats, FOOD_SATURATION_LEVEL, f);
  156. }
  157. // -----------------------------------------------------------------------------------
  158. // player stats
  159. // -----------------------------------------------------------------------------------
  160. private final static Field FLY_SPEED = getField(PlayerCapabilities.class, "field_75096_f", "flySpeed");
  161. public static void setFlySpeed(PlayerCapabilities cap, float f)
  162. {
  163. setFloat(cap, FLY_SPEED, f);
  164. }
  165. private final static Field WALK_SPEED = getField(PlayerCapabilities.class, "field_75097_g", "walkSpeed");
  166. public static void setWalkSpeed(PlayerCapabilities cap, float f)
  167. {
  168. setFloat(cap, WALK_SPEED, f);
  169. }
  170. // -----------------------------------------------------------------------------------
  171. // explosion stuff
  172. // -----------------------------------------------------------------------------------
  173. private final static Field IS_FLAMING = getField(Explosion.class, "field_77286_a", "causesFire");
  174. private final static Field IS_SMOKING = getField(Explosion.class, "field_82755_b", "damagesTerrain");
  175. private final static Field EXPLOSION_RNG = getField(Explosion.class, "field_77290_i", "random");
  176. private final static Field EXPLOSION_SIZE = getField(Explosion.class, "field_77280_f", "size");
  177. private final static Field EXPLODER = getField(Explosion.class, "field_77283_e", "exploder");
  178. public static boolean isFlaming(Explosion ex)
  179. {
  180. return getBoolean(ex, IS_FLAMING, false);
  181. }
  182. public static boolean isSmoking(Explosion ex)
  183. {
  184. return getBoolean(ex, IS_SMOKING, false);
  185. }
  186. public static Random getRandom(Explosion ex)
  187. {
  188. return getFieldValue(Random.class, ex, EXPLOSION_RNG);
  189. }
  190. public static float getSize(Explosion ex)
  191. {
  192. return getFloat(ex, EXPLOSION_SIZE, 1); // 1 for preventing zero dividing
  193. }
  194. public static void setSize(Explosion ex, float f)
  195. {
  196. setFloat(ex, EXPLOSION_SIZE, f);
  197. }
  198. public static Entity getExploder(Explosion ex)
  199. {
  200. return getFieldValue(Entity.class, ex, EXPLODER);
  201. }
  202. // -----------------------------------------------------------------------------------
  203. // random field gets
  204. // -----------------------------------------------------------------------------------
  205. private final static Field TIME_IN_GROUND = getField(EntityArrow.class, "field_184552_b", "timeInGround");
  206. public static int getArrowTimeInGround(EntityArrow arrow)
  207. {
  208. return getInt(arrow, TIME_IN_GROUND, 0);
  209. }
  210. private final static Field UUID_TO_PLAYER_MAP = getField(PlayerList.class, "field_177454_f", "uuidToPlayerMap");
  211. public static Map<UUID, EntityPlayerMP> getUuidToPlayerMap(PlayerList list)
  212. {
  213. return getFieldValue(Map.class, list, UUID_TO_PLAYER_MAP);
  214. }
  215. private final static Field ENTITY_ITEM_AGE = getField(EntityItem.class, "field_70292_b", "age");
  216. public static int getAge(EntityItem item)
  217. {
  218. return getInt(item, ENTITY_ITEM_AGE, 0);
  219. }
  220. public static void setAge(EntityItem item, int age)
  221. {
  222. setInt(item, ENTITY_ITEM_AGE, age);
  223. }
  224. private final static Field BLOCK_MATERIAL = getField(Block.class, "field_149764_J", "blockMaterial");
  225. public static Material getBlockMaterial(Block b)
  226. {
  227. return getFieldValue(Material.class, b, BLOCK_MATERIAL);
  228. }
  229. // -----------------------------------------------------------------------------------
  230. // EntityLivingBase stuff
  231. // -----------------------------------------------------------------------------------
  232. private final static Method APPLY_POTION_DAMAGE_CALCULATIONS = getMethod(
  233. EntityLivingBase.class,
  234. "applyPotionDamageCalculations",
  235. "func_70672_c", DamageSource.class, float.class);
  236. public static float applyPotionDamageCalculations(EntityLivingBase liv, DamageSource ds, float damage)
  237. {
  238. try
  239. {
  240. return (float) APPLY_POTION_DAMAGE_CALCULATIONS.invoke(liv, ds, damage);
  241. }
  242. catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex)
  243. {
  244. return damage;
  245. }
  246. }
  247. private final static Method DAMAGE_ARMOR = getMethod(
  248. EntityLivingBase.class,
  249. "damageArmor",
  250. "func_70675_k", float.class);
  251. public static void damageArmor(EntityLivingBase liv, float damage)
  252. {
  253. try
  254. {
  255. DAMAGE_ARMOR.invoke(liv, damage);
  256. }
  257. catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex)
  258. {
  259. }
  260. }
  261. }