本帖最后由 azbh111 于 2018-8-19 12:06 编辑
关于本插件
本人开发各种插件时,发现总是会做很多重复烦人的工作
以下列举一些重复烦人的工作,并提供框架下优化后的代码(学霸食用,学渣直接看帖子结尾吧)
? 配置文件的 生成/读取/重载/保存
复制代码
? 自定义数据的 创建/读取/保存
复制代码
? 数据库连接的....
复制代码
? 插件加载时,各种java对象的初始化,装配....
复制代码
? 根据各种条件判断是启用某个功能
复制代码
? 制作指令时,无限if else,各种参数解析,权限判断简直烦死,
复制代码
? mns的混淆名查找,记不住啊。。。神烦
复制代码
? 等等。。。。。
鉴于以上情况,特开发了这个插件框架来加快插件开发速度,并最大程度优化以上情况
ps:此后本人所有其他插件均会直接依赖此插件
关于Minecraft版本
因为本人只在1.7.10下开服,所以目前只支持1.7.10
指令
只有一个指令 /pluginloader reload [<plugin>] 用于重载所有/指定插件的插件(当然前提是在此框架下开发的插件)
下载
因为打包了很多类库,所以很大Orz。。
最近很穷啊,希望各位大佬在笑纳时顺便评分赏赏金粒吧
地址
链接:https://pan.baidu.com/s/1saTd4ADpyT7D-uIJGJLEAg 密码:7a88
关于本插件
本人开发各种插件时,发现总是会做很多重复烦人的工作
以下列举一些重复烦人的工作,并提供框架下优化后的代码(学霸食用,学渣直接看帖子结尾吧)
? 配置文件的 生成/读取/重载/保存
- // 一个自定义配置文件
- @Inject(args = "{.}/plugins/Clann/configItem.conf")
- ConfigWrapper configWrapper;
- // 配置采用注入的方式
- @Configure(value = "modules.autoSave.interval", comment = "间隔(s)")
- private long saveInterval = 600; //10分钟保存一次
- // 重载插件时的回调
- @ReLoad
- public void reload() {
- // doSomething
- }
? 自定义数据的 创建/读取/保存
- // 定义一个数据文件
- @Ignore
- @Inject(args = {"{.}/data/clann/blocklog"})
- FileDataHolder dataFile;
- // 读取数据
- @Load
- public void load() {
- if (!dataFile.exist()) {
- dataFile.save(this);
- } else {
- dataFile.fill(this);
- }
- }
- // 保存数据
- public void save() {
- dataFile.save(this);
- }
? 数据库连接的....
- // 创建一个数据库连接,(本框架使用h2数据库)
- @Inject(id = AutoBackup.dataSourceId, args = "${Clann:modules.backupInv.jdbcUrl}")
- SqlSource sqlSource;
- // 创建一个PreparedStatement
- @Inject(depends = {AutoBackup.dataSourceId}, args = {AutoBackup.dataSourceId
- , "SELECT id,created,player,temp,invId FROM " + BackupTable.tableName
- + " where player=? and temp=1 order by id desc limit 1"})
- private PreparedStatement getTemp;
- // 创建一个数据库表
- @Inject(id = BackupTable.tableName, depends = AutoBackup.dataSourceId)
- @Table(BackupTable.tableName)
- public class BackupTable implements Pojo {
- public static final String tableName = "clann_invbackup";
- // some column define
- }
? 插件加载时,各种java对象的初始化,装配....
- // 依赖注入,实现Listener的Service会自动注册监听器
- @Service(successMsg = "检测到MOD:应用能源,监听器**"
- , needClass = "appeng.core.AppEng"
- , enableConfigPath = "enable"
- , comment = "是否启用")
- public class Appliedenergistics2 implements Listener {
- // 依赖注入
- @Inject
- AEFixer plugin;
- @Inject
- WorldUtils worldUtils;
- @Inject
- TileEntityUtils tileEntityUtils;
- @Inject
- NBTCompoundUtils nbtCompoundUtils;
- // 配置注入
- @Configure(value = "singleController", comment = "是否禁止CPU相邻放置(防止网络规模过大)")
- private boolean singleController = true;
- @Configure(value = "protectWorkingCPU", comment = "是否禁止破坏正在工作的CPU(总感觉有问题)")
- private boolean protectWorkingCPU = true;
- @Configure(value = "safeCPU", comment = "是否禁止CPU跨区块放置(刷物品)")
- private boolean safeCPU = true;
- // 插件生命周期
- @Load
- private void load(){
- // do something
- }
- // 插件生命周期
- @Reload
- private void reload(){
- // do something
- }
- // 插件生命周期
- @UnLoad
- private void unload(){
- // do something
- }
- }
? 根据各种条件判断是启用某个功能
- // Class.forName("appeng.core.AppEng")不抛异常
- // 配置文件中 enable为true
- // 插件Essentials存在
- // 物品DIAMOND存在(可用来判断mod是否存在)
- // AEFixer实例化的Service存在
- // 满足以上条件才会加载此Service
- @Service(successMsg = "检测到MOD:应用能源,监听器**"
- , needClass = "appeng.core.AppEng"
- , enableConfigPath = "enable"
- , comment = "是否启用"
- , needPlugin = "Essentials"
- , needItemType = "DIAMOND"
- , depend = AEFixer.class)
- public class Appliedenergistics2 {
- }
? 制作指令时,无限if else,各种参数解析,权限判断简直烦死,
- // 指令/pluginloader reload [<plugin>]的实现类
- @Service
- public class LoaderCommand extends ICommand {
- public LoaderCommand() {
- super("PluginLoader", "pluginloader");
- }
- // @CommandAnnotation可以控制这条指令执行所需权限,是否要OP,是否必须玩家才能执行
- // 会自动解析参数
- // 这只是个例子
- // 实现指令,不需要op权限,有mplayer的玩家才能执行 /pluginloader tp <x> <y> <z> [<world>]
- // 没有world参数时,为当前世界
- @CommandAnnotation(permission = "mplayer", needOp = false, mustPlayer = true, args = "<x> <y> <z> [<world>]", des = "重载插件")
- public void tp(@Sender Player sender, int x, int y, int z, @OptionalParam World world) {
- if (world == null) {
- world = sender.getWorld();
- }
- // do something
- }
- // 实现/pluginloader reload [<plugin>]
- @CommandAnnotation(args = "[<plugin>]", des = "重载插件")
- public void reload(@Sender CommandSender sender, @OptionalParam String plugin) {
- if (plugin == null) {
- plugin = "";
- }
- logger.info("开始重载插件{}", plugin);
- sender.sendMessage("开始重载插件" + plugin);
- Stopwatch watch = Stopwatch.createStarted();
- List<ServiceHolder> services = BeanContext.getServices();
- String pluginId = plugin;
- services.stream()
- .forEach(s -> {
- if (!StringUtils.isEmpty(pluginId) && !s.getPlugin().getId().equalsIgnoreCase(pluginId)) {
- return;
- }
- try {
- //重载默认配置文件
- s.getPlugin().setConfigNode(s.getPlugin().getConfigLoader().load());
- long count = ConfigUtils.injectConfigure(s.getPlugin().getConfigNode(), s.getHandle());
- if (count > 0) {
- logger.info("重载配置:" + s.getId());
- }
- } catch (Throwable e) {
- logger.error("配置注入失败:" + s.getId(), e);
- }
- });
- LoaderUtils.invokeMethods(services, Reload.class, "reload");
- this.plugin.saveConfig();
- watch.stop();
- sender.sendMessage("重载完毕,耗时" + watch.elapsed(TimeUnit.MILLISECONDS) + "ms");
- }
- }
? mns的混淆名查找,记不住啊。。。神烦
- // 假设服务器是多线,怎么能知道玩家连接的是服务器的哪个ip呢
- // 这里使用反射拿到玩家对应的nettyChannel,反射使用的名字全是为混淆的名字,会根据1.7.10的混淆规则自动映射混淆的方法
- public String getServerIp(Player p) {
- //常规方式
- WrapClass<? extends Player> wc = ClassUtils.wrap(p.getClass());
- WrapField wentity = wc.getField("entity");
- WrapField wplayerNetServerHandler = ClassUtils.wrap(wentity.getType()).getField("playerNetServerHandler");
- WrapField wnetManager = ClassUtils.wrap(wplayerNetServerHandler.getType()).getField("netManager");
- WrapMethod wchannel = ClassUtils.wrap(wnetManager.getType()).getMethod("channel");
- io.netty.channel.Channel channel0 = (Channel) wchannel.invoke(wnetManager.get(wplayerNetServerHandler.get(wentity.get(p))));
- //快捷方式,链式调用
- io.netty.channel.Channel channel = Invoker.of(p)
- .get("entity")
- .get("playerNetServerHandler")
- .get("netManager")
- .invoke("channel")
- .get();
- return channel.localAddress().toString().replaceFirst("/", "").split(":", 2)[0];
- }
? 等等。。。。。
鉴于以上情况,特开发了这个插件框架来加快插件开发速度,并最大程度优化以上情况
ps:此后本人所有其他插件均会直接依赖此插件
关于Minecraft版本
因为本人只在1.7.10下开服,所以目前只支持1.7.10
指令
只有一个指令 /pluginloader reload [<plugin>] 用于重载所有/指定插件的插件(当然前提是在此框架下开发的插件)
下载
因为打包了很多类库,所以很大Orz。。
最近很穷啊,希望各位大佬在笑纳时顺便评分赏赏金粒吧
地址
链接:https://pan.baidu.com/s/1saTd4ADpyT7D-uIJGJLEAg 密码:7a88
非优秀禁止使用回复可见
网盘炸了呀
非常不错的插件
66666666666666666
6666666666666666666666666
有个有没有UTF-8呢
bbs有你更精彩