Skip to content

Commit 61f0574

Browse files
authored
Merge pull request #173 from KasumiNova/1.12.2
Feat: 使用 MethodHandle 替换原来的 Method, Field, Constructor.
2 parents c00b0f9 + 51be74b commit 61f0574

File tree

2 files changed

+196
-144
lines changed

2 files changed

+196
-144
lines changed

src/main/java/com/glodblock/github/util/Ae2Reflect.java

Lines changed: 128 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,69 +23,94 @@
2323
import net.minecraft.inventory.InventoryCrafting;
2424
import net.minecraft.world.World;
2525

26+
import java.lang.invoke.MethodHandle;
27+
import java.lang.invoke.MethodHandles;
28+
import java.lang.reflect.Constructor;
2629
import java.lang.reflect.Field;
2730
import java.lang.reflect.Method;
2831
import java.util.Arrays;
2932
import java.util.Map;
3033

3134
public 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

Comments
 (0)