Skip to content

Commit

Permalink
feat: 生成抽卡记录图片
Browse files Browse the repository at this point in the history
  • Loading branch information
TomyJan committed Jun 1, 2024
1 parent bdbde3f commit aa7d536
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 35 deletions.
24 changes: 15 additions & 9 deletions apps/gameCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ export class gameCard extends plugin {
)
else await this.reply(`切换账号失败, 请检查索引是否正确`)
}
let data = await gameCardData.get(this.e, 'gameCardPns', this.e.user_id)
if (!data) return false
let data = await gameCardData.get(this.e, 'gameCardPns')
if (!data) {
kuroLogger.warn('战双卡片数据获取失败')
await this.reply('卡片数据获取失败')
return false}
let img = await this.cachePns(data)
await this.reply(img)
}
Expand Down Expand Up @@ -91,22 +94,25 @@ export class gameCard extends plugin {
)
else await this.reply(`切换账号失败, 请检查索引是否正确`)
}
let data = await gameCardData.get(this.e, 'gameCardMc', this.e.user_id)
if (!data) return false
let data = await gameCardData.get(this.e, 'gameCardMc')
if (!data) {
kuroLogger.warn('战双卡片数据获取失败')
await this.reply('卡片数据获取失败')
return false}
let img = await this.cacheMc(data)
await this.reply(img)
}

async cacheMc(data) {
let tmp = md5(JSON.stringify(data))
if (gameCard.mcCardData.md5 === tmp) {
return gameCard.mcCardData.img
if (this.mcCardData.md5 === tmp) {
return this.mcCardData.img
}

gameCard.mcCardData.img = await puppeteer.screenshot('gameCardMc', data)
gameCard.mcCardData.md5 = tmp
this.mcCardData.img = await puppeteer.screenshot('gameCardMc', data)
this.mcCardData.md5 = tmp

return gameCard.mcCardData.img
return this.mcCardData.img
}

static mcCardData = {
Expand Down
87 changes: 78 additions & 9 deletions apps/mcGacha.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import mcGachaData from '../model/mcGachaData.js'
import plugin from '../../../lib/plugins/plugin.js'
import md5 from 'md5'
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
import mcGachaCard from '../model/mcGachaCard.js'
import kuroLogger from '../components/logger.js'

export class mcGacha extends plugin {
constructor() {
Expand Down Expand Up @@ -39,18 +43,83 @@ export class mcGacha extends plugin {

async mcGachaDataShow(e) {
let gacha = new mcGachaData(e)
await gacha.show()
return true
if(await gacha.check()){ // 通过检查, 可以生成抽卡分析
// 从消息中提取卡池类型
let msg = this.e.msg.replace(/#| /g, '').replace(/鸣潮|记录|唤取|分析|池/g, '')
let gachaType = 0
let cardPoolName = ''
switch (msg) {
case '抽卡':
case '角色':
case 'up':
case '抽奖':
case '角色活动':
case '角色up':
gachaType = 1
cardPoolName = '角色活动唤取'
break
case '武器':
case '武器活动':
case '武器up':
gachaType = 2
cardPoolName = '武器活动唤取'
break
case '常驻':
case '角色常驻':
gachaType = 3
cardPoolName = '角色常驻唤取'
break
case '武器常驻':
gachaType = 4
cardPoolName = '武器常驻唤取'
break
case '新手':
gachaType = 5
cardPoolName = '新手唤取'
break
case '新手自选':
case '自选':
gachaType = 6
cardPoolName = '新手自选唤取'
break
default:
gachaType = 1
cardPoolName = '角色活动唤取'
}
let data = await mcGachaCard.get(this.e, gachaType, cardPoolName)
if (!data) {
kuroLogger.warn('抽卡记录卡片数据获取失败')
return false}
if (typeof data === 'string') {
await this.reply(data)
return false
}
let img = await this.cache(data)
await this.reply(img)
}
return false
}

async cache(data) {
let tmp = md5(JSON.stringify(data))
if (mcGacha.mcGachaCardData.md5 === tmp) {
return mcGacha.mcGachaCardData.img
}

mcGacha.mcGachaCardData.img = await puppeteer.screenshot('mcGachaRecord', data)
mcGacha.mcGachaCardData.md5 = tmp

return mcGacha.mcGachaCardData.img
}

static mcGachaCardData = {
md5: '',
img: '',
}

async mcGachaHelp(e) {
e.reply(
`可通过以下两种方式获取抽卡记录:
#鸣潮本地获取抽卡记录
- 在本地访问链接获取抽卡记录, 快速但是无法自动更新
#鸣潮上传抽卡记录链接
- 通过日志中的抽卡记录链接上传, 繁琐但是一次获取长期有效
请发送相应指令查看帮助` // 抽卡链接有效期
`可通过以下两种方式获取抽卡记录: \n#鸣潮本地获取抽卡记录 \n - 在本地访问链接获取抽卡记录, 快速但是无法自动更新 \n#鸣潮上传抽卡记录链接 \n - 通过日志中的抽卡记录链接上传, 繁琐但是一次获取长期有效 \n请发送相应指令查看帮助` // TODO: 抽卡链接有效期
)
return true
}
Expand Down Expand Up @@ -83,7 +152,7 @@ export class mcGacha extends plugin {
let gacha = new mcGachaData(e)
let gachaRecord = await gacha.get(e.msg, e.user_id)
if (typeof gachaRecord === 'string') {
e.reply(`抽卡记录更新失败: \n${gachaRecord}`)
e.reply(`抽卡记录更新失败: \n${gachaRecord} \n请检查链接是否正确 `)
return true
} else {
let failedReason = await gacha.update(e.user_id, gachaRecord)
Expand Down
102 changes: 102 additions & 0 deletions model/mcGachaCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import kuroLogger from '../components/logger.js'
import {
mcGachaDataPath,
pluginName,
pluginVer,
resPath,
_ResPath,
} from '../data/system/pluginConstants.js'
import mcGachaData from './mcGachaData.js'
import userConfig from './userConfig.js'

export default class mcGachaCard {
constructor(e, gachaType) {
this.e = e
}

/** 获取抽卡记录卡片数据
* @param {object} e - 消息对象
* @param {number} gachaType - 抽卡类型
* @returns {object|string} - 抽卡记录卡片数据 json, 失败返回错误信息 str
*/
static async get(e, gachaType, cardPoolName) {
if (typeof gachaType !== 'number' || gachaType > 6 || gachaType < 1) return '抽卡类型错误'
let gacha = new mcGachaData(e)
let user = new userConfig()
let OriginGachaRecord = await gacha.getUigfRecord(e.user_id, (await user.getCurGameUidLocal(e.user_id, 3))?.gameUid)
if (typeof OriginGachaRecord !== 'object' || OriginGachaRecord.length === 0) {
kuroLogger.warn(`抽卡记录卡片数据获取失败: ${OriginGachaRecord}`)
await e.reply(`抽卡记录卡片数据获取失败: ${OriginGachaRecord}`)
return `抽卡记录卡片数据获取失败: ${OriginGachaRecord}`
}

// 提取符合 gachaType 的记录
let gachaRecord = []
for (let i = 0; i < OriginGachaRecord.list.length; i++) {
if (OriginGachaRecord.list[i].gacha_type == gachaType.toString()) {
gachaRecord.push(OriginGachaRecord.list[i])
}
}
// 将 gachaRecord 倒序, 以便分析金卡所需抽数
gachaRecord.reverse()

// 分析每次出金卡所需抽数
let goldCardRecord = []
let lastGoldIndex = -1
for (let i = 0; i < gachaRecord.length; i++) {
if (gachaRecord[i].rank_type === '5') {
goldCardRecord.push({
id: gachaRecord[i].id,
gachaType: gachaRecord[i].gacha_type,
itemId: gachaRecord[i].item_id,
itemCount: gachaRecord[i].count,
itemName: gachaRecord[i].name,
itemType: gachaRecord[i].item_type,
itemRank: gachaRecord[i].rank_type,
time: gachaRecord[i].time,
totalGachaTimes: i + 1,
thisCardCost: i - lastGoldIndex,
})
lastGoldIndex = i
}

if (i === gachaRecord.length - 1 && i !== lastGoldIndex) { // 最后一次未出金卡的抽数统计
goldCardRecord.push({
id: gachaRecord[i].id,
gachaType: gachaRecord[i].gacha_type,
itemId: '-1',
itemCount: '-1',
itemName: '?',
itemType: '-1',
itemRank: '-1',
time: gachaRecord[i].time,
totalGachaTimes: i + 1,
thisCardCost: i - lastGoldIndex,
})
}
}

// 再次倒序, 把新的记录放在最前面
goldCardRecord.reverse()

kuroLogger.debug('分析后的抽卡记录:', JSON.stringify(goldCardRecord))

// return JSON.stringify(goldCardRecord)

let ret = {
tplFile: `${resPath}/html/mcGachaRecord/index.html`,
goldCardRecord,
cardPoolName,
pluResPath: _ResPath,
pluginName,
pluginVer,
}
if (!ret) {
await e.reply(`抽卡记录卡片数据获取失败: 未知错误`)
return '抽卡记录卡片数据获取失败: 未知错误'
}

return ret

}
}
54 changes: 38 additions & 16 deletions model/mcGachaData.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export default class mcGachaData {
}
}

async show() {
let msg = this.e.msg.replace(/#| /g, '').replace(/记录|唤取|分析|池/g, '')

/** 检查是否可以生成抽卡记录
* @returns {boolean} 是否通过检查, 没通过检查就不生成了
*/
async check() {
const tokenData = await getToken(this.e.user_id)
kuroLogger.debug(
`QQ ${this.e.user_id} 的 tokenData: ${JSON.stringify(tokenData)}`
Expand All @@ -40,29 +41,29 @@ export default class mcGachaData {

// 先检查本地是否既没有抽卡记录也没有抽卡链接, 如果没有就提示获取抽卡记录
if (!(await this.exist(this.e.user_id, gameUid)) && !gachaLink) {
this.e.reply(
await this.e.reply(
`QQ ${this.e.user_id} 的游戏 uid ${gameUid} 暂未获取抽卡记录\n请发送 #鸣潮抽卡记录帮助 以获取记录`
)
return
return false
}

// 然后检查是否是通过链接上传的信息, 如果是链接上传就更新再生成, 如果是本地上传就直接生成
if (gachaLink) {
this.e.reply(
await this.e.reply(
`QQ ${this.e.user_id} 的游戏 uid ${gameUid} 本地存在抽卡链接, 尝试更新抽卡记录...`
)
let gachaRecord = await this.get(gachaLink, this.e.user_id)
if (typeof gachaRecord === 'string') {
// 如果记录更新失败, 进行提示; 如果更新成功, 不提示直接进入生成
this.e.reply(
await this.e.reply(
`QQ ${this.e.user_id} 的游戏 uid ${gameUid} 更新抽卡记录失败: \n${failedReason}\n将展示历史抽卡记录`
)
} else {
// 更新成功, 存入本地
await this.update(this.e.user_id, gachaRecord)
}
} else {
this.e.reply(
await this.e.reply(
`QQ ${this.e.user_id} 的游戏 uid ${gameUid} 通过本地上传的抽卡记录, 将展示历史抽卡记录`
)
}
Expand All @@ -72,17 +73,12 @@ export default class mcGachaData {
} else {
// 没绑定当然也能获取 ,但是警告一下获取不到部分信息
// TODO: 把这个放到绑定抽卡链接的提示吧
// this.e.reply(
// await this.e.reply(
// `QQ ${this.e.user_id} 暂未绑定 token, 将无法获取到部分额外信息, 建议发送 #库洛验证码登录 绑定 token`
// )
}

// 开始生成抽卡记录
this.generateAndReply()
}

async generateAndReply() {
// TODO
return true
}

/** 通过抽卡链接获取抽卡记录
Expand Down Expand Up @@ -159,7 +155,7 @@ export default class mcGachaData {
kuroLogger.debug(
`QQ ${qq} 的抽卡链接 ${link} 获取失败: ${rsp_mcGachaRecord}`
)
return `QQ ${qq} 的抽卡链接 ${link} 获取失败: \n${rsp_mcGachaRecord}`
return `获取失败: ${rsp_mcGachaRecord}`
}

// 完成测试, 保存记录到本地
Expand Down Expand Up @@ -342,4 +338,30 @@ export default class mcGachaData {
return null
}
}

/** 以原格式输出抽卡记录
* @param {number} qq QQ
* @param {number} gameUid 游戏 uid, 如果传入 0 则输出第一个 uid
* @returns {object|string} 成功则返回原始 UIGF 格式的抽卡记录, 失败则返回 str 原因
*/
async getUigfRecord(qq, gameUid) {
// gameUid 无效时获取第一个 uid
if (!gameUid) {
gameUid = this.exist(qq, 0)
if (!gameUid) {
return '未找到抽卡记录'
}
}
let path = `${mcGachaDataPath}/${qq}-${gameUid}.json`
if (!fs.existsSync(path)) {
return '未找到抽卡记录'
}
// 使用 try catch 捕获错误
try {
let data = fs.readFileSync(path)
return JSON.parse(data)
} catch (error) {
return '提取抽卡记录失败: ' + error.message
}
}
}
2 changes: 1 addition & 1 deletion resources/html/gameCardMc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<div class="container" id="container">
<div class="head-box">
<div class="title" style="color: white;">鸣潮卡片 - 库洛插件</div>
<div class="label" style="color: white;">Handmade With ❤️ by TomyJan.</div>
<div class="label" style="color: white;">Handmade With ❤️ by TomyJan. | 当前页面正在绝赞监修中</div>
</div>


Expand Down
Loading

0 comments on commit aa7d536

Please sign in to comment.