PageRenderTime 87ms CodeModel.GetById 19ms RepoModel.GetById 3ms app.codeStats 0ms

/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/util/MineTweakerHacks.java

https://gitlab.com/MineYourMind/MineTweaker3
Java | 306 lines | 244 code | 47 blank | 15 comment | 7 complexity | 8fd07d9fc1ff22291b3bdd58376dd065 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.mc164.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.List;
  14. import java.util.Map;
  15. import java.util.Set;
  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.NBTTagCompound;
  28. import net.minecraft.server.MinecraftServer;
  29. import net.minecraft.util.StatCollector;
  30. import net.minecraft.util.StringTranslate;
  31. import net.minecraft.util.WeightedRandomItem;
  32. import net.minecraftforge.common.ChestGenHooks;
  33. import net.minecraftforge.common.ForgeHooks;
  34. import net.minecraftforge.fluids.FluidContainerRegistry;
  35. import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData;
  36. import net.minecraftforge.oredict.OreDictionary;
  37. import net.minecraftforge.oredict.ShapedOreRecipe;
  38. /**
  39. * Common class for all runtime hacks (stuff requiring reflection). It is not
  40. * unexpected to have it break with new minecraft versions and may need regular
  41. * adjustment - as such, those have been collected here.
  42. *
  43. * @author Stan Hebben
  44. */
  45. public class MineTweakerHacks {
  46. private static final Field NBTTAGCOMPOUND_TAGMAP;
  47. private static final Field OREDICTIONARY_ORESTACKS;
  48. private static final Field MINECRAFTSERVER_ANVILFILE;
  49. private static final Field SHAPEDORERECIPE_WIDTH;
  50. private static final Field INVENTORYCRAFTING_EVENTHANDLER;
  51. private static final Field SLOTCRAFTING_PLAYER;
  52. private static final Field ENTITYREGISTRY_CLASSREGISTRATIONS;
  53. private static final Field SEEDENTRY_SEED;
  54. private static final Constructor<? extends WeightedRandomItem> SEEDENTRY_CONSTRUCTOR;
  55. static {
  56. NBTTAGCOMPOUND_TAGMAP = getField(NBTTagCompound.class, MineTweakerObfuscation.NBTTAGCOMPOUND_TAGMAP);
  57. OREDICTIONARY_ORESTACKS = getField(OreDictionary.class, MineTweakerObfuscation.OREDICTIONARY_ORESTACKS);
  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 WeightedRandomItem> forgeSeedEntry = null;
  64. try {
  65. forgeSeedEntry = (Class<? extends WeightedRandomItem>) Class.forName("net.minecraftforge.common.ForgeHooks$SeedEntry");
  66. } catch (ClassNotFoundException ex) {}
  67. SEEDENTRY_SEED = getField(forgeSeedEntry, "seed");
  68. Constructor<? extends WeightedRandomItem> 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 Map<String, NBTBase> getNBTCompoundMap(NBTTagCompound tag) {
  90. try {
  91. return (Map<String, NBTBase>) NBTTAGCOMPOUND_TAGMAP.get(tag);
  92. } catch (IllegalArgumentException ex) {
  93. return null;
  94. } catch (IllegalAccessException ex) {
  95. return null;
  96. }
  97. }
  98. public static List getSeeds() {
  99. return getPrivateStaticObject(ForgeHooks.class, "seedList");
  100. }
  101. public static Map<String, ChestGenHooks> getChestLoot() {
  102. return getPrivateStaticObject(ChestGenHooks.class, "chestInfo");
  103. }
  104. public static Map getTranslations() {
  105. return getPrivateObject(
  106. getPrivateStaticObject(StatCollector.class, "localizedName", "field_74839_a"),
  107. "languageList",
  108. "field_74816_c");
  109. }
  110. public static Map<Integer, List<ItemStack>> getOreStacks() {
  111. try {
  112. return (Map<Integer, List<ItemStack>>) OREDICTIONARY_ORESTACKS.get(null);
  113. } catch (IllegalAccessException ex) {
  114. MineTweakerAPI.logError("ERROR - could not load ore dictionary stacks!");
  115. return null;
  116. }
  117. }
  118. public static File getAnvilFile(MinecraftServer server) {
  119. try {
  120. return (File) MINECRAFTSERVER_ANVILFILE.get(server);
  121. } catch (IllegalAccessException ex) {
  122. MineTweakerAPI.logError("could not load anvil file!");
  123. return null;
  124. }
  125. }
  126. public static File getWorldDirectory(MinecraftServer server) {
  127. if (server.isDedicatedServer()) {
  128. return server.getFile("world");
  129. } else {
  130. File worldsDir = getAnvilFile(server);
  131. if (worldsDir == null) return null;
  132. return new File(worldsDir, server.getFolderName());
  133. }
  134. }
  135. public static int getShapedOreRecipeWidth(ShapedOreRecipe recipe) {
  136. try {
  137. return SHAPEDORERECIPE_WIDTH.getInt(recipe);
  138. } catch (IllegalAccessException ex) {
  139. MineTweakerAPI.logError("could not load anvil file!");
  140. return 3;
  141. }
  142. }
  143. public static Container getCraftingContainer(InventoryCrafting inventory) {
  144. try {
  145. return (Container) INVENTORYCRAFTING_EVENTHANDLER.get(inventory);
  146. } catch (IllegalAccessException ex) {
  147. MineTweakerAPI.logError("could not get inventory eventhandler");
  148. return null;
  149. }
  150. }
  151. public static EntityPlayer getCraftingSlotPlayer(SlotCrafting slot) {
  152. try {
  153. return (EntityPlayer) SLOTCRAFTING_PLAYER.get(slot);
  154. } catch (IllegalAccessException ex) {
  155. MineTweakerAPI.logError("could not get inventory eventhandler");
  156. return null;
  157. }
  158. }
  159. public static StringTranslate getStringTranslateInstance() {
  160. try {
  161. Field field = getField(StringTranslate.class, MineTweakerObfuscation.STRINGTRANSLATE_INSTANCE);
  162. return (StringTranslate) field.get(null);
  163. } catch (IllegalAccessException ex) {
  164. MineTweakerAPI.logError("could not get string translator");
  165. return null;
  166. }
  167. }
  168. public static Map<List, FluidContainerData> getFluidContainerMap() {
  169. try {
  170. Field field = getField(FluidContainerRegistry.class, new String[] {"containerFluidMap"});
  171. return (Map<List, FluidContainerData>) field.get(null);
  172. } catch (IllegalAccessException ex) {
  173. MineTweakerAPI.logError("could not get fluid container registry");
  174. return null;
  175. }
  176. }
  177. public static Map<List, FluidContainerData> getFilledContainerMap() {
  178. try {
  179. Field field = getField(FluidContainerRegistry.class, new String[] {"filledContainerMap"});
  180. return (Map<List, FluidContainerData>) field.get(null);
  181. } catch (IllegalAccessException ex) {
  182. MineTweakerAPI.logError("could not get filled container map");
  183. return null;
  184. }
  185. }
  186. public static Set<List> getEmptyContainers() {
  187. try {
  188. Field field = getField(FluidContainerRegistry.class, new String[] {"emptyContainers"});
  189. return (Set<List>) field.get(null);
  190. } catch (IllegalAccessException ex) {
  191. MineTweakerAPI.logError("could not get filled container map");
  192. return null;
  193. }
  194. }
  195. public static ItemStack getSeedEntrySeed(Object entry) {
  196. try {
  197. return (ItemStack) SEEDENTRY_SEED.get(entry);
  198. } catch (IllegalAccessException ex) {
  199. MineTweakerAPI.logError("could not get SeedEntry seed");
  200. return null;
  201. }
  202. }
  203. public static WeightedRandomItem constructSeedEntry(WeightedItemStack stack) {
  204. try {
  205. return SEEDENTRY_CONSTRUCTOR.newInstance(MineTweakerMC.getItemStack(stack.getStack()), (int) stack.getChance());
  206. } catch (InstantiationException ex) {
  207. MineTweakerAPI.logError("could not construct SeedEntry");
  208. } catch (IllegalAccessException ex) {
  209. MineTweakerAPI.logError("could not construct SeedEntry");
  210. } catch (IllegalArgumentException ex) {
  211. MineTweakerAPI.logError("could not construct SeedEntry");
  212. } catch (InvocationTargetException ex) {
  213. MineTweakerAPI.logError("could not construct SeedEntry");
  214. }
  215. return null;
  216. }
  217. public static <T> T getPrivateStaticObject(Class<?> cls, String... names) {
  218. for (String name : names) {
  219. try {
  220. Field field = cls.getDeclaredField(name);
  221. field.setAccessible(true);
  222. return (T) field.get(null);
  223. } catch (NoSuchFieldException ex) {
  224. } catch (SecurityException ex) {
  225. } catch (IllegalAccessException ex) {
  226. }
  227. }
  228. return null;
  229. }
  230. public static <T> T getPrivateObject(Object object, String... names) {
  231. Class<?> cls = object.getClass();
  232. for (String name : names) {
  233. try {
  234. Field field = cls.getDeclaredField(name);
  235. field.setAccessible(true);
  236. return (T) field.get(object);
  237. } catch (NoSuchFieldException ex) {
  238. } catch (SecurityException ex) {
  239. } catch (IllegalAccessException ex) {
  240. }
  241. }
  242. return null;
  243. }
  244. // #######################
  245. // ### Private Methods ###
  246. // #######################
  247. private static Field getField(Class cls, String... names) {
  248. for (String name : names) {
  249. try {
  250. Field field = cls.getDeclaredField(name);
  251. field.setAccessible(true);
  252. return field;
  253. } catch (NoSuchFieldException ex) {
  254. } catch (SecurityException ex) {
  255. }
  256. }
  257. return null;
  258. }
  259. }