摸鱼派客户端扩展开发指南
如果你还没下载摸鱼派的客户端,请移步这里下载:https://github.com/imlinhanchao/fishpi-desktop/releases/
最新文档可以查看这里。
扩展目前分为两类:主题和插件。所有扩展都需要先新建一个 package.json
。内容包含扩展的一些基本属性。如下示例:
{
"name": "xiaoice", // 扩展唯一标识,同一个 publisher 下不可重复
"publisher": "hancel", // 扩展发布者
"version": "1.0.0", // 版本号
"displayName": "小冰游戏", // 扩展对外展示名
"description": "摸鱼文字修仙游戏", // 扩展的描述
"main": "extension/index.js", // 扩展的入口,主题为 css 文件,插件为 JavaScript 文件
"author": "Hancel.Lin", // 扩展的作者
"homepage": "https://github.com/imlinhanchao/fishpi-ext-xiaoice", // 扩展的首页,会连接在扩展页面
"repository": "https://github.com/imlinhanchao/fishpi-ext-xiaoice", // 扩展的仓库地址,若没有设置 homepage,则会连接这个地址
"fishpi": { // 扩展的属性
"type": "extension", // 扩展的类型
"icon": "public/icon.png" // 扩展的 icon,会显示在扩展页面
}
}
主题扩展
主题扩展相对简单,只要新建一个要设置的 CSS 的文件。可以先复制一份客户端的 CSS 变量修改主题颜色,还可以对各个不同页面选择器分别再写样式覆写。下面是各个不同页面的 id,可用于样式覆写获得更高优先级。
#app // 全局页面
#home-sidebar // 侧边栏
#main // 主页面
#header // 主页面顶部栏
#win-title // 顶部栏标题处
#content // 主页面内容区
#liveness // 活跃度模块
#login // 登录页面
#breezemoons // 清风明月页面
#chatroom // 聊天室页面
#chats // 私聊页面
#setting // 设置页面
#card // 个人名片窗口
#autocomplete // 自动完成窗口
#redpacket // 红包窗口
#img-form // 图片弹出窗
插件扩展
插件扩展是通过将 JavaScript 作为模块引入到客户端中,并通过 export
接口实现各种对接客户端的功能。
入口函数
function activate(context, electron):void
context
: 这是一个事件处理器,可以监听从主程序发送的系统消息,也可以自定义消息与自己嵌入的webview
通信。electron
: 这是一个原生的Electron
对象,可以用于调用各种 electron 的原生 API📃,实现诸如新建窗口或其他系统操作。
例如:
function activate(context, electron) {
// 插件激活操作
}
// extension.js
module.exports = {
activate
}
可选接口
可选接口不是非必须实现。
function getSettingUrl():string
设置扩展设置地址,返回一个 html 文件地址,如果文件包含其他支援引用,必须使用相对于此文件的相对地址。或有实现该函数,则会在扩展页面出现一个设置按钮。
function hooks(): {
async messageEvent(msg:Message) : Message | Boolean | Null,
async sendMsgEvent(text:string): string,
async liveness(data:Number) : void,
}
返回一个 hook 对象,分别实现三个函数(可选),用于 hook 聊天室操作。
messageEvent
: 新的聊天消息 Hook,返回 False 或 Null 则 中断响应该消息,返回 True 则继续响应,也可以对消息内容做修改。数据结构见 Message 对象定义sendMsgEvent
: 发送消息 Hook,不会 Hook 复读与红包消息。text
为发送内容的原文。可以进行修改后返回。若不修改也要返回text
。liveness
: 活跃度响应 Hook,当客户端有请求到活跃度数据时,会调用此函数,data
为活跃度数值。注意:客户端启动后一分钟才会首次反馈此数据。反馈频次为 1 分钟一次。
Context 对象接口详解
入口函数 activate
包含 Context
对象,基于 EventEmitter
实现。目前 Context
包含以下接口:
fishpi
: fishpi 接口对象,具体参考 Fishpi API Package 。function on(event, listener:(...args: any[]) => void)
: 事件监听接口,目前包含如下事件。login
: 用户登录,监听函数为(token) => void
,token
为用户登录 API。此时fishpi
可以调用需用户登录态接口。logout
: 用户退出登录。quit
: 客户端退出。command
: 用户自定义事件监听,监听函数为(event:string, args:data, callback:(data) => void) => void
,具体使用方法见 Webview 通信。
function once(event, listener:(...args: any[]) => void)
: 同上,仅触发一次。function off(event, listener:(...args: any[]) => void)
: 关闭指定函数与事件的监听。function send(event, data:any)
: 发送自定义事件到 Webview。function setSidebar(icon:string, url:string)
: 设置侧边栏,icon
为侧边栏 icon 图片地址,需为纯色 svg。url
为侧边栏对应 Webview 地址。
Webview 通信
扩展支援自定义侧边栏页面或设置界面为 Webview,只需要通过 Context.setSidebar
(侧边栏)和 getSettingUrl
(设置界面)指定。在开发模式下,载入 Webview 时会启动开发者调试工具。通过给客户端传参 --dev
或设置环境变量 EXT_ENV
为 development
后启动客户端来进入开发模式。
所有 Webview 都包含一个 $ipc
对象:
$ipc = {
/**
* 发送自定义事件到扩展后端
* - `event`: 自定义事件
* - `args`: 事件参数
* - `callback`: 扩展后端回传数据回调,可不传
*/
send (event:string, args:any[, callback:(data) => void]):void,
/**
* 发送自定义事件到扩展后端,后端通过 Context 监听 `command` 事件获取
* - `event`: 自定义事件
* - `args`: 事件参数
* return 后端返回的数据
*/
invoke (event:string, args:any): Promise<any>,
/**
* 监听后端发送的自定义事件
* - `event`: 自定义事件
* - `listener`: 监听函数
*/
on (event:string, listener:(data) => void):void,
/**
* 关闭自定义事件监听
* - `event`: 自定义事件
* - `listener`: 监听函数
*/
off (event:string, listener:(data) => void):void,
}
Webview 通信示例:
// Webview 发送自定义事件到后端:
$ipc.send('send-event', 'send data', (rsp) => {
console.dir(rsp);
})
// Webview 发送自定义事件到后端,异步获取后端 Response:
let rsp = await $ipc.invoke('invoke-event', 'invoke data')
console.dir(rsp);
// Extension 监听 Webview 发送事件
context.on('command', (command, args, callback) => {
switch (command) {
case 'send-event':
console.log(args) // 'send data'
callback('get send');
break;
case 'invoke-event':
console.log(args) // 'invoke data'
callback('get invoke');
break;
}
})
// Webview 监听 Extension
$ipc.on('on-event', (data) => {
console.log(data) // 'your data'
})
// Extension 发送事件到 Webview
context.send('on-event', 'your data')
Message 对象定义
type Message = {
/**
* 消息类型,
*/
type: 'online'|'discussChanged'|'revoke'|'msg'|'redPacket'|'redPacketStatus';
/**
* 消息内容
*/
data: OnlineMsg | discussMsg | RevokeMsg | ChatMsg | RedpacketMsg | RedpacketStatusMsg
}
/**
* 在线用户消息
*/
type OnlineMsg = Array<{
/**
* 用户首页
*/
homePage: string,
/**
* 用户头像
*/
userAvatarURL: string,
/**
* 用户名
*/
userName: string,
}>
/**
* 主题修改消息,主题内容
*/
type discussMsg = string
/**
* 撤回消息,被撤回消息的 oId
*/
type RevokeMsg = string
/**
* 聊天消息
*/
type ChatMsg = {
/**
* 消息 oId
*/
oId: string,
/**
* 消息发送时间
*/
time: string,
/**
* 发送者用户名
*/
userName: string,
/**
* 发送者昵称
*/
userNickname: string,
/**
* 发送者头像
*/
userAvatarURL: string,
/**
* 消息内容
*/
content: string,
/**
* 消息内容 Markdown
*/
md: string
}
/**
* 红包消息
*/
type RedpacketMsg = {
/**
* 消息 oId
*/
oId: string,
/**
* 消息发送时间
*/
time: string,
/**
* 发送者用户名
*/
userName: string,
/**
* 发送者昵称
*/
userNickname: string,
/**
* 发送者头像
*/
userAvatarURL: string,
/**
* 消息内容
*/
content: {
/**
* 固定为 redPacket
*/
msgType: string;
/**
* 红包数
*/
count: number;
/**
* 领取数
*/
got: number;
/**
* 内含积分
*/
money: number;
/**
* 祝福语
*/
msg: string;
/**
* 发送者 id
*/
senderId: string;
/**
* 红包类型
*/
type: string;
/**
* 接收者,专属红包有效
*/
recivers: Array<string>;
/**
* 已领取者列表
*/
who: Array<{
/**
* 用户 id
*/
userId: string;
/**
* 用户名
*/
userName: string;
/**
* 用户头像
*/
avatar: string;
/**
* 领取到的积分
*/
userMoney: number;
/**
* 领取积分时间
*/
time: string;
}>
},
}
type RedpacketStatusMsg = {
/**
* 对应红包消息 oId
*/
oId: string,
/**
* 红包个数
*/
count: number,
/**
* 已领取数量
*/
got: number,
/**
* 发送者信息
*/
whoGive: any,
/**
* 领取者信息
*/
whoGot: Array<any>
}
牛的
巨佬 !
坐等大佬们开发新的主题插件 嘿嘿