feat: 为 BeatLeader 和 ScoreSaber 添加通用歌曲 ID 获取方法
This commit is contained in:
parent
7dbdaed21f
commit
8b4866b4d3
@ -9,6 +9,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.lxtend.com/qqbot/sqlite3"
|
||||
@ -286,38 +287,11 @@ func (bl *blQuery) SaveRecord(scoreData ScoreData) {
|
||||
}
|
||||
|
||||
func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, error) {
|
||||
db := sqlite3.GetDB() // 假设 sqlite3.GetDB() 返回 *sqlx.DB
|
||||
tx, err := db.Beginx()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil, errors.New("数据库连接失败,请稍后重试")
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// 查询绑定的 blId
|
||||
blId, err := getBLID(qqId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// // 查询记录
|
||||
// var records []RecordDataLite
|
||||
// err = tx.Select(&records, "SELECT * FROM blRecordData WHERE bl_id = ? ORDER BY generated_time DESC LIMIT ?", blId, count)
|
||||
// if err != nil {
|
||||
// if err == sql.ErrNoRows {
|
||||
// return nil, errors.New("未查询到数据")
|
||||
// }
|
||||
// log.Println("查询数据出错:", err)
|
||||
// return nil, errors.New("查询记录失败")
|
||||
// }
|
||||
|
||||
// // 提交事务
|
||||
// err = tx.Commit()
|
||||
// if err != nil {
|
||||
// log.Print(err)
|
||||
// return nil, errors.New("提交事务失败")
|
||||
// }
|
||||
|
||||
// return records, nil
|
||||
playerData, err := FetchPlayerData(blId)
|
||||
if err != nil {
|
||||
@ -372,15 +346,56 @@ func (bl *blQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, er
|
||||
DeviceControllerRight: GetControllerStr(score.Controller),
|
||||
GeneratedTime: time.Unix(score.Timepost, 0).Format("2006-01-02 15:04:05.999999999-07:00"),
|
||||
}
|
||||
if score.Leaderboard.Song.ID != "" && len(score.Leaderboard.Song.ID) > 5 {
|
||||
dataLite.SongId = score.Leaderboard.Song.ID[0:5]
|
||||
} else if score.Leaderboard.Song.ID != "" {
|
||||
dataLite.SongId = score.Leaderboard.Song.ID
|
||||
}
|
||||
if score.Leaderboard.Difficulty.Stars != nil {
|
||||
dataLite.Stars = *score.Leaderboard.Difficulty.Stars
|
||||
}
|
||||
records = append(records, dataLite)
|
||||
}
|
||||
// 获取歌曲ID
|
||||
hashs := make([]string, 0)
|
||||
for _, record := range records {
|
||||
hashs = append(hashs, record.SongHash)
|
||||
}
|
||||
hashToSongId, err := GetSongIdsByHash(hashs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(records); i++ {
|
||||
records[i].SongId = hashToSongId[records[i].SongHash]
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func GetSongIdsByHash(hashs []string) (hashToSongId map[string]string, err error) {
|
||||
//每批最多49个
|
||||
batchSize := 49
|
||||
for i := 0; i < len(hashs); i += batchSize {
|
||||
end := i + batchSize
|
||||
if end > len(hashs) {
|
||||
end = len(hashs)
|
||||
}
|
||||
batchHashs := hashs[i:end]
|
||||
queryUrl := "https://api.beatsaver.com/maps/hash/" + strings.Join(batchHashs, ",")
|
||||
resp, err := http.Get(queryUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response map[string]struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for hash, data := range response {
|
||||
hashToSongId[hash] = data.ID
|
||||
}
|
||||
}
|
||||
return hashToSongId, nil
|
||||
}
|
||||
|
@ -2,9 +2,14 @@ package scoresaber
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.lxtend.com/qqbot/sqlite3"
|
||||
@ -242,6 +247,7 @@ func (ss *ssQuery) SaveRecord(cmdData CommandData) {
|
||||
SongSubName: cmdData.Leaderboard.SongSubName,
|
||||
SongAuthorName: cmdData.Leaderboard.SongAuthorName,
|
||||
SongHash: cmdData.Leaderboard.SongHash,
|
||||
SongId: "",
|
||||
CoverImage: cmdData.Leaderboard.CoverImage,
|
||||
DifficultyRaw: cmdData.Leaderboard.Difficulty.DifficultyRaw,
|
||||
Stars: cmdData.Leaderboard.Stars,
|
||||
@ -298,36 +304,126 @@ func (ss *ssQuery) SaveRecord(cmdData CommandData) {
|
||||
}
|
||||
|
||||
func (ss *ssQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, error) {
|
||||
db := sqlite3.GetDB() // 假设 sqlite3.GetDB() 返回 *sqlx.DB
|
||||
tx, err := db.Beginx()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil, errors.New("数据库连接失败,请稍后重试")
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
ssId, err := GetSSID(qqId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 查询记录
|
||||
var records []RecordDataLite
|
||||
err = tx.Select(&records, "SELECT * FROM ssRecordData WHERE ss_id = ? ORDER BY generated_time DESC LIMIT ?", ssId, count)
|
||||
playerData, err := FetchPlayerData(ssId)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, errors.New("未查询到数据")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
historyUrl := "https://scoresaber.com/api/player/%s/scores?page=1&sort=recent"
|
||||
fullUrl := fmt.Sprintf(historyUrl, ssId)
|
||||
resp, err := http.Get(fullUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response struct {
|
||||
Data []struct {
|
||||
Score Score `json:"score"`
|
||||
Leaderboard Leaderboard `json:"leaderboard"`
|
||||
} `json:"playerScores"`
|
||||
}
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scores := response.Data
|
||||
records := make([]RecordDataLite, 0)
|
||||
for k, score := range scores {
|
||||
if k > count {
|
||||
break
|
||||
}
|
||||
log.Println("查询数据出错:", err)
|
||||
return nil, errors.New("查询记录失败")
|
||||
record := RecordDataLite{
|
||||
ScoreID: score.Score.ID,
|
||||
SsID: ssId,
|
||||
Name: playerData.Name,
|
||||
Country: playerData.Country,
|
||||
SongName: score.Leaderboard.SongName,
|
||||
SongSubName: score.Leaderboard.SongSubName,
|
||||
SongAuthorName: score.Leaderboard.SongAuthorName,
|
||||
SongHash: score.Leaderboard.SongHash,
|
||||
SongId: "",
|
||||
CoverImage: score.Leaderboard.CoverImage,
|
||||
DifficultyRaw: score.Leaderboard.Difficulty.DifficultyRaw,
|
||||
Stars: score.Leaderboard.Stars,
|
||||
PP: score.Score.Pp,
|
||||
Weight: score.Score.Weight,
|
||||
Modifiers: score.Score.Modifiers,
|
||||
Multiplier: score.Score.Multiplier,
|
||||
Rank: score.Score.Rank,
|
||||
BadCuts: score.Score.BadCuts,
|
||||
Score: score.Score.ModifiedScore,
|
||||
MaxScore: score.Leaderboard.MaxScore,
|
||||
FullCombo: score.Score.FullCombo,
|
||||
DeviceHmd: "",
|
||||
DeviceControllerLeft: "",
|
||||
DeviceControllerRight: "",
|
||||
GeneratedTime: score.Score.TimeSet.Format("2006-01-02 15:04:05.999999999-07:00"),
|
||||
}
|
||||
// 检查设备信息并设置
|
||||
if score.Score.DeviceHmd != nil {
|
||||
record.DeviceHmd = *score.Score.DeviceHmd
|
||||
}
|
||||
if score.Score.DeviceControllerLeft != nil {
|
||||
record.DeviceControllerLeft = *score.Score.DeviceControllerLeft
|
||||
}
|
||||
if score.Score.DeviceControllerRight != nil {
|
||||
record.DeviceControllerRight = *score.Score.DeviceControllerRight
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
err = tx.Commit()
|
||||
// 获取歌曲ID
|
||||
hashs := make([]string, 0)
|
||||
for _, record := range records {
|
||||
hashs = append(hashs, record.SongHash)
|
||||
}
|
||||
hashToSongId, err := GetSongIdsByHash(hashs)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil, errors.New("提交事务失败")
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(records); i++ {
|
||||
records[i].SongId = hashToSongId[records[i].SongHash]
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func GetSongIdsByHash(hashs []string) (hashToSongId map[string]string, err error) {
|
||||
//每批最多49个
|
||||
batchSize := 49
|
||||
for i := 0; i < len(hashs); i += batchSize {
|
||||
end := i + batchSize
|
||||
if end > len(hashs) {
|
||||
end = len(hashs)
|
||||
}
|
||||
batchHashs := hashs[i:end]
|
||||
queryUrl := "https://api.beatsaver.com/maps/hash/" + strings.Join(batchHashs, ",")
|
||||
resp, err := http.Get(queryUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response map[string]struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for hash, data := range response {
|
||||
hashToSongId[hash] = data.ID
|
||||
}
|
||||
}
|
||||
return hashToSongId, nil
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ type RecordDataLite struct {
|
||||
SongSubName string `json:"songSubName" db:"song_sub_name"`
|
||||
SongAuthorName string `json:"songAuthorName" db:"song_author_name"`
|
||||
SongHash string `json:"songHash" db:"song_hash"`
|
||||
SongId string `json:"songId" db:"song_id"`
|
||||
CoverImage string `json:"coverImage" db:"cover_image"`
|
||||
DifficultyRaw string `json:"difficultyRaw" db:"difficulty_raw"`
|
||||
Stars float64 `json:"stars" db:"stars"`
|
||||
|
Loading…
x
Reference in New Issue
Block a user