2323import net .minecraft .inventory .InventoryCrafting ;
2424import net .minecraft .world .World ;
2525
26+ import java .lang .invoke .MethodHandle ;
27+ import java .lang .invoke .MethodHandles ;
28+ import java .lang .reflect .Constructor ;
2629import java .lang .reflect .Field ;
2730import java .lang .reflect .Method ;
2831import java .util .Arrays ;
2932import java .util .Map ;
3033
3134public class Ae2Reflect {
3235
33- private static final Method mItemSlot_setExtractable ;
34- private static final Method mCPU_getGrid ;
35- private static final Method mCPU_postChange ;
36- private static final Method mCPU_markDirty ;
37- private static final Method mContain_getPart ;
38- private static final Field fDisassembleRecipe_nonCellMappings ;
39- private static final Field fInventory_container ;
40- private static final Field fCPU_inventory ;
41- private static final Field fCPU_machineSrc ;
42- private static final Field fCPU_isComplete ;
43- private static final Field fDualInterface_fluidPacket ;
44- private static final Field fDualInterface_allowSplitting ;
45- private static final Field fDualInterface_blockModeEx ;
46- private static final Field fDualInterface_gridProxy ;
47- private static final Field fDualityFluidInterface_gridProxy ;
48- private static final Field fAppEngInternalInventory_filter ;
49- private static final Field fContainerOpenContext_w ;
50- private static final Field fContainerOpenContext_x ;
51- private static final Field fContainerOpenContext_y ;
52- private static final Field fContainerOpenContext_z ;
53- private static final Field fCraftingCPURecord_cpu ;
54- private static final Field fDualityGasInterface_gridProxy ;
36+ private static final MethodHandle mItemSlot_setExtractable ;
37+ private static final MethodHandle mCPU_getGrid ;
38+ private static final MethodHandle mCPU_postChange ;
39+ private static final MethodHandle mCPU_markDirty ;
40+ private static final MethodHandle mContain_getPart ;
41+ private static final MethodHandle fGetDisassembleRecipe_nonCellMappings ;
42+ private static final MethodHandle fGetInventory_container ;
43+ private static final MethodHandle fGetCPU_inventory ;
44+ private static final MethodHandle fSetCPU_inventory ;
45+ private static final MethodHandle fGetCPU_machineSrc ;
46+ private static final MethodHandle fGetCPU_isComplete ;
47+ private static final MethodHandle fGetDualInterface_fluidPacket ;
48+ private static final MethodHandle fSetDualInterface_fluidPacket ;
49+ private static final MethodHandle fGetDualInterface_allowSplitting ;
50+ private static final MethodHandle fSetDualInterface_allowSplitting ;
51+ private static final MethodHandle fGetDualInterface_blockModeEx ;
52+ private static final MethodHandle fSetDualInterface_blockModeEx ;
53+ private static final MethodHandle fGetDualInterface_gridProxy ;
54+ private static final MethodHandle fGetDualityFluidInterface_gridProxy ;
55+ private static final MethodHandle fGetAppEngInternalInventory_filter ;
56+ private static final MethodHandle fGetContainerOpenContext_w ;
57+ private static final MethodHandle fGetContainerOpenContext_x ;
58+ private static final MethodHandle fGetContainerOpenContext_y ;
59+ private static final MethodHandle fGetContainerOpenContext_z ;
60+ private static final MethodHandle fGetCraftingCPURecord_cpu ;
61+ private static final MethodHandle fGetDualityGasInterface_gridProxy ;
5562
5663 static {
5764 try {
58- mItemSlot_setExtractable = reflectMethod (ItemSlot .class , "setExtractable" , boolean .class );
59- mCPU_getGrid = reflectMethod (CraftingCPUCluster .class , "getGrid" );
60- mCPU_postChange = reflectMethod (CraftingCPUCluster .class , "postChange" , IAEItemStack .class , IActionSource .class );
61- mCPU_markDirty = reflectMethod (CraftingCPUCluster .class , "markDirty" );
62- mContain_getPart = reflectMethod (ContainerPatternEncoder .class , new String []{"getPatternTerminal" , "getPart" });
63- fInventory_container = reflectField (InventoryCrafting .class , "eventHandler" , "field_70465_c" , "c" );
64- fDisassembleRecipe_nonCellMappings = reflectField (DisassembleRecipe .class , "nonCellMappings" );
65- fCPU_inventory = reflectField (CraftingCPUCluster .class , "inventory" );
66- fCPU_machineSrc = reflectField (CraftingCPUCluster .class , "machineSrc" );
67- fCPU_isComplete = reflectField (CraftingCPUCluster .class , "isComplete" );
68- fDualInterface_fluidPacket = reflectField (DualityInterface .class , "fluidPacket" );
69- fDualInterface_allowSplitting = reflectField (DualityInterface .class , "allowSplitting" );
70- fDualInterface_blockModeEx = reflectField (DualityInterface .class , "blockModeEx" );
71- fDualInterface_gridProxy = reflectField (DualityInterface .class , "gridProxy" );
72- fDualityFluidInterface_gridProxy = reflectField (DualityFluidInterface .class , "gridProxy" );
73- fAppEngInternalInventory_filter = reflectField (AppEngInternalInventory .class , "filter" );
74- fContainerOpenContext_w = reflectField (ContainerOpenContext .class , "w" );
75- fContainerOpenContext_x = reflectField (ContainerOpenContext .class , "x" );
76- fContainerOpenContext_y = reflectField (ContainerOpenContext .class , "y" );
77- fContainerOpenContext_z = reflectField (ContainerOpenContext .class , "z" );
78- fCraftingCPURecord_cpu = reflectField (CraftingCPURecord .class , "cpu" );
65+ mItemSlot_setExtractable = reflectMethodHandle (ItemSlot .class , "setExtractable" , boolean .class );
66+ mCPU_getGrid = reflectMethodHandle (CraftingCPUCluster .class , "getGrid" );
67+ mCPU_postChange = reflectMethodHandle (CraftingCPUCluster .class , "postChange" , IAEItemStack .class , IActionSource .class );
68+ mCPU_markDirty = reflectMethodHandle (CraftingCPUCluster .class , "markDirty" );
69+ mContain_getPart = reflectMethodHandle (ContainerPatternEncoder .class , new String []{"getPatternTerminal" , "getPart" });
70+ fGetInventory_container = reflectFieldGetter (InventoryCrafting .class , "eventHandler" , "field_70465_c" , "c" );
71+ fGetDisassembleRecipe_nonCellMappings = reflectFieldGetter (DisassembleRecipe .class , "nonCellMappings" );
72+ fGetCPU_inventory = reflectFieldGetter (CraftingCPUCluster .class , "inventory" );
73+ fSetCPU_inventory = reflectFieldSetter (CraftingCPUCluster .class , "inventory" );
74+ fGetCPU_machineSrc = reflectFieldGetter (CraftingCPUCluster .class , "machineSrc" );
75+ fGetCPU_isComplete = reflectFieldGetter (CraftingCPUCluster .class , "isComplete" );
76+ fGetDualInterface_fluidPacket = reflectFieldGetter (DualityInterface .class , "fluidPacket" );
77+ fSetDualInterface_fluidPacket = reflectFieldSetter (DualityInterface .class , "fluidPacket" );
78+ fGetDualInterface_allowSplitting = reflectFieldGetter (DualityInterface .class , "allowSplitting" );
79+ fSetDualInterface_allowSplitting = reflectFieldSetter (DualityInterface .class , "allowSplitting" );
80+ fGetDualInterface_blockModeEx = reflectFieldGetter (DualityInterface .class , "blockModeEx" );
81+ fSetDualInterface_blockModeEx = reflectFieldSetter (DualityInterface .class , "blockModeEx" );
82+ fGetDualInterface_gridProxy = reflectFieldGetter (DualityInterface .class , "gridProxy" );
83+ fGetDualityFluidInterface_gridProxy = reflectFieldGetter (DualityFluidInterface .class , "gridProxy" );
84+ fGetAppEngInternalInventory_filter = reflectFieldGetter (AppEngInternalInventory .class , "filter" );
85+ fGetContainerOpenContext_w = reflectFieldGetter (ContainerOpenContext .class , "w" );
86+ fGetContainerOpenContext_x = reflectFieldGetter (ContainerOpenContext .class , "x" );
87+ fGetContainerOpenContext_y = reflectFieldGetter (ContainerOpenContext .class , "y" );
88+ fGetContainerOpenContext_z = reflectFieldGetter (ContainerOpenContext .class , "z" );
89+ fGetCraftingCPURecord_cpu = reflectFieldGetter (CraftingCPURecord .class , "cpu" );
7990 if (ModAndClassUtil .GAS ) {
80- fDualityGasInterface_gridProxy = reflectField (DualityGasInterface .class , "gridProxy" );
91+ fGetDualityGasInterface_gridProxy = reflectFieldGetter (DualityGasInterface .class , "gridProxy" );
8192 } else {
82- fDualityGasInterface_gridProxy = null ;
93+ fGetDualityGasInterface_gridProxy = null ;
8394 }
8495 } catch (Exception e ) {
8596 throw new IllegalStateException ("Failed to initialize AE2 reflection hacks!" , e );
8697 }
8798 }
8899
100+ public static MethodHandle reflectConstructor (Class <?> owner , Class <?>... paramTypes ) throws NoSuchMethodException , IllegalAccessException {
101+ Constructor <?> constructor = owner .getDeclaredConstructor (paramTypes );
102+ constructor .setAccessible (true );
103+ return MethodHandles .lookup ().unreflectConstructor (constructor );
104+ }
105+
106+ public static MethodHandle reflectMethodHandle (Class <?> owner , String name , Class <?>... paramTypes ) throws NoSuchMethodException , IllegalAccessException {
107+ return reflectMethodHandle (owner , new String []{name }, paramTypes );
108+ }
109+
110+ public static MethodHandle reflectMethodHandle (Class <?> owner , String [] names , Class <?>... paramTypes ) throws NoSuchMethodException , IllegalAccessException {
111+ return MethodHandles .lookup ().unreflect (reflectMethod (owner , names , paramTypes ));
112+ }
113+
89114 public static Method reflectMethod (Class <?> owner , String name , Class <?>... paramTypes ) throws NoSuchMethodException {
90115 return reflectMethod (owner , new String []{name }, paramTypes );
91116 }
@@ -106,6 +131,14 @@ public static Method reflectMethod(Class<?> owner, String[] names, Class<?>... p
106131 return m ;
107132 }
108133
134+ public static MethodHandle reflectFieldGetter (Class <?> owner , String ...names ) throws IllegalAccessException , NoSuchFieldException {
135+ return MethodHandles .lookup ().unreflectGetter (reflectField (owner , names ));
136+ }
137+
138+ public static MethodHandle reflectFieldSetter (Class <?> owner , String ...names ) throws IllegalAccessException , NoSuchFieldException {
139+ return MethodHandles .lookup ().unreflectSetter (reflectField (owner , names ));
140+ }
141+
109142 @ SuppressWarnings ("all" )
110143 public static Field reflectField (Class <?> owner , String ...names ) throws NoSuchFieldException {
111144 Field f = null ;
@@ -131,6 +164,18 @@ public static <T> T readField(Object owner, Field field) {
131164 }
132165 }
133166
167+ public static <T > T readField (Object owner , MethodHandle field ) {
168+ try {
169+ if (owner == null ) {
170+ return (T )field .invoke ();
171+ } else {
172+ return (T )field .invoke (owner );
173+ }
174+ } catch (Throwable e ) {
175+ throw new IllegalStateException ("Failed to read field: " + field );
176+ }
177+ }
178+
134179 public static void writeField (Object owner , Field field , Object value ) {
135180 try {
136181 field .set (owner , value );
@@ -139,128 +184,140 @@ public static void writeField(Object owner, Field field, Object value) {
139184 }
140185 }
141186
187+ public static void writeField (Object owner , MethodHandle field , Object value ) {
188+ try {
189+ if (owner == null ) {
190+ field .invoke (value );
191+ } else {
192+ field .invoke (owner , value );
193+ }
194+ } catch (Throwable e ) {
195+ throw new IllegalStateException ("Failed to write field: " + field );
196+ }
197+ }
198+
142199 public static Container getCraftContainer (InventoryCrafting inv ) {
143- return Ae2Reflect .readField (inv , fInventory_container );
200+ return Ae2Reflect .readField (inv , fGetInventory_container );
144201 }
145202
146203 public static void setItemSlotExtractable (ItemSlot slot , boolean extractable ) {
147204 try {
148205 mItemSlot_setExtractable .invoke (slot , extractable );
149- } catch (Exception e ) {
206+ } catch (Throwable e ) {
150207 throw new IllegalStateException ("Failed to invoke method: " + mItemSlot_setExtractable , e );
151208 }
152209 }
153210
154211 public static Map <IItemDefinition , IItemDefinition > getDisassemblyNonCellMap (DisassembleRecipe recipe ) {
155- return readField (recipe , fDisassembleRecipe_nonCellMappings );
212+ return readField (recipe , fGetDisassembleRecipe_nonCellMappings );
156213 }
157214
158215 public static IGrid getGrid (CraftingCPUCluster cpu ) {
159216 try {
160217 return (IGrid ) mCPU_getGrid .invoke (cpu );
161- } catch (Exception e ) {
218+ } catch (Throwable e ) {
162219 throw new IllegalStateException ("Failed to invoke method: " + mCPU_getGrid , e );
163220 }
164221 }
165222
166223 public static MECraftingInventory getCPUInventory (CraftingCPUCluster cpu ) {
167- return Ae2Reflect .readField (cpu , fCPU_inventory );
224+ return Ae2Reflect .readField (cpu , fGetCPU_inventory );
168225 }
169226
170227 public static void setCPUInventory (CraftingCPUCluster cpu , MECraftingInventory value ) {
171- Ae2Reflect .writeField (cpu , fCPU_inventory , value );
228+ Ae2Reflect .writeField (cpu , fSetCPU_inventory , value );
172229 }
173230
174231 public static IActionSource getCPUSource (CraftingCPUCluster cpu ) {
175- return Ae2Reflect .readField (cpu , fCPU_machineSrc );
232+ return Ae2Reflect .readField (cpu , fGetCPU_machineSrc );
176233 }
177234
178235 public static boolean getCPUComplete (CraftingCPUCluster cpu ) {
179- return Ae2Reflect .readField (cpu , fCPU_isComplete );
236+ return Ae2Reflect .readField (cpu , fGetCPU_isComplete );
180237 }
181238
182239 public static AbstractPartEncoder getPart (ContainerPatternEncoder owner ) {
183240 try {
184241 return (AbstractPartEncoder ) mContain_getPart .invoke (owner );
185- } catch (Exception e ) {
242+ } catch (Throwable e ) {
186243 throw new IllegalStateException ("Failed to invoke method: " + mContain_getPart , e );
187244 }
188245 }
189246
190247 public static void postCPUChange (CraftingCPUCluster cpu , IAEItemStack stack , IActionSource src ) {
191248 try {
192249 mCPU_postChange .invoke (cpu , stack , src );
193- } catch (Exception e ) {
250+ } catch (Throwable e ) {
194251 throw new IllegalStateException ("Failed to invoke method: " + mCPU_postChange , e );
195252 }
196253 }
197254
198255 public static void markCPUDirty (CraftingCPUCluster cpu ) {
199256 try {
200257 mCPU_markDirty .invoke (cpu );
201- } catch (Exception e ) {
258+ } catch (Throwable e ) {
202259 throw new IllegalStateException ("Failed to invoke method: " + mCPU_markDirty , e );
203260 }
204261 }
205262
206263 public static boolean getFluidPacketMode (DualityInterface owner ) {
207- return readField (owner , fDualInterface_fluidPacket );
264+ return readField (owner , fGetDualInterface_fluidPacket );
208265 }
209266
210267 public static void setFluidPacketMode (DualityInterface owner , boolean value ) {
211- writeField (owner , fDualInterface_fluidPacket , value );
268+ writeField (owner , fSetDualInterface_fluidPacket , value );
212269 }
213270
214271 public static boolean getSplittingMode (DualityInterface owner ) {
215- return readField (owner , fDualInterface_allowSplitting );
272+ return readField (owner , fGetDualInterface_allowSplitting );
216273 }
217274
218275 public static void setSplittingMode (DualityInterface owner , boolean value ) {
219- writeField (owner , fDualInterface_allowSplitting , value );
276+ writeField (owner , fSetDualInterface_allowSplitting , value );
220277 }
221278
222279 public static int getExtendedBlockMode (DualityInterface owner ) {
223- return readField (owner , fDualInterface_blockModeEx );
280+ return readField (owner , fGetDualInterface_blockModeEx );
224281 }
225282
226283 public static void setExtendedBlockMode (DualityInterface owner , int value ) {
227- writeField (owner , fDualInterface_blockModeEx , value );
284+ writeField (owner , fSetDualInterface_blockModeEx , value );
228285 }
229286
230287 public static AENetworkProxy getInterfaceProxy (DualityInterface owner ) {
231- return readField (owner , fDualInterface_gridProxy );
288+ return readField (owner , fGetDualInterface_gridProxy );
232289 }
233290
234291 public static AENetworkProxy getInterfaceProxy (DualityFluidInterface owner ) {
235- return readField (owner , fDualityFluidInterface_gridProxy );
292+ return readField (owner , fGetDualityFluidInterface_gridProxy );
236293 }
237294
238295 public static IAEItemFilter getInventoryFilter (AppEngInternalInventory owner ) {
239- return readField (owner , fAppEngInternalInventory_filter );
296+ return readField (owner , fGetAppEngInternalInventory_filter );
240297 }
241298
242299 public static World getContextWorld (ContainerOpenContext owner ) {
243- return readField (owner , fContainerOpenContext_w );
300+ return readField (owner , fGetContainerOpenContext_w );
244301 }
245302
246303 public static int getContextX (ContainerOpenContext owner ) {
247- return readField (owner , fContainerOpenContext_x );
304+ return readField (owner , fGetContainerOpenContext_x );
248305 }
249306
250307 public static int getContextY (ContainerOpenContext owner ) {
251- return readField (owner , fContainerOpenContext_y );
308+ return readField (owner , fGetContainerOpenContext_y );
252309 }
253310
254311 public static int getContextZ (ContainerOpenContext owner ) {
255- return readField (owner , fContainerOpenContext_z );
312+ return readField (owner , fGetContainerOpenContext_z );
256313 }
257314
258315 public static ICraftingCPU getCraftingCPU (CraftingCPURecord owner ) {
259- return readField (owner , fCraftingCPURecord_cpu );
316+ return readField (owner , fGetCraftingCPURecord_cpu );
260317 }
261318
262319 public static AENetworkProxy getGasInterfaceGrid (Object owner ) {
263- return readField (owner , fDualityGasInterface_gridProxy );
320+ return readField (owner , fGetDualityGasInterface_gridProxy );
264321 }
265322
266323}
0 commit comments