feat: backup plugins
This commit is contained in:
		
							
								
								
									
										104
									
								
								packages/plugins/src/MiaoCoin.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								packages/plugins/src/MiaoCoin.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
import { constants, task, server, channel } from "@ccms/api"
 | 
			
		||||
import { JSPlugin, interfaces, Cmd, Tab, Listener, Config } from "@ccms/plugin"
 | 
			
		||||
 | 
			
		||||
import { QRCode, QRErrorCorrectLevel } from '@ccms/common/dist/qrcode'
 | 
			
		||||
 | 
			
		||||
import { inject, JSClass, optional } from '@ccms/container'
 | 
			
		||||
import http from '@ccms/common/dist/http'
 | 
			
		||||
import chat from '@ccms/bukkit/dist/enhance/chat'
 | 
			
		||||
 | 
			
		||||
const MapView = Java.type('org.bukkit.map.MapView')
 | 
			
		||||
const Bukkit = Java.type('org.bukkit.Bukkit')
 | 
			
		||||
const MapRenderer = Java.type('org.bukkit.map.MapRenderer')
 | 
			
		||||
const ItemStack = Java.type('org.bukkit.inventory.ItemStack')
 | 
			
		||||
const Material = Java.type('org.bukkit.Material')
 | 
			
		||||
 | 
			
		||||
const BufferedImage = Java.type('java.awt.image.BufferedImage')
 | 
			
		||||
const Graphics2D = Java.type('java.awt.Graphics2D')
 | 
			
		||||
const Color = Java.type('java.awt.Color')
 | 
			
		||||
const Image = Java.type('java.awt.Image')
 | 
			
		||||
const Font = Java.type('java.awt.Font')
 | 
			
		||||
const RenderingHints = Java.type('java.awt.RenderingHints')
 | 
			
		||||
 | 
			
		||||
class QRCodeRender {
 | 
			
		||||
    private _proxy
 | 
			
		||||
    constructor(image: any) {
 | 
			
		||||
        const ProxyAdapter = Java.extend(MapRenderer, {
 | 
			
		||||
            render: (_mapView, mapCanvas) => {
 | 
			
		||||
                mapCanvas.drawImage(0, 0, image)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        this._proxy = new ProxyAdapter()
 | 
			
		||||
    }
 | 
			
		||||
    getHandler() {
 | 
			
		||||
        return this._proxy
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface PlaceholderAPI {
 | 
			
		||||
    registerPlaceholderHook: (key: string, onPlaceholderRequest: (player, s) => string) => void
 | 
			
		||||
    setPlaceholders: (player: any, str: string) => string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ version: '1.0.0', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], source: __filename })
 | 
			
		||||
export class MiaoCoin extends interfaces.Plugin {
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private server: server.Server
 | 
			
		||||
    @inject(task.TaskManager)
 | 
			
		||||
    private taskManager: task.TaskManager
 | 
			
		||||
 | 
			
		||||
    @JSClass('me.clip.placeholderapi.PlaceholderAPI')
 | 
			
		||||
    private PlaceholderAPI: PlaceholderAPI
 | 
			
		||||
    @JSClass('me.clip.placeholderapi.PlaceholderHook')
 | 
			
		||||
    private PlaceholderHook: any
 | 
			
		||||
 | 
			
		||||
    @Config()
 | 
			
		||||
    private config = {
 | 
			
		||||
        MySQL: {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
        if (!this.PlaceholderAPI) {
 | 
			
		||||
            console.console("§cCan't found me.clip.placeholderapi.PlaceholderAPI variable will not be replaced!")
 | 
			
		||||
        } else {
 | 
			
		||||
            this.PlaceholderAPI.registerPlaceholderHook("mcn", new this.PlaceholderHook({
 | 
			
		||||
                onPlaceholderRequest: (player: any, s: string) => {
 | 
			
		||||
                    switch (s.toLowerCase()) {
 | 
			
		||||
                        case "has":
 | 
			
		||||
                            return ''
 | 
			
		||||
                        case "add":
 | 
			
		||||
                            return ''
 | 
			
		||||
                        case "remove":
 | 
			
		||||
                            return ''
 | 
			
		||||
                        default:
 | 
			
		||||
                    }
 | 
			
		||||
                    return `未知的参数: ${s}`
 | 
			
		||||
                }
 | 
			
		||||
            }))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd()
 | 
			
		||||
    mrd(sender: any, command: string, args: string[]) {
 | 
			
		||||
        let cmd = args[0] || 'help'
 | 
			
		||||
        let cmdKey = 'cmd' + cmd
 | 
			
		||||
        if (!this[cmdKey]) {
 | 
			
		||||
            console.sender(sender, '§4未知的子命令: §c' + cmd)
 | 
			
		||||
            console.sender(sender, `§6请执行 §b/${command} §ahelp §6查看帮助!`)
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        args.shift()
 | 
			
		||||
        this.taskManager.create(() => this[cmdKey](sender, ...args)).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Tab()
 | 
			
		||||
    tabmrd(sender: any, _command: any, args: string | any[]) {
 | 
			
		||||
        if (args.length === 1) return ['help', 'bind', 'show', 'query', 'draw', "ratio"]
 | 
			
		||||
        if (args.length === 2 && args[0] === "bind" && sender.isOp()) return ['server']
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								packages/plugins/src/MiaoGUI.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								packages/plugins/src/MiaoGUI.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
import { constants, channel, server } from "@ccms/api"
 | 
			
		||||
import { JSPlugin, interfaces, Cmd, Tab } from "@ccms/plugin"
 | 
			
		||||
import { inject, optional } from '@ccms/container'
 | 
			
		||||
 | 
			
		||||
const StandardCharsets = Java.type('java.nio.charset.StandardCharsets')
 | 
			
		||||
const JavaString = Java.type('java.lang.String')
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], source: __filename })
 | 
			
		||||
export class MiaoGUI extends interfaces.Plugin {
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private server: server.Server
 | 
			
		||||
    @inject(channel.Channel)
 | 
			
		||||
    @optional()
 | 
			
		||||
    private channel: channel.Channel
 | 
			
		||||
 | 
			
		||||
    private CHANNEL_NAME = `${MiaoGUI.name}:NORMAL`.toLowerCase();
 | 
			
		||||
    private channelOff: { off: () => void }
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
        this.channelOff = this.channel?.listen(this, this.CHANNEL_NAME, (data) => {
 | 
			
		||||
            this.logger.info('MiaoGUI', new JavaString(data))
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
        this.channelOff?.off()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd()
 | 
			
		||||
    mgui(sender: any, command: string, args: string[]) {
 | 
			
		||||
        let cmd = args[0] || 'help'
 | 
			
		||||
        let cmdKey = 'cmd' + cmd
 | 
			
		||||
        if (!this[cmdKey]) {
 | 
			
		||||
            console.sender(sender, '§4未知的子命令: §c' + cmd)
 | 
			
		||||
            console.sender(sender, `§6请执行 §b/${command} §ahelp §6查看帮助!`)
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        args.shift()
 | 
			
		||||
        this[cmdKey](sender, ...args)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdhhelp(sender: any) {
 | 
			
		||||
        this.logger.sender(sender, '')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdrun(sender: any, ...args: string[]) {
 | 
			
		||||
        this.send(sender, "run", { cmd: args.join(' ') })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdconfig(sender: org.bukkit.entity.Player) {
 | 
			
		||||
        this.send(sender, "config")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdopen(sender: any, name: string) {
 | 
			
		||||
        this.send(sender, "open", { name })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdopenfor(sender: any, target: string, name: string) {
 | 
			
		||||
        let player = this.server.getPlayer(target)
 | 
			
		||||
        if (!player) { return this.logger.sender(sender, `§c玩家 ${target} 不在线或不存在!`) }
 | 
			
		||||
        this.send(player, "open", { name })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdadd(sender: any, type: string, ...param: string[]) {
 | 
			
		||||
        if (!type) return this.logger.sender(sender, '§c组件类型不得为空!')
 | 
			
		||||
        this.send(sender, "add", { type, param })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdclear(sender: org.bukkit.entity.Player) {
 | 
			
		||||
        this.send(sender, "clear")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Tab()
 | 
			
		||||
    tabmgui(args: string[]) {
 | 
			
		||||
        if (args.length == 1) return ['open', 'openfor', 'config', 'add', 'clear']
 | 
			
		||||
        if (args.length == 2) {
 | 
			
		||||
            switch (args[0]) {
 | 
			
		||||
                case "add":
 | 
			
		||||
                    return ['text', 'image', 'broadcast']
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private send(target: any, type: string, data: any = {}) {
 | 
			
		||||
        this.channel?.send(target, this.CHANNEL_NAME, new JavaString(JSON.stringify({ type, data })).getBytes(StandardCharsets.UTF_8))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										498
									
								
								packages/plugins/src/MiaoReward.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								packages/plugins/src/MiaoReward.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,498 @@
 | 
			
		||||
import { constants, task, server, channel } from "@ccms/api"
 | 
			
		||||
import { JSPlugin, interfaces, Cmd, Tab, Listener, Config } from "@ccms/plugin"
 | 
			
		||||
 | 
			
		||||
import { QRCode, QRErrorCorrectLevel } from '@ccms/common/dist/qrcode'
 | 
			
		||||
 | 
			
		||||
import { inject, JSClass, optional } from '@ccms/container'
 | 
			
		||||
import http from '@ccms/common/dist/http'
 | 
			
		||||
import chat from '@ccms/bukkit/dist/enhance/chat'
 | 
			
		||||
 | 
			
		||||
const MapView = Java.type('org.bukkit.map.MapView')
 | 
			
		||||
const Bukkit = Java.type('org.bukkit.Bukkit')
 | 
			
		||||
const MapRenderer = Java.type('org.bukkit.map.MapRenderer')
 | 
			
		||||
const ItemStack = Java.type('org.bukkit.inventory.ItemStack')
 | 
			
		||||
const Material = Java.type('org.bukkit.Material')
 | 
			
		||||
 | 
			
		||||
const BufferedImage = Java.type('java.awt.image.BufferedImage')
 | 
			
		||||
const Graphics2D = Java.type('java.awt.Graphics2D')
 | 
			
		||||
const Color = Java.type('java.awt.Color')
 | 
			
		||||
const Image = Java.type('java.awt.Image')
 | 
			
		||||
const Font = Java.type('java.awt.Font')
 | 
			
		||||
const RenderingHints = Java.type('java.awt.RenderingHints')
 | 
			
		||||
 | 
			
		||||
class QRCodeRender {
 | 
			
		||||
  private _proxy
 | 
			
		||||
  constructor(image: any) {
 | 
			
		||||
    const ProxyAdapter = Java.extend(MapRenderer, {
 | 
			
		||||
      render: (_mapView, mapCanvas) => {
 | 
			
		||||
        mapCanvas.drawImage(0, 0, image)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    this._proxy = new ProxyAdapter()
 | 
			
		||||
  }
 | 
			
		||||
  getHandler() {
 | 
			
		||||
    return this._proxy
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface PlaceholderAPI {
 | 
			
		||||
  registerPlaceholderHook: (key: string, onPlaceholderRequest: (player, s) => string) => void
 | 
			
		||||
  setPlaceholders: (player: any, str: string) => string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ prefix: 'MRD', version: '1.1.0', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], source: __filename })
 | 
			
		||||
export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
  private cacheBindUuid = ''
 | 
			
		||||
  private cacheTasks = new Map<number, task.Cancelable>()
 | 
			
		||||
  private isBinding = false
 | 
			
		||||
  private isBindingUser = 'unknow'
 | 
			
		||||
  private drawCooldown = new Map<string, number>()
 | 
			
		||||
 | 
			
		||||
  @inject(server.Server)
 | 
			
		||||
  private server: server.Server
 | 
			
		||||
  @inject(task.TaskManager)
 | 
			
		||||
  private taskManager: task.TaskManager
 | 
			
		||||
  @inject(channel.Channel)
 | 
			
		||||
  @optional() private Channel: channel.Channel
 | 
			
		||||
 | 
			
		||||
  @Config()
 | 
			
		||||
  private config = {
 | 
			
		||||
    prefix: '§6[§b广告系统§6]§r',
 | 
			
		||||
    serverId: '',
 | 
			
		||||
    serverToken: '',
 | 
			
		||||
    drawCommand: 'p give %player_name% %amount%',
 | 
			
		||||
    drawCooldown: 300
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @JSClass('me.clip.placeholderapi.PlaceholderAPI')
 | 
			
		||||
  private PlaceholderAPI: PlaceholderAPI
 | 
			
		||||
  @JSClass('me.clip.placeholderapi.PlaceholderHook')
 | 
			
		||||
  private PlaceholderHook: any
 | 
			
		||||
 | 
			
		||||
  private isBungeeCord = undefined
 | 
			
		||||
  private channelOff: { off: () => void }
 | 
			
		||||
 | 
			
		||||
  load() {
 | 
			
		||||
    this.config.prefix = this.config.prefix || '§6[§b广告系统§6]§r'
 | 
			
		||||
    this.config.drawCommand = this.config.drawCommand || 'p give %player_name% %amount%'
 | 
			
		||||
    this.config.drawCooldown = this.config.drawCooldown || 300
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  enable() {
 | 
			
		||||
    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) => {
 | 
			
		||||
          switch (s.toLowerCase()) {
 | 
			
		||||
            case "server":
 | 
			
		||||
            case "bserver":
 | 
			
		||||
            default:
 | 
			
		||||
          }
 | 
			
		||||
          return "未知的参数"
 | 
			
		||||
        }
 | 
			
		||||
      }))
 | 
			
		||||
    }
 | 
			
		||||
    this.channelOff = this.Channel?.listen(this, 'BungeeCord', (data) => { this.isBungeeCord = true })
 | 
			
		||||
    let players = this.server.getOnlinePlayers()
 | 
			
		||||
    if (players.length) this.bungeeCordDetect(players[0])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  disable() {
 | 
			
		||||
    this.cacheTasks.forEach(t => t.cancel())
 | 
			
		||||
    this.server.getOnlinePlayers().forEach(p => this.checkAndClear(p))
 | 
			
		||||
    this.channelOff?.off()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Cmd()
 | 
			
		||||
  mrd(sender: any, command: string, args: string[]) {
 | 
			
		||||
    let cmd = args[0] || 'help'
 | 
			
		||||
    let cmdKey = 'cmd' + cmd
 | 
			
		||||
    if (!this[cmdKey]) {
 | 
			
		||||
      console.sender(sender, '§4未知的子命令: §c' + cmd)
 | 
			
		||||
      console.sender(sender, `§6请执行 §b/${command} §ahelp §6查看帮助!`)
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    args.shift()
 | 
			
		||||
    this.taskManager.create(() => this[cmdKey](sender, ...args)).async().submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdbind(sender: org.bukkit.entity.Player, server: boolean) {
 | 
			
		||||
    if (this.isBinding) {
 | 
			
		||||
      let bindUser = Bukkit.getPlayerExact(this.isBindingUser)
 | 
			
		||||
      if (bindUser && bindUser.isOnline() && this.isQrCodeItem(bindUser.getItemInHand())[0]) {
 | 
			
		||||
        return this.logger.sender(sender, "§c当前 §a" + this.isBindingUser + " §c玩家正在绑定账号 请稍候重试...")
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (sender.getItemInHand()?.getType() !== Material.AIR) { return this.logger.sender(sender, "§c请空手执行此命令!") }
 | 
			
		||||
    this.isBinding = true
 | 
			
		||||
    this.isBindingUser = sender.getDisplayName() || sender.getName()
 | 
			
		||||
    if (server) {
 | 
			
		||||
      if (!sender.isOp()) { return this.logger.sender(sender, '§4您没有配置服务器的权限!') }
 | 
			
		||||
      this.bindServer(sender)
 | 
			
		||||
    } else {
 | 
			
		||||
      this.bindUser(sender)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmddraw(sender: org.bukkit.entity.Player, amount: number) {
 | 
			
		||||
    if (this.drawCooldown.has(sender.getName())) {
 | 
			
		||||
      let leftTime = this.config.drawCooldown - (Date.now() - this.drawCooldown.get(sender.getName())) / 1000
 | 
			
		||||
      if (leftTime > 0) {
 | 
			
		||||
        return this.logger.sender(sender, `§c点券兑换冷却中 剩余 ${leftTime} 秒!`)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    amount = Number(amount)
 | 
			
		||||
    if (!Number.isInteger(amount)) {
 | 
			
		||||
      return this.logger.sender(sender, '§4金额必须是数字!')
 | 
			
		||||
    }
 | 
			
		||||
    if (amount % 100 !== 0) {
 | 
			
		||||
      return this.logger.sender(sender, '§4金额必须是100倍数!')
 | 
			
		||||
    }
 | 
			
		||||
    let address = `https://reward.yumc.pw/server/draw/id/${this.config.serverId}/token/${this.config.serverToken}/uuid/${sender.getUniqueId().toString()}/username/${sender.getName()}/amount/${amount}`
 | 
			
		||||
    let draw = http.get(address)
 | 
			
		||||
    if (draw.code !== 200) {
 | 
			
		||||
      return this.sendError(sender, `§4兑换异常 §6服务器返回: §c${draw.msg}`)
 | 
			
		||||
    }
 | 
			
		||||
    let drawAmount = draw.data
 | 
			
		||||
    if (!drawAmount) {
 | 
			
		||||
      return this.sendError(sender, '§c服务器返回金额 ' + draw.data + ' 可能存在异常')
 | 
			
		||||
    }
 | 
			
		||||
    let command = `p give ${sender.getName()} ${draw.data}`
 | 
			
		||||
    if (!this.server.dispatchConsoleCommand(command)) {
 | 
			
		||||
      return this.sendError(sender, '§6执行命令 §3/' + command + ' §c可能存在异常')
 | 
			
		||||
    }
 | 
			
		||||
    this.logger.sender(sender, draw.msg.split('\n'))
 | 
			
		||||
    this.drawCooldown.set(sender.getName(), Date.now())
 | 
			
		||||
    this.sendBoardcast(sender, `${this.config.prefix}§6玩家 §b${sender.getName()} §6成功将 §a${amount}喵币 §6兑换成 §c${draw.data}点券!`)
 | 
			
		||||
    this.sendBoardcast(sender, `${this.config.prefix}§c/mrd help §b查看广告系统帮助 §6快来一起看广告赚点券吧!`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private sendError(sender, error) {
 | 
			
		||||
    return this.logger.sender(sender, [
 | 
			
		||||
      `§c========== ${this.config.prefix}§4兑换异常 §c==========`,
 | 
			
		||||
      error,
 | 
			
		||||
      `§6异常账号: §b${sender.getName()}`,
 | 
			
		||||
      `§6异常时间: §a${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`,
 | 
			
		||||
      `§c如果喵币被扣除且未得到奖励 请截图发往QQ群!`,
 | 
			
		||||
      `§c========== ${this.config.prefix}§4兑换异常 §c==========`,
 | 
			
		||||
    ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdrank(sender: any, boardcast: boolean) {
 | 
			
		||||
    if (!sender.isOp()) { return this.logger.sender(sender, '§4你没有此命令的权限!') }
 | 
			
		||||
    let result = http.get(`https://reward.yumc.pw/server/rank/id/${this.config.serverId}/token/${this.config.serverToken}`)
 | 
			
		||||
    if (result.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, `§c今日未查询到数据!`)
 | 
			
		||||
    }
 | 
			
		||||
    let ranks = [
 | 
			
		||||
      `§6====== ${this.config.prefix} §a喵币兑换排行 §6======`,
 | 
			
		||||
      ...result.data.map((e, i) => `§6${i + 1}. §a${e.username} §6兑换 §3${e.count} §6次 §c${e.amount} §6喵币`),
 | 
			
		||||
      `§6====== ${this.config.prefix} §a喵币兑换排行 §6======`,
 | 
			
		||||
    ]
 | 
			
		||||
    if (boardcast) {
 | 
			
		||||
      ranks.forEach(l => this.sendBoardcast(sender, l))
 | 
			
		||||
    } else {
 | 
			
		||||
      this.logger.sender(sender, ranks)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdserver(sender: any) {
 | 
			
		||||
    if (!sender.isOp()) { return this.logger.sender(sender, '§4你没有此命令的权限!') }
 | 
			
		||||
    let result = http.get(`https://reward.yumc.pw/server/server/id/${this.config.serverId}/token/${this.config.serverToken}`)
 | 
			
		||||
    if (result.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, `§4操作异常 §6服务器返回: §c${result.msg}`)
 | 
			
		||||
    }
 | 
			
		||||
    this.logger.sender(sender, [
 | 
			
		||||
      `§6====== ${this.config.prefix} §a服务器信息 §6======`,
 | 
			
		||||
      `§6服务器: §a${result.data.name}`,
 | 
			
		||||
      `§6喵币余额: §b${result.data.score} §6喵币`,
 | 
			
		||||
      `§6喵币比例: §b${result.data.ratio}`,
 | 
			
		||||
      `§6今日收入: §b${result.data.today} §6喵币`,
 | 
			
		||||
      `§6====== ${this.config.prefix} §a服务器信息 §6======`,
 | 
			
		||||
    ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdratio(sender: any, ratio: number, confirm: string) {
 | 
			
		||||
    if (!sender.isOp()) { return this.logger.sender(sender, '§4你没有此命令的权限!') }
 | 
			
		||||
    let mbr = (1 / ratio).toFixed(4)
 | 
			
		||||
    if (!confirm) {
 | 
			
		||||
      return this.logger.sender(sender, [
 | 
			
		||||
        '§4警告: 您正在设置服务器喵币/点券兑换比例 设置后将实时生效!',
 | 
			
		||||
        `§6您设置的兑换比例为 §c${ratio} §6=> §a${mbr}喵币 §6兑换 §c1点券`,
 | 
			
		||||
        `§6玩家至少需要 §a${mbr}喵币 §6才可以兑换点券!`,
 | 
			
		||||
        `§6请执行 §b/mrd ratio §c${ratio} §econfirm §c确认修改!`
 | 
			
		||||
      ])
 | 
			
		||||
    }
 | 
			
		||||
    if (confirm != 'confirm') return this.logger.sender(sender, `§6请执行 §b/mrd ratio §c${ratio} §econfirm §c确认修改!`)
 | 
			
		||||
    let result = http.get(`https://reward.yumc.pw/server/ratio/id/${this.config.serverId}/token/${this.config.serverToken}/ratio/${ratio}`)
 | 
			
		||||
    if (result.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, `§4操作异常 §6服务器返回: §c${result.msg}`)
 | 
			
		||||
    }
 | 
			
		||||
    this.logger.sender(sender, `§a操作成功 §6服务器返回: §a${result.msg}`)
 | 
			
		||||
    this.sendBoardcast(sender, `${this.config.prefix} §6当前兑换比例已调整为 §c${ratio} §6=> §a${mbr}喵币 §6兑换 §c1点券!`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @JSClass('java.io.ByteArrayOutputStream')
 | 
			
		||||
  private ByteArrayOutputStream
 | 
			
		||||
  @JSClass('java.io.DataOutputStream')
 | 
			
		||||
  private DataOutputStream
 | 
			
		||||
 | 
			
		||||
  private sendBoardcast(player, message) {
 | 
			
		||||
    if (!this.isBungeeCord) { return org.bukkit.Bukkit.broadcastMessage(message) }
 | 
			
		||||
    let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
    let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
    out.writeUTF("Message")
 | 
			
		||||
    out.writeUTF("ALL")
 | 
			
		||||
    out.writeUTF(message)
 | 
			
		||||
    player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private bindServer(sender: org.bukkit.entity.Player) {
 | 
			
		||||
    let scanObj = http.get(`https://reward.yumc.pw/server/scan`)
 | 
			
		||||
    if (scanObj.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, '§c获取服务器绑定码失败! Error: ' + scanObj.msg)
 | 
			
		||||
    }
 | 
			
		||||
    this.cacheBindUuid = scanObj.data.uuid
 | 
			
		||||
    this.setItemAndTp(sender, scanObj.data.url, () => {
 | 
			
		||||
      let check = http.get(`https://reward.yumc.pw/server/check/token/${this.cacheBindUuid}`)
 | 
			
		||||
      if (check.code == 200) {
 | 
			
		||||
        this.config.serverId = check.data.serverId
 | 
			
		||||
        this.config.serverToken = check.data.serverToken
 | 
			
		||||
        // @ts-ignore
 | 
			
		||||
        this.config.save()
 | 
			
		||||
        this.checkAndClear(sender)
 | 
			
		||||
        this.logger.sender(sender, '§a已成功绑定服务器: §b' + check.data.serverName)
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private bindUser(sender: org.bukkit.entity.Player) {
 | 
			
		||||
    if (!this.config.serverId || !this.config.serverToken) { return this.logger.sender(sender, '§4当前服务器尚未配置绑定ID 请联系腐竹进行配置!') }
 | 
			
		||||
    let check = http.get(`https://reward.yumc.pw/server/query?id=${this.config.serverId}&token=${this.config.serverToken}`)
 | 
			
		||||
    if (check.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, '§4获取绑定参数异常! §cError: ' + check.msg)
 | 
			
		||||
    }
 | 
			
		||||
    let queryUser = this.queryUser(sender)
 | 
			
		||||
    if (queryUser.code == 200) {
 | 
			
		||||
      return this.logger.sender(sender, ['§4当前用户已绑定! §c如需解绑 请联系腐竹!', '§b如需看广告请进QQ群 点击聊天框上的圈云盒子!'])
 | 
			
		||||
    }
 | 
			
		||||
    let bindUrl = 'https://m.q.qq.com/a/p/1110360279?s=' + encodeURIComponent(`pages/my/index?bindType=user&serverId=${this.config.serverId}&uuid=${sender.getUniqueId().toString()}&username=${sender.getName()}`)
 | 
			
		||||
    this.setItemAndTp(sender, bindUrl, () => {
 | 
			
		||||
      let queryUser = this.queryUser(sender)
 | 
			
		||||
      if (queryUser.code == 200) {
 | 
			
		||||
        this.sendResult(sender, '绑定成功', queryUser.data)
 | 
			
		||||
        this.checkAndClear(sender)
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private setItemAndTp(sender: org.bukkit.entity.Player, content: string, func: () => boolean) {
 | 
			
		||||
    this.taskManager.create(() => {
 | 
			
		||||
      let [id, item] = this.createQrCodeMapItem(content)
 | 
			
		||||
      let times = 0
 | 
			
		||||
      let task = this.taskManager.create(() => {
 | 
			
		||||
        chat.send(sender, JSON.stringify({
 | 
			
		||||
          text: '§c§l请使用手机QQ扫描二维码绑定!'
 | 
			
		||||
        }), 2)
 | 
			
		||||
        if (func() || !sender.isOnline()) {
 | 
			
		||||
          task.cancel()
 | 
			
		||||
          this.cacheTasks.delete(id)
 | 
			
		||||
          this.isBinding = false
 | 
			
		||||
        }
 | 
			
		||||
        if (times++ > 120) {
 | 
			
		||||
          this.logger.sender(sender, '§c绑定超时!')
 | 
			
		||||
          this.checkAndClear(sender)
 | 
			
		||||
          task.cancel()
 | 
			
		||||
          this.cacheTasks.delete(id)
 | 
			
		||||
          this.isBinding = false
 | 
			
		||||
        }
 | 
			
		||||
      }).async().later(20).timer(20).submit()
 | 
			
		||||
      this.cacheTasks.set(id, task)
 | 
			
		||||
      sender.setItemInHand(item)
 | 
			
		||||
      let temp = sender.getLocation()
 | 
			
		||||
      temp.setPitch(90)
 | 
			
		||||
      sender.teleport(temp)
 | 
			
		||||
    }).submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private queryUser(sender: org.bukkit.entity.Player) {
 | 
			
		||||
    return http.get(`https://reward.yumc.pw/server/queryUser/id/${this.config.serverId}/token/${this.config.serverToken}/uuid/${sender.getUniqueId().toString()}/username/${sender.getName()}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdquery(sender: org.bukkit.entity.Player) {
 | 
			
		||||
    let check = this.queryUser(sender)
 | 
			
		||||
    if (check.code !== 200) {
 | 
			
		||||
      return this.logger.sender(sender, '§4查询异常! §cError: ' + check.msg)
 | 
			
		||||
    }
 | 
			
		||||
    this.sendResult(sender, '查询结果', check.data)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private sendResult(sender: any, title: string, data: any) {
 | 
			
		||||
    this.logger.sender(sender, [
 | 
			
		||||
      `§6====== ${this.config.prefix} §a${title} §6======`,
 | 
			
		||||
      `§6用 户 名: §a${sender.getName()}`,
 | 
			
		||||
      `§6U U I D: §b${sender.getUniqueId().toString()}`,
 | 
			
		||||
      `§6喵    币: §b${data.balance}`,
 | 
			
		||||
      `§6签    到: §b${data.sign}`,
 | 
			
		||||
      `§6视频广告: §b${data.video}`,
 | 
			
		||||
      `§6盒子广告: §b${data.box}`,
 | 
			
		||||
      '§6==========================='
 | 
			
		||||
    ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private createQrCodeMapItem(contents: string): [number, any] {
 | 
			
		||||
    let view = Bukkit.createMap(Bukkit.getWorlds()[0])
 | 
			
		||||
    view.setScale(MapView.Scale.FARTHEST)
 | 
			
		||||
    view.getRenderers().forEach(r => view.removeRenderer(r))
 | 
			
		||||
    view.addRenderer(new QRCodeRender(this.createQrcode(contents)).getHandler())
 | 
			
		||||
    let item: org.bukkit.inventory.ItemStack = new ItemStack(Material.MAP)
 | 
			
		||||
    let meta = item.getItemMeta()
 | 
			
		||||
    meta.setDisplayName('§c请使用手机QQ扫描二维码绑定!')
 | 
			
		||||
    meta.setLore(["QRCODE"])
 | 
			
		||||
    item.setDurability(view.getId())
 | 
			
		||||
    item.setItemMeta(meta)
 | 
			
		||||
    return [view.getId(), item]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private createQrcode(contents: string) {
 | 
			
		||||
    let bufferedImage = new BufferedImage(128, 128, BufferedImage.TYPE_INT_RGB)
 | 
			
		||||
    let graphics2D = bufferedImage.getGraphics()
 | 
			
		||||
    graphics2D.setPaint(Color.WHITE)
 | 
			
		||||
    graphics2D.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight())
 | 
			
		||||
    let qrcode = this.js2qr(contents)
 | 
			
		||||
    let startPoint = Math.round((bufferedImage.getWidth() - qrcode.getWidth()) / 2)
 | 
			
		||||
    graphics2D.drawImage(qrcode, startPoint, startPoint, null)
 | 
			
		||||
    // let font = new Font("DejaVuSans", Font.PLAIN, 10)
 | 
			
		||||
    // graphics2D.setFont(font)
 | 
			
		||||
    // let fm = graphics2D.getFontMetrics(font)
 | 
			
		||||
    // let text = "Use QQ Scan Bind!"
 | 
			
		||||
    // let textWidth = fm.stringWidth(text)
 | 
			
		||||
    // let widthX = (128 - textWidth) / 2
 | 
			
		||||
    // graphics2D.setColor(Color.BLACK)
 | 
			
		||||
    // graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB)
 | 
			
		||||
    // graphics2D['drawString(java.lang.String, int, int)'](text, Math.round(widthX), 122)
 | 
			
		||||
    graphics2D.dispose()
 | 
			
		||||
    return bufferedImage
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private js2qr(contents: string) {
 | 
			
		||||
    let qrcode = new QRCode(14, QRErrorCorrectLevel.H)
 | 
			
		||||
    qrcode.addData(contents)
 | 
			
		||||
    qrcode.make()
 | 
			
		||||
    let length = qrcode.getModuleCount()
 | 
			
		||||
    let image: java.awt.image.BufferedImage = new BufferedImage(length, length, BufferedImage.TYPE_INT_RGB)
 | 
			
		||||
    for (let x = 0; x < length; x++) {
 | 
			
		||||
      for (let y = 0; y < length; y++) {
 | 
			
		||||
        image.setRGB(x, y, qrcode.isDark(x, y) ? 0xFF000000 : 0xFFFFFFFF)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return image
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
  // let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
  // out.writeUTF("GetServer")
 | 
			
		||||
  // player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
 | 
			
		||||
  private bungeeCordDetect(player) {
 | 
			
		||||
    if (this.isBungeeCord === undefined && player) {
 | 
			
		||||
      let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
      let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
      out.writeUTF("GetServer")
 | 
			
		||||
      player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Listener()
 | 
			
		||||
  PlayerJoinEvent(event: org.bukkit.event.player.PlayerJoinEvent) {
 | 
			
		||||
    this.bungeeCordDetect(event.getPlayer())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Listener()
 | 
			
		||||
  PlayerDropItemEvent(event: org.bukkit.event.player.PlayerDropItemEvent) {
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(event.getItemDrop().getItemStack())
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      event.getItemDrop().remove()
 | 
			
		||||
      this.cancelTask(id)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Listener()
 | 
			
		||||
  PlayerItemHeldEvent(event: org.bukkit.event.player.PlayerItemHeldEvent) {
 | 
			
		||||
    let inv = event.getPlayer().getInventory()
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(inv.getItem(event.getPreviousSlot() as any))
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      inv.setItem(event.getPreviousSlot(), null)
 | 
			
		||||
      this.cancelTask(id)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Listener()
 | 
			
		||||
  InventoryClickEvent(event: org.bukkit.event.inventory.InventoryClickEvent) {
 | 
			
		||||
    let item = event.getCurrentItem()
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(item)
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      event.getInventory().setItem(event.getSlot(), null)
 | 
			
		||||
      this.cancelTask(id)
 | 
			
		||||
      event.setCancelled(true)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Listener()
 | 
			
		||||
  PlayerQuitEvent(event: org.bukkit.event.player.PlayerQuitEvent) {
 | 
			
		||||
    this.checkAndClear(event.getPlayer())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private cancelTask(id) {
 | 
			
		||||
    this.cacheTasks.get(id)?.cancel()
 | 
			
		||||
    this.cacheTasks.delete(id)
 | 
			
		||||
    this.isBinding = false
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private checkAndClear(player: org.bukkit.entity.Player) {
 | 
			
		||||
    if (this.isQrCodeItem(player.getItemInHand())[0]) {
 | 
			
		||||
      player.setItemInHand(null)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private isQrCodeItem(item: org.bukkit.inventory.ItemStack): [boolean, number?] {
 | 
			
		||||
    if (!item) { return [false] }
 | 
			
		||||
    if ((item?.getType() == Material.MAP || item?.getType() == Material.FILLED_MAP) && item.hasItemMeta()) {
 | 
			
		||||
      let meta = item.getItemMeta()
 | 
			
		||||
      return [!!(Java.from(meta.getLore()).indexOf('QRCODE') != -1), item.getDurability()]
 | 
			
		||||
    }
 | 
			
		||||
    return [false]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdhelp(sender: any) {
 | 
			
		||||
    let help = [
 | 
			
		||||
      `§6====== ${this.config.prefix} §a帮助菜单 §6======`,
 | 
			
		||||
      `§6/mrd bind §a绑定圈云盒子`,
 | 
			
		||||
      `§6/mrd query §a查询当前账户`,
 | 
			
		||||
      `§6/mrd draw §e<兑换数量> §a兑换点券`
 | 
			
		||||
    ]
 | 
			
		||||
    if (sender.isOp()) {
 | 
			
		||||
      help = help.concat([
 | 
			
		||||
        `§c由于您是管理员 以为您展示额外命令`,
 | 
			
		||||
        `§6/mrd bind server §a绑定服务器`,
 | 
			
		||||
        `§6/mrd ratio §e<兑换比例> §a设置喵币/点券兑换比例`,
 | 
			
		||||
        `§6/mrd statistic §3近期收入统计`,
 | 
			
		||||
        `§6/mrd rank <boardcast>(是否公告) §2今日兑换排行`,
 | 
			
		||||
        `§6/mrd server §c当前服务器信息`,
 | 
			
		||||
        `§6兑换比例设置说明: §b默认比例为 0.001 §6=> §a1000喵币 §6兑换 §c1点券`,
 | 
			
		||||
        `§c注意 设置比例后 玩家兑换点券数量不能少于 1点券`,
 | 
			
		||||
        `§c比如 设置了0.001 那就是 玩家至少 1000喵币 才能兑换!`
 | 
			
		||||
      ])
 | 
			
		||||
    }
 | 
			
		||||
    this.logger.sender(sender, help)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Tab()
 | 
			
		||||
  tabmrd(sender: any, _command: any, args: string | any[]) {
 | 
			
		||||
    if (args.length === 1) return ['help', 'bind', 'show', 'query', 'draw', 'ratio', 'rank', 'server']
 | 
			
		||||
    if (args.length === 2 && args[0] === "bind" && sender.isOp()) return ['server']
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import { plugin as pluginApi, task, server } from '@ccms/api'
 | 
			
		||||
import { plugin as pluginApi, task, server, plugin, channel, constants } from '@ccms/api'
 | 
			
		||||
 | 
			
		||||
import { Translate } from '@ccms/i18n'
 | 
			
		||||
import { inject, DefaultContainer as container } from '@ccms/container'
 | 
			
		||||
import { interfaces, plugin, cmd, tab } from '@ccms/plugin'
 | 
			
		||||
import { inject, DefaultContainer as container, optional, JSClass } from '@ccms/container'
 | 
			
		||||
import { interfaces, JSPlugin, Cmd, Tab, enable, Listener, disable } from '@ccms/plugin'
 | 
			
		||||
 | 
			
		||||
import * as fs from '@ccms/common/dist/fs'
 | 
			
		||||
import * as reflect from '@ccms/common/dist/reflect'
 | 
			
		||||
@@ -26,15 +26,16 @@ let langMap = {
 | 
			
		||||
    'main.command.not.exists': '§4未知的子命令: §c{command}',
 | 
			
		||||
    'main.command.help.tip': '§6请执行 §b/{command} §ahelp §6查看帮助!',
 | 
			
		||||
    'list.install.header': '§6当前 §bMiaoScript §6已安装下列插件:',
 | 
			
		||||
    'list.install.body': '§6插件名称: §b{name} §6版本: §a{version} §6作者: §3{author} §6来源: §c{from}',
 | 
			
		||||
    'list.install.body': '§6插件名称: §b{name}\n§6版本: §a{version}\n§6作者: §3{author}\n§6来源: §c{from}',
 | 
			
		||||
    'list.header': '§6当前 §bMiaoScriptPackageCenter §6中存在下列插件:',
 | 
			
		||||
    'list.body': '§6插件名称: §b{name} §6版本: §a{version} §6作者: §3{author} §6更新时间: §9{updated_at}',
 | 
			
		||||
    'list.body': '§6插件名称: §b{name}\n§6版本: §a{version}\n§6作者: §3{author}\n§6更新时间: §9{updated_at}',
 | 
			
		||||
    'plugin.not.exists': '§6插件 §b{name} §c不存在!',
 | 
			
		||||
    'plugin.unload.finish': '§6插件 §b{name} §a已卸载!',
 | 
			
		||||
    'plugin.reload.finish': '§6插件 §b{name} §a重载完成!',
 | 
			
		||||
    '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}!',
 | 
			
		||||
    'download.start': '§6开始下载插件: §b{name}',
 | 
			
		||||
    'download.url': '§6插件下载地址: §b{url}',
 | 
			
		||||
    'download.finish': '§6插件 §b{name} §a下载完毕 开始加载 ...',
 | 
			
		||||
@@ -51,9 +52,9 @@ let langMap = {
 | 
			
		||||
 | 
			
		||||
let fallbackMap = langMap
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'MiaoScriptPackageManager', prefix: 'PM', version: '1.0.2', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
@JSPlugin({ prefix: 'PM', version: '1.2.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
    @inject(plugin.PluginManager)
 | 
			
		||||
    private pluginManager: pluginApi.PluginManager
 | 
			
		||||
    @inject(task.TaskManager)
 | 
			
		||||
    private taskManager: task.TaskManager
 | 
			
		||||
@@ -63,11 +64,22 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    private server: server.Server
 | 
			
		||||
    @inject(pluginApi.PluginFolder)
 | 
			
		||||
    private pluginFolder: string
 | 
			
		||||
    @inject(channel.Channel)
 | 
			
		||||
    @optional() private channel: channel.Channel
 | 
			
		||||
 | 
			
		||||
    @JSClass('java.io.ByteArrayOutputStream')
 | 
			
		||||
    private ByteArrayOutputStream: any
 | 
			
		||||
    @JSClass('java.io.DataOutputStream')
 | 
			
		||||
    private DataOutputStream: any
 | 
			
		||||
    @JSClass('com.google.common.io.ByteStreams')
 | 
			
		||||
    private ByteStreams: any
 | 
			
		||||
 | 
			
		||||
    private packageCache: any[] = [];
 | 
			
		||||
    private packageNameCache: string[] = [];
 | 
			
		||||
 | 
			
		||||
    private serverName: string
 | 
			
		||||
    private translate: Translate
 | 
			
		||||
    private channelOff: { off: () => void }
 | 
			
		||||
 | 
			
		||||
    load() {
 | 
			
		||||
        this.translate = new Translate({
 | 
			
		||||
@@ -77,13 +89,100 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
        this.updateRepo(this.server.getConsoleSender())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @cmd()
 | 
			
		||||
    @enable({ servers: [constants.ServerType.Bukkit, constants.ServerType.Sponge] })
 | 
			
		||||
    serverEnbale() {
 | 
			
		||||
        this.channelOff = this.channel?.listen(this, 'BungeeCord', (data) => {
 | 
			
		||||
            let input = this.ByteStreams.newDataInput(data)
 | 
			
		||||
            let subChannel = input.readUTF()
 | 
			
		||||
            switch (subChannel) {
 | 
			
		||||
                case "GetServer":
 | 
			
		||||
                    this.serverName = input.readUTF()
 | 
			
		||||
                    break
 | 
			
		||||
                case "MiaoScriptPackageManager":
 | 
			
		||||
                    this.readForward(input)
 | 
			
		||||
                    break
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        let players = this.server.getOnlinePlayers()
 | 
			
		||||
        if (players.length) this.bungeeCordDetect(players[0])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @disable({ servers: [constants.ServerType.Bukkit, constants.ServerType.Sponge] })
 | 
			
		||||
    serverDisable() {
 | 
			
		||||
        this.channelOff?.off()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private bungeeCordDetect(player) {
 | 
			
		||||
        if (player) {
 | 
			
		||||
            let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
            let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
            out.writeUTF("GetServer")
 | 
			
		||||
            player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private bungeeCordForward(player, command) {
 | 
			
		||||
        if (player) {
 | 
			
		||||
            let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
            let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
            out.writeUTF("Forward")
 | 
			
		||||
            out.writeUTF("ALL")
 | 
			
		||||
            out.writeUTF("MiaoScriptPackageManager")
 | 
			
		||||
            out.writeUTF(JSON.stringify(command))
 | 
			
		||||
            player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private readForward(input) {
 | 
			
		||||
        let message = JSON.parse(input.readUTF())
 | 
			
		||||
        this.taskManager.create(() => this.main(this.server.getConsoleSender(), message.command, message.args)).async().submit()
 | 
			
		||||
        this.sendBungeeCordMessage(message.sender, `§6[§cMS§6][§bPM§6] [§3BPM§6][§a${this.serverName}§6] §6命令 §b/mpm ${message.args?.join?.(' ')} §a执行成功!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Listener({ servers: [constants.ServerType.Bukkit] })
 | 
			
		||||
    PlayerJoinEvent(event: org.bukkit.event.player.PlayerJoinEvent) {
 | 
			
		||||
        this.bungeeCordDetect(event.getPlayer())
 | 
			
		||||
        if (event.getPlayer().isOp()) {
 | 
			
		||||
            this.updateRepo(event.getPlayer())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Listener({ servers: [constants.ServerType.Sponge] })
 | 
			
		||||
    ClientConnectionEvent$Join(event: org.spongepowered.api.event.network.ClientConnectionEvent.Join) {
 | 
			
		||||
        if (event.getTargetEntity().hasPermission('ms.mpm.admin')) {
 | 
			
		||||
            this.updateRepo(event.getTargetEntity())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private sendBungeeCordMessage(sender, message) {
 | 
			
		||||
        let players = this.server.getOnlinePlayers()
 | 
			
		||||
        if (players.length) {
 | 
			
		||||
            let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
            let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
            out.writeUTF("Message")
 | 
			
		||||
            out.writeUTF(sender)
 | 
			
		||||
            out.writeUTF(message)
 | 
			
		||||
            this.channel.send(players[0], "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
        this.channelOff?.off()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd()
 | 
			
		||||
    bmpm(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!sender.isOp()) { return this.logger.sender(sender, '§c你没有此命令的权限!') }
 | 
			
		||||
        this.bungeeCordForward(sender, { sender: sender.getName(), command, args })
 | 
			
		||||
        this.logger.sender(sender, `[§3BPM§6][§a${this.serverName}§6] §6命令 §b/mpm ${args.join?.(' ')} §a发布成功!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd()
 | 
			
		||||
    mpm(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!sender.isOp()) { return this.logger.sender(sender, '§c你没有此命令的权限!') }
 | 
			
		||||
        this.taskManager.create(() => this.main(sender, command, args)).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i18n(sender: any, name: string, params?: any) {
 | 
			
		||||
        this.logger.sender(sender, this.translate.translate(name, params))
 | 
			
		||||
        this.logger.sender(sender, this.translate.translate(name, params).split('\n'))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    main(sender: any, command: string, args: string[]) {
 | 
			
		||||
@@ -255,7 +354,7 @@ return '§a返回结果: §r'+ eval(${JSON.stringify(code)});`)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @tab()
 | 
			
		||||
    @Tab()
 | 
			
		||||
    tabmpm(sender: any, command: any, args: string | any[]) {
 | 
			
		||||
        if (args.length === 1) { return ['list', 'install', 'update', 'upgrade', 'reload', 'restart', 'run', 'help', 'create', 'deploy'] }
 | 
			
		||||
        if (args.length > 1) {
 | 
			
		||||
@@ -284,6 +383,13 @@ return '§a返回结果: §r'+ eval(${JSON.stringify(code)});`)
 | 
			
		||||
            for (const pl of result.data) { this.packageCache[pl.name] = pl }
 | 
			
		||||
            this.packageNameCache = Object.keys(this.packageCache)
 | 
			
		||||
            this.i18n(sender, 'cloud.update.finish', { length: this.packageNameCache.length })
 | 
			
		||||
            this.pluginManager.getPlugins().forEach(p => {
 | 
			
		||||
                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 })
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        }).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -157,7 +157,7 @@ class SearchRankingController {
 | 
			
		||||
 | 
			
		||||
    private createKeyworkSearch(keyword: string, type: string) {
 | 
			
		||||
        let cacheDate = Date.now()
 | 
			
		||||
        this.redisTemplate.opsForValue().set(this.getCacheKey(keyword, type), cacheDate)
 | 
			
		||||
        this.redisTemplate.opsForValue().set(this.getCacheKey(keyword, type), cacheDate, 15, java.util.concurrent.TimeUnit.DAYS)
 | 
			
		||||
        this.sendSearchCmd(keyword, type, cacheDate)
 | 
			
		||||
        return { status: 201, msg: `关键词: ${keyword} 排名类型: ${type} 查询任务以创建...`, createTime: cacheDate }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,74 +1,110 @@
 | 
			
		||||
import { plugin as pluginApi } from '@ccms/api'
 | 
			
		||||
import { plugin, interfaces, cmd, listener, tab } from '@ccms/plugin'
 | 
			
		||||
import { inject } from '@ccms/container';
 | 
			
		||||
import { inject } from '@ccms/container'
 | 
			
		||||
 | 
			
		||||
import * as reflect from '@ccms/common/dist/reflect';
 | 
			
		||||
import http from '@ccms/common/dist/http';
 | 
			
		||||
import * as reflect from '@ccms/common/dist/reflect'
 | 
			
		||||
import http from '@ccms/common/dist/http'
 | 
			
		||||
 | 
			
		||||
const ByteArrayInputStream = Java.type("java.io.ByteArrayInputStream")
 | 
			
		||||
const ByteArrayOutputStream = Java.type("java.io.ByteArrayOutputStream")
 | 
			
		||||
const StandardCharsets = Java.type("java.nio.charset.StandardCharsets")
 | 
			
		||||
const GZIPInputStream = Java.type("java.util.zip.GZIPInputStream")
 | 
			
		||||
const GZIPOutputStream = Java.type("java.util.zip.GZIPOutputStream")
 | 
			
		||||
const JavaString = Java.type('java.lang.String')
 | 
			
		||||
const ByteArray = Java.type("byte[]")
 | 
			
		||||
 | 
			
		||||
class MiaoMessage {
 | 
			
		||||
    // public static final String CHANNEL = "MiaoChat:Default".toLowerCase();
 | 
			
		||||
    public static CHANNEL: string = "MiaoChat:Default".toLowerCase()
 | 
			
		||||
    // private static final int MAX_MESSAGE_LENGTH = 32000;
 | 
			
		||||
    private static MAX_MESSAGE_LENGTH = 32000;
 | 
			
		||||
 | 
			
		||||
    private static copy(input, output) {
 | 
			
		||||
        let buffer = new ByteArray(1024)
 | 
			
		||||
        let n: number
 | 
			
		||||
        while ((n = input.read(buffer)) != -1) {
 | 
			
		||||
            output.write(buffer, 0, n)
 | 
			
		||||
        }
 | 
			
		||||
        input.close()
 | 
			
		||||
        output.close()
 | 
			
		||||
    }
 | 
			
		||||
    public static encode(input: any): any {
 | 
			
		||||
        let baos = new ByteArrayOutputStream()
 | 
			
		||||
        MiaoMessage.copy(new ByteArrayInputStream(new JavaString(JSON.stringify(input)).getBytes(StandardCharsets.UTF_8)), new GZIPOutputStream(baos))
 | 
			
		||||
        if (baos.size() > MiaoMessage.MAX_MESSAGE_LENGTH) { return null }
 | 
			
		||||
        return baos.toByteArray()
 | 
			
		||||
    }
 | 
			
		||||
    public static decode(input: any): any {
 | 
			
		||||
        let baos = new ByteArrayOutputStream()
 | 
			
		||||
        MiaoMessage.copy(new GZIPInputStream(new ByteArrayInputStream(input)), baos)
 | 
			
		||||
        return JSON.parse(baos.toString(StandardCharsets.UTF_8.name()))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'Test', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class Test extends interfaces.Plugin {
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
    private PluginManager: pluginApi.PluginManager;
 | 
			
		||||
    private PluginManager: pluginApi.PluginManager
 | 
			
		||||
 | 
			
		||||
    load() {
 | 
			
		||||
        this.logger.log('Test Plugin load from MiaoScript Plugin System...');
 | 
			
		||||
        this.logger.log('Test Plugin load from MiaoScript Plugin System...')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
        this.logger.log('Test Plugin enable from MiaoScript Plugin System...');
 | 
			
		||||
        this.logger.log('Test Plugin enable from MiaoScript Plugin System...')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
        this.logger.log('Test Plugin disable from MiaoScript Plugin System...');
 | 
			
		||||
        this.logger.log('Test Plugin disable from MiaoScript Plugin System...')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @cmd()
 | 
			
		||||
    test(sender: any, command: string, args: string[]) {
 | 
			
		||||
        switch (args[0]) {
 | 
			
		||||
            case "run":
 | 
			
		||||
                var script = args.slice(1).join(' ');
 | 
			
		||||
                console.sender(sender, '§b运行脚本:§r', script);
 | 
			
		||||
                console.sender(sender, '§a返回结果:§r', eval(script) || '§4没有返回结果!');
 | 
			
		||||
                break;
 | 
			
		||||
                var script = args.slice(1).join(' ')
 | 
			
		||||
                console.sender(sender, '§b运行脚本:§r', script)
 | 
			
		||||
                console.sender(sender, '§a返回结果:§r', eval(script) || '§4没有返回结果!')
 | 
			
		||||
                break
 | 
			
		||||
            case "reload":
 | 
			
		||||
                this.PluginManager.reload(this);
 | 
			
		||||
                break;
 | 
			
		||||
                this.PluginManager.reload(this)
 | 
			
		||||
                break
 | 
			
		||||
            case "yaml":
 | 
			
		||||
                let yaml = require("js-yaml");
 | 
			
		||||
                this.logger.log(yaml.safeDump({ key: 'value', map: { k1: 1, k2: '2' } }));
 | 
			
		||||
                break;
 | 
			
		||||
                let yaml = require("js-yaml")
 | 
			
		||||
                this.logger.log(yaml.safeDump({ key: 'value', map: { k1: 1, k2: '2' } }))
 | 
			
		||||
                break
 | 
			
		||||
            case "speed":
 | 
			
		||||
                this.logger.sender(sender, sender.location);
 | 
			
		||||
                break;
 | 
			
		||||
                this.logger.sender(sender, sender.location)
 | 
			
		||||
                break
 | 
			
		||||
            case "top":
 | 
			
		||||
                let loc = sender.location;
 | 
			
		||||
                let topY = loc.world.getHighestBlockYAt(loc);
 | 
			
		||||
                loc.y = topY;
 | 
			
		||||
                sender.teleport(loc);
 | 
			
		||||
                break;
 | 
			
		||||
                let loc = sender.location
 | 
			
		||||
                let topY = loc.world.getHighestBlockYAt(loc)
 | 
			
		||||
                loc.y = topY
 | 
			
		||||
                sender.teleport(loc)
 | 
			
		||||
                break
 | 
			
		||||
            case "up":
 | 
			
		||||
                if (!sender.openInventory) { return; }
 | 
			
		||||
                let player = sender;
 | 
			
		||||
                let location = player.location;
 | 
			
		||||
                player.velocity = player.velocity.setY(0.5);
 | 
			
		||||
                setTimeout(() => location.block.type = Java.type('org.bukkit.Material').STONE, 8);
 | 
			
		||||
                break;
 | 
			
		||||
                if (!sender.openInventory) { return }
 | 
			
		||||
                let player = sender
 | 
			
		||||
                let location = player.location
 | 
			
		||||
                player.velocity = player.velocity.setY(0.5)
 | 
			
		||||
                setTimeout(() => location.block.type = Java.type('org.bukkit.Material').STONE, 8)
 | 
			
		||||
                break
 | 
			
		||||
            case "add":
 | 
			
		||||
                break;
 | 
			
		||||
                break
 | 
			
		||||
            case "get":
 | 
			
		||||
                let result = http.get('https://www.baidu.com');
 | 
			
		||||
                this.logger.sender(sender, JSON.stringify(result));
 | 
			
		||||
                let result = http.get('https://www.baidu.com')
 | 
			
		||||
                this.logger.sender(sender, JSON.stringify(result))
 | 
			
		||||
                // 好了 扯结束 继续咸鱼
 | 
			
		||||
                break;
 | 
			
		||||
                break
 | 
			
		||||
            case "ws":
 | 
			
		||||
                let Sponge = Java.type('org.spongepowered.api.Sponge');
 | 
			
		||||
                let Sponge = Java.type('org.spongepowered.api.Sponge')
 | 
			
		||||
                // let promise = reflect.on(Bukkit.server).get('console').get('field_147144_o').get('field_151274_e').get().get(0);
 | 
			
		||||
                console.log(reflect.on(Sponge.server).get('field_147144_o').get())
 | 
			
		||||
                // let channel = reflect.on(promise).get('channel').get().pipeline().first();
 | 
			
		||||
                // console.log(channel);
 | 
			
		||||
                break;
 | 
			
		||||
                break
 | 
			
		||||
            default:
 | 
			
		||||
                this.logger.log(sender, command, args);
 | 
			
		||||
                this.logger.log(sender, command, args)
 | 
			
		||||
                sender.sendMessage(JSON.stringify({ command, ...args }))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user