refactor: 调整 BeatLeader 模块,注释并移除热门成绩相关功能

This commit is contained in:
lixiangwuxian 2025-03-08 19:22:41 +08:00
parent 33a59e6118
commit bfac7dfa59
4 changed files with 124 additions and 119 deletions

View File

@ -23,8 +23,8 @@ func init() {
handler.RegisterHelpInform("解绑bl", "beatleader", "解绑bl 解绑您的beatleader账号") handler.RegisterHelpInform("解绑bl", "beatleader", "解绑bl 解绑您的beatleader账号")
handler.RegisterHandler("最新bl", getMyRecentScore, constants.LEVEL_USER) handler.RegisterHandler("最新bl", getMyRecentScore, constants.LEVEL_USER)
handler.RegisterHelpInform("最新bl", "beatleader", "最新bl 查看您的最新游戏记录") handler.RegisterHelpInform("最新bl", "beatleader", "最新bl 查看您的最新游戏记录")
handler.RegisterHandler("最热bl", getRecentScore, constants.LEVEL_USER) // handler.RegisterHandler("最热bl", getRecentScore, constants.LEVEL_USER)
handler.RegisterHelpInform("最热bl", "beatleader", "最热bl 查看全大陆的最新游戏记录") // handler.RegisterHelpInform("最热bl", "beatleader", "最热bl 查看全大陆的最新游戏记录")
handler.RegisterHandler("截bl", screenShotBL, constants.LEVEL_USER) handler.RegisterHandler("截bl", screenShotBL, constants.LEVEL_USER)
handler.RegisterHelpInform("截bl", "beatleader", "截bl 截bl 截bl主页截图") handler.RegisterHelpInform("截bl", "beatleader", "截bl 截bl 截bl主页截图")
handler.RegisterHandler("jbl", screenShotBL, constants.LEVEL_USER) handler.RegisterHandler("jbl", screenShotBL, constants.LEVEL_USER)
@ -82,35 +82,35 @@ func unbindBL(msg model.Message) (reply model.Reply) {
} }
} }
func getRecentScore(msg model.Message) (reply model.Reply) { // func getRecentScore(msg model.Message) (reply model.Reply) {
count := 1 // count := 1
if len(msg.RawMsg) > len("最热bl ") { // if len(msg.RawMsg) > len("最热bl ") {
var err error // var err error
count, err = strconv.Atoi(msg.RawMsg[len("最热bl "):]) // count, err = strconv.Atoi(msg.RawMsg[len("最热bl "):])
if err != nil || count <= 0 { // if err != nil || count <= 0 {
return model.Reply{ // return model.Reply{
ReplyMsg: "", // ReplyMsg: "",
ReferOriginMsg: true, // ReferOriginMsg: true,
FromMsg: msg, // FromMsg: msg,
} // }
} // }
if count > 10 { // if count > 10 {
count = 10 // count = 10
} // }
} // }
scoreMsg := "" // scoreMsg := ""
for _, v := range beatleader.BlScoresManager.GetRecentScores(count, " WHERE country = 'CN' ") { // for _, v := range beatleader.BlScoresManager.GetRecentScores(count, " WHERE country = 'CN' ") {
scoreMsg += v.ToString() + "\n\n" // scoreMsg += v.ToString() + "\n\n"
} // }
if len(scoreMsg) > 0 { // if len(scoreMsg) > 0 {
scoreMsg = scoreMsg[:len(scoreMsg)-len("\n\n")] // scoreMsg = scoreMsg[:len(scoreMsg)-len("\n\n")]
} // }
return model.Reply{ // return model.Reply{
ReplyMsg: scoreMsg, // ReplyMsg: scoreMsg,
ReferOriginMsg: true, // ReferOriginMsg: true,
FromMsg: msg, // FromMsg: msg,
} // }
} // }
func getMyRecentScore(msg model.Message) (reply model.Reply) { func getMyRecentScore(msg model.Message) (reply model.Reply) {
count := 1 count := 1

View File

@ -42,6 +42,7 @@ func init() {
song_sub_name VARCHAR(255), song_sub_name VARCHAR(255),
song_author_name VARCHAR(255), song_author_name VARCHAR(255),
song_hash VARCHAR(64), song_hash VARCHAR(64),
song_id VARCHAR(64),
cover_image TEXT, cover_image TEXT,
difficulty_raw VARCHAR(100), difficulty_raw VARCHAR(100),
pp REAL, pp REAL,
@ -320,8 +321,8 @@ func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, er
// return records, nil // return records, nil
//从线上获取 //从线上获取
historyUrl := "https://api.beatleader.xyz/player/%s/scores" historyUrl := "https://api.beatleader.xyz/player/%s/scores?count=%d"
fullUrl := fmt.Sprintf(historyUrl, blId) fullUrl := fmt.Sprintf(historyUrl, blId, count)
resp, err := http.Get(fullUrl) resp, err := http.Get(fullUrl)
if err != nil { if err != nil {
return nil, err return nil, err
@ -338,7 +339,7 @@ func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, er
} }
records := make([]RecordDataLite, 0) records := make([]RecordDataLite, 0)
for _, score := range scores { for _, score := range scores {
records = append(records, RecordDataLite{ dataLite := RecordDataLite{
ScoreID: score.ID, ScoreID: score.ID,
BlID: score.Player.ID, BlID: score.Player.ID,
Name: score.Player.Name, Name: score.Player.Name,
@ -347,24 +348,28 @@ func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, er
SongSubName: score.Leaderboard.Song.SubName, SongSubName: score.Leaderboard.Song.SubName,
SongAuthorName: score.Leaderboard.Song.Author, SongAuthorName: score.Leaderboard.Song.Author,
SongHash: score.Leaderboard.Song.Hash, SongHash: score.Leaderboard.Song.Hash,
SongId: score.Leaderboard.Song.ID, SongId: score.Leaderboard.Song.ID[0:5],
CoverImage: score.Leaderboard.Song.CoverImage, CoverImage: score.Leaderboard.Song.CoverImage,
DifficultyRaw: score.Leaderboard.Difficulty.DifficultyName, DifficultyRaw: score.Leaderboard.Difficulty.DifficultyName,
PP: score.Pp, PP: score.Pp,
Stars: *score.Leaderboard.Difficulty.Stars, Stars: 0,
Weight: score.Weight, Weight: score.Weight,
Modifiers: score.Modifiers, Modifiers: score.Modifiers,
Multiplier: float64(score.ModifiedScore) / float64(score.BaseScore), Multiplier: float64(score.ModifiedScore) / float64(score.BaseScore),
BadCuts: score.BadCuts, BadCuts: score.BadCuts,
Score: score.ModifiedScore, Score: score.ModifiedScore,
Rank: score.Rank, Rank: score.Rank,
MaxScore: score.ModifiedScore, MaxScore: int(float64(score.ModifiedScore) / score.Accuracy),
FullCombo: score.FullCombo, FullCombo: score.FullCombo,
DeviceHmd: GetHMDStr(score.HMD), DeviceHmd: GetHMDStr(score.HMD),
DeviceControllerLeft: GetControllerStr(score.Controller), DeviceControllerLeft: GetControllerStr(score.Controller),
DeviceControllerRight: GetControllerStr(score.Controller), DeviceControllerRight: GetControllerStr(score.Controller),
GeneratedTime: time.Now().Format("2006-01-02 15:04:05.999999999-07:00"), GeneratedTime: time.Now().Format("2006-01-02 15:04:05.999999999-07:00"),
}) }
if score.Leaderboard.Difficulty.Stars != nil {
dataLite.Stars = *score.Leaderboard.Difficulty.Stars
}
records = append(records, dataLite)
} }
return records, nil return records, nil
} }

View File

@ -1,87 +1,87 @@
package beatleader package beatleader
import ( // import (
"log" // "log"
"time" // "time"
"git.lxtend.com/qqbot/sqlite3" // "git.lxtend.com/qqbot/sqlite3"
"git.lxtend.com/qqbot/util" // "git.lxtend.com/qqbot/util"
"github.com/gorilla/websocket" // "github.com/gorilla/websocket"
) // )
const wsURL = "wss://sockets.api.beatleader.xyz/scores" // const wsURL = "wss://sockets.api.beatleader.xyz/scores"
var BlScoresManager = blScoresManager{} // var BlScoresManager = blScoresManager{}
type blScoresManager struct { // type blScoresManager struct {
conn *websocket.Conn // conn *websocket.Conn
retryTimes int // retryTimes int
} // }
func init() { // func init() {
for err := BlScoresManager.connect(); err != nil; err = BlScoresManager.connect() { // for err := BlScoresManager.connect(); err != nil; err = BlScoresManager.connect() {
log.Print("连接 WebSocket 失败:", err) // log.Print("连接 WebSocket 失败:", err)
time.Sleep(time.Second) // time.Sleep(time.Second)
} // }
util.AddCycleTask("cleanOldScores", 0, 1*time.Hour, cleanOldScores) // util.AddCycleTask("cleanOldScores", 0, 1*time.Hour, cleanOldScores)
} // }
func (bm *blScoresManager) connect() error { // func (bm *blScoresManager) connect() error {
var err error // var err error
bm.conn, _, err = websocket.DefaultDialer.Dial(wsURL, nil) // bm.conn, _, err = websocket.DefaultDialer.Dial(wsURL, nil)
if err != nil { // if err != nil {
return err // return err
} // }
bm.retryTimes = 0 // bm.retryTimes = 0
go bm.receiveData() // go bm.receiveData()
return nil // return nil
} // }
func (sm *blScoresManager) receiveData() { // func (sm *blScoresManager) receiveData() {
defer func() { // defer func() {
for err := BlScoresManager.connect(); err != nil; err = BlScoresManager.connect() { // for err := BlScoresManager.connect(); err != nil; err = BlScoresManager.connect() {
log.Printf("连接 WebSocket 失败:%v", err) // log.Printf("连接 WebSocket 失败:%v", err)
time.Sleep(time.Second) // time.Sleep(time.Second)
} // }
}() // }()
for { // for {
var scoreData ScoreData // var scoreData ScoreData
err := sm.conn.ReadJSON(&scoreData) // err := sm.conn.ReadJSON(&scoreData)
if err != nil { // if err != nil {
log.Print("读取数据失败:", err) // log.Print("读取数据失败:", err)
time.Sleep(time.Second) // time.Sleep(time.Second)
sm.retryTimes++ // sm.retryTimes++
if sm.retryTimes > 3 { // if sm.retryTimes > 3 {
return // return
} // }
continue // continue
} // }
BLQuery.SaveRecord(scoreData) // BLQuery.SaveRecord(scoreData)
} // }
} // }
func (sm *blScoresManager) GetRecentScores(count int, predict string) []RecordDataLite { // // func (sm *blScoresManager) GetRecentScores(count int, predict string) []RecordDataLite {
db := sqlite3.GetDB() // // db := sqlite3.GetDB()
scoresCopy := make([]RecordDataLite, 0, count) // // scoresCopy := make([]RecordDataLite, 0, count)
query := "SELECT * FROM blRecordData" // // query := "SELECT * FROM blRecordData"
if predict != "" { // // if predict != "" {
query += " " + predict // // query += " " + predict
} // // }
query += " ORDER BY generated_time DESC LIMIT ?" // // query += " ORDER BY generated_time DESC LIMIT ?"
err := db.Select(&scoresCopy, query, count) // // err := db.Select(&scoresCopy, query, count)
if err != nil { // // if err != nil {
log.Print(err) // // log.Print(err)
return nil // // return nil
} // // }
return scoresCopy // // return scoresCopy
} // // }
func cleanOldScores() { // func cleanOldScores() {
db := sqlite3.GetDB() // db := sqlite3.GetDB()
ssBind := make([]string, 0) // ssBind := make([]string, 0)
db.Select(&ssBind, "SELECT ssid FROM ssBind") // db.Select(&ssBind, "SELECT ssid FROM ssBind")
db.Exec("DELETE FROM blRecordData WHERE generated_time < ? AND ssid NOT IN (?)", time.Now().AddDate(0, 0, -1).Unix(), ssBind) // db.Exec("DELETE FROM blRecordData WHERE generated_time < ? AND ssid NOT IN (?)", time.Now().AddDate(0, 0, -1).Unix(), ssBind)
} // }

View File

@ -198,23 +198,23 @@ type RecordDataLite struct {
} }
func (r RecordDataLite) ToString() string { func (r RecordDataLite) ToString() string {
formatedStrRanked := "%s%s 使用 %s 在 %s 的 %s 难度(%.1f🌟)中打到了全球排名第%dpp 为 %.2f,准度为 %s。" formatedStrRanked := "%s%s 使用 %s 在 %s(%s) 的 %s 难度(%.1f🌟)中打到了全球排名第%dpp 为 %.2f,准度为 %s。"
formatedStrUnranked := "%s, %s 使用 %s 在 %s 的 %s 难度中打到了全球排名第%d准度为 %s。" formatedStrUnranked := "%s, %s 使用 %s 在 %s(%s) 的 %s 难度中打到了全球排名第%d准度为 %s。"
formatedStrWithoutDevice := "%s, %s 在 %s 的 %s 难度(%.1f🌟)中打到了全球排名第%dpp 为 %.2f,准度为 %s。" formatedStrWithoutDevice := "%s, %s 在 %s(%s) 的 %s 难度(%.1f🌟)中打到了全球排名第%dpp 为 %.2f,准度为 %s。"
formatedStrWithoutDeviceAndRank := "%s, %s 在 %s 的 %s 难度中打到了全球排名第%d准度为 %s。" formatedStrWithoutDeviceAndRank := "%s, %s 在 %s(%s) 的 %s 难度中打到了全球排名第%d准度为 %s。"
hardStr := r.DifficultyRaw hardStr := r.DifficultyRaw
layout := "2006-01-02 15:04:05.999999999-07:00" layout := "2006-01-02 15:04:05.999999999-07:00"
parsedTime, _ := time.Parse(layout, r.GeneratedTime) parsedTime, _ := time.Parse(layout, r.GeneratedTime)
duration := time.Since(parsedTime) duration := time.Since(parsedTime)
timeStr := timeConvert(duration) timeStr := timeConvert(duration)
if r.Stars == 0 && r.DeviceHmd != "" { if r.Stars == 0 && r.DeviceHmd != "" {
return fmt.Sprintf(formatedStrUnranked, timeStr, r.Name, r.DeviceHmd, r.SongName, hardStr, r.Rank, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100)) return fmt.Sprintf(formatedStrUnranked, timeStr, r.Name, r.DeviceHmd, r.SongName, r.SongId, hardStr, r.Rank, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100))
} else if r.Stars != 0 && r.DeviceHmd != "" { } else if r.Stars != 0 && r.DeviceHmd != "" {
return fmt.Sprintf(formatedStrRanked, timeStr, r.Name, r.DeviceHmd, r.SongName, hardStr, r.Stars, r.Rank, r.PP, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100)) return fmt.Sprintf(formatedStrRanked, timeStr, r.Name, r.DeviceHmd, r.SongName, r.SongId, hardStr, r.Stars, r.Rank, r.PP, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100))
} else if r.Stars != 0 && r.DeviceHmd == "" { } else if r.Stars != 0 && r.DeviceHmd == "" {
return fmt.Sprintf(formatedStrWithoutDevice, timeStr, r.Name, r.SongName, hardStr, r.Stars, r.Rank, r.PP, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100)) return fmt.Sprintf(formatedStrWithoutDevice, timeStr, r.Name, r.SongName, r.SongId, hardStr, r.Stars, r.Rank, r.PP, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100))
} else { } else {
return fmt.Sprintf(formatedStrWithoutDeviceAndRank, timeStr, r.Name, r.SongName, hardStr, r.Rank, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100)) return fmt.Sprintf(formatedStrWithoutDeviceAndRank, timeStr, r.Name, r.SongName, r.SongId, hardStr, r.Rank, fmt.Sprintf("%.2f%%", float64(r.Score)/float64(r.MaxScore)*100))
} }
} }