KajetansTransformer.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. package me.kcm;
  2. import me.kcm.events.*;
  3. import net.minecraft.launchwrapper.IClassTransformer;
  4. import net.minecraft.launchwrapper.Launch;
  5. import org.objectweb.asm.ClassReader;
  6. import org.objectweb.asm.ClassWriter;
  7. import org.objectweb.asm.Opcodes;
  8. import org.objectweb.asm.tree.AbstractInsnNode;
  9. import org.objectweb.asm.tree.ClassNode;
  10. import org.objectweb.asm.tree.FieldInsnNode;
  11. import org.objectweb.asm.tree.FrameNode;
  12. import org.objectweb.asm.tree.InsnList;
  13. import org.objectweb.asm.tree.InsnNode;
  14. import org.objectweb.asm.tree.JumpInsnNode;
  15. import org.objectweb.asm.tree.LabelNode;
  16. import org.objectweb.asm.tree.LineNumberNode;
  17. import org.objectweb.asm.tree.MethodInsnNode;
  18. import org.objectweb.asm.tree.MethodNode;
  19. import org.objectweb.asm.tree.VarInsnNode;
  20. public class KajetansTransformer implements IClassTransformer
  21. {
  22. private final boolean obfuscated;
  23. public KajetansTransformer()
  24. {
  25. Boolean ldev = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
  26. if(ldev == null)
  27. {
  28. obfuscated = true;
  29. }
  30. else
  31. {
  32. obfuscated = !ldev;
  33. }
  34. //System.out.println(obfuscated);
  35. }
  36. private void printPatch(String s)
  37. {
  38. System.out.println("|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾");
  39. System.out.println("| Patching " + s);
  40. System.out.println("|___________________________________________________");
  41. }
  42. @Override
  43. public byte[] transform(String old, String searge, byte[] bytes)
  44. {
  45. switch(searge)
  46. {
  47. /*case "net.minecraft.entity.EntityLivingBase":
  48. printPatch(LivingDamageCalculationEvent.class.getSimpleName());
  49. return patchDamageHook(old, bytes);*/
  50. case "net.minecraft.entity.player.EntityPlayerMP":
  51. printPatch(PlayerTabListNameEvent.class.getSimpleName());
  52. return patchTabList(old, bytes);
  53. case "net.minecraft.entity.Entity":
  54. printPatch(FarmlandTrampleEvent.class.getSimpleName());
  55. return patchEntityCanTrample(old, bytes);
  56. case "net.minecraft.server.management.PlayerList":
  57. printPatch("PlayerList");
  58. return patchPlayerList(old, bytes);
  59. case "net.minecraft.server.MinecraftServer":
  60. printPatch("MinecraftServer");
  61. return patchMinecraftServer(old, bytes);
  62. case "net.minecraft.network.NetHandlerPlayServer":
  63. printPatch("NetHandlerPlayServer");
  64. return patchNetHandlerPlayServer(old, bytes);
  65. /*case "net.minecraft.item.crafting.CraftingManager":
  66. printPatch("CraftingManager");
  67. return patchCraftingManager(old, bytes);*/
  68. }
  69. return bytes;
  70. }
  71. /*ListIterator<AbstractInsnNode> list = ins.iterator();
  72. while(list.hasNext())
  73. {
  74. AbstractInsnNode next = list.next();
  75. System.out.println(getString(next));
  76. }*/
  77. public byte[] patchDamageHook(String c, byte[] bytes)
  78. {
  79. try
  80. {
  81. ClassNode classNode = new ClassNode();
  82. ClassReader classReader = new ClassReader(bytes);
  83. classReader.accept(classNode, 0);
  84. // EntityLivingBase <--> vp
  85. // damageEntity <--> func_70665_d <--> d
  86. MethodNode mn;
  87. if(obfuscated)
  88. {
  89. mn = classNode.methods.stream().filter(me -> me.name.equals("d")).filter(me -> "(Lur;F)V".equals(me.desc)).findAny().get();
  90. }
  91. else
  92. {
  93. mn = classNode.methods.stream().filter(me -> me.name.equals("damageEntity")).findAny().get();
  94. }
  95. InsnList ins = mn.instructions;
  96. ins.insert(ins.get(3), new VarInsnNode(Opcodes.FLOAD, 2));
  97. if(obfuscated)
  98. {
  99. ins.insert(ins.get(4), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onDamageCalculation", "(Lvp;Lur;F)V", false));
  100. }
  101. else
  102. {
  103. ins.insert(ins.get(4), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  104. "onDamageCalculation", "(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/util/DamageSource;F)V", false));
  105. }
  106. while(ins.size() > 8)
  107. {
  108. ins.remove(ins.get(6));
  109. }
  110. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  111. classNode.accept(writer);
  112. return writer.toByteArray();
  113. }
  114. catch(Exception ex)
  115. {
  116. ex.printStackTrace();
  117. }
  118. return bytes;
  119. }
  120. public byte[] patchTabList(String c, byte[] bytes)
  121. {
  122. try
  123. {
  124. ClassNode classNode = new ClassNode();
  125. ClassReader classReader = new ClassReader(bytes);
  126. classReader.accept(classNode, 0);
  127. // EntityPlayerMP <--> oq
  128. // getTabListDisplayName <--> func_175396_E <--> K
  129. // MD: oq/K ()Lhh; net/minecraft/entity/player/EntityPlayerMP/func_175396_E ()Lnet/minecraft/util/text/ITextComponent;
  130. MethodNode mn;
  131. if(obfuscated)
  132. {
  133. mn = classNode.methods.stream().filter(me -> me.name.equals("K")).filter(me -> "()Lhh;".equals(me.desc)).findAny().get();
  134. }
  135. else
  136. {
  137. mn = classNode.methods.stream().filter(me -> me.name.equals("getTabListDisplayName")).findAny().get();
  138. }
  139. InsnList ins = mn.instructions;
  140. ins.remove(ins.get(2));
  141. ins.insert(ins.get(1), new VarInsnNode(Opcodes.ALOAD, 0));
  142. if(obfuscated)
  143. {
  144. ins.insert(ins.get(2), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onGetTabListDisplayName", "(Loq;)Lhh;", false));
  145. }
  146. else
  147. {
  148. ins.insert(ins.get(2), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  149. "onGetTabListDisplayName", "(Lnet/minecraft/entity/player/EntityPlayerMP;)Lnet/minecraft/util/text/ITextComponent;", false));
  150. }
  151. // patching setEntityActionState
  152. // MD: net/minecraft/entity/player/EntityPlayerMP/setEntityActionState (FFZZ)V oq/a (FFZZ)V
  153. /*if(obfuscated)
  154. {
  155. mn = classNode.methods.stream().filter(me -> me.name.equals("a")).filter(me -> "(FFZZ)V".equals(me.desc)).findAny().get();
  156. }
  157. else
  158. {
  159. mn = classNode.methods.stream().filter(me -> me.name.equals("setEntityActionState")).findAny().get();
  160. }
  161. ins = mn.instructions;
  162. if(obfuscated)
  163. {
  164. ins.insert(ins.get(1), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onSetEntityActionState", "(Loq;FFZZ)V", false));
  165. }
  166. else
  167. {
  168. ins.insert(ins.get(1), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  169. "onSetEntityActionState", "(Lnet/minecraft/entity/player/EntityPlayerMP;FFZZ)V", false));
  170. }
  171. ins.insert(ins.get(1), new VarInsnNode(Opcodes.ILOAD, 4));
  172. ins.insert(ins.get(1), new VarInsnNode(Opcodes.ILOAD, 3));
  173. ins.insert(ins.get(1), new VarInsnNode(Opcodes.FLOAD, 2));
  174. ins.insert(ins.get(1), new VarInsnNode(Opcodes.FLOAD, 1));
  175. ins.insert(ins.get(1), new VarInsnNode(Opcodes.ALOAD, 0));
  176. java.util.ListIterator<AbstractInsnNode> list = ins.iterator();
  177. while(list.hasNext())
  178. {
  179. System.out.println(getString(list.next()));
  180. }*/
  181. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  182. classNode.accept(writer);
  183. return writer.toByteArray();
  184. }
  185. catch(Exception ex)
  186. {
  187. ex.printStackTrace();
  188. }
  189. return bytes;
  190. }
  191. public byte[] patchEntityCanTrample(String c, byte[] bytes)
  192. {
  193. try
  194. {
  195. ClassNode classNode = new ClassNode();
  196. ClassReader classReader = new ClassReader(bytes);
  197. classReader.accept(classNode, 0);
  198. // CL: vg net/minecraft/entity/Entity
  199. // Entity <--> vg
  200. // canTrample is forge function
  201. // Lnet/minecraft/world/World;Lnet/minecraft/block/Block;Lnet/minecraft/util/math/BlockPos;F
  202. // World <--> amu
  203. // Block <--> aow
  204. // BlockPos <--> et
  205. MethodNode mn = classNode.methods.stream().filter(me -> me.name.equals("canTrample")).findAny().get();
  206. InsnList ins = mn.instructions;
  207. int i = ins.size();
  208. LabelNode label = null;
  209. int counter = 0;
  210. while(counter < 3)
  211. {
  212. i--;
  213. if(ins.get(i) instanceof LabelNode)
  214. {
  215. counter++;
  216. label = (LabelNode) ins.get(i);
  217. }
  218. }
  219. while(ins.get(i).getOpcode() != Opcodes.IFLE)
  220. {
  221. i--;
  222. }
  223. ins.insert(ins.get(i), new JumpInsnNode(Opcodes.IFEQ, label));
  224. if(obfuscated)
  225. {
  226. ins.insert(ins.get(i), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  227. "onEntityCanTrample", "(Lvg;Lamu;Laow;Let;F)Z", false));
  228. }
  229. else
  230. {
  231. ins.insert(ins.get(i), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  232. "onEntityCanTrample", "(Lnet/minecraft/entity/Entity;Lnet/minecraft/world/World;"
  233. + "Lnet/minecraft/block/Block;Lnet/minecraft/util/math/BlockPos;F)Z", false));
  234. }
  235. ins.insert(ins.get(i), new VarInsnNode(Opcodes.FLOAD, 4));
  236. ins.insert(ins.get(i), new VarInsnNode(Opcodes.ALOAD, 3));
  237. ins.insert(ins.get(i), new VarInsnNode(Opcodes.ALOAD, 2));
  238. ins.insert(ins.get(i), new VarInsnNode(Opcodes.ALOAD, 1));
  239. ins.insert(ins.get(i), new VarInsnNode(Opcodes.ALOAD, 0));
  240. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  241. classNode.accept(writer);
  242. return writer.toByteArray();
  243. }
  244. catch(Exception ex)
  245. {
  246. ex.printStackTrace();
  247. }
  248. return bytes;
  249. }
  250. public byte[] patchPlayerList(String c, byte[] bytes)
  251. {
  252. try
  253. {
  254. ClassNode classNode = new ClassNode();
  255. ClassReader classReader = new ClassReader(bytes);
  256. classReader.accept(classNode, 0);
  257. int index = 0;
  258. AbstractInsnNode node;
  259. // -----------------------------------------------------------------
  260. // first part - inserting PlayerConnectionEvent hook
  261. // -----------------------------------------------------------------
  262. // EntityPlayerMP <--> oq
  263. // initializeConnectionToPlayer <--> func_72355_a <--> a
  264. //MD: pl/a (Lgw;Loq;)V net/minecraft/server/management/PlayerList/func_72355_a
  265. // (Lnet/minecraft/network/NetworkManager;Lnet/minecraft/entity/player/EntityPlayerMP;)V
  266. // CL: pa net/minecraft/network/NetHandlerPlayServer
  267. // public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver)
  268. // its something else: (Lgw;Loq;Lpa;)V
  269. // it seems forge is already overwriting this method
  270. MethodNode mn = classNode.methods.stream().filter(me -> me.name.equals("initializeConnectionToPlayer")).findAny().get();
  271. InsnList ins = mn.instructions;
  272. // connection <--> field_71135_a <--> a
  273. // FD: oq/a net/minecraft/entity/player/EntityPlayerMP/field_71135_a
  274. // searching for line: p.connection = nethandlerplayserver;
  275. String search = obfuscated ? "a" : "connection";
  276. String playerOwner = obfuscated ? "oq" : "net/minecraft/entity/player/EntityPlayerMP";
  277. boolean found = false;
  278. while(index < ins.size())
  279. {
  280. node = ins.get(index);
  281. if(node instanceof FieldInsnNode)
  282. {
  283. FieldInsnNode field = (FieldInsnNode) node;
  284. if(field.name.equals(search) && field.owner.equals(playerOwner))
  285. {
  286. found = true;
  287. break;
  288. }
  289. }
  290. index++;
  291. }
  292. if(!found)
  293. {
  294. System.out.println("Start of player connection was not found");
  295. return bytes;
  296. }
  297. node = ins.get(index);
  298. if(obfuscated)
  299. {
  300. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onPlayerConnection", "(Loq;)V", false));
  301. }
  302. else
  303. {
  304. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  305. "onPlayerConnection", "(Lnet/minecraft/entity/player/EntityPlayerMP;)V", false));
  306. }
  307. ins.insert(node, new VarInsnNode(Opcodes.ALOAD, 2));
  308. // -----------------------------------------------------------------
  309. // end of first part - inserting PlayerConnectionEvent hook
  310. // second part - removing join message
  311. // -----------------------------------------------------------------
  312. // func_70005_c_
  313. // MD: aed/h_ ()Ljava/lang/String; net/minecraft/entity/player/EntityPlayer/func_70005_c_ ()Ljava/lang/String;
  314. // Searching for: if (playerIn.getName().equalsIgnoreCase(s))
  315. String start = "equalsIgnoreCase";
  316. String startDesc = "(Ljava/lang/String;)Z";
  317. // func_148539_a
  318. // MD: pl/a (Lhh;)V net/minecraft/server/management/PlayerList/func_148539_a (Lnet/minecraft/util/text/ITextComponent;)V
  319. String end = obfuscated ? "a" : "sendMessage";
  320. String endDesc = obfuscated ? "(Lhh;)V" : "(Lnet/minecraft/util/text/ITextComponent;)V";
  321. found = false;
  322. while(index < ins.size())
  323. {
  324. node = ins.get(index);
  325. if(node instanceof MethodInsnNode)
  326. {
  327. MethodInsnNode mnode = (MethodInsnNode) node;
  328. if(mnode.name.equals(start) && mnode.desc.equals(startDesc))
  329. {
  330. found = true;
  331. break;
  332. }
  333. }
  334. index++;
  335. }
  336. if(!found)
  337. {
  338. System.out.println("Start of player join message was not found");
  339. return bytes;
  340. }
  341. // moving to real start of the block "p.getName()..."
  342. index -= 3;
  343. while(true)
  344. {
  345. node = ins.get(index);
  346. if(node instanceof MethodInsnNode)
  347. {
  348. MethodInsnNode mnode = (MethodInsnNode) node;
  349. if(mnode.name.equals(end) && mnode.desc.equals(endDesc))
  350. {
  351. ins.remove(node);
  352. break;
  353. }
  354. }
  355. ins.remove(node);
  356. }
  357. // -----------------------------------------------------------------
  358. // end of second part - removing join message
  359. // third part - inserting PlayerPreRespawnEvent hook
  360. // -----------------------------------------------------------------
  361. // recreatePlayerEntity <--> func_72368_a <--> a
  362. // MD: pl/a (Loq;IZ)Loq; net/minecraft/server/management/PlayerList/func_72368_a
  363. // (Lnet/minecraft/entity/player/EntityPlayerMP;IZ)Lnet/minecraft/entity/player/EntityPlayerMP;
  364. if(obfuscated)
  365. {
  366. mn = classNode.methods.stream().filter(me -> me.name.equals("a")).filter(me -> "(Loq;IZ)Loq;".equals(me.desc)).findAny().get();
  367. }
  368. else
  369. {
  370. mn = classNode.methods.stream().filter(me -> me.name.equals("recreatePlayerEntity")).findAny().get();
  371. }
  372. ins = mn.instructions;
  373. node = ins.get(1);
  374. if(obfuscated)
  375. {
  376. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onPlayerPreRespawn", "(Loq;IZ)V", false));
  377. }
  378. else
  379. {
  380. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  381. "onPlayerPreRespawn", "(Lnet/minecraft/entity/player/EntityPlayerMP;IZ)V", false));
  382. }
  383. ins.insert(node, new VarInsnNode(Opcodes.ILOAD, 3));
  384. ins.insert(node, new VarInsnNode(Opcodes.ILOAD, 2));
  385. ins.insert(node, new VarInsnNode(Opcodes.ALOAD, 1));
  386. // -----------------------------------------------------------------
  387. // end of third part - inserting PlayerPreRespawnEvent hook
  388. // -----------------------------------------------------------------
  389. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  390. classNode.accept(writer);
  391. return writer.toByteArray();
  392. }
  393. catch(Exception ex)
  394. {
  395. ex.printStackTrace();
  396. }
  397. return bytes;
  398. }
  399. public byte[] patchMinecraftServer(String c, byte[] bytes)
  400. {
  401. try
  402. {
  403. ClassNode classNode = new ClassNode();
  404. ClassReader classReader = new ClassReader(bytes);
  405. classReader.accept(classNode, 0);
  406. // createCommandManager <--> func_175582_h <--> i
  407. // MD: net/minecraft/server/MinecraftServer/i ()Ldh;
  408. // MD: chd/i ()Ldh; net/minecraft/server/integrated/IntegratedServer/func_175582_h
  409. // ()Lnet/minecraft/command/ServerCommandManager;
  410. MethodNode mn;
  411. if(obfuscated)
  412. {
  413. mn = classNode.methods.stream().filter(me -> me.name.equals("i")).filter(me -> "()Ldh;".equals(me.desc)).findAny().get();
  414. }
  415. else
  416. {
  417. mn = classNode.methods.stream().filter(me -> me.name.equals("createCommandManager")).findAny().get();
  418. }
  419. InsnList ins = mn.instructions;
  420. ins.remove(ins.get(2));
  421. ins.remove(ins.get(2));
  422. ins.remove(ins.get(3));
  423. /*if(obfuscated)
  424. {
  425. ins.insert(ins.get(2), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  426. "onCreateCommandManager", "(Ldh;)Lme/kcm/command/ModServerCommandManager;", false));
  427. }
  428. else
  429. {*/
  430. ins.insert(ins.get(2), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks",
  431. "onCreateCommandManager", "(Lnet/minecraft/server/MinecraftServer;)Lme/kcm/command/ModServerCommandManager;", false));
  432. //}
  433. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  434. classNode.accept(writer);
  435. return writer.toByteArray();
  436. }
  437. catch(Exception ex)
  438. {
  439. ex.printStackTrace();
  440. }
  441. return bytes;
  442. }
  443. public byte[] patchNetHandlerPlayServer(String c, byte[] bytes)
  444. {
  445. try
  446. {
  447. ClassNode classNode = new ClassNode();
  448. ClassReader classReader = new ClassReader(bytes);
  449. classReader.accept(classNode, 0);
  450. // public void onDisconnect(ITextComponent reason)
  451. // onDisconnect <--> func_147231_a <--> a
  452. // MD: pa/a (Lhh;)V net/minecraft/network/NetHandlerPlayServer/func_147231_a (Lnet/minecraft/util/text/ITextComponent;)V
  453. MethodNode mn;
  454. if(obfuscated)
  455. {
  456. mn = classNode.methods.stream().filter(me -> me.name.equals("a")).filter(me -> "(Lhh;)V".equals(me.desc)).findAny().get();
  457. }
  458. else
  459. {
  460. mn = classNode.methods.stream().filter(me -> me.name.equals("onDisconnect")).findAny().get();
  461. }
  462. InsnList ins = mn.instructions;
  463. // VarInsnNode 25 2 0
  464. // FieldInsnNode 180 4 Lnet/minecraft/server/MinecraftServer; serverController net/minecraft/network/NetHandlerPlayServer
  465. // MethodInsnNode 182 5 ()Lnet/minecraft/server/management/PlayerList; false getPlayerList net/minecraft/server/MinecraftServer
  466. // VarInsnNode 25 2 2
  467. // MethodInsnNode 182 5 (Lnet/minecraft/util/text/ITextComponent;)V false sendMessage net/minecraft/server/management/PlayerList
  468. // sendMessage <--> func_148539_a <--> a
  469. // MD: pl/a (Lhh;)V net/minecraft/server/management/PlayerList/func_148539_a (Lnet/minecraft/util/text/ITextComponent;)V
  470. int index = 0;
  471. AbstractInsnNode node;
  472. String search = obfuscated ? "a" : "sendMessage";
  473. String owner = obfuscated ? "pl" : "net/minecraft/server/management/PlayerList";
  474. boolean found = false;
  475. while(index < ins.size())
  476. {
  477. node = ins.get(index);
  478. if(node instanceof MethodInsnNode)
  479. {
  480. MethodInsnNode field = (MethodInsnNode) node;
  481. if(field.name.equals(search) && field.owner.equals(owner))
  482. {
  483. found = true;
  484. break;
  485. }
  486. }
  487. index++;
  488. }
  489. if(!found)
  490. {
  491. System.out.println("Start of sendMessage was not found");
  492. return bytes;
  493. }
  494. index -= 4;
  495. for(int i = 0; i < 5; i++)
  496. {
  497. ins.remove(ins.get(index));
  498. }
  499. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  500. classNode.accept(writer);
  501. return writer.toByteArray();
  502. }
  503. catch(Exception ex)
  504. {
  505. ex.printStackTrace();
  506. }
  507. return bytes;
  508. }
  509. public byte[] patchCraftingManager(String c, byte[] bytes)
  510. {
  511. try
  512. {
  513. ClassNode classNode = new ClassNode();
  514. ClassReader classReader = new ClassReader(bytes);
  515. classReader.accept(classNode, 0);
  516. MethodNode mn;
  517. if(obfuscated)
  518. {
  519. mn = classNode.methods.stream().filter(me -> me.name.equals("b")).filter(me -> "(Lafy;Lamu;)Lakt;".equals(me.desc)).findAny().get();
  520. }
  521. else
  522. {
  523. mn = classNode.methods.stream().filter(me -> me.name.equals("findMatchingRecipe")).findAny().get();
  524. }
  525. InsnList ins = mn.instructions;
  526. // sendMessage <--> func_148539_a <--> a
  527. // MD: aku/b (Lafy;Lamu;)Lakt; net/minecraft/item/crafting/CraftingManager/func_192413_b
  528. // (Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Lnet/minecraft/item/crafting/IRecipe;
  529. AbstractInsnNode node = ins.get(1);
  530. ins.insert(node, new InsnNode(Opcodes.ARETURN));
  531. if(obfuscated)
  532. {
  533. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onfindMatchingRecipe", "(Lafy;Lamu;)Lakt;", false));
  534. }
  535. else
  536. {
  537. ins.insert(node, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/kcm/events/Hooks", "onfindMatchingRecipe",
  538. "(Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Lnet/minecraft/item/crafting/IRecipe;", false));
  539. }
  540. ins.insert(node, new VarInsnNode(Opcodes.ALOAD, 1));
  541. ins.insert(node, new VarInsnNode(Opcodes.ALOAD, 0));
  542. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  543. classNode.accept(writer);
  544. return writer.toByteArray();
  545. }
  546. catch(Exception ex)
  547. {
  548. ex.printStackTrace();
  549. }
  550. return bytes;
  551. }
  552. public String getString(AbstractInsnNode node)
  553. {
  554. StringBuilder sb = new StringBuilder();
  555. sb.append(node.getClass().getSimpleName());
  556. sb.append(" ");
  557. sb.append(node.getOpcode());
  558. sb.append(" ");
  559. sb.append(node.getType());
  560. sb.append(" ");
  561. if(node instanceof LineNumberNode)
  562. {
  563. LineNumberNode n = (LineNumberNode) node;
  564. sb.append(n.line);
  565. sb.append(" ");
  566. sb.append(n.start);
  567. }
  568. else if(node instanceof VarInsnNode)
  569. {
  570. VarInsnNode n = (VarInsnNode) node;
  571. sb.append(n.var);
  572. }
  573. else if(node instanceof MethodInsnNode)
  574. {
  575. MethodInsnNode n = (MethodInsnNode) node;
  576. sb.append(n.desc);
  577. sb.append(" ");
  578. sb.append(n.itf);
  579. sb.append(" ");
  580. sb.append(n.name);
  581. sb.append(" ");
  582. sb.append(n.owner);
  583. }
  584. else if(node instanceof FrameNode)
  585. {
  586. FrameNode n = (FrameNode) node;
  587. if(n.local != null)
  588. {
  589. n.local.forEach(s -> {sb.append(s); sb.append(" ");});
  590. }
  591. if(n.stack != null)
  592. {
  593. n.stack.forEach(s -> {sb.append(s); sb.append(" ");});
  594. }
  595. }
  596. else if(node instanceof InsnNode)
  597. {
  598. }
  599. else if(node instanceof FieldInsnNode)
  600. {
  601. FieldInsnNode n = (FieldInsnNode) node;
  602. sb.append(n.desc);
  603. sb.append(" ");
  604. sb.append(n.name);
  605. sb.append(" ");
  606. sb.append(n.owner);
  607. }
  608. return sb.toString();
  609. }
  610. }