PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/util/MineTweakerHacks.java

https://gitlab.com/MineYourMind/MineTweaker3
Java | 287 lines | 228 code | 44 blank | 15 comment | 9 complexity | 6182d8a964e48ed0abf77822e0ad5f87 MD5 | raw file
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package minetweaker.mc172.util;
  7. import com.google.common.collect.BiMap;
  8. import cpw.mods.fml.common.registry.EntityRegistry;
  9. import java.io.File;
  10. import java.lang.reflect.Constructor;
  11. import java.lang.reflect.Field;
  12. import java.lang.reflect.InvocationTargetException;
  13. import java.util.ArrayList;
  14. import java.util.List;
  15. import java.util.Map;
  16. import java.util.logging.Level;
  17. import java.util.logging.Logger;
  18. import minetweaker.MineTweakerAPI;
  19. import minetweaker.api.item.WeightedItemStack;
  20. import minetweaker.api.minecraft.MineTweakerMC;
  21. import net.minecraft.entity.Entity;
  22. import net.minecraft.entity.player.EntityPlayer;
  23. import net.minecraft.inventory.Container;
  24. import net.minecraft.inventory.InventoryCrafting;
  25. import net.minecraft.inventory.SlotCrafting;import net.minecraft.item.ItemStack;
  26. import net.minecraft.nbt.NBTBase;
  27. import net.minecraft.nbt.NBTTagList;
  28. import net.minecraft.server.MinecraftServer;
  29. import net.minecraft.util.StatCollector;
  30. import net.minecraft.util.StringTranslate;
  31. import net.minecraft.util.WeightedRandom;
  32. import net.minecraftforge.common.ChestGenHooks;
  33. import net.minecraftforge.common.ForgeHooks;
  34. import net.minecraftforge.oredict.OreDictionary;
  35. import net.minecraftforge.oredict.ShapedOreRecipe;
  36. /**
  37. * Common class for all runtime hacks (stuff requiring reflection). It is not
  38. * unexpected to have it break with new minecraft versions and may need regular
  39. * adjustment - as such, those have been collected here.
  40. *
  41. * @author Stan Hebben
  42. */
  43. public class MineTweakerHacks {
  44. private static final Field NBTTAGLIST_TAGLIST;
  45. private static final Field OREDICTIONARY_IDTOSTACK;
  46. private static final Field OREDICTIONARY_IDTOSTACKUN;
  47. private static final Field MINECRAFTSERVER_ANVILFILE;
  48. private static final Field SHAPEDORERECIPE_WIDTH;
  49. private static final Field INVENTORYCRAFTING_EVENTHANDLER;
  50. private static final Field SLOTCRAFTING_PLAYER;
  51. private static final Field ENTITYREGISTRY_CLASSREGISTRATIONS;
  52. private static final Field SEEDENTRY_SEED;
  53. private static final Constructor<? extends WeightedRandom.Item> SEEDENTRY_CONSTRUCTOR;
  54. static {
  55. NBTTAGLIST_TAGLIST = getField(NBTTagList.class, MineTweakerObfuscation.NBTTAGLIST_TAGLIST);
  56. OREDICTIONARY_IDTOSTACK = getField(OreDictionary.class, MineTweakerObfuscation.OREDICTIONARY_IDTOSTACK);
  57. OREDICTIONARY_IDTOSTACKUN = getField(OreDictionary.class, MineTweakerObfuscation.OREDICTIONARY_IDTOSTACKUN);
  58. MINECRAFTSERVER_ANVILFILE = getField(MinecraftServer.class, MineTweakerObfuscation.MINECRAFTSERVER_ANVILFILE);
  59. SHAPEDORERECIPE_WIDTH = getField(ShapedOreRecipe.class, new String[] {"width"});
  60. INVENTORYCRAFTING_EVENTHANDLER = getField(InventoryCrafting.class, MineTweakerObfuscation.INVENTORYCRAFTING_EVENTHANDLER);
  61. SLOTCRAFTING_PLAYER = getField(SlotCrafting.class, MineTweakerObfuscation.SLOTCRAFTING_PLAYER);
  62. ENTITYREGISTRY_CLASSREGISTRATIONS = getField(EntityRegistry.class, new String[] {"entityClassRegistrations"});
  63. Class<? extends WeightedRandom.Item> forgeSeedEntry = null;
  64. try {
  65. forgeSeedEntry = (Class<? extends WeightedRandom.Item>) Class.forName("net.minecraftforge.common.ForgeHooks$SeedEntry");
  66. } catch (ClassNotFoundException ex) {}
  67. SEEDENTRY_SEED = getField(forgeSeedEntry, "seed");
  68. Constructor<? extends WeightedRandom.Item> seedEntryConstructor = null;
  69. try {
  70. seedEntryConstructor = forgeSeedEntry.getConstructor(ItemStack.class, int.class);
  71. seedEntryConstructor.setAccessible(true);
  72. } catch (NoSuchMethodException ex) {
  73. Logger.getLogger(MineTweakerHacks.class.getName()).log(Level.SEVERE, null, ex);
  74. } catch (SecurityException ex) {
  75. Logger.getLogger(MineTweakerHacks.class.getName()).log(Level.SEVERE, null, ex);
  76. }
  77. SEEDENTRY_CONSTRUCTOR = seedEntryConstructor;
  78. }
  79. private MineTweakerHacks() {}
  80. public static BiMap<Class<? extends Entity>, EntityRegistry.EntityRegistration> getEntityClassRegistrations() {
  81. try {
  82. return (BiMap<Class<? extends Entity>, EntityRegistry.EntityRegistration>) ENTITYREGISTRY_CLASSREGISTRATIONS.get(EntityRegistry.instance());
  83. } catch (IllegalArgumentException ex) {
  84. return null;
  85. } catch (IllegalAccessException ex) {
  86. return null;
  87. }
  88. }
  89. public static List<NBTBase> getTagList(NBTTagList list) {
  90. if (NBTTAGLIST_TAGLIST == null) {
  91. return null;
  92. }
  93. try {
  94. return (List) NBTTAGLIST_TAGLIST.get(list);
  95. } catch (IllegalArgumentException ex) {
  96. return null;
  97. } catch (IllegalAccessException ex) {
  98. return null;
  99. }
  100. }
  101. public static List getSeeds() {
  102. return getPrivateStaticObject(ForgeHooks.class, "seedList");
  103. }
  104. public static Map<String, ChestGenHooks> getChestLoot() {
  105. return getPrivateStaticObject(ChestGenHooks.class, "chestInfo");
  106. }
  107. public static Map getTranslations() {
  108. return getPrivateObject(
  109. getPrivateStaticObject(StatCollector.class, "localizedName", "field_74839_a"),
  110. "languageList",
  111. "field_74816_c");
  112. }
  113. public static List<ArrayList<ItemStack>> getOreIdStacks() {
  114. try {
  115. return (List<ArrayList<ItemStack>>) OREDICTIONARY_IDTOSTACK.get(null);
  116. } catch (IllegalAccessException ex) {
  117. MineTweakerAPI.logError("ERROR - could not load ore dictionary stacks!");
  118. return null;
  119. }
  120. }
  121. public static List<ArrayList<ItemStack>> getOreIdStacksUn() {
  122. try {
  123. return (List<ArrayList<ItemStack>>) OREDICTIONARY_IDTOSTACKUN.get(null);
  124. } catch (IllegalAccessException ex) {
  125. MineTweakerAPI.logError("ERROR - could not load ore dictionary stacks!");
  126. return null;
  127. }
  128. }
  129. public static File getAnvilFile(MinecraftServer server) {
  130. try {
  131. return (File) MINECRAFTSERVER_ANVILFILE.get(server);
  132. } catch (IllegalAccessException ex) {
  133. MineTweakerAPI.logError("could not load anvil file!");
  134. return null;
  135. }
  136. }
  137. public static File getWorldDirectory(MinecraftServer server) {
  138. if (server.isDedicatedServer()) {
  139. return server.getFile("world");
  140. } else {
  141. File worldsDir = getAnvilFile(server);
  142. if (worldsDir == null) return null;
  143. return new File(worldsDir, server.getFolderName());
  144. }
  145. }
  146. public static int getShapedOreRecipeWidth(ShapedOreRecipe recipe) {
  147. try {
  148. return SHAPEDORERECIPE_WIDTH.getInt(recipe);
  149. } catch (IllegalAccessException ex) {
  150. MineTweakerAPI.logError("could not load anvil file!");
  151. return 3;
  152. }
  153. }
  154. public static Container getCraftingContainer(InventoryCrafting inventory) {
  155. try {
  156. return (Container) INVENTORYCRAFTING_EVENTHANDLER.get(inventory);
  157. } catch (IllegalAccessException ex) {
  158. MineTweakerAPI.logError("could not get inventory eventhandler");
  159. return null;
  160. }
  161. }
  162. public static EntityPlayer getCraftingSlotPlayer(SlotCrafting slot) {
  163. try {
  164. return (EntityPlayer) SLOTCRAFTING_PLAYER.get(slot);
  165. } catch (IllegalAccessException ex) {
  166. MineTweakerAPI.logError("could not get inventory eventhandler");
  167. return null;
  168. }
  169. }
  170. public static StringTranslate getStringTranslateInstance() {
  171. try {
  172. Field field = getField(StringTranslate.class, MineTweakerObfuscation.STRINGTRANSLATE_INSTANCE);
  173. return (StringTranslate) field.get(null);
  174. } catch (IllegalAccessException ex) {
  175. MineTweakerAPI.logError("could not get string translator");
  176. return null;
  177. }
  178. }
  179. public static ItemStack getSeedEntrySeed(Object entry) {
  180. try {
  181. return (ItemStack) SEEDENTRY_SEED.get(entry);
  182. } catch (IllegalAccessException ex) {
  183. MineTweakerAPI.logError("could not get SeedEntry seed");
  184. return null;
  185. }
  186. }
  187. public static WeightedRandom.Item constructSeedEntry(WeightedItemStack stack) {
  188. try {
  189. return SEEDENTRY_CONSTRUCTOR.newInstance(MineTweakerMC.getItemStack(stack.getStack()), (int) stack.getChance());
  190. } catch (InstantiationException ex) {
  191. MineTweakerAPI.logError("could not construct SeedEntry");
  192. } catch (IllegalAccessException ex) {
  193. MineTweakerAPI.logError("could not construct SeedEntry");
  194. } catch (IllegalArgumentException ex) {
  195. MineTweakerAPI.logError("could not construct SeedEntry");
  196. } catch (InvocationTargetException ex) {
  197. MineTweakerAPI.logError("could not construct SeedEntry");
  198. }
  199. return null;
  200. }
  201. public static <T> T getPrivateStaticObject(Class<?> cls, String... names) {
  202. for (String name : names) {
  203. try {
  204. Field field = cls.getDeclaredField(name);
  205. field.setAccessible(true);
  206. return (T) field.get(null);
  207. } catch (NoSuchFieldException ex) {
  208. } catch (SecurityException ex) {
  209. } catch (IllegalAccessException ex) {
  210. }
  211. }
  212. return null;
  213. }
  214. public static <T> T getPrivateObject(Object object, String... names) {
  215. Class<?> cls = object.getClass();
  216. for (String name : names) {
  217. try {
  218. Field field = cls.getDeclaredField(name);
  219. field.setAccessible(true);
  220. return (T) field.get(object);
  221. } catch (NoSuchFieldException ex) {
  222. } catch (SecurityException ex) {
  223. } catch (IllegalAccessException ex) {
  224. }
  225. }
  226. return null;
  227. }
  228. // #######################
  229. // ### Private Methods ###
  230. // #######################
  231. private static Field getField(Class cls, String... names) {
  232. for (String name : names) {
  233. try {
  234. Field field = cls.getDeclaredField(name);
  235. field.setAccessible(true);
  236. return field;
  237. } catch (NoSuchFieldException ex) {
  238. } catch (SecurityException ex) {
  239. }
  240. }
  241. return null;
  242. }
  243. }