Files
miaosic/providers/qq/login.go
2025-09-29 23:05:07 +08:00

119 lines
3.1 KiB
Go

package qq
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/AynaLivePlayer/miaosic"
"time"
)
func (p *QQMusicProvider) Login(username string, password string) error {
return miaosic.ErrNotImplemented
}
func (p *QQMusicProvider) Logout() error {
// todo api request
p.cred = NewCredential()
return nil
}
func (p *QQMusicProvider) IsLogin() bool {
// todo check if token expires
return p.cred.HasMusicID() && p.cred.HasMusicKey()
}
func (p *QQMusicProvider) RefreshLogin() error {
return p.refreshToken()
}
func (p *QQMusicProvider) refreshToken() error {
if p.cred.RefreshKey == "" || p.cred.RefreshToken == "" || !p.cred.HasMusicKey() || !p.cred.HasMusicKey() {
return errors.New("miaosic (qq): invalid credentials")
}
params := map[string]interface{}{
"refresh_key": p.cred.RefreshKey,
"refresh_token": p.cred.RefreshToken,
"musickey": p.cred.MusicKey,
"musicid": p.cred.MusicID,
}
data, err := p.makeApiRequest("music.login.LoginServer",
"Login", params)
if err != nil {
return err
}
if !data.Get("data.musickey").Exists() || data.Get("data.musickey").String() == "" {
return errors.New("miaosic (qq): fail to get login status data")
}
p.cred.OpenID = data.Get("data.openid").String()
p.cred.RefreshToken = data.Get("data.refresh_token").String()
p.cred.AccessToken = data.Get("data.access_token").String()
p.cred.ExpiredAt = data.Get("data.expired_at").Int()
p.cred.MusicID = data.Get("data.musicid").Int()
p.cred.MusicKey = data.Get("data.musickey").String()
p.cred.UnionID = data.Get("data.unionid").String()
p.cred.StrMusicID = data.Get("data.str_musicid").String()
p.cred.RefreshKey = data.Get("data.refresh_key").String()
p.cred.EncryptUin = data.Get("data.encryptUin").String()
p.cred.LoginType = int(data.Get("data.loginType").Int())
p.cred.CreatedAt = time.Now().Unix()
return nil
}
func (p *QQMusicProvider) QrLogin() (*miaosic.QrLoginSession, error) {
if p.channel == "wechat" {
return p.getWxQR()
}
return p.getQQQR()
}
func (p *QQMusicProvider) QrLoginVerify(qrlogin *miaosic.QrLoginSession) (*miaosic.QrLoginResult, error) {
if p.channel == "wechat" {
return p.checkWxQR(qrlogin)
}
return p.checkQQQR(qrlogin)
}
func (p *QQMusicProvider) RestoreSession(session string) error {
if session == "" {
return errors.New("miaosic (qq): session is empty")
}
b, err := base64.StdEncoding.DecodeString(session)
if err != nil {
return err
}
var data struct {
Device *Device `json:"device"`
Credential *Credential `json:"credential"`
}
err = json.Unmarshal(b, &data)
if err != nil {
return fmt.Errorf("miaosic (qq): failed to unmarshal session data: %w", err)
}
if data.Device == nil {
return errors.New("miaosic (qq): missing device info in session")
}
if data.Credential == nil {
return errors.New("miaosic (qq): missing credential info in session")
}
p.device = data.Device
p.cred = data.Credential
p.qimeiUpdated = false
return nil
}
func (p *QQMusicProvider) SaveSession() string {
data := map[string]interface{}{
"device": p.device,
"credential": p.cred,
}
val, _ := json.Marshal(data)
return base64.StdEncoding.EncodeToString(val)
}