From efa5e6d11079088527bebf536eb025bcc69bd212 Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Fri, 26 Mar 2021 16:43:45 +0800 Subject: [PATCH] backup: plugins & docs Signed-off-by: MiaoWoo --- packages/plugins/docs/MiaoMail.md | 33 +++ packages/plugins/docs/MiaoPay.md | 14 ++ packages/plugins/docs/MiaoReport.md | 112 +++++++++ packages/plugins/src/MiaoConsole.ts | 44 ++-- packages/plugins/src/MiaoPay.ts | 229 +++++++++++++----- packages/plugins/src/MiaoReward.ts | 108 ++++++--- packages/plugins/src/MiaoRobot.ts | 11 +- .../plugins/src/MiaoScriptPackageManager.ts | 25 +- 8 files changed, 449 insertions(+), 127 deletions(-) create mode 100644 packages/plugins/docs/MiaoMail.md create mode 100644 packages/plugins/docs/MiaoPay.md create mode 100644 packages/plugins/docs/MiaoReport.md diff --git a/packages/plugins/docs/MiaoMail.md b/packages/plugins/docs/MiaoMail.md new file mode 100644 index 00000000..b443e13f --- /dev/null +++ b/packages/plugins/docs/MiaoMail.md @@ -0,0 +1,33 @@ + private static void injectInventoryAddItemMethod() { + System.out.println("Injectoring Mail..."); + try { + ClassPool pool = ClassPool.getDefault(); + String inventoryClassName = Bukkit.getServer().getClass().getPackage().getName() + ".inventory.CraftInventory"; + File classFile = new File(URLDecoder.decode(InventoryDragEvent.class.getProtectionDomain().getCodeSource().getLocation().getPath().split("!")[0], "UTF-8")); + pool.appendClassPath(classFile.getPath()); + classFile = new File(URLDecoder.decode(MailPlugin.class.getProtectionDomain().getCodeSource().getLocation().getPath().split("!")[0], "UTF-8")); + pool.appendClassPath(classFile.getPath()); + CtClass inventoryClass = pool.get(inventoryClassName); + CtMethod addItemMethod = inventoryClass.getDeclaredMethod("addItem"); + + addItemMethod.insertAfter( + "if(this instanceof org.bukkit.inventory.PlayerInventory){" + + " final org.bukkit.inventory.PlayerInventory playerInventory = (org.bukkit.inventory.PlayerInventory)this;" + + " final org.bukkit.entity.Player player = (org.bukkit.entity.Player)playerInventory.getHolder();" + + " if(!$_.values().isEmpty()){" + + " org.bukkit.event.inventory.InventoryDragEvent event = new org.bukkit.event.inventory.InventoryDragEvent(player.getOpenInventory(), new org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR), new org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR), true, $_);" + + " event.setCancelled(true);" + + " event.setResult(org.bukkit.event.Event.Result.DENY);" + + " org.bukkit.Bukkit.getPluginManager().callEvent(event);" + + " }" + + "}"); + try { + inventoryClass.toClass(); + System.out.println("Injected"); + } catch (Exception e) { + System.out.println("Inject fail, Please restart server"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } diff --git a/packages/plugins/docs/MiaoPay.md b/packages/plugins/docs/MiaoPay.md new file mode 100644 index 00000000..71acfc57 --- /dev/null +++ b/packages/plugins/docs/MiaoPay.md @@ -0,0 +1,14 @@ +# MiaoPay + +## 安装方式 +先按照帖子 + +### 网关 +- https://pay.yumc.pw/api + +### 相关接口 + +#### 创建订单 +- METHOD: /create +- PARAM: + - diff --git a/packages/plugins/docs/MiaoReport.md b/packages/plugins/docs/MiaoReport.md new file mode 100644 index 00000000..dc45d6ab --- /dev/null +++ b/packages/plugins/docs/MiaoReport.md @@ -0,0 +1,112 @@ +# MiaoReport(喵式报告) + +## 插件简介 + +- 本插件只有一个功能 就是上报当前服务器信息和运行日志到 Ubuntu Paste +- 适用于哪些 有问题 但是不知道怎么提供报错的用户 + +## 插件命令 + +- 只有一个 `/mbrp` +- 并且只有 OP 权限用户才可以执行 + +## 功能预览 + +- 报告地址 https://paste.ubuntu.com/p/mVjJtb6Xcg/ +- 报告详情(已删除无用信息 并不是完整报告) + +``` +当前报告由 MiaoBugReport(0.0.1) 生成 作者 MiaoWoo 官网 https://w.yumc.pw +生成时间: 2021-02-13 21:52:54 +============================== 以下为本次报告内容 ============================== +服务器版本: git-Spigot-dcd1643-e60fc34 (MC: 1.12.2) +Bukkit版本: 1.12.2-R0.1-SNAPSHOT +============================== 运行数据 ============================== +运行时间: 1 小时 25 分 48 秒 +CPU 核心: 16 +最大内存: 7282 MB +分配内存: 626 MB +空闲内存: 307 MB +============================== 数据统计 ============================== +世界列表: + - world(NORMAL) + - 已加载区块: 272 + - 实体数量: 146 + - Tile数量: 10 + - 玩家数量: 0 + - world_nether(NETHER) + - 已加载区块: 0 + - 实体数量: 0 + - Tile数量: 0 + - 玩家数量: 0 + - world_the_end(THE_END) + - 已加载区块: 0 + - 实体数量: 0 + - Tile数量: 0 + - 玩家数量: 0 +在线玩家: Mr_jtb +插件列表: MiaoBugReport(0.0.1) +============================== 服务器线程堆栈 ============================== +"Spigot Metrics Thread" daemon prio=5 id=32 + java.lang.Thread.State: TIMED_WAITING + at java.lang.Object.wait(Native Method) + at java.util.TimerThread.mainLoop(Unknown Source) + at java.util.TimerThread.run(Unknown Source) + +"Spigot Watchdog Thread" prio=5 id=31 + java.lang.Thread.State: TIMED_WAITING + at java.lang.Thread.sleep(Native Method) + at org.spigotmc.WatchdogThread.run(WatchdogThread.java:92) + +"Server thread" prio=5 id=26 + java.lang.Thread.State: TIMED_WAITING + at java.lang.Thread.sleep(Native Method) + at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:560) + at java.lang.Thread.run(Unknown Source) + +"Server console handler" daemon prio=5 id=29 + java.lang.Thread.State: RUNNABLE + at org.fusesource.jansi.internal.Kernel32.ReadConsoleInputW(Native Method) + at org.fusesource.jansi.internal.Kernel32.readConsoleInputHelper(Kernel32.java:761) + at org.fusesource.jansi.internal.Kernel32.readConsoleKeyInput(Kernel32.java:794) + at org.fusesource.jansi.internal.WindowsSupport.readConsoleInput(WindowsSupport.java:97) + at org.bukkit.craftbukkit.libs.jline.WindowsTerminal.readConsoleInput(WindowsTerminal.java:215) + at org.bukkit.craftbukkit.libs.jline.WindowsTerminal.access$000(WindowsTerminal.java:55) + at org.bukkit.craftbukkit.libs.jline.WindowsTerminal$1.read(WindowsTerminal.java:157) + at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:169) + at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:137) + at org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:246) + at org.bukkit.craftbukkit.libs.jline.internal.InputStreamReader.read(InputStreamReader.java:261) + at org.bukkit.craftbukkit.libs.jline.internal.InputStreamReader.read(InputStreamReader.java:198) + at org.bukkit.craftbukkit.libs.jline.console.ConsoleReader.readCharacter(ConsoleReader.java:2145) + at org.bukkit.craftbukkit.libs.jline.console.ConsoleReader.readLine(ConsoleReader.java:2349) + at net.minecraft.server.v1_12_R1.DedicatedServer$2.run(DedicatedServer.java:85) + +"Netty Server IO #0" daemon prio=5 id=34 + java.lang.Thread.State: RUNNABLE + at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method) + at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source) + at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source) + at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source) + at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source) + at sun.nio.ch.SelectorImpl.select(Unknown Source) + at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) + at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:753) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:409) + at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) + at java.lang.Thread.run(Unknown Source) +...忽略其他线程信息 +============================== 本次运行日志 ============================== +[20:27:18] [Server thread/INFO]: Starting minecraft server version 1.12.2 +...忽略启动日志 +[20:27:27] [Server thread/INFO]: [MiaoBugReport] Enabling MiaoBugReport v0.0.1 +[20:27:28] [Server thread/INFO]: Server permissions file permissions.yml is empty, ignoring it +[20:27:28] [Server thread/INFO]: Done (8.205s)! For help, type "help" or "?" +[20:27:53] [Craft Scheduler Thread - 0/INFO]: [MiaoBugReport] 正在生成日志数据... +[20:27:55] [Craft Scheduler Thread - 0/INFO]: [MiaoBugReport] 正在上报数据至UbuntuPaste... +[20:27:55] [Craft Scheduler Thread - 0/INFO]: [MiaoBugReport] 数据上报完成 您可以分享地址给他人 +============================== 报告结束 ============================== +``` + +## 下载地址 + diff --git a/packages/plugins/src/MiaoConsole.ts b/packages/plugins/src/MiaoConsole.ts index 98dea07b..1e786c82 100644 --- a/packages/plugins/src/MiaoConsole.ts +++ b/packages/plugins/src/MiaoConsole.ts @@ -19,7 +19,7 @@ let help = [ '§6/mconsole §areload §6- §3重载插件', ] -@plugin({ prefix: 'Console', version: '1.1.0', author: 'MiaoWoo', servers: ['!nukkit'], source: __filename }) +@plugin({ prefix: 'Console', version: '1.1.1', author: 'MiaoWoo', servers: ['!nukkit'], source: __filename }) export class MiaoConsole extends interfaces.Plugin { @Autowired(ContainerInstance) private container: Container @@ -43,6 +43,7 @@ export class MiaoConsole extends interfaces.Plugin { private appender: any private handler: any private babel: any + private downgrade = true private logCache: string[] = [] @@ -59,17 +60,23 @@ export class MiaoConsole extends interfaces.Plugin { } process.on('message', (msg) => { this.logCache.push(msg) - if (this.logCache.length > 30) { - this.logCache = this.logCache.slice(this.logCache.length - 30, this.logCache.length) + if (this.logCache.length > 100) { + this.logCache = this.logCache.slice(this.logCache.length - 100, this.logCache.length) } }) this.task.create(() => { if (!this.babel) { - this.logger.console('§3脚本 Babel 引擎初始化中 请稍候...') - let startTime = Date.now() - this.babel = require('@babel/standalone') - this.compileCode(`() => console.log("Babel ready!")`) - this.logger.console(`§3脚本 Babel 引擎初始化完毕 耗时 §a${Date.now() - startTime}ms...`) + try { + this.logger.console('§3脚本 Babel 引擎初始化中 请稍候...') + let startTime = Date.now() + this.babel = require('@babel/standalone') + this.compileCode(`() => console.log("Babel ready!")`) + this.logger.console(`§3脚本 Babel 引擎初始化完毕 耗时 §a${Date.now() - startTime}ms...`) + this.downgrade = false + } catch (error) { + this.logger.console(`§c脚本 Babel 引擎初始化失败 将无法使用ES5以上语法!`) + console.ex(error) + } } }).async().submit() } @@ -332,6 +339,17 @@ export class MiaoConsole extends interfaces.Plugin { } private compileCode(code: string) { + if (!this.downgrade && this.babel?.transform) { + code = this.babel.transform(code, { + filename: 'miaoconsole-temp.ts', + presets: ['typescript', 'es2015'], + plugins: [ + ['proposal-decorators', { legacy: true }], + 'transform-runtime' + ], + sourceMaps: "inline" + }).code + } return `var api = require('@ccms/api'); if (this.serverType == "spring") { var dbm = container.get(api.database.DataBaseManager) @@ -339,15 +357,7 @@ if (this.serverType == "spring") { var bf = base.getInstance().getAutowireCapableBeanFactory() } var startTime = Date.now() -var result = eval(${JSON.stringify(this.babel.transform(code, { - filename: 'miaoconsole-temp.ts', - presets: ['typescript', 'es2015'], - plugins: [ - ['proposal-decorators', { legacy: true }], - 'transform-runtime' - ], - sourceMaps: "inline" - }).code)}); +var result = eval(${JSON.stringify(code)}); return '§3代码执行完成 耗时 §e' + (Date.now() - startTime) + 'ms §a返回结果: §r'+ result` } } diff --git a/packages/plugins/src/MiaoPay.ts b/packages/plugins/src/MiaoPay.ts index 055a0792..ea98c853 100644 --- a/packages/plugins/src/MiaoPay.ts +++ b/packages/plugins/src/MiaoPay.ts @@ -4,12 +4,14 @@ import { plugin, server, task } from '@ccms/api' import { Autowired, JSClass } from '@ccms/container' -import { Cmd, Config, interfaces, JSPlugin, PluginConfig, Tab } from '@ccms/plugin' +import { Cmd, Config, interfaces, JSPlugin, Listener, PluginConfig, Tab } from '@ccms/plugin' import type { MiaoReward } from './MiaoReward' import http from '@ccms/common/dist/http' import * as CryptoJS from "crypto-js" +const Thread = java.lang.Thread + interface PlayerPointsAPI { look(name: string) give(name: string, amount: number) @@ -18,14 +20,15 @@ interface PlayerPointsAPI { interface Order { order_id: string - amount: string - url: string + amount: number + url?: string } interface Sync { scaned: boolean start?: number left?: number cancelled?: boolean + paying?: boolean } interface PlaceholderAPI { @@ -36,15 +39,41 @@ interface PlaceholderAPI { const defaultConfig = { prefix: '§6[§b喵式支付§6]', + name: '', id: '', secret: '', - command: 'p give %player_name% %amount%', + command: 'points give %player_name% %amount%', check: '%playerpoints_points%', ratio: 100, - coinName: '点券' + coinName: '点券', + reward: { + '*': [ + 'msg %player_name% 充值 %amount% 点券成功...' + ], + 10: [ + "points give %player_name% 1", + 'msg %player_name% 充值 10 点券 奖励 1 点券...' + ], + 300: [ + "points give %player_name% 15", + 'msg %player_name% 充值 300 点券 奖励 15 点券...' + ], + 500: [ + "points give %player_name% 25", + 'msg %player_name% 充值 500 点券 奖励 25 点券...' + ], + 680: [ + "points give %player_name% 35", + 'msg %player_name% 充值 680 点券 奖励 35 点券...' + ], + 1280: [ + "points give %player_name% 70", + 'msg %player_name% 充值 1280 点券 奖励 70 点券...' + ], + } } -@JSPlugin({ version: '1.2.0', author: 'MiaoWoo', source: __filename, depends: ['MiaoReward'], nativeDepends: ['PlaceholderAPI'] }) +@JSPlugin({ version: '1.3.5', author: 'MiaoWoo', source: __filename, depends: ['MiaoReward'], nativeDepends: ['PlaceholderAPI'] }) export class MiaoPay extends interfaces.Plugin { @Autowired() private server: server.Server @@ -56,6 +85,7 @@ export class MiaoPay extends interfaces.Plugin { @JSClass('me.clip.placeholderapi.PlaceholderAPI') private PlaceholderAPI: PlaceholderAPI + private apiGateWay = "https://pay.yumc.pw" private MiaoReward: MiaoReward private cacheMap = new Map(); @@ -75,14 +105,6 @@ export class MiaoPay extends interfaces.Plugin { needSave && this.config.save() } - cmdtest(sender: org.bukkit.entity.Player) { - try { - this.logger.sender(sender, this.getPlayerAmount(sender)) - } catch (error) { - return this.logger.sender(sender, error.message) - } - } - enable() { this.MiaoReward = this.pluginManager.getPlugin('MiaoReward') as MiaoReward if (!this.MiaoReward) { return this.logger.error('当前脚本插件需要 MiaoReward 作为前置脚本插件!') } @@ -99,7 +121,7 @@ export class MiaoPay extends interfaces.Plugin { @Cmd({ autoMain: true }) mpay() { } - cmdpay(sender: org.bukkit.entity.Player, amount: number) { + cmdpay(sender: org.bukkit.entity.Player, amount: number = 0) { if (!sender.getItemInHand) { return this.logger.sender(sender, '§4控制台无法执行此命令!') } if (!this.MiaoReward.serverInfo) { return this.logger.sender(sender, '§4当前服务器尚未配置 请联系管理员先配置MiaoReward!') } if (!this.config.id || !this.config.secret) { return this.logger.sender(sender, '§c当前服务器尚未配置 请联系管理员配置支付密钥!') } @@ -107,24 +129,28 @@ export class MiaoPay extends interfaces.Plugin { this.logger.sender(sender, '§c您有一笔订单尚未完成 请完成支付或等待订单超时!') let sync = this.cacheSyncMap.get(sender.getName()) if (!sync.cancelled) { return } - sync.left = 55 - (Math.round(Date.now() / 1000) - sync.start) + sync.scaned = false + sync.left = (sync.paying ? 100 : 55) - (Math.round(Date.now() / 1000) - sync.start) let order = this.cacheMap.get(sender.getName()) - this.MiaoReward.setItemAndTp(sender, order.url, sync, `充值 ${order.amount} ${this.config.coinName}`, `支付宝/微信/QQ 扫码支付`) + this.MiaoReward.setItemAndTp(sender, order.url, sync, `充值 ${this.config.ratio * order.amount} ${this.config.coinName}`, `支付宝/微信/QQ 扫码支付`) return } if (amount < 1) { return this.logger.sender(sender, `§c充值异常 §4充值金额不得小于 1 ${this.config.coinName}!`) } + if (amount / this.config.ratio > 1000) { return this.logger.sender(sender, `§c充值异常 §4充值金额不得大于 ${this.config.ratio * 1000} ${this.config.coinName}!`) } + if (amount != Math.round(amount)) { return this.logger.sender(sender, `§c充值异常 §4充值金额必须为整数!`) } try { this.getPlayerAmount(sender) } catch (error) { - return this.logger.sender(sender, error.message) + return this.logger.sender(sender, error.message || error) } this.MiaoReward.sendTitle(sender, `§6充值 §a${amount} §6${this.config.coinName}`, '§c正在请求充值二维码 请稍候...') - let sync = { scaned: false, start: Math.round(Date.now() / 1000) } + let sync: any = { scaned: false, start: Math.round(Date.now() / 1000) } let order = this.createOrder(sender, amount) this.cacheMap.set(sender.getName(), order) this.cacheSyncMap.set(sender.getName(), sync) let order_id = order.order_id this.MiaoReward.setItemAndTp(sender, order.url, sync, `充值 ${amount} ${this.config.coinName}`, `支付宝/微信/QQ 扫码支付`) + this.logger.sender(sender, [`§3请使用 §b支付宝§3/§a微信§3/§5QQ §3扫描二维码支付!`, `§c如未显示二维码 请打开下列网址完成充值!`, `§6地址: §3${order.url}`]) this.taskManager.create(() => { try { let status = this.queryStatus(order_id, 0, 55) @@ -132,15 +158,15 @@ export class MiaoPay extends interfaces.Plugin { this.MiaoReward.sendTitle(sender, '§a已扫码', `§3订单已创建 请及时支付!`) this.MiaoReward.sendActionBar(sender, '§6订单号: §3' + order_id) sync.scaned = true - status = this.queryStatus(order_id, 1, 120) + sync.start = Math.round(Date.now() / 1000) + sync.paying = true + status = this.queryStatus(order_id, 1, 100) if (status.code != 200) { throw new Error('§c支付超时 请重新充值!') } if (status.data == 2) { this.MiaoReward.sendTitle(sender, '§a已支付', `§3订单已支付 请等待充值到账...`) this.MiaoReward.sendActionBar(sender, '§6订单号: §3' + order_id) this.logger.sender(sender, `§6订单号: §3${order_id} §a支付成功!`) - this.recharge(sender, order_id, order.amount) - } else { - this.logger.sender(sender, `§c充值系统异常 §4订单状态异常${status.data} §c点券可能未到账 请联系管理员!`) + this.recharge(sender, order) } } catch (error) { let cacheOrder = this.cacheMap.get(sender.getName()) @@ -172,46 +198,120 @@ export class MiaoPay extends interfaces.Plugin { ]) if (order.status > 1 && order.status < 4) { this.logger.sender(sender, `§3当前订单已支付 尚未完成充值 开始补单操作...`) - this.recharge(sender, id, order.amount) + this.recharge(sender, order) + } + }).async().submit() + } + + cmdcheck(sender: org.bukkit.entity.Player, force = 1) { + this.logger.sender(sender, `§3正在检查需要补单充值的订单 请稍候...`) + this.taskManager.create(() => { + let result = this.queryUnconverted(sender.getName(), force) + if (result.code != 200) { return this.logger.sender(sender, `§c订单查询失败: ${result.msg}`) } + let unconverteds = result.data + if (!unconverteds.length) { return this.logger.sender(sender, `§c未发现需要进行补单充值的订单!`) } + this.logger.sender(sender, `§3发现 §a${unconverteds.length}笔 §3未充值订单 §c正在充值 请稍候...`) + for (const unconverted of unconverteds) { + this.logger.sender(sender, `§3正在处理订单 §a${unconverted.order_id} §3请稍候...`) + this.recharge(sender, unconverted) + Thread.sleep(300) } }).async().submit() } /** + * 请在异步线程执行此方法 * @param amount 订单金额(非点券金额) */ - recharge(sender: org.bukkit.entity.Player, order_id: string, amount: number) { - let point = amount * this.config.ratio - this.taskManager.create(() => { - let finish = this.preFinishOrder(order_id) - if (finish.code != 200) { - return this.logger.console(`§c充值系统异常 订单 §3${order_id} 预标记异常! §4${this.config.coinName}已停止充值 §c请手动补单!`) + recharge(sender: org.bukkit.entity.Player, order: Order) { + let order_id = order.order_id + let amount = order.amount + let point = this.safeMultiply(amount, this.config.ratio) + let finish = this.preFinishOrder(order_id) + if (finish.code != 200) { + this.sendError(sender, order_id, amount, '§4充值预标记异常!') + return this.logger.console(`§c充值系统异常 订单 §3${order_id} 预标记异常! §4${this.config.coinName}已停止充值 §c请手动补单!`) + } + this.taskManager.callSyncMethod(() => { + let prePoint = this.getPlayerAmount(sender) + let command = this.config.command.replace('%player_name%', sender.getName()).replace('%amount%', `${point}`).replace('%remark%', `${order_id}`) + if (!this.server.dispatchConsoleCommand(command)) { + return this.sendError(sender, order_id, amount, '§4充值命令执行异常!') + } + this.checkRecharge(sender, order_id, amount, prePoint, point) + }) + } + + @Listener() + private PlayerJoinEvent(event: org.bukkit.event.player.PlayerJoinEvent) { + const player = event.getPlayer() + this.cmdcheck(player, 0) + } + + private checkRecharge(sender: org.bukkit.entity.Player, order_id: string, amount: number, prePoint: number, point: number) { + this.taskManager.create(() => { + let nowPoint = this.checkNowPoint(sender, point, prePoint) + if (nowPoint === false) { + return this.sendError(sender, order_id, amount, '§4充值结果检测异常!') + } + this.logger.sender(sender, [ + `§6充值 §a${point} §6${this.config.coinName} §a成功 §6当前账户余额: §3${nowPoint} §6${this.config.coinName}`, + `§c如出现未到账的情况 请联系管理员!` + ]) + this.rewardOrder(sender, order_id, point) + let finish = this.finishOrder(order_id) + if (finish.code != 200) { + return this.logger.console(`§c充值系统异常 订单 §3${order_id} 完成标记异常! §4${this.config.coinName}可能重复到账!`) } - this.taskManager.callSyncMethod(() => { - let prePoint = this.getPlayerAmount(sender) - let command = this.config.command.replace('%player_name%', sender.getName()).replace('%amount%', `${point}`).replace('%remark%', `${order_id}`) - if (!this.server.dispatchConsoleCommand(command)) { - return this.sendError(sender, order_id, amount, '§4充值命令执行异常!') - } - let nowPoint = this.getPlayerAmount(sender) - if (nowPoint != prePoint + point) { - return this.sendError(sender, order_id, amount, '§4充值结果检测异常!') - } else { - this.taskManager.create(() => { - this.logger.sender(sender, [ - `§6充值 §a${point} §6${this.config.coinName} §a成功 §6当前账户余额: §3${nowPoint} §6${this.config.coinName}`, - `§c如出现未到账的情况 请联系管理员!` - ]) - let finish = this.finishOrder(order_id) - if (finish.code != 200) { - return this.logger.console(`§c充值系统异常 订单 §3${order_id} 完成标记异常! §4${this.config.coinName}可能重复到账!`) - } - }).async().submit() - } - }) }).async().submit() } + private checkNowPoint(sender: org.bukkit.entity.Player, point: number, prePoint: number) { + let nowPoint = this.getPlayerAmount(sender) + if (nowPoint == prePoint + point) { + return nowPoint + } + Thread.sleep(100) + nowPoint = this.getPlayerAmount(sender) + if (nowPoint == prePoint + point) { + return nowPoint + } + Thread.sleep(200) + nowPoint = this.getPlayerAmount(sender) + if (nowPoint == prePoint + point) { + return nowPoint + } + Thread.sleep(300) + nowPoint = this.getPlayerAmount(sender) + return false + } + + private rewardOrder(sender, order_id, point) { + this.taskManager.callSyncMethod(() => { + try { + if (this.config.reward['*']) { + let rewardCommands: string[] = this.config.reward['*'] + for (const command of rewardCommands) { + this.dispatchConsoleCommand(sender, command, point, order_id) + } + } + let rewardCommands: string[] = this.config.reward[point] + if (rewardCommands && rewardCommands.length) { + for (const command of rewardCommands) { + this.dispatchConsoleCommand(sender, command, point, order_id) + } + } + } catch (error) { + console.error('§4充值奖励命令执行错误: §c' + error) + console.ex(error) + } + }) + } + + private dispatchConsoleCommand(sender, command, point, order_id) { + return this.server.dispatchConsoleCommand(command.replace('%player_name%', sender.getName()).replace('%amount%', `${point}`).replace('%remark%', `${order_id}`)) + } + sendError(sender: org.bukkit.entity.Player, order_id: string, amount: number, error: string) { return this.logger.sender(sender, [ `§c========== ${this.config.prefix}§4充值异常 §c==========`, @@ -220,7 +320,7 @@ export class MiaoPay extends interfaces.Plugin { `§6异常原因: §4${error}`, `§6异常账号: §b${sender.getName()}`, `§6异常时间: §a${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`, - `§c如果已付款但${this.config.coinName}未到账 请截图发往QQ群!`, + `§c如果已付款但${this.config.coinName}未到账 请截图发给腐竹!`, `§c========== ${this.config.prefix}§4充值异常 §c==========`, ]) } @@ -228,11 +328,16 @@ export class MiaoPay extends interfaces.Plugin { @Tab() tabmpay() { } + private safeMultiply(a: number, b: number) { + return parseFloat((a * b).toFixed(0)) + } + private getPlayerAmount(sender: any): number { let result = this.PlaceholderAPI.setPlaceholders(sender, this.config.check) let amount = parseFloat(result) if (isNaN(amount)) { - throw new Error(`§c读取玩家 §3${this.config.coinName} §c异常 §6请检查 §3check §6配置是否正确!\n§6数据解析链路: §3${this.config.check} §6=> §3${result} §6=> §3${amount}`) + throw new Error(`§c读取玩家 §3${this.config.coinName} §c异常 §6请检查 §3check §6配置是否正确! +§6数据解析链路: §3${this.config.check} §6=> §3${result} §6=> §3${amount}`) } return amount } @@ -249,12 +354,14 @@ export class MiaoPay extends interfaces.Plugin { return this.httpPost('/finish', { id }) } - private createOrder(sender: org.bukkit.entity.Player, amount: number) { + private createOrder(sender: org.bukkit.entity.Player, amount: number): Order { + let serverName = this.MiaoReward.serverInfo.name + if (this.config.name) { serverName = `${serverName}(${this.config.name})` } let result = this.httpPost('/create', { - subject: `${this.MiaoReward.serverInfo.name} 充值 ${amount} ${this.config.coinName}`, - totalAmount: amount / this.config.ratio, + subject: `${serverName} 充值 ${amount} ${this.config.coinName}`, + amount: amount / this.config.ratio, username: sender.getName(), - union_id: sender.getUniqueId().toString() + unionId: sender.getUniqueId().toString() }) if (result.code != 200) { throw new Error(`订单创建失败: ${result.msg}`) @@ -266,12 +373,16 @@ export class MiaoPay extends interfaces.Plugin { return this.httpPost('/query', { id, username, uuid }) } + private queryUnconverted(username: string, force: number) { + return this.httpPost('/unconverted', { username, force }) + } + private httpPost(method: string, data: any) { let startTime = Date.now() data.appid = this.config.id data.timestamp = Math.round(Date.now() / 1000) data.sign = this.sign(data) - let url = `https://pay.yumc.pw/api${method}` + let url = `${this.apiGateWay}/api${method}` let result = http.post(url, data) console.debug(` ====== HTTP POST ====== diff --git a/packages/plugins/src/MiaoReward.ts b/packages/plugins/src/MiaoReward.ts index 32746a56..fe6bb44c 100644 --- a/packages/plugins/src/MiaoReward.ts +++ b/packages/plugins/src/MiaoReward.ts @@ -12,10 +12,19 @@ const Bytes = Java.type('byte[]') interface PlaceholderAPI { registerPlaceholderHook: (key: string, onPlaceholderRequest: (player, s) => string) => void + registerExpansion: (expansion: PlaceholderExpansion) => void unregisterPlaceholderHook: (key: string) => void setPlaceholders: (player: any, str: string) => string } +interface PlaceholderExpansion { + getIdentifier: () => string + getAuthor: () => string + getVersion: () => string + persist: () => string + onPlaceholderRequest: (player, s) => string +} + interface UserInfo { balance: number sign: string @@ -54,14 +63,15 @@ const defaultConfig = { prefix: '§6[§b广告系统§6]§r', serverId: '', serverToken: '', - drawCommand: 'p give %player_name% %amount%', + drawCommand: 'points give %player_name% %amount%', coinName: '点券', joinTip: true } -@JSPlugin({ prefix: 'MRD', version: '1.5.1', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], nativeDepends: ['ProtocolLib', 'PlaceholderAPI'], source: __filename }) +@JSPlugin({ prefix: 'MRD', version: '1.5.9', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], nativeDepends: ['ProtocolLib', 'PlaceholderAPI'], source: __filename }) export class MiaoReward extends interfaces.Plugin { public serverInfo: ServerInfo + private notifyError = true private cacheBindUuid = '' private zeroMapView = undefined private playerImageCache = new Map() @@ -91,6 +101,9 @@ export class MiaoReward extends interfaces.Plugin { private PlaceholderAPI: PlaceholderAPI @JSClass('me.clip.placeholderapi.PlaceholderHook') private PlaceholderHook: any + @JSClass('me.clip.placeholderapi.expansion.PlaceholderExpansion') + private PlaceholderExpansion: any + private expansion: any @JSClass('com.comphenix.protocol.ProtocolLibrary') private ProtocolLibrary: any @@ -108,11 +121,11 @@ export class MiaoReward extends interfaces.Plugin { load() { this.config.prefix = this.config.prefix || '§6[§b广告系统§6]§r' this.config.drawCommand = this.config.drawCommand || 'p give %player_name% %amount%' - if (!this.config.coinName) { + if (this.config.coinName == undefined) { this.config.coinName = '点券' this.config.save() } - if (!this.config.joinTip) { + if (this.config.joinTip == undefined) { this.config.joinTip = true this.config.save() } @@ -191,21 +204,28 @@ export class MiaoReward extends interfaces.Plugin { if (!this.PlaceholderAPI) { console.console("§cCan't found me.clip.placeholderapi.PlaceholderAPI variable will not be replaced!") } else { - this.PlaceholderAPI.registerPlaceholderHook("mrd", new this.PlaceholderHook({ - onPlaceholderRequest: (player: any, s: string) => { - if (!this.playerInfoCache.has(player.getName())) { return '数据加载中' } - let data = this.playerInfoCache.get(player.getName()) - if (!data) { return '用户未绑定' } - switch (s.toLowerCase()) { - case "balance": return data.balance - case "sign": return data.sign - case "video": return data.video - case "box": return data.box - case "block": return data.block - default: return "未知的参数: " + s - } - } - })) + this.expansion = new this.PlaceholderExpansion({ + getIdentifier: () => 'mrd', + persist: () => true, + getAuthor: () => 'MiaoWoo', + getVersion: () => '1.0.0', + onPlaceholderRequest: this.onPlaceholderRequest.bind(this) + }) + this.taskManager.create(() => this.expansion.register()).submit() + } + } + + private onPlaceholderRequest(player: any, s: string) { + if (!this.playerInfoCache.has(player.getName())) { return '数据加载中' } + let data = this.playerInfoCache.get(player.getName()) + if (!data) { return '用户未绑定' } + switch (s.toLowerCase()) { + case "balance": return data.balance + case "sign": return data.sign + case "video": return data.video + case "box": return data.box + case "block": return data.block + default: return "未知的参数: " + s } } @@ -261,10 +281,19 @@ export class MiaoReward extends interfaces.Plugin { java.util.Arrays.fill(arritemStack, new org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR)) arritemStack[36 + player.getInventory().getHeldItemSlot()] = mapItem var packetContainer = protocolManager.createPacket(this.PacketType.Play.Server.WINDOW_ITEMS) - if (packetContainer.getItemArrayModifier().size() > 0) { + try { packetContainer.getItemArrayModifier().write(0, arritemStack) - } else { - packetContainer.getItemListModifier().write(0, java.util.Arrays.asList(arritemStack)) + } catch (error) { + try { + packetContainer.getItemListModifier().write(0, java.util.Arrays.asList(arritemStack)) + } catch (error) { + if (this.notifyError) { + console.console('§4发送虚拟物品包失败 可能是ProtocolLib版本不兼容!') + console.ex(error) + this.notifyError = false + return + } + } } protocolManager.sendServerPacket(player, packetContainer) } catch (ex) { @@ -273,8 +302,7 @@ export class MiaoReward extends interfaces.Plugin { } disable() { - if (!this.ProtocolLibrary) return - this.PlaceholderAPI?.unregisterPlaceholderHook("mrd") + try { this.expansion?.unregister() } catch (error) { } this.adapter && this.ProtocolLibrary.getProtocolManager().removePacketListener(this.adapter) Java.from(this.server.getOnlinePlayers()).forEach(p => this.checkAndClear(p)) this.channelOff?.off() @@ -420,6 +448,7 @@ export class MiaoReward extends interfaces.Plugin { this.logger.sender(sender, draw.msg.split('\n').map(s => s.replace('点券', this.config.coinName))) this.sendBroadcast(sender, `${this.config.prefix}§6玩家 §b${sender.getName()} §6成功将 §a${amount}喵币 §6兑换成 §c${draw.data}${this.config.coinName}!`) this.sendBroadcast(sender, `${this.config.prefix}§c/mrd help §b查看广告系统帮助 §6快来一起看广告赚${this.config.coinName}吧!`) + this.queryUser(sender) }).submit() } @@ -626,20 +655,7 @@ export class MiaoReward extends interfaces.Plugin { } }, this).async().later(20).timer(20).submit() this.playerTaskCache.set(sender.getName(), task) - if (this.downgrade) { - this.logger.sender(sender, '§c低版本客户端 二维码渲染中 请等待 3 秒 稍候扫码!') - let waitTask = this.taskManager.create(() => { - let temp = sender.getLocation() - temp.setPitch(-90) - sender.teleport(temp) - }, this).later(0).timer(20).submit() - this.taskManager.create(() => { - waitTask.cancel() - let temp = sender.getLocation() - temp.setPitch(90) - sender.teleport(temp) - }).later(80).submit() - } + if (this.downgrade) { this.downgradeTask(sender) } this.playerImageCache.set(sender.getName(), org.bukkit.map.MapPalette.imageToBytes(this.createQrcode(content))) if (!this.downgrade) { let temp = sender.getLocation() @@ -648,9 +664,25 @@ export class MiaoReward extends interfaces.Plugin { } this.sendWindowItems(sender, this.createQrCodeMapItem(name)) sender.sendMap(this.zeroMapView) + this.taskManager.create(() => this.sendWindowItems(sender, this.createQrCodeMapItem(name))).later(20).async().submit() }).submit() } + private downgradeTask(sender) { + this.logger.sender(sender, '§c低版本客户端 二维码渲染中 请等待 3 秒 稍候扫码!') + let waitTask = this.taskManager.create(() => { + let temp = sender.getLocation() + temp.setPitch(-90) + sender.teleport(temp) + }, this).later(0).timer(20).submit() + this.taskManager.create(() => { + waitTask.cancel() + let temp = sender.getLocation() + temp.setPitch(90) + sender.teleport(temp) + }).later(80).submit() + } + private queryUser(sender: org.bukkit.entity.Player, sync = false) { if (!this.serverInfo) { return this.logger.sender(sender, '§4当前服务器尚未配置绑定ID 请联系腐竹进行配置!') } let result = this.httpPost(`https://reward.yumc.pw/server/queryUser`, { diff --git a/packages/plugins/src/MiaoRobot.ts b/packages/plugins/src/MiaoRobot.ts index 3c4bd5ca..6612333b 100644 --- a/packages/plugins/src/MiaoRobot.ts +++ b/packages/plugins/src/MiaoRobot.ts @@ -32,10 +32,6 @@ export class MiaoRobot extends interfaces.Plugin { } enable() { - if (!this.config.address || !this.config.token) { - return this.logger - } - this.cmdconnect(this.server.getConsoleSender(), this.config.address, this.config.token) } disable() { @@ -46,13 +42,10 @@ export class MiaoRobot extends interfaces.Plugin { mbot() { } cmdconnect(sender: org.bukkit.entity.Player, address: string = this.config.address, token: string = this.config.token) { - if (this.client && this.client.readyState == WebSocket.OPEN) { - this.client.close() - this.client = undefined - } if (!address || !token) { return this.logger.sender(sender, '§4错误 请配置服务器地址和Token!') } + this.cmdclose(sender) try { this.client = new WebSocket(address, '', { Authorization: `Bearer ${token}` }) this.initRobot(this.client) @@ -83,7 +76,7 @@ export class MiaoRobot extends interfaces.Plugin { } cmdclose(sender: org.bukkit.entity.Player) { - if (this.client) { + if (this.client && this.client.readyState != WebSocket.CLOSED) { this.client.close(0, 'plugin close socket') } } diff --git a/packages/plugins/src/MiaoScriptPackageManager.ts b/packages/plugins/src/MiaoScriptPackageManager.ts index fe542c07..55b5b971 100644 --- a/packages/plugins/src/MiaoScriptPackageManager.ts +++ b/packages/plugins/src/MiaoScriptPackageManager.ts @@ -11,8 +11,9 @@ let help = [ '§6========= §6[§aMiaoScriptPackageManager§6] 帮助 §aBy §bMiaoWoo §6=========', '§6/mspm §ainstall §e<插件名称> §6- §3安装仓库插件', '§6/mspm §aload §e<插件名称> §6- §3安装本地插件', - '§6/mspm §aunload §e<插件名称> §6- §3卸载已安装插件', + '§6/mspm §cunload §e<插件名称> §6- §3卸载已安装插件', '§6/mspm §areload §e<插件名称> §6- §3重载已安装插件(无名称则重载自身)', + '§6/mspm §cdelete §e<插件名称> §6- §3删除已安装插件', '§6/mspm §alist [i] §6- §3列出仓库插件[已安装的插件]', '§6/mspm §aupdate §e[插件名称] §6- §3更新插件(无名称则更新源)', '§6/mspm §aupgrade §e[插件名称|system] §6- §3升级插件/§4框架(§csystem§3)', @@ -44,7 +45,7 @@ let langMap = { 'plugin.name.empty': '§c请输入插件名称!', 'cloud.update.finish': '§6成功从 §aMiaoScriptPackageCenter §6获取到 §a{length} §6个插件!', 'cloud.not.exists': '§6当前 §aMiaoScriptPackageCenter §c不存在 §a{name} §c插件!', - 'cloud.update.exists': '§6插件 §b{name} §a发现新版本 §3{new_version} §6当前版本 §3{old_version}!', + 'cloud.update.exists': '§6插件 §b{name} §6版本 §3{old_version} §a发现更新 §3{new_version} §r{changelog}§6!', 'download.start': '§6开始下载插件: §b{name} §6版本 §3{version}', 'download.url': '§6插件下载地址: §b{url}', 'download.finish': '§6插件 §b{name} §6版本 §3{version} §a下载完毕 开始加载 ...', @@ -106,7 +107,7 @@ class SpongeFakeSender extends FakeSender { } } -@JSPlugin({ prefix: 'PM', version: '1.3.1', author: 'MiaoWoo', source: __filename }) +@JSPlugin({ prefix: 'PM', version: '1.3.2', author: 'MiaoWoo', source: __filename }) export class MiaoScriptPackageManager extends interfaces.Plugin { @Autowired() private pluginManager: pluginApi.PluginManager @@ -332,6 +333,8 @@ export class MiaoScriptPackageManager extends interfaces.Plugin { try { this.i18n(sender, 'upgrade.start') base.delete(enginePath) + // @ts-ignore + require.setUpgradeMode?.(true) this.cmdrestart(sender) } catch (ex) { if (global.debug) { @@ -359,6 +362,15 @@ export class MiaoScriptPackageManager extends interfaces.Plugin { } } + cmddelete(sender: any, name: string) { + if (this.checkPlugin(sender, name)) { + let plugin = this.pluginManager.getPlugins().get(name) + this.i18n(sender, 'plugin.delete.start', { name, version: plugin.description.version }) + base.delete(plugin.description.source) + this.i18n(sender, 'plugin.delete.finish', { name, version: plugin.description.version }) + } + } + cmdreload(sender: any, name: string) { name = name || this.description.name this.reload(sender, name) @@ -517,7 +529,12 @@ return eval(${JSON.stringify(code)});`) let cloudPlugin = this.packageCache[p.description.name] //§6插件名称: §b{name}\n§6版本: §a{version}\n§6作者: §3{author}\§6更新时间: §9{updated_at} if (cloudPlugin && cloudPlugin.version != p.description.version) { - this.i18n(sender, 'cloud.update.exists', { name: p.description.name, new_version: cloudPlugin.version, old_version: p.description.version }) + this.i18n(sender, 'cloud.update.exists', { + name: p.description.name, + new_version: cloudPlugin.version, + old_version: p.description.version, + changelog: cloudPlugin.changelog || '' + }) } }) }).async().submit()