package pw.yumc.BukkitInjectedTools; import java.io.File; import java.net.URLDecoder; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; import javassist.CtMethod; import pw.yumc.injected.event.SetOpEvent; /** * 注入工具集 * * @since 2016年3月31日 下午7:44:25 * @author 喵♂呜 */ public class InjectedKit { public static String prefix = "§6[§bYum §a注入工具§6]§r "; public static String NMS = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; public static void fixPS(final CommandSender sender, final String path, final Class clazz) { sender.sendMessage(prefix + "§c生成 ProtucolSupport 修复类..."); try { final ClassPool pool = ClassPool.getDefault(); final File classFile = new File(URLDecoder.decode(clazz.getProtectionDomain().getCodeSource().getLocation().getPath().split("!")[0], "UTF-8")); pool.appendClassPath(classFile.getPath()); final CtClass statusListener = pool.get(clazz.getName()); final CtMethod setOpMethod = statusListener.getDeclaredMethod("a"); statusListener.addField( CtField.make("private static final net.minecraft.server." + NMS + ".IChatBaseComponent infoAlreadySent = new net.minecraft.server." + NMS + ".ChatComponentText(\"Status request has already been handled.\");", statusListener)); statusListener.addField(CtField.make("private boolean sentInfo = false;", statusListener)); final String checkStatus = "" + "{ if (sentInfo) { nmanager.close(infoAlreadySent); } sentInfo = true; }"; setOpMethod.insertBefore(checkStatus); try { statusListener.writeFile(path); sender.sendMessage(prefix + "§a生成成功 §b请复制 §e" + path + " §b下所有文件到插件内部!"); } catch (final Exception e) { e.printStackTrace(); sender.sendMessage(prefix + "§4生成失败 请查看后台报错!"); } } catch (final Exception e) { e.printStackTrace(); } } public static void injectProtocolSupport(final CommandSender sender, final String path, final boolean newver) { if (newver) { fixPS(sender, path, protocolsupport.protocol.packet.handler.StatusListener.class); } else { fixPS(sender, path, protocolsupport.protocol.transformer.handlers.StatusListener.class); } } public static void injectSetOpMethod(final CommandSender sender, final String path) { sender.sendMessage(prefix + "§c生成 SetOp 拦截类..."); try { final ClassPool pool = ClassPool.getDefault(); final String craftOfflinePlayerClassName = Bukkit.getServer().getClass().getPackage().getName() + ".CraftOfflinePlayer"; final File classFile = new File(URLDecoder.decode(SetOpEvent.class.getProtectionDomain().getCodeSource().getLocation().getPath().split("!")[0], "UTF-8")); pool.appendClassPath(classFile.getPath()); final CtClass craftOfflinePlayer = pool.get(craftOfflinePlayerClassName); final CtClass setOpEvent = pool.get(SetOpEvent.class.getName()); final CtMethod setOpMethod = craftOfflinePlayer.getDeclaredMethod("setOp"); final String setop = "" + "{" + " pw.yumc.injected.event.SetOpEvent event = new pw.yumc.injected.event.SetOpEvent($0,$1);" + " org.bukkit.Bukkit.getPluginManager().callEvent(event);" + " if(event.isCancelled()){" + " return;" + " }" + " if ($1 == isOp()) {" + " return;" + " }" + " if ($1) {" + " server.getHandle().addOp(profile);" + " } else {" + " server.getHandle().removeOp(profile);" + " }" + "}"; setOpMethod.setBody(setop); try { setOpEvent.writeFile(path); craftOfflinePlayer.writeFile(path); sender.sendMessage(prefix + "§a生成成功 §b请复制 §e" + path + " §b下所有文件到服务器Jar内!"); } catch (final Exception e) { e.printStackTrace(); sender.sendMessage(prefix + "§4生成失败 请查看后台报错!"); } } catch (final Exception e) { e.printStackTrace(); } } }