2024-10-09 01:30:50 +08:00

290 lines
9.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package scoresaber
import (
"database/sql"
"errors"
"log"
"strconv"
"time"
_ "github.com/mattn/go-sqlite3"
)
func initDB() {
db, err := sql.Open("sqlite3", "./bindss.db")
if err != nil {
log.Print(err)
}
defer db.Close()
createBindTableSQL := `CREATE TABLE IF NOT EXISTS ssBind (
id INTEGER PRIMARY KEY AUTOINCREMENT,
qqid TEXT UNIQUE,
ssid TEXT UNIQUE
);`
createScoreTableSQL := `CREATE TABLE IF NOT EXISTS ssData (
id TEXT,
name TEXT,
country TEXT,
pp REAL,
rank INTEGER,
country_rank INTEGER,
total_score INTEGER,
total_ranked_score INTEGER,
average_ranked_accuracy REAL,
total_play_count INTEGER,
ranked_play_count INTEGER,
replays_watched INTEGER,
generated_time TEXT
);`
createRecordTableSQL := `CREATE TABLE IF NOT EXISTS ssRecordData (
id INTEGER PRIMARY KEY AUTOINCREMENT,
score_id INT,
ss_id TEXT,
name TEXT,
country TEXT,
song_name VARCHAR(255),
song_sub_name VARCHAR(255),
song_author_name VARCHAR(255),
song_hash VARCHAR(64),
cover_image TEXT,
difficulty_raw VARCHAR(100),
pp REAL,
stars REAL,
weight REAL,
modifiers VARCHAR(255),
multiplier REAL,
bad_cuts INT,
missed_notes INT,
max_combo INT,
score INT,
full_combo BOOLEAN,
device_hmd VARCHAR(100),
device_controller_left VARCHAR(100),
device_controller_right VARCHAR(100),
generated_time TEXT
);`
_, err = db.Exec(createBindTableSQL)
if err != nil {
log.Print(err)
}
_, err = db.Exec(createScoreTableSQL)
if err != nil {
log.Print(err)
}
_, err = db.Exec(createRecordTableSQL)
if err != nil {
log.Print(err)
}
}
var SSQuery = &ssQuery{}
type ssQuery struct {
db *sql.DB
}
func init() {
initDB()
db, err := sql.Open("sqlite3", "./bindss.db")
if err != nil {
log.Print(err)
}
SSQuery = &ssQuery{db: db}
}
func (ss *ssQuery) BindSS(qqId string, ssId string) (reply string) {
tx, err := ss.db.Begin()
if err != nil {
log.Print(err)
}
defer tx.Rollback()
// ssId为数字
if _, isNum := strconv.Atoi(ssId); isNum != nil {
return "ssId格式错误,应当为一串数字"
}
data, _ := FetchPlayerData(ssId)
if data == nil {
return "未找到玩家"
}
//去重
if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil {
if rows.Next() {
return "您已绑定过ss账号,请先输入\"解绑ss\"解绑"
}
rows.Close()
}
_, err = tx.Exec("INSERT INTO ssBind(qqid, ssid) VALUES(?, ?)", qqId, ssId)
if err != nil {
return "绑定失败"
}
err = tx.Commit()
if err != nil {
return "无法提交事务"
}
return "和用户名为 " + data.Name + " 的用户绑定成功,输入\"查ss\"查看个人数据"
}
func (ss *ssQuery) UnbindSS(qqId string) (reply string) {
tx, err := ss.db.Begin()
if err != nil {
log.Print(err)
}
defer tx.Rollback()
//是否已绑定
if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil {
if !rows.Next() {
return "您未绑定ss账号输入\"绑定ss [ssId]\"绑定"
}
rows.Close()
}
_, err = tx.Exec("DELETE FROM ssBind WHERE qqid = ?", qqId)
if err != nil {
return "解绑失败"
}
err = tx.Commit()
if err != nil {
return "无法提交事务"
}
return "解绑成功,重新绑定请输入\"绑定ss [ssId]\""
}
func (ss *ssQuery) GetScore(qqId string) (reply string) {
tx, err := ss.db.Begin()
if err != nil {
log.Print(err)
}
defer tx.Rollback()
//是否已绑定
if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil {
if !rows.Next() {
return "您未绑定ss账号输入\"绑定ss [ssId]\"绑定"
}
}
var ssId string
tx.QueryRow("SELECT ssid FROM ssBind WHERE qqid = ?", qqId).Scan(&ssId)
data, _ := FetchPlayerData(ssId)
if data == nil {
return "查询出错,服务器返回了空数据"
}
dataLite := PlayerDataLite{
ID: data.ID,
Name: data.Name,
Country: data.Country,
PP: data.PP,
Rank: data.Rank,
CountryRank: data.CountryRank,
TotalScore: data.ScoreStats.TotalScore,
TotalRankedScore: data.ScoreStats.TotalRankedScore,
AverageRankedAccuracy: data.ScoreStats.AverageRankedAccuracy,
TotalPlayCount: data.ScoreStats.TotalPlayCount,
RankedPlayCount: data.ScoreStats.RankedPlayCount,
ReplaysWatched: data.ScoreStats.ReplaysWatched,
GeneratedTime: time.Now(),
}
var lastDataLite PlayerDataLite
tx.QueryRow("SELECT * FROM ssData WHERE id = ? ORDER BY generated_time DESC LIMIT 1", dataLite.ID).Scan(&lastDataLite.ID, &lastDataLite.Name, &lastDataLite.Country, &lastDataLite.PP, &lastDataLite.Rank, &lastDataLite.CountryRank, &lastDataLite.TotalScore, &lastDataLite.TotalRankedScore, &lastDataLite.AverageRankedAccuracy, &lastDataLite.TotalPlayCount, &lastDataLite.RankedPlayCount, &lastDataLite.ReplaysWatched, &lastDataLite.GeneratedTime)
if lastDataLite.TotalPlayCount != dataLite.TotalPlayCount {
tx.Exec("INSERT INTO ssData(id, name, country, pp, rank, country_rank, total_score, total_ranked_score, average_ranked_accuracy, total_play_count, ranked_play_count, replays_watched, generated_time) VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)", dataLite.ID, dataLite.Name, dataLite.Country, dataLite.PP, dataLite.Rank, dataLite.CountryRank, dataLite.TotalScore, dataLite.TotalRankedScore, dataLite.AverageRankedAccuracy, dataLite.TotalPlayCount, dataLite.RankedPlayCount, dataLite.ReplaysWatched, dataLite.GeneratedTime)
err = tx.Commit()
if err != nil {
return "SQL事务提交失败请重试"
}
return data.LastDiffToString(lastDataLite)
}
err = tx.Commit()
if err != nil {
return "SQL事务提交失败请重试"
}
return data.ToString()
}
func (ss *ssQuery) SaveRecord(cmdData CommandData) {
tx, err := ss.db.Begin()
if err != nil {
log.Print(err)
}
defer tx.Rollback()
dataLite := RecordDataLite{
ScoreID: cmdData.Score.ID,
SsID: cmdData.Score.LeaderboardPlayerInfo.ID,
Name: cmdData.Score.LeaderboardPlayerInfo.Name,
Country: cmdData.Score.LeaderboardPlayerInfo.Country,
SongName: cmdData.Leaderboard.SongName,
SongSubName: cmdData.Leaderboard.SongSubName,
SongAuthorName: cmdData.Leaderboard.SongAuthorName,
SongHash: cmdData.Leaderboard.SongHash,
CoverImage: cmdData.Leaderboard.CoverImage,
DifficultyRaw: cmdData.Leaderboard.Difficulty.DifficultyRaw,
Stars: cmdData.Leaderboard.Stars,
PP: cmdData.Score.Pp,
Weight: cmdData.Score.Weight,
Modifiers: cmdData.Score.Modifiers,
Multiplier: cmdData.Score.Multiplier,
BadCuts: cmdData.Score.BadCuts,
Score: cmdData.Score.ModifiedScore,
MissedNotes: cmdData.Score.MissedNotes,
MaxCombo: cmdData.Score.MaxCombo,
FullCombo: cmdData.Score.FullCombo,
DeviceHmd: "",
DeviceControllerLeft: "",
DeviceControllerRight: "",
GeneratedTime: time.Now().Format("2006-01-02 15:04:05.999999999-07:00"),
}
if cmdData.Score.DeviceHmd != nil {
dataLite.DeviceHmd = *cmdData.Score.DeviceHmd
}
if cmdData.Score.DeviceControllerLeft != nil {
dataLite.DeviceControllerLeft = *cmdData.Score.DeviceControllerLeft
}
if cmdData.Score.DeviceControllerRight != nil {
dataLite.DeviceControllerRight = *cmdData.Score.DeviceControllerRight
}
if _, err = tx.Exec("INSERT INTO ssRecordData(score_id, ss_id, name, country, song_name, song_sub_name, song_author_name, song_hash, cover_image, difficulty_raw, pp, stars, weight, modifiers, multiplier, bad_cuts, missed_notes, max_combo,score, full_combo, device_hmd, device_controller_left, device_controller_right, generated_time) VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23,?24)", dataLite.ScoreID, dataLite.SsID, dataLite.Name, dataLite.Country, dataLite.SongName, dataLite.SongSubName, dataLite.SongAuthorName, dataLite.SongHash, dataLite.CoverImage, dataLite.DifficultyRaw, dataLite.PP, dataLite.Stars, dataLite.Weight, dataLite.Modifiers, dataLite.Multiplier, dataLite.BadCuts, dataLite.MissedNotes, dataLite.MaxCombo, dataLite.Score, dataLite.FullCombo, dataLite.DeviceHmd, dataLite.DeviceControllerLeft, dataLite.DeviceControllerRight, dataLite.GeneratedTime); err != nil {
log.Print(err)
}
err = tx.Commit()
if err != nil {
log.Print(err)
}
}
func (ss *ssQuery) GetRecentScores(count int, qqId string) ([]RecordDataLite, error) {
tx, err := ss.db.Begin()
if err != nil {
log.Print(err)
}
defer tx.Rollback()
var ssId string
tx.QueryRow("SELECT ssid FROM ssBind WHERE qqid = ?", qqId).Scan(&ssId)
if ssId == "" {
return nil, errors.New("未绑定ss账号输入\"绑定ss [ssId]\"绑定")
}
rows, err := tx.Query("SELECT * FROM ssRecordData WHERE ss_id = ? ORDER BY generated_time DESC LIMIT ?", ssId, count)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("未查询到数据")
}
log.Println("Query error:", err)
return nil, errors.New("")
}
defer rows.Close()
var records []RecordDataLite
for rows.Next() {
var record RecordDataLite
if err := rows.Scan(&record.ID, &record.ScoreID, &record.SsID, &record.Name, &record.Country, &record.SongName, &record.SongSubName, &record.SongAuthorName, &record.SongHash, &record.CoverImage, &record.DifficultyRaw, &record.PP, &record.Stars, &record.Weight, &record.Modifiers, &record.Multiplier, &record.BadCuts, &record.MissedNotes, &record.MaxCombo, &record.Score, &record.FullCombo, &record.DeviceHmd, &record.DeviceControllerLeft, &record.DeviceControllerRight, &record.GeneratedTime); err != nil {
log.Println("Scan error:", err)
return nil, err
}
records = append(records, record)
}
err = tx.Commit()
if err != nil {
log.Print(err)
}
return records, nil
}