From b107fe6796855614c8cb4afbd968efe1b1be68dc Mon Sep 17 00:00:00 2001 From: lzghzr Date: Mon, 19 Nov 2018 21:20:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E4=BB=BB=E5=8A=A1=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bilive/@types/bilive.d.ts | 309 +++------------------------- bilive/daily.ts | 298 --------------------------- bilive/index.ts | 28 +-- bilive/online.ts | 9 +- bilive/options.default.json | 44 +--- bilive/plugin.ts | 42 ++++ bilive/plugins/calcgift/index.ts | 16 +- bilive/plugins/getbag/index.ts | 67 ++++++ bilive/plugins/raffle/index.ts | 10 +- bilive/plugins/raffle/raffle.ts | 3 +- bilive/plugins/sendgift/index.ts | 184 +++++++++++++++++ bilive/plugins/sign/index.ts | 87 ++++++++ bilive/plugins/signgroup/index.ts | 129 ++++++++++++ bilive/plugins/silver2coin/index.ts | 86 ++++++++ bilive/plugins/task/index.ts | 88 ++++++++ bilive/plugins/test/index.ts | 21 -- bilive/plugins/treasureBox/index.ts | 119 +++++++++++ bilive/webapi.ts | 8 +- 18 files changed, 868 insertions(+), 680 deletions(-) delete mode 100644 bilive/daily.ts create mode 100644 bilive/plugin.ts create mode 100644 bilive/plugins/getbag/index.ts create mode 100644 bilive/plugins/sendgift/index.ts create mode 100644 bilive/plugins/sign/index.ts create mode 100644 bilive/plugins/signgroup/index.ts create mode 100644 bilive/plugins/silver2coin/index.ts create mode 100644 bilive/plugins/task/index.ts delete mode 100644 bilive/plugins/test/index.ts create mode 100644 bilive/plugins/treasureBox/index.ts diff --git a/bilive/@types/bilive.d.ts b/bilive/@types/bilive.d.ts index 4ce8ed1..26d232c 100644 --- a/bilive/@types/bilive.d.ts +++ b/bilive/@types/bilive.d.ts @@ -41,13 +41,6 @@ interface userData { refreshToken: string cookie: string status: boolean - doSign: boolean - treasureBox: boolean - eventRoom: boolean - silver2coin: boolean - sendGift: boolean - sendGiftRoom: number - signGroup: boolean } interface optionsInfo { [index: string]: configInfoData @@ -63,13 +56,6 @@ interface optionsInfo { refreshToken: configInfoData cookie: configInfoData status: configInfoData - doSign: configInfoData - treasureBox: configInfoData - eventRoom: configInfoData - silver2coin: configInfoData - sendGift: configInfoData - sendGiftRoom: configInfoData - signGroup: configInfoData } interface configInfoData { description: string @@ -80,20 +66,23 @@ interface configInfoData { /******************* ****** User ****** *******************/ -interface AppClient { - readonly actionKey: string - readonly platform: string - readonly appKey: string - readonly build: string - readonly device: string - readonly mobiApp: string - readonly TS: number - readonly RND: number - readonly DeviceID: string - readonly baseQuery: string - signQuery(params: string, ts?: boolean): string - signQueryBase(params?: string): string - readonly status: typeof status +interface requestHeaders { + [index: string]: string +} +declare class AppClient { + static actionKey: string + static platform: string + static appKey: string + static build: string + static device: string + static mobiApp: string + static TS: number + static RND: number + static DeviceID: string + static baseQuery: string + static signQuery(params: string, ts?: boolean): string + static signQueryBase(params?: string): string + static status: typeof status captcha: string userName: string passWord: string @@ -101,14 +90,15 @@ interface AppClient { accessToken: string refreshToken: string cookieString: string - headers: Headers + headers: requestHeaders init(): Promise getCaptcha(): Promise login(): Promise logout(): Promise refresh(): Promise } -interface Online extends AppClient { +declare class Online extends AppClient { + uid: string userData: userData readonly nickname: string jar: { @@ -120,21 +110,7 @@ interface Online extends AppClient { Stop(): void getOnlineInfo(roomID?: number): Promise<'captcha' | 'stop' | void> } -interface Daily extends Online { - uid: string - Start(): Promise<'captcha' | 'stop' | void> - Stop(): void - nextDay(): Promise - daily(): Promise - sign(): Promise - treasureBox(): Promise - eventRoom(): Promise - silver2coin(): Promise - sendGift(): Promise - checkBag(): Promise | undefined> - signGroup(): Promise -} -type User = Daily +type User = Online /******************* **** dm_client **** *******************/ @@ -510,241 +486,6 @@ interface userOnlineHeart { code: number msg: string } -/******************* - ***** daily ******* - *******************/ -/** - * 签到信息 - * - * @interface signInfo - */ -interface signInfo { - code: number - msg: string - data: signInfoData -} -interface signInfoData { - text: string - status: number - allDays: string - curMonth: string - newTask: number - hadSignDays: number - remindDays: number -} -/** - * 在线领瓜子宝箱 - * - * @interface currentTask - */ -interface currentTask { - code: number - msg: string - data: currentTaskData -} -interface currentTaskData { - minute: number - silver: number - time_start: number - time_end: number -} -/** - * 领瓜子答案提交返回 - * - * @interface award - */ -interface award { - code: number - msg: string - data: awardData -} -interface awardData { - silver: number - awardSilver: number - isEnd: number -} -/** - * 房间信息 - * - * @interface roomInit - */ -interface roomInit { - code: number - msg: string - message: string - data: roomInitDataData -} -interface roomInitDataData { - room_id: number - short_id: number - uid: number - need_p2p: number - is_hidden: boolean - is_locked: boolean - is_portrait: boolean - live_status: number - hidden_till: number - lock_till: number - encrypted: boolean - pwd_verified: boolean -} -/** - * 分享房间返回 - * - * @interface shareCallback - */ -interface shareCallback { - code: number - msg: string - message: string -} -/** - * 每日包裹 - * - * @interface getBagGift - */ -interface getBagGift { - code: number -} -/** - * 包裹信息 - * - * @interface bagInfo - */ -interface bagInfo { - code: number - msg: string - message: string - data: bagInfoData[] -} -interface bagInfoData { - id: number - uid: number - gift_id: number - gift_num: number - expireat: number - gift_type: number - gift_name: string - gift_price: string - img: string - count_set: string - combo_num: number - super_num: number -} -/** - * 赠送包裹礼物 - * - * @interface sendBag - */ -interface sendBag { - code: number - msg: string - message: string - data: sendBagData -} -interface sendBagData { - tid: string - uid: number - uname: string - ruid: number - rcost: number - gift_id: number - gift_type: number - gift_name: string - gift_num: number - gift_action: string - gift_price: number - coin_type: string - total_coin: number - metadata: string - rnd: string -} -/** - * 应援团 - * - * @interface linkGroup - */ -interface linkGroup { - code: number - msg: string - message: string - data: linkGroupData -} -interface linkGroupData { - list: linkGroupInfo[] -} -interface linkGroupInfo { - group_id: number - owner_uid: number - owner_name: string - group_type: number - group_level: number - group_cover: string - group_name: string - group_notice: string - group_status: number -} -/** - * 应援团签到返回 - * - * @interface signGroup - */ -interface signGroup { - code: number - msg: string - message: string - data: signGroupData -} -interface signGroupData { - add_num: number - status: number -} -/** - * 银瓜子兑换硬币返回 - * - * @interface silver2coin - */ -interface silver2coin { - code: number - msg: string - message: string - data: silver2coinData -} -interface silver2coinData { - silver: string - gold: string - tid: string - coin: number -} -/** - * 每日任务 - * - * @interface taskInfo - */ -interface taskInfo { - code: number - msg: string - data: taskInfoData -} -interface taskInfoData { - [index: string]: taskInfoDoublewatchinfo -} -interface taskInfoDoublewatchinfo { - task_id: string | undefined -} -/** - * 兑换扭蛋币 - * - * @interface capsule - */ -interface capsule { - code: number - msg: string - data: capsuleData | any[] -} -interface capsuleData { - capsule: SEND_GIFT_data_capsule -} /******************* ***** options ***** *******************/ @@ -754,8 +495,8 @@ interface Options { whiteList: Set shortRoomID: Map longRoomID: Map - init: () => void - save: () => Promise + init(): void + save(): Promise } /******************* ****** plugin ***** @@ -766,8 +507,8 @@ interface IPlugin { version: string author: string loaded: boolean - start?({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }): Promise - once?({ options, users }: { options: options, users: Map }): Promise + load?({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }): Promise + start?({ options, users }: { options: options, users: Map }): Promise loop?({ cst, cstMin, cstHour, cstString, options, users }: { cst: Date, cstMin: number, cstHour: number, cstString: string, options: options, users: Map }): Promise msg?({ message, options, users }: { message: raffleMessage | lotteryMessage | beatStormMessage, options: options, users: Map }): Promise } \ No newline at end of file diff --git a/bilive/daily.ts b/bilive/daily.ts deleted file mode 100644 index 24646e2..0000000 --- a/bilive/daily.ts +++ /dev/null @@ -1,298 +0,0 @@ -import tools from './lib/tools' -import Online from './online' -import AppClient from './lib/app_client' -import Options, { liveOrigin, apiVCOrigin, apiLiveOrigin } from './options' -import { Options as requestOptions } from 'request' -/** - * Creates an instance of Daily. - * - * @class Daily - * @extends {Online} - */ -class Daily extends Online { - /** - * Creates an instance of Daily. - * @param {string} uid - * @param {userData} userData - * @memberof Daily - */ - constructor(uid: string, userData: userData) { - super(userData) - this.uid = uid - } - // 存储用户信息 - public uid: string - // 用户状态 - private _sign = false - private _treasureBox = false - private _eventRoom = false - private _silver2coin = false - /** - * 当账号出现异常时, 会返回'captcha'或'stop' - * 'captcha'为登录需要验证码, 若无法处理需Stop() - * - * @returns {(Promise<'captcha' | 'stop' | void>)} - * @memberof Daily - */ - public Start(): Promise<'captcha' | 'stop' | void> { - // @ts-ignore 继承属性 - if (!Options.user.has(this.uid)) Options.user.set(this.uid, this) - return super.Start() - } - /** - * 停止挂机 - * - * @memberof Daily - */ - public Stop() { - Options.user.delete(this.uid) - return super.Stop() - } - /** - * 零点重置 - * 为了少几个定时器, 统一由外部调用 - * - * @memberof Daily - */ - public async nextDay() { - // 每天刷新token和cookie - const refresh = await this.refresh() - if (refresh.status === AppClient.status.success) { - this.jar = tools.setCookie(this.cookieString) - Options.save() - } - else if (refresh.status === AppClient.status.error) { - const status = await this._tokenError() - if (status !== undefined) return this.Stop() - } - this._sign = false - this._treasureBox = false - this._eventRoom = false - this._silver2coin = false - } - /** - * 日常 - * - * @memberof Daily - */ - public async daily() { - await this.sign() - this.treasureBox() - this.eventRoom() - this.silver2coin() - this.sendGift() - this.signGroup() - } - /** - * 每日签到 - * - * @memberof Daily - */ - public async sign() { - if (this._sign || !this.userData.doSign) return - let ok = 0 - // 签到 - const sign: requestOptions = { - uri: `${apiLiveOrigin}/AppUser/getSignInfo?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - const signInfo = await tools.XHR(sign, 'Android') - if (signInfo !== undefined && signInfo.response.statusCode === 200 && signInfo.body.code === 0) { - ok++ - tools.Log(this.nickname, '每日签到', '已签到') - } - // 道具包裹 - const getBag: requestOptions = { - uri: `${apiLiveOrigin}/AppBag/getSendGift?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - const getBagGift = await tools.XHR(getBag, 'Android') - if (getBagGift !== undefined && getBagGift.response.statusCode === 200 && getBagGift.body.code === 0) { - ok++ - tools.Log(this.nickname, '每日签到', '已获取每日包裹') - } - if (ok === 2) this._sign = true - } - /** - * 每日宝箱 - * - * @memberof Daily - */ - public async treasureBox() { - if (this._treasureBox || !this.userData.treasureBox) return - // 获取宝箱状态,换房间会重新冷却 - const current: requestOptions = { - uri: `${apiLiveOrigin}/mobile/freeSilverCurrentTask?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - const currentTask = await tools.XHR(current, 'Android') - if (currentTask !== undefined && currentTask.response.statusCode === 200) { - if (currentTask.body.code === 0) { - await tools.Sleep(currentTask.body.data.minute * 6e4) - const award: requestOptions = { - uri: `${apiLiveOrigin}/mobile/freeSilverAward?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - await tools.XHR(award, 'Android') - this.treasureBox() - } - else if (currentTask.body.code === -10017) { - this._treasureBox = true - tools.Log(this.nickname, '每日宝箱', '已领取所有宝箱') - } - } - } - /** - * 每日任务 - * - * @memberof Daily - */ - public async eventRoom() { - if (this._eventRoom || !this.userData.eventRoom) return - // 做任务 - const task: requestOptions = { - method: 'POST', - uri: `${apiLiveOrigin}/activity/v1/task/receive_award`, - body: `task_id=double_watch_task`, - jar: this.jar, - json: true, - headers: { 'Referer': `${liveOrigin}/p/center/index` } - } - const doubleWatchTask = await tools.XHR<{ code: number }>(task) - if (doubleWatchTask === undefined || doubleWatchTask.response.statusCode !== 200) return - if (doubleWatchTask.body.code === 0 || doubleWatchTask.body.code === -400) - tools.Log(this.nickname, '每日任务', '每日任务已完成') - else tools.Log(this.nickname, '每日任务', doubleWatchTask.body) - } - /** - * 银瓜子兑换硬币 - * - * @memberof Daily - */ - public async silver2coin() { - if (this._silver2coin || !this.userData.silver2coin) return - const exchange: requestOptions = { - method: 'POST', - uri: `${apiLiveOrigin}/AppExchange/silver2coin?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - const silver2coin = await tools.XHR(exchange, 'Android') - if (silver2coin === undefined || silver2coin.response.statusCode !== 200) return - if (silver2coin.body.code === 0) { - this._silver2coin = true - tools.Log(this.nickname, '银瓜子兑换硬币', '成功兑换 1 个硬币') - } - else if (silver2coin.body.code === 403) { - this._silver2coin = true - tools.Log(this.nickname, '银瓜子兑换硬币', silver2coin.body.msg) - } - else tools.Log(this.nickname, '银瓜子兑换硬币', '兑换失败', silver2coin.body) - } - /** - * 自动送礼 - * - * @memberof Daily - */ - public async sendGift() { - if (!this.userData.sendGift || this.userData.sendGiftRoom === 0) return - const roomID = this.userData.sendGiftRoom - // 获取房间信息 - const room: requestOptions = { - uri: `${apiLiveOrigin}/room/v1/Room/mobileRoomInit?id=${roomID}}`, - json: true - } - const roomInit = await tools.XHR(room, 'Android') - if (roomInit === undefined || roomInit.response.statusCode !== 200) return - if (roomInit.body.code === 0) { - // masterID - const mid = roomInit.body.data.uid - const room_id = roomInit.body.data.room_id - // 获取包裹信息 - const bagInfo = await this.checkBag() - if (bagInfo === undefined || bagInfo.response.statusCode !== 200) return - if (bagInfo.body.code === 0) { - if (bagInfo.body.data.length > 0) { - for (const giftData of bagInfo.body.data) { - if (giftData.expireat > 0 && giftData.expireat < 24 * 60 * 60) { - // expireat单位为分钟, 永久礼物值为0 - const send: requestOptions = { - method: 'POST', - uri: `${apiLiveOrigin}/gift/v2/live/bag_send?${AppClient.signQueryBase(this.tokenQuery)}`, - body: `uid=${giftData.uid}&ruid=${mid}&gift_id=${giftData.gift_id}&gift_num=${giftData.gift_num}&bag_id=${giftData.id}\ -&biz_id=${room_id}&rnd=${AppClient.RND}&biz_code=live&jumpFrom=21002`, - json: true, - headers: this.headers - } - const sendBag = await tools.XHR(send, 'Android') - if (sendBag === undefined || sendBag.response.statusCode !== 200) continue - if (sendBag.body.code === 0) { - const sendBagData = sendBag.body.data - tools.Log(this.nickname, '自动送礼', `向房间 ${roomID} 赠送 ${sendBagData.gift_num} 个${sendBagData.gift_name}`) - } - else tools.Log(this.nickname, '自动送礼', `向房间 ${roomID} 赠送 ${giftData.gift_num} 个${giftData.gift_name} 失败`, sendBag.body) - await tools.Sleep(3000) - } - } - } - } - else tools.Log(this.nickname, '自动送礼', '获取包裹信息失败', bagInfo.body) - } - else tools.Log(this.nickname, '自动送礼', '获取房间信息失败', roomInit.body) - } - /** - * 获取包裹信息 - * - * @returns {(Promise | undefined>)} - * @memberof Daily - */ - public checkBag() { - const bag: requestOptions = { - uri: `${apiLiveOrigin}/gift/v2/gift/m_bag_list?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - return tools.XHR(bag, 'Android') - } - /** - * 应援团签到 - * - * @memberof Daily - */ - public async signGroup() { - if (!this.userData.signGroup) return - // 获取已加入应援团列表 - const group: requestOptions = { - uri: `${apiVCOrigin}/link_group/v1/member/my_groups?${AppClient.signQueryBase(this.tokenQuery)}`, - json: true, - headers: this.headers - } - const linkGroup = await tools.XHR(group, 'Android') - if (linkGroup === undefined || linkGroup.response.statusCode !== 200) return - if (linkGroup.body.code === 0) { - if (linkGroup.body.data.list.length > 0) { - for (const groupInfo of linkGroup.body.data.list) { - const sign: requestOptions = { - uri: `${apiVCOrigin}/link_setting/v1/link_setting/sign_in?${AppClient.signQueryBase(`${this.tokenQuery}&group_id=${groupInfo.group_id}\ -&owner_id=${groupInfo.owner_uid}`)}`, - json: true, - headers: this.headers - } - // 应援团自动签到 - const signGroup = await tools.XHR(sign, 'Android') - if (signGroup === undefined || signGroup.response.statusCode !== 200) continue - if (signGroup.body.data.add_num > 0) - tools.Log(this.nickname, '应援团签到', `在${groupInfo.group_name}签到获得 ${signGroup.body.data.add_num} 点亲密度`) - else tools.Log(this.nickname, '应援团签到', `已在${groupInfo.group_name}签到过`) - await tools.Sleep(3000) - } - } - } - else tools.Log(this.nickname, '应援团签到', '获取应援团列表失败', linkGroup.body) - } -} -export default Daily \ No newline at end of file diff --git a/bilive/index.ts b/bilive/index.ts index ca61774..5085eef 100644 --- a/bilive/index.ts +++ b/bilive/index.ts @@ -1,7 +1,7 @@ import fs from 'fs' import util from 'util' import tools from './lib/tools' -import User from './daily' +import User from './online' import WebAPI from './webapi' import Listener from './listener' import Options from './options' @@ -35,18 +35,24 @@ class BiLive { public async Start() { // 加载插件 await this._loadPlugin() + // 初始化设置 Options.init() + // 新用户 + Options.on('newUser', (user: User) => { + // 运行插件 + this._pluginList.forEach(plugin => { + if (plugin.start !== undefined) plugin.start({ options: Options._, users: new Map([[user.uid, user]]) }) + }) + }) for (const uid in Options._.user) { if (!Options._.user[uid].status) continue const user = new User(uid, Options._.user[uid]) const status = await user.Start() if (status !== undefined) user.Stop() } - Options.user.forEach(user => user.daily()) - // 插件运行 + // 运行插件 this._pluginList.forEach(plugin => { - if (plugin.once !== undefined) - plugin.once({ options: Options._, users: Options.user }) + if (plugin.start !== undefined) plugin.start({ options: Options._, users: Options.user }) }) this.loop = setInterval(() => this._loop(), 50 * 1000) new WebAPI().Start() @@ -66,19 +72,13 @@ class BiLive { this._lastTime = cstString const cstHour = cst.getUTCHours() const cstMin = cst.getUTCMinutes() - // 每天00:10刷新任务 - if (cstString === '00:10') Options.user.forEach(user => user.nextDay()) - // 每天13:55再次自动送礼, 因为一般活动14:00结束 - else if (cstString === '13:55') Options.user.forEach(user => user.sendGift()) - // 每天04:30, 12:30, 20:30做日常 - if (cstMin === 30 && cstHour % 8 === 4) Options.user.forEach(user => user.daily()) if (cstMin % 10 === 0) { // 更新监听房间 this._Listener.updateAreaRoom() // 清空ID缓存 this._Listener.clearAllID() } - // 插件运行 + // 运行插件 this._pluginList.forEach(plugin => { if (plugin.loop !== undefined) plugin.loop({ cst, cstMin, cstHour, cstString, options: Options._, users: Options.user }) @@ -95,7 +95,7 @@ class BiLive { const plugins = await FSreadDir(pluginsPath) for (const pluginName of plugins) { const { default: plugin }: { default: IPlugin } = await import(`${pluginsPath}/${pluginName}/index.js`) - if (plugin.start !== undefined) await plugin.start({ defaultOptions: Options._, whiteList: Options.whiteList }) + if (plugin.load !== undefined) await plugin.load({ defaultOptions: Options._, whiteList: Options.whiteList }) if (plugin.loaded) { const { name, description, version, author } = plugin tools.Log(`已加载: ${name}, 用于: ${description}, 版本: ${version}, 作者: ${author}`) @@ -125,7 +125,7 @@ class BiLive { * @memberof BiLive */ private async _Message(raffleMessage: raffleMessage | lotteryMessage | beatStormMessage) { - // 插件运行 + // 运行插件 this._pluginList.forEach(plugin => { if (plugin.msg !== undefined) plugin.msg({ message: raffleMessage, options: Options._, users: Options.user }) diff --git a/bilive/online.ts b/bilive/online.ts index 2332428..ec8b139 100644 --- a/bilive/online.ts +++ b/bilive/online.ts @@ -10,15 +10,18 @@ import Options, { apiLiveOrigin, liveOrigin } from './options' */ class Online extends AppClient { /** - * Creates an instance of Online. + *Creates an instance of Online. + * @param {string} uid * @param {userData} userData * @memberof Online */ - constructor(userData: userData) { + constructor(uid: string, userData: userData) { super() + this.uid = uid this.userData = userData } // 存储用户信息 + public uid: string public userData: userData public get nickname(): string { return this.userData.nickname } public get userName(): string { return this.userData.userName } @@ -66,6 +69,7 @@ class Online extends AppClient { */ public async Start(): Promise<'captcha' | 'stop' | void> { clearTimeout(this._heartTimer) + if (!Options.user.has(this.uid)) Options.user.set(this.uid, this) if (this.jar === undefined) { await this.init() this.jar = tools.setCookie(this.cookieString) @@ -81,6 +85,7 @@ class Online extends AppClient { */ public Stop() { clearTimeout(this._heartTimer) + Options.user.delete(this.uid) this.userData.status = false Options.save() tools.sendSCMSG(`${this.nickname} 已停止挂机`) diff --git a/bilive/options.default.json b/bilive/options.default.json index 9ec0edb..8f1ffbc 100644 --- a/bilive/options.default.json +++ b/bilive/options.default.json @@ -22,14 +22,7 @@ "accessToken": "", "refreshToken": "", "cookie": "", - "status": false, - "doSign": false, - "treasureBox": false, - "eventRoom": false, - "silver2coin": false, - "sendGift": false, - "sendGiftRoom": 0, - "signGroup": false + "status": false }, "info": { "defaultUserID": { @@ -81,41 +74,6 @@ "description": "开关", "tip": "用户设置的总开关, 关闭时以下设置全部失效", "type": "boolean" - }, - "doSign": { - "description": "签到", - "tip": "每日签到", - "type": "boolean" - }, - "treasureBox": { - "description": "宝箱", - "tip": "宝箱领瓜子", - "type": "boolean" - }, - "eventRoom": { - "description": "每日任务", - "tip": "每日任务", - "type": "boolean" - }, - "silver2coin": { - "description": "银瓜子兑换硬币", - "tip": "自动将银瓜子兑换成硬币, 每天两个", - "type": "boolean" - }, - "sendGift": { - "description": "自动送礼", - "tip": "自动送出剩余时间不足24小时的礼物", - "type": "boolean" - }, - "sendGiftRoom": { - "description": "自动送礼房间", - "tip": "要自动送出礼物的房间号", - "type": "number" - }, - "signGroup": { - "description": "应援团签到", - "tip": "自动签到所有已加入的应援团", - "type": "boolean" } }, "roomList": [ diff --git a/bilive/plugin.ts b/bilive/plugin.ts new file mode 100644 index 0000000..885031a --- /dev/null +++ b/bilive/plugin.ts @@ -0,0 +1,42 @@ +import { EventEmitter } from 'events' +import tools from './lib/tools' +import AppClient from './lib/app_client' + +class Plugin extends EventEmitter implements IPlugin { + constructor() { + super() + } + /** + * 插件名 + * + * @memberof Plugin + */ + public name = '测试插件' + /** + * 说明 + * + * @memberof Plugin + */ + public description = '这是用来测试的' + /** + * 版本 + * + * @memberof Plugin + */ + public version = '0.0.1' + /** + * 作者 + * + * @memberof Plugin + */ + public author = 'lzghzr' + /** + * 是否已加载 + * + * @memberof Plugin + */ + public loaded = false +} + +export default Plugin +export { tools, AppClient } \ No newline at end of file diff --git a/bilive/plugins/calcgift/index.ts b/bilive/plugins/calcgift/index.ts index d783aec..9ae7648 100644 --- a/bilive/plugins/calcgift/index.ts +++ b/bilive/plugins/calcgift/index.ts @@ -1,14 +1,15 @@ import { Options as requestOptions } from 'request' -import tools from '../../lib/tools' -import AppClient from '../../lib/app_client' +import Plugin, { tools } from '../../plugin' -class CalcGift implements IPlugin { - public name = '礼物统计插件' - public description = '固定时间统计礼物, 并发送到指定位置' +class CalcGift extends Plugin { + constructor() { + super() + } + public name = '礼物统计' + public description = '指定时间统计礼物, 并发送到指定位置' public version = '0.0.1' public author = 'lzghzr' - public loaded = false - public async start({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { defaultOptions.config['calcGiftTime'] = '' defaultOptions.info['calcGiftTime'] = { description: '汇报礼物时间', @@ -81,7 +82,6 @@ class CalcGift implements IPlugin { tools.sendSCMSG(table) } } - public async msg() { } } /** diff --git a/bilive/plugins/getbag/index.ts b/bilive/plugins/getbag/index.ts new file mode 100644 index 0000000..5fcff1f --- /dev/null +++ b/bilive/plugins/getbag/index.ts @@ -0,0 +1,67 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class Bag extends Plugin { + constructor() { + super() + } + public name = '包裹道具' + public description = '领取直播包裹道具' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof Bag + */ + private _getBagList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 包裹道具 + defaultOptions.newUserData['getBag'] = false + defaultOptions.info['getBag'] = { + description: '包裹道具', + tip: '领取直播包裹道具', + type: 'boolean' + } + whiteList.add('getBag') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._getBag(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._getBagList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._getBag(users) + } + /** + * 包裹道具 + * + * @private + * @memberof Bag + */ + private _getBag(users: Map) { + users.forEach(async (user, uid) => { + if (this._getBagList.get(uid) || !user.userData['getBag']) return + const getBag: requestOptions = { + uri: `https://api.live.bilibili.com/AppBag/getSendGift?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const getBagGift = await tools.XHR<{ code: number }>(getBag, 'Android') + if (getBagGift !== undefined && getBagGift.response.statusCode === 200) { + if (getBagGift.body.code === 0) { + this._getBagList.set(uid, true) + tools.Log(user.nickname, '包裹道具', '已获取每日包裹道具') + } + else tools.Log(user.nickname, '包裹道具', getBagGift.body) + } + else tools.Log(user.nickname, '包裹道具', '网络错误') + }) + } +} + +export default new Bag() \ No newline at end of file diff --git a/bilive/plugins/raffle/index.ts b/bilive/plugins/raffle/index.ts index 260f8e9..25791a3 100644 --- a/bilive/plugins/raffle/index.ts +++ b/bilive/plugins/raffle/index.ts @@ -1,15 +1,17 @@ import Lottery from './raffle' -import tools from '../../lib/tools' +import Plugin, { tools } from '../../plugin' -class Raffle implements IPlugin { +class Raffle extends Plugin { + constructor() { + super() + } public name = '抽奖插件' public description = '自动参与抽奖' public version = '0.0.1' public author = 'lzghzr' - public loaded = false // 是否开启抽奖 private _raffle = false - public async start({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { // 抽奖延时 defaultOptions.config['raffleDelay'] = 0 defaultOptions.info['raffleDelay'] = { diff --git a/bilive/plugins/raffle/raffle.ts b/bilive/plugins/raffle/raffle.ts index 166892d..473dd82 100644 --- a/bilive/plugins/raffle/raffle.ts +++ b/bilive/plugins/raffle/raffle.ts @@ -1,6 +1,5 @@ import { Options as requestOptions } from 'request' -import tools from '../../lib/tools' -import AppClient from '../../lib/app_client' +import { tools, AppClient } from '../../plugin' /** * 自动参与抽奖 * diff --git a/bilive/plugins/sendgift/index.ts b/bilive/plugins/sendgift/index.ts new file mode 100644 index 0000000..b1aad26 --- /dev/null +++ b/bilive/plugins/sendgift/index.ts @@ -0,0 +1,184 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class SendGift extends Plugin { + constructor() { + super() + } + public name = '自动送礼' + public description = '在指定房间送出剩余时间不足24小时的礼物' + public version = '0.0.1' + public author = 'lzghzr' + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 自动送礼 + defaultOptions.newUserData['sendGift'] = false + defaultOptions.info['sendGift'] = { + description: '自动送礼', + tip: '自动送出剩余时间不足24小时的礼物', + type: 'boolean' + } + whiteList.add('sendGift') + // 自动送礼房间 + defaultOptions.newUserData['sendGiftRoom'] = 0 + defaultOptions.info['sendGiftRoom'] = { + description: '自动送礼房间', + tip: '要自动送出礼物的房间号', + type: 'number' + } + whiteList.add('sendGiftRoom') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._sendGift(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天04:30, 12:30, 13:55, 20:30自动送礼, 因为一般活动14:00结束 + if (cstMin === 30 && cstHour % 8 === 4 || cstString === '13:55') this._sendGift(users) + } + /** + * 自动送礼 + * + * @private + * @memberof SendGift + */ + private _sendGift(users: Map) { + users.forEach(async user => { + if (!user.userData['sendGift'] || user.userData['sendGiftRoom'] === 0) return + const roomID = user.userData.sendGiftRoom + // 获取房间信息 + const room: requestOptions = { + uri: `https://api.live.bilibili.com/room/v1/Room/mobileRoomInit?id=${roomID}}`, + json: true + } + const roomInit = await tools.XHR(room, 'Android') + if (roomInit !== undefined && roomInit.response.statusCode === 200) { + if (roomInit.body.code === 0) { + // masterID + const mid = roomInit.body.data.uid + const room_id = roomInit.body.data.room_id + // 获取包裹信息 + const bag: requestOptions = { + uri: `https://api.live.bilibili.com/gift/v2/gift/m_bag_list?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const bagInfo = await tools.XHR(bag, 'Android') + if (bagInfo !== undefined && bagInfo.response.statusCode === 200) { + if (bagInfo.body.code === 0) { + if (bagInfo.body.data.length > 0) { + for (const giftData of bagInfo.body.data) { + if (giftData.expireat > 0 && giftData.expireat < 24 * 60 * 60) { + // expireat单位为分钟, 永久礼物值为0 + const send: requestOptions = { + method: 'POST', + uri: `https://api.live.bilibili.com/gift/v2/live/bag_send?${AppClient.signQueryBase(user.tokenQuery)}`, + body: `uid=${giftData.uid}&ruid=${mid}&gift_id=${giftData.gift_id}&gift_num=${giftData.gift_num}\ +&bag_id=${giftData.id}&biz_id=${room_id}&rnd=${AppClient.RND}&biz_code=live&jumpFrom=21002`, + json: true, + headers: user.headers + } + const sendBag = await tools.XHR(send, 'Android') + if (sendBag !== undefined && sendBag.response.statusCode === 200) { + if (sendBag.body.code === 0) { + const sendBagData = sendBag.body.data + tools.Log(user.nickname, '自动送礼', `向房间 ${roomID} 赠送 ${sendBagData.gift_num} 个${sendBagData.gift_name}`) + } + else tools.Log(user.nickname, '自动送礼', sendBag.body) + } + else tools.Log(user.nickname, '自动送礼', '网络错误') + await tools.Sleep(3000) + } + } + } + } + else tools.Log(user.nickname, '自动送礼', '包裹信息', bagInfo.body) + } + else tools.Log(user.nickname, '自动送礼', '包裹信息', '网络错误') + } + else tools.Log(user.nickname, '自动送礼', '房间信息', roomInit.body) + } + else tools.Log(user.nickname, '自动送礼', '房间信息', '网络错误') + }) + } +} + +/** + * 房间信息 + * + * @interface roomInit + */ +interface roomInit { + code: number + msg: string + message: string + data: roomInitDataData +} +interface roomInitDataData { + room_id: number + short_id: number + uid: number + need_p2p: number + is_hidden: boolean + is_locked: boolean + is_portrait: boolean + live_status: number + hidden_till: number + lock_till: number + encrypted: boolean + pwd_verified: boolean +} +/** + * 包裹信息 + * + * @interface bagInfo + */ +interface bagInfo { + code: number + msg: string + message: string + data: bagInfoData[] +} +interface bagInfoData { + id: number + uid: number + gift_id: number + gift_num: number + expireat: number + gift_type: number + gift_name: string + gift_price: string + img: string + count_set: string + combo_num: number + super_num: number +} +/** + * 赠送包裹礼物 + * + * @interface sendBag + */ +interface sendBag { + code: number + msg: string + message: string + data: sendBagData +} +interface sendBagData { + tid: string + uid: number + uname: string + ruid: number + rcost: number + gift_id: number + gift_type: number + gift_name: string + gift_num: number + gift_action: string + gift_price: number + coin_type: string + total_coin: number + metadata: string + rnd: string +} + +export default new SendGift() \ No newline at end of file diff --git a/bilive/plugins/sign/index.ts b/bilive/plugins/sign/index.ts new file mode 100644 index 0000000..ef43d92 --- /dev/null +++ b/bilive/plugins/sign/index.ts @@ -0,0 +1,87 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class Sign extends Plugin { + constructor() { + super() + } + public name = '自动签到' + public description = '每天自动签到' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof Sign + */ + private _signList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 自动签到 + defaultOptions.newUserData['doSign'] = false + defaultOptions.info['doSign'] = { + description: '自动签到', + tip: '每天自动签到', + type: 'boolean' + } + whiteList.add('doSign') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._sign(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._signList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._sign(users) + } + /** + * 自动签到 + * + * @private + * @memberof Sign + */ + private _sign(users: Map) { + users.forEach(async (user, uid) => { + if (this._signList.get(uid) || !user.userData['doSign']) return + const sign: requestOptions = { + uri: `https://api.live.bilibili.com/AppUser/getSignInfo?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const signInfo = await tools.XHR(sign, 'Android') + if (signInfo !== undefined && signInfo.response.statusCode === 200) { + if (signInfo.body.code === 0 || signInfo.body.code === -500) { + this._signList.set(uid, true) + tools.Log(user.nickname, '自动签到', '已签到') + } + else tools.Log(user.nickname, '自动签到', signInfo.body) + } + else tools.Log(user.nickname, '自动签到', '网络错误') + }) + } +} + +/** + * 签到信息 + * + * @interface signInfo + */ +interface signInfo { + code: number + msg: string + data: signInfoData +} +interface signInfoData { + text: string + status: number + allDays: string + curMonth: string + newTask: number + hadSignDays: number + remindDays: number +} + +export default new Sign() \ No newline at end of file diff --git a/bilive/plugins/signgroup/index.ts b/bilive/plugins/signgroup/index.ts new file mode 100644 index 0000000..4d6e658 --- /dev/null +++ b/bilive/plugins/signgroup/index.ts @@ -0,0 +1,129 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class SignGroup extends Plugin { + constructor() { + super() + } + public name = '应援团签到' + public description = '在已加入的应援团签到' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof SignGroup + */ + private _signGroupList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 应援团签到 + defaultOptions.newUserData['signGroup'] = false + defaultOptions.info['signGroup'] = { + description: '应援团签到', + tip: '在已加入的应援团签到', + type: 'boolean' + } + whiteList.add('signGroup') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._signGroup(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._signGroupList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._signGroup(users) + } + /** + * 应援团签到 + * + * @private + * @memberof SignGroup + */ + private _signGroup(users: Map) { + users.forEach(async (user, uid) => { + if (this._signGroupList.get(uid) || !user.userData['signGroup']) return + // 获取已加入应援团列表 + const group: requestOptions = { + uri: `https://api.live.bilibili.com/link_group/v1/member/my_groups?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const linkGroup = await tools.XHR(group, 'Android') + if (linkGroup !== undefined && linkGroup.response.statusCode === 200) { + if (linkGroup.body.code === 0) { + const listLength = linkGroup.body.data.list.length + if (listLength === 0 || listLength === this._signGroupList.get(uid)) return + let ok = 0 + for (const groupInfo of linkGroup.body.data.list) { + const sign: requestOptions = { + uri: `https://api.live.bilibili.com/link_setting/v1/link_setting/sign_in?\ +${AppClient.signQueryBase(`${user.tokenQuery}&group_id=${groupInfo.group_id}&owner_id=${groupInfo.owner_uid}`)}`, + json: true, + headers: user.headers + } + // 应援团签到 + const signGroup = await tools.XHR(sign, 'Android') + if (signGroup !== undefined && signGroup.response.statusCode === 200) { + ok++ + if (signGroup.body.data.add_num > 0) + tools.Log(user.nickname, '应援团签到', `在${groupInfo.group_name}签到获得 ${signGroup.body.data.add_num} 点亲密度`) + else tools.Log(user.nickname, '应援团签到', `已在${groupInfo.group_name}签到过`) + } + else tools.Log(user.nickname, '应援团签到', '网络错误') + await tools.Sleep(3000) + } + this._signGroupList.set(uid, ok) + } + else tools.Log(user.nickname, '应援团签到', '获取列表', linkGroup.body) + } + else tools.Log(user.nickname, '应援团签到', '获取列表', '网络错误') + }) + } +} + +/** + * 应援团 + * + * @interface linkGroup + */ +interface linkGroup { + code: number + msg: string + message: string + data: linkGroupData +} +interface linkGroupData { + list: linkGroupInfo[] +} +interface linkGroupInfo { + group_id: number + owner_uid: number + owner_name: string + group_type: number + group_level: number + group_cover: string + group_name: string + group_notice: string + group_status: number +} +/** + * 应援团签到返回 + * + * @interface signGroup + */ +interface signGroup { + code: number + msg: string + message: string + data: signGroupData +} +interface signGroupData { + add_num: number + status: number +} + +export default new SignGroup() \ No newline at end of file diff --git a/bilive/plugins/silver2coin/index.ts b/bilive/plugins/silver2coin/index.ts new file mode 100644 index 0000000..1dc5d90 --- /dev/null +++ b/bilive/plugins/silver2coin/index.ts @@ -0,0 +1,86 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class Coin extends Plugin { + constructor() { + super() + } + public name = '兑换硬币' + public description = '将银瓜子兑换成硬币' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof Coin + */ + private _silver2coinList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 兑换硬币 + defaultOptions.newUserData['silver2coin'] = false + defaultOptions.info['silver2coin'] = { + description: '兑换硬币', + tip: '将银瓜子兑换成硬币', + type: 'boolean' + } + whiteList.add('silver2coin') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._silver2coin(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._silver2coinList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._silver2coin(users) + } + /** + * 兑换硬币 + * + * @private + * @memberof Coin + */ + private _silver2coin(users: Map) { + users.forEach(async (user, uid) => { + if (this._silver2coinList.get(uid) || !user.userData['silver2coin']) return + const exchange: requestOptions = { + method: 'POST', + uri: `https://api.live.bilibili.com/AppExchange/silver2coin?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const silver2coin = await tools.XHR(exchange, 'Android') + if (silver2coin !== undefined && silver2coin.response.statusCode === 200) { + if (silver2coin.body.code === 0 || silver2coin.body.code === 403) { + this._silver2coinList.set(uid, true) + tools.Log(user.nickname, '兑换硬币', '已成功兑换硬币') + } + else tools.Log(user.nickname, '兑换硬币', silver2coin.body) + } + else tools.Log(user.nickname, '兑换硬币', '网络错误') + }) + } +} + +/** + * 银瓜子兑换硬币返回 + * + * @interface silver2coin + */ +interface silver2coin { + code: number + msg: string + message: string + data: silver2coinData +} +interface silver2coinData { + silver: string + gold: string + tid: string + coin: number +} + +export default new Coin() \ No newline at end of file diff --git a/bilive/plugins/task/index.ts b/bilive/plugins/task/index.ts new file mode 100644 index 0000000..942d197 --- /dev/null +++ b/bilive/plugins/task/index.ts @@ -0,0 +1,88 @@ +import { Options as requestOptions, CookieJar as requestCookieJar } from 'request' +import Plugin, { tools } from '../../plugin' + +class Task extends Plugin { + constructor() { + super() + } + public name = '日常任务' + public description = '完成日常任务' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof Task + */ + private _taskList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 日常任务 + defaultOptions.newUserData['doTask'] = false + defaultOptions.info['doTask'] = { + description: '日常任务', + tip: '完成日常任务', + type: 'boolean' + } + whiteList.add('doTask') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._task(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._taskList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._task(users) + } + /** + * 日常任务 + * + * @private + * @memberof Task + */ + private _task(users: Map) { + users.forEach(async (user, uid) => { + if (this._taskList.get(uid) || !user.userData['doTask']) return + const task: requestOptions = { + method: 'POST', + uri: 'https://api.live.bilibili.com/activity/v1/task/receive_award', + body: `task_id=double_watch_task`, + jar: user.jar, + json: true, + headers: { 'Referer': 'https://live.bilibili.com/p/center/index' } + } + const doubleWatchTask = await tools.XHR<{ code: number }>(task) + if (doubleWatchTask !== undefined && doubleWatchTask.response.statusCode === 200) { + if (doubleWatchTask.body.code === 0 || doubleWatchTask.body.code === -400) { + this._taskList.set(uid, true) + tools.Log(user.nickname, '日常任务', '日常任务已完成') + } + else tools.Log(user.nickname, '日常任务', doubleWatchTask.body) + } + else tools.Log(user.nickname, '日常任务', '网络错误') + }) + } +} + +/** + * 日常任务 + * + * @interface taskInfo + */ +// @ts-ignore +interface taskInfo { + code: number + msg: string + data: taskInfoData +} +interface taskInfoData { + [index: string]: taskInfoDoublewatchinfo +} +interface taskInfoDoublewatchinfo { + task_id: string | undefined +} + +export default new Task() \ No newline at end of file diff --git a/bilive/plugins/test/index.ts b/bilive/plugins/test/index.ts deleted file mode 100644 index 97e931e..0000000 --- a/bilive/plugins/test/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -class Test implements IPlugin { - public name = '测试插件' - public description = '这是用来测试的' - public version = '0.0.1' - public author = 'lzghzr' - public loaded = false - public async start({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { - !{ defaultOptions, whiteList } - } - public async once({ options, users }: { options: options, users: Map }) { - !{ options, users } - } - public async loop({ cst, cstMin, cstHour, cstString, options, users }: { cst: Date, cstMin: number, cstHour: number, cstString: string, options: options, users: Map }) { - !{ cst, cstMin, cstHour, cstString, options, users } - } - public async msg({ message, options, users }: { message: raffleMessage | lotteryMessage | beatStormMessage, options: options, users: Map }) { - !{ message, options, users } - } -} - -export default new Test() \ No newline at end of file diff --git a/bilive/plugins/treasureBox/index.ts b/bilive/plugins/treasureBox/index.ts new file mode 100644 index 0000000..d120320 --- /dev/null +++ b/bilive/plugins/treasureBox/index.ts @@ -0,0 +1,119 @@ +import { Options as requestOptions } from 'request' +import Plugin, { tools, AppClient } from '../../plugin' + +class TreasureBox extends Plugin { + constructor() { + super() + } + public name = '宝箱道具' + public description = '领取宝箱道具' + public version = '0.0.1' + public author = 'lzghzr' + /** + * 任务表 + * + * @private + * @type {Map} + * @memberof TreasureBox + */ + private _treasureBoxList: Map = new Map() + public async load({ defaultOptions, whiteList }: { defaultOptions: options, whiteList: Set }) { + // 宝箱道具 + defaultOptions.newUserData['treasureBox'] = false + defaultOptions.info['treasureBox'] = { + description: '宝箱道具', + tip: '领取宝箱道具', + type: 'boolean' + } + whiteList.add('treasureBox') + this.loaded = true + } + public async start({ users }: { users: Map }) { + this._treasureBox(users) + } + public async loop({ cstMin, cstHour, cstString, users }: { cstMin: number, cstHour: number, cstString: string, users: Map }) { + // 每天00:10刷新任务 + if (cstString === '00:10') this._treasureBoxList.clear() + // 每天04:30, 12:30, 20:30做任务 + if (cstMin === 30 && cstHour % 8 === 4) this._treasureBox(users) + } + /** + * 宝箱道具 + * + * @private + * @memberof TreasureBox + */ + private _treasureBox(users: Map) { + users.forEach((user, uid) => this._treasureBoxUser(uid, user)) + } + /** + * 分用户进行 + * + * @private + * @param {string} uid + * @param {User} user + * @memberof TreasureBox + */ + private async _treasureBoxUser(uid: string, user: User) { + if (this._treasureBoxList.get(uid) || !user.userData['treasureBox']) return + // 获取宝箱状态,换房间会重新冷却 + const current: requestOptions = { + uri: `https://api.live.bilibili.com/mobile/freeSilverCurrentTask?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + const currentTask = await tools.XHR(current, 'Android') + if (currentTask !== undefined && currentTask.response.statusCode === 200) { + if (currentTask.body.code === 0) { + await tools.Sleep(currentTask.body.data.minute * 60 * 1000) + const award: requestOptions = { + uri: `https://api.live.bilibili.com/mobile/freeSilverAward?${AppClient.signQueryBase(user.tokenQuery)}`, + json: true, + headers: user.headers + } + await tools.XHR(award, 'Android') + this._treasureBoxUser(uid, user) + } + else if (currentTask.body.code === -10017) { + this._treasureBoxList.set(uid, true) + tools.Log(user.nickname, '宝箱道具', '已领取所有宝箱') + } + else tools.Log(user.nickname, '宝箱道具', currentTask.body) + } + else tools.Log(user.nickname, '宝箱道具', '网络错误') + } +} + +/** + * 在线领瓜子宝箱 + * + * @interface currentTask + */ +interface currentTask { + code: number + msg: string + data: currentTaskData +} +interface currentTaskData { + minute: number + silver: number + time_start: number + time_end: number +} +/** + * 领瓜子答案提交返回 + * + * @interface award + */ +interface award { + code: number + msg: string + data: awardData +} +interface awardData { + silver: number + awardSilver: number + isEnd: number +} + +export default new TreasureBox() \ No newline at end of file diff --git a/bilive/webapi.ts b/bilive/webapi.ts index 35778ca..a801571 100644 --- a/bilive/webapi.ts +++ b/bilive/webapi.ts @@ -4,7 +4,7 @@ import http from 'http' import { randomBytes } from 'crypto' import { EventEmitter } from 'events' import tools from './lib/tools' -import Daily from './daily' +import User from './online' import Options from './options' /** * 程序设置 @@ -200,11 +200,11 @@ class WebAPI extends EventEmitter { for (const i in userData) userData[i] = setUserData[i] if (userData.status && !Options.user.has(setUID)) { // 因为使用了Map保存已激活的用户, 所以需要添加一次 - const newUser = new Daily(setUID, userData) + const newUser = new User(setUID, userData) const status = await newUser.Start() // 账号会尝试登录, 如果需要验证码status会返回'captcha', 并且验证码会以DataUrl形式保存在captchaJPEG if (status === 'captcha') captcha = newUser.captchaJPEG - else if (Options.user.has(setUID)) newUser.daily() + else if (Options.user.has(setUID)) Options.emit('newUser', newUser) } else if (userData.status && Options.user.has(setUID)) { // 对于已经存在的用户, 可能处在验证码待输入阶段 @@ -214,7 +214,7 @@ class WebAPI extends EventEmitter { captchaUser.captcha = message.captcha const status = await captchaUser.Start() if (status === 'captcha') captcha = captchaUser.captchaJPEG - else if (Options.user.has(setUID)) captchaUser.daily() + else if (Options.user.has(setUID)) Options.emit('newUser', captchaUser) } } else if (!userData.status && Options.user.has(setUID)) (Options.user.get(setUID)).Stop()