diff --git a/packages/plugins/docs/MiaoRGBSupport.md b/packages/plugins/docs/MiaoRGBSupport.md new file mode 100644 index 00000000..5c63e7a1 --- /dev/null +++ b/packages/plugins/docs/MiaoRGBSupport.md @@ -0,0 +1,37 @@ + [综合|信息]MiaoRGBSupport —— 喵式RGB 支持任意插件的RGB展示[1.16+] + +# MiaoRGBSupport + +## 插件简介 +- 支持1.16+彩色字体展示 +- 兼容原版聊天以及任意聊天插件 +- 兼容任意记分板插件 +- 仅需安装插件配置权限即可生效 + +## 插件权限 +- `MiaoRGBSupport.color` 默认玩家没权限 需要手动添加 + +## 安装方式 +- 本插件基于 MiaoScript 开发 +- 请先安装 MiaoScript [坛内地址](https://www.mcbbs.net/thread-774401-1-1.html) +- 然后安装 ProtocolLib 自己解决 +- 执行 `/mspm install MiaoChatRGBSupport` + +## 使用方式 +- 颜色格式 `#FFFFFF` 标准 HTML 的色彩格式 + +### 聊天插件配置 +- 例如 配置 `MiaoChat` 的 `format.yml` +- ![image.png](https://i.loli.net/2021/06/24/1DiupnoPjaI7tZr.png) +- 配置完成后 重载插件 + +### 聊天时使用 +- 聊天时 直接输入颜色代码即可 +- ![image.png](https://i.loli.net/2021/06/24/2dnTlyv6oZrcBzg.png) + +## 星球特供版本 +- ![image.png](https://i.loli.net/2021/06/24/DOmhJRflxS3qwju.png) +- 此版本为知识星球特供 +- 支持 聊天和记分板 +- 支持 彩虹字 +- 详情加群 650545561 diff --git a/packages/plugins/src/MiaoRGBSupport.ts b/packages/plugins/src/MiaoRGBSupport.ts new file mode 100644 index 00000000..5e5cf9af --- /dev/null +++ b/packages/plugins/src/MiaoRGBSupport.ts @@ -0,0 +1,157 @@ +import { constants } from "@ccms/api" +import { JSClass } from "@ccms/container" +import { interfaces, JSPlugin } from "@ccms/plugin" + +let createPacketAdapterFunction = eval(` +function(cls, plugin, type, onPacketSending){ + return new cls(plugin, type) { + onPacketSending: onPacketSending + } +} +`) +const Color = Java.type('java.awt.Color') +const Pattern = Java.type('java.util.regex.Pattern') +const ChatColor = Java.type('net.md_5.bungee.api.ChatColor') + +@JSPlugin({ prefix: 'MRS', version: '1.0.0', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], nativeDepends: ['ProtocolLib'], source: __filename }) +export class MiaoRGBSupport extends interfaces.Plugin { + private supportRGB: boolean = false + // 用于匹配 '#FFFFFF' 颜色格式 + private RGBCOLOR_PATTERN = Pattern.compile("(#[a-fA-F0-9]{6}?)([^#?]*)") + // 用于匹配彩虹格式 + private RAINBOW_PATTERN = Pattern.compile("#RAINBOW([0-9]{1,3})([^#?]*)") + + @JSClass('com.comphenix.protocol.events.PacketAdapter') + private PacketAdapter: any + @JSClass('com.comphenix.protocol.PacketType') + private PacketType: any + @JSClass('com.comphenix.protocol.ProtocolLibrary') + private ProtocolLibrary: any + + private adapter: any + + load() { + try { + ChatColor.of('#FFFFFF').toString() + this.supportRGB = true + this.logger.console('§a检测到兼容RGB的服务端 已启动相关支持...') + } catch (error) { + this.logger.console('§c当前服务端不支持RGB色彩 Error: ' + error) + } + } + + enable() { + if (this.supportRGB) { + this.initPacketAdapter() + } + } + + disable() { + if (this.supportRGB) { + this.ProtocolLibrary.getProtocolManager().removePacketListener(this.adapter) + } + } + + createPacketAdapter(onPacketSending: (event) => void) { + return createPacketAdapterFunction(this.PacketAdapter, base.getInstance(), [ + this.PacketType.Play.Server.CHAT, + this.PacketType.Play.Server.SCOREBOARD_OBJECTIVE, + this.PacketType.Play.Server.SCOREBOARD_SCORE, + this.PacketType.Play.Server.SCOREBOARD_TEAM + ], onPacketSending) + } + + colorJson(jsonObj) { + return this.processJson(jsonObj, this.RGBCOLOR_PATTERN, (extras, colors) => { + return (value, index) => { + extras.push({ + text: value, + color: colors[index] + }) + } + }) + } + + rainbowJson(jsonObj) { + return this.processJson(jsonObj, this.RAINBOW_PATTERN, (extras, colors) => { + return (value: string, index) => { + let textArr = value.split("") + let rainbowColors = this.createRainbow(textArr.length, colors[index]) + textArr.forEach((value, index) => { + extras.push({ + text: value, + color: rainbowColors[index] + }) + }) + } + }) + } + + private processJson(jsonObj, PATTERN, process: (extras, colors) => (value, index) => void) { + let text: string = jsonObj.text + if (jsonObj.extra && jsonObj.extra.length) { + for (const extra of jsonObj.extra) { + this.processJson(extra, PATTERN, process) + } + } + if (!text) { return jsonObj } + var matcher = PATTERN.matcher(text) + let colors = [] + let texts = [] + let lastStart = 0 + while (matcher.find()) { + if (lastStart == 0) { + texts.push(text.substr(lastStart, matcher.start())) + lastStart = matcher.end() + } + colors.push(matcher.group(1)) + texts.push(matcher.group(2)) + } + if (colors.length) { + jsonObj.text = '' + let extras = [] + let firstText = texts.shift() + if (firstText) { extras.push({ text: firstText }) } + texts.forEach(process(extras, colors)) + if (jsonObj.extra) { + jsonObj.extra = extras.concat(jsonObj.extra) + } else { + jsonObj.extra = extras + } + } + return jsonObj + } + + private createRainbow(step, saturation) { + var colors = [] + var colorStep = (1.00 / step) + for (var i = 0; i < step; i++) { + colors.push("#" + java.lang.String.format("%08x", Color.getHSBColor((colorStep * i), saturation, saturation).getRGB()).substring(2)) + } + return colors + } + + initPacketAdapter() { + this.adapter = this.createPacketAdapter((event) => { + try { + if (!event.getPlayer().hasPermission('MiaoRGBSupport.color')) { return } + let ccs = event.getPacket().getChatComponents() + let size = ccs.size() + for (let i = 0; i < size; i++) { + let wcc = ccs.read(i) + if (wcc == null) { continue } + let json = JSON.parse(wcc.getJson()) + json = this.colorJson(json) + if (event.getPlayer().hasPermission('MiaoRGBSupport.rainbow')) { + json = this.rainbowJson(json) + } + wcc.setJson(JSON.stringify(json)) + ccs.write(i, wcc) + } + } catch (error) { + console.ex(error) + } + }) + this.ProtocolLibrary.getProtocolManager().addPacketListener(this.adapter) + } +} diff --git a/packages/plugins/src/MiaoScriptPackageManager.ts b/packages/plugins/src/MiaoScriptPackageManager.ts index 64fd9d33..9d3f83b0 100644 --- a/packages/plugins/src/MiaoScriptPackageManager.ts +++ b/packages/plugins/src/MiaoScriptPackageManager.ts @@ -109,7 +109,7 @@ class SpongeFakeSender extends FakeSender { } } -@JSPlugin({ prefix: 'PM', version: '1.5.0', author: 'MiaoWoo', source: __filename }) +@JSPlugin({ prefix: 'PM', version: '1.5.1', author: 'MiaoWoo', source: __filename }) export class MiaoScriptPackageManager extends interfaces.Plugin { @Autowired() private pluginManager: pluginApi.PluginManager @@ -468,7 +468,7 @@ return eval(${JSON.stringify(code)});`) return tfunc.apply(_this, params) } - cmddeploy(sender: any, name: any) { + cmddeploy(sender: string, name: string, changelog: string) { if (!process.env.AccessToken) { return this.i18n(sender, 'deploy.token.not.exists') } this.taskManager.create(() => { if (this.checkPlugin(sender, name)) { @@ -477,7 +477,8 @@ return eval(${JSON.stringify(code)});`) name, author: plugin.description.author, version: plugin.description.version, - source: base.read((plugin.description.source || plugin.description.loadMetadata.file).toString()) + source: base.read((plugin.description.source || plugin.description.loadMetadata.file).toString()), + changelog: changelog.replace('&', '§') }) this.i18n(sender, result.code == 200 ? 'deploy.success' : 'deploy.fail', { name, version: plugin.description.version, msg: result.msg }) }