diff --git a/service/scoresaber/bind_ss.go b/service/scoresaber/bind_ss.go index ca5290d..401591e 100644 --- a/service/scoresaber/bind_ss.go +++ b/service/scoresaber/bind_ss.go @@ -4,6 +4,7 @@ import ( "database/sql" "log" "strconv" + "time" _ "github.com/mattn/go-sqlite3" ) @@ -15,13 +16,33 @@ func initDB() { } defer db.Close() - createTableSQL := `CREATE TABLE IF NOT EXISTS ssBind ( + createBindTableSQL := `CREATE TABLE IF NOT EXISTS ssBind ( id INTEGER PRIMARY KEY AUTOINCREMENT, qqid TEXT UNIQUE, ssid TEXT UNIQUE );` - _, err = db.Exec(createTableSQL) + 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 + );` + + _, err = db.Exec(createBindTableSQL) + if err != nil { + log.Fatal(err) + } + _, err = db.Exec(createScoreTableSQL) if err != nil { log.Fatal(err) } @@ -41,6 +62,11 @@ func NewSSQuery() *SSQuery { } func (ss *SSQuery) BindSS(qqId string, ssId string) (reply string) { + tx, err := ss.db.Begin() + if err != nil { + log.Fatal(err) + } + defer tx.Rollback() // ssId为数字 if _, isNum := strconv.Atoi(ssId); isNum != nil { return "ssId格式错误,应当为一串数字" @@ -50,46 +76,93 @@ func (ss *SSQuery) BindSS(qqId string, ssId string) (reply string) { return "未找到玩家" } //去重 - if rows, err := ss.db.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { + if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { if rows.Next() { return "您已绑定过ss账号,请先输入\"解绑ss\"解绑" } rows.Close() } - _, err := ss.db.Exec("INSERT INTO ssBind(qqid, ssid) VALUES(?, ?)", qqId, ssId) + _, 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.Fatal(err) + } + defer tx.Rollback() //是否已绑定 - if rows, err := ss.db.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { + if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { if !rows.Next() { return "您未绑定ss账号,输入\"绑定ss [ssId]\"绑定" } rows.Close() } - _, err := ss.db.Exec("DELETE FROM ssBind WHERE qqid = ?", qqId) + _, 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.Fatal(err) + } + defer tx.Rollback() //是否已绑定 - if rows, err := ss.db.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { + if rows, err := tx.Query("SELECT * FROM ssBind WHERE qqid = ?", qqId); err == nil { if !rows.Next() { return "您未绑定ss账号,输入\"绑定ss [ssId]\"绑定" } } var ssId string - ss.db.QueryRow("SELECT ssid FROM ssBind WHERE qqid = ?", qqId).Scan(&ssId) + tx.QueryRow("SELECT ssid FROM ssBind WHERE qqid = ?", qqId).Scan(&ssId) data, _ := FetchPlayerData(ssId) if data == nil { - return "未找到玩家" + 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 "无法提交事务" + } + return data.LastDiffToString(lastDataLite) + } + err = tx.Commit() + if err != nil { + return "无法提交事务" } return data.ToString() } diff --git a/service/scoresaber/model.go b/service/scoresaber/model.go index 7e8096e..a29c3ab 100644 --- a/service/scoresaber/model.go +++ b/service/scoresaber/model.go @@ -162,6 +162,21 @@ func (p PlayerData) ToString() string { return fmt.Sprintf(formatedStr, p.Name, p.Country, p.PP, p.Rank, p.CountryRank, p.ScoreStats.TotalScore, p.ScoreStats.TotalRankedScore, p.ScoreStats.AverageRankedAccuracy, p.ScoreStats.TotalPlayCount, p.ScoreStats.RankedPlayCount, p.ScoreStats.ReplaysWatched) } +func (p PlayerDataLite) ToString() string { + formatedStr := "玩家 %s\n" + + "区域 %s\n" + + "PP %.1f\n" + + "全球排名 %d\n" + + "区域排名 %d\n" + + "总分 %d\n" + + "Ranked谱面总分 %d\n" + + "平均Ranked谱面准确率 %.2f\n" + + "总游玩次数 %d\n" + + "Ranked谱面游玩次数 %d\n" + + "回放被观看次数 %d" + return fmt.Sprintf(formatedStr, p.Name, p.Country, p.PP, p.Rank, p.CountryRank, p.TotalScore, p.TotalRankedScore, p.AverageRankedAccuracy, p.TotalPlayCount, p.RankedPlayCount, p.ReplaysWatched) +} + func (p PlayerData) LastDiffToString(lastDayQueryData PlayerDataLite) string { formatedStr := "玩家 %s\n" + "区域 %s\n" +