ReflectionUtils.java 11 KB

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