package huya import ( "math" "strconv" "strings" "huya-go/internal/taf" ) const ( ActivityWebUA = "web&1.0&huya" ActivityRecordUA = "webh5&1.0.0&huya" ActivityBindUA = "pc&1.0.0&huya" ServantWebActUI = "webActUI" FuncGetUserScore = "getUserScore" FuncPrizeList = "getActPrizeList" FuncPrizeRecords = "getUserPrizeRecords" FuncExchangePrize = "scoreExchangePrize" ) type ActivityUserID struct { UID int64 `json:"uid"` GUID string `json:"guid,omitempty"` Token string `json:"token,omitempty"` HuyaUA string `json:"huya_ua"` Cookie string `json:"-"` TokenType int32 `json:"token_type"` DeviceInfo string `json:"device_info,omitempty"` } func NewActivityUserID(uid int64, cookie, ua string) ActivityUserID { return ActivityUserID{ UID: uid, HuyaUA: ua, Cookie: NormalizeCookie(cookie), TokenType: 0, } } func (u *ActivityUserID) WriteTo(w *taf.Writer) error { if err := w.WriteInt64(0, u.UID); err != nil { return err } if err := w.WriteString(1, u.GUID); err != nil { return err } if err := w.WriteString(2, u.Token); err != nil { return err } if err := w.WriteString(3, u.HuyaUA); err != nil { return err } if err := w.WriteString(4, u.Cookie); err != nil { return err } if err := w.WriteInt32(5, int64(u.TokenType)); err != nil { return err } return w.WriteString(6, u.DeviceInfo) } func (u *ActivityUserID) ReadFrom(r *taf.Reader) error { var err error if u.UID, err = r.ReadInt64(0, false, u.UID); err != nil { return err } if u.GUID, err = r.ReadString(1, false, u.GUID); err != nil { return err } if u.Token, err = r.ReadString(2, false, u.Token); err != nil { return err } if u.HuyaUA, err = r.ReadString(3, false, u.HuyaUA); err != nil { return err } if u.Cookie, err = r.ReadString(4, false, u.Cookie); err != nil { return err } if u.TokenType, err = r.ReadInt32(5, false, u.TokenType); err != nil { return err } u.DeviceInfo, err = r.ReadString(6, false, u.DeviceInfo) return err } type GetUserScoreReq struct { User ActivityUserID SID int32 } func (q *GetUserScoreReq) WriteTo(w *taf.Writer) error { if err := w.WriteStruct(0, &q.User); err != nil { return err } return w.WriteInt32(1, int64(q.SID)) } func (q *GetUserScoreReq) ReadFrom(r *taf.Reader) error { _, err := r.ReadStruct(0, false, &q.User) if err != nil { return err } q.SID, err = r.ReadInt32(1, false, q.SID) return err } type GetUserScoreResp struct { Status int32 `json:"status"` Msg string `json:"msg"` GainScore int32 `json:"gain_score"` UsedScore int32 `json:"used_score"` NewGainScore int64 `json:"new_gain_score"` NewUsedScore int64 `json:"new_used_score"` Score int64 `json:"score"` IsOpenExchangeTip int32 `json:"is_open_exchange_tip"` } func (r *GetUserScoreResp) WriteTo(w *taf.Writer) error { return nil } func (r *GetUserScoreResp) ReadFrom(rd *taf.Reader) error { var err error if r.Status, err = rd.ReadInt32(0, false, r.Status); err != nil { return err } if r.Msg, err = rd.ReadString(1, false, r.Msg); err != nil { return err } if r.GainScore, err = rd.ReadInt32(2, false, r.GainScore); err != nil { return err } if r.UsedScore, err = rd.ReadInt32(3, false, r.UsedScore); err != nil { return err } if r.NewGainScore, err = rd.ReadInt64(4, false, r.NewGainScore); err != nil { return err } if r.NewUsedScore, err = rd.ReadInt64(5, false, r.NewUsedScore); err != nil { return err } if r.Score, err = rd.ReadInt64(6, false, r.Score); err != nil { return err } r.IsOpenExchangeTip, err = rd.ReadInt32(7, false, r.IsOpenExchangeTip) return err } func (r GetUserScoreResp) AvailableScore() int64 { if r.NewGainScore != 0 || r.NewUsedScore != 0 { score := r.NewGainScore - r.NewUsedScore if score < 0 { return 0 } return score } return r.Score } type GetActPrizeListReq struct { User ActivityUserID SID int32 } func (q *GetActPrizeListReq) WriteTo(w *taf.Writer) error { if err := w.WriteStruct(0, &q.User); err != nil { return err } return w.WriteInt32(1, int64(q.SID)) } func (q *GetActPrizeListReq) ReadFrom(r *taf.Reader) error { _, err := r.ReadStruct(0, false, &q.User) if err != nil { return err } q.SID, err = r.ReadInt32(1, false, q.SID) return err } type PrizeInfo struct { ID int64 `json:"id"` SID int64 `json:"sid"` Name string `json:"name"` Score int64 `json:"score"` Type int32 `json:"type"` Image string `json:"img,omitempty"` Sort int32 `json:"sort"` Frequency int32 `json:"frequency"` FrequencyLimit int32 `json:"frequency_limit"` CreateTime int64 `json:"create_time"` Num int64 `json:"num"` Status int32 `json:"status"` Percent string `json:"percent"` NewScore int64 `json:"new_score"` Tags string `json:"tags,omitempty"` LeftNum int64 `json:"left_num"` IsShowNum int32 `json:"is_show_num"` } func (p *PrizeInfo) WriteTo(w *taf.Writer) error { return nil } func (p *PrizeInfo) ReadFrom(r *taf.Reader) error { var err error if p.ID, err = r.ReadInt64(0, false, p.ID); err != nil { return err } if p.SID, err = r.ReadInt64(1, false, p.SID); err != nil { return err } if p.Name, err = r.ReadString(2, false, p.Name); err != nil { return err } if p.Score, err = r.ReadInt64(3, false, p.Score); err != nil { return err } if p.Type, err = r.ReadInt32(4, false, p.Type); err != nil { return err } if p.Image, err = r.ReadString(5, false, p.Image); err != nil { return err } if p.Sort, err = r.ReadInt32(6, false, p.Sort); err != nil { return err } if p.Frequency, err = r.ReadInt32(7, false, p.Frequency); err != nil { return err } if p.FrequencyLimit, err = r.ReadInt32(8, false, p.FrequencyLimit); err != nil { return err } if p.CreateTime, err = r.ReadInt64(9, false, p.CreateTime); err != nil { return err } if p.Num, err = r.ReadInt64(10, false, p.Num); err != nil { return err } if p.Status, err = r.ReadInt32(11, false, p.Status); err != nil { return err } if p.Percent, err = r.ReadString(12, false, p.Percent); err != nil { return err } if p.NewScore, err = r.ReadInt64(13, false, p.NewScore); err != nil { return err } if p.Tags, err = r.ReadString(14, false, p.Tags); err != nil { return err } if p.LeftNum, err = r.ReadInt64(15, false, p.LeftNum); err != nil { return err } p.IsShowNum, err = r.ReadInt32(16, false, p.IsShowNum) return err } func (p PrizeInfo) Price() int64 { if p.NewScore != 0 { return p.NewScore } return p.Score } func (p PrizeInfo) EstimatedLeft() int64 { if p.LeftNum > 0 { return p.LeftNum } text := strings.TrimSuffix(strings.TrimSpace(p.Percent), "%") if text == "" || p.Num <= 0 { return 0 } percent, err := strconv.ParseFloat(text, 64) if err != nil { return 0 } return int64(math.Floor(float64(p.Num)*percent/100.0 + 1e-9)) } type PrizeTag struct { ID int64 `json:"id"` Name string `json:"name"` Weight int32 `json:"weight"` } func (t *PrizeTag) WriteTo(w *taf.Writer) error { return nil } func (t *PrizeTag) ReadFrom(r *taf.Reader) error { var err error if t.ID, err = r.ReadInt64(0, false, t.ID); err != nil { return err } if t.Name, err = r.ReadString(1, false, t.Name); err != nil { return err } t.Weight, err = r.ReadInt32(2, false, t.Weight) return err } type GetActPrizeListResp struct { Status int32 `json:"status"` Msg string `json:"msg"` Prizes []PrizeInfo `json:"prizes"` ModuleID int32 `json:"module_id"` Tags []PrizeTag `json:"tags"` } func (r *GetActPrizeListResp) WriteTo(w *taf.Writer) error { return nil } func (r *GetActPrizeListResp) ReadFrom(rd *taf.Reader) error { var err error if r.Status, err = rd.ReadInt32(0, false, r.Status); err != nil { return err } if r.Msg, err = rd.ReadString(1, false, r.Msg); err != nil { return err } items, err := rd.ReadListStruct(2, false, func() taf.Unmarshaler { return &PrizeInfo{} }) if err != nil { return err } r.Prizes = make([]PrizeInfo, 0, len(items)) for _, item := range items { if prize, ok := item.(*PrizeInfo); ok { r.Prizes = append(r.Prizes, *prize) } } if r.ModuleID, err = rd.ReadInt32(3, false, r.ModuleID); err != nil { return err } tags, err := rd.ReadListStruct(4, false, func() taf.Unmarshaler { return &PrizeTag{} }) if err != nil { return err } r.Tags = make([]PrizeTag, 0, len(tags)) for _, item := range tags { if tag, ok := item.(*PrizeTag); ok { r.Tags = append(r.Tags, *tag) } } return nil } type GetUserPrizeRecordsReq struct { User ActivityUserID SID int32 } func (q *GetUserPrizeRecordsReq) WriteTo(w *taf.Writer) error { if err := w.WriteStruct(0, &q.User); err != nil { return err } return w.WriteInt32(1, int64(q.SID)) } func (q *GetUserPrizeRecordsReq) ReadFrom(r *taf.Reader) error { _, err := r.ReadStruct(0, false, &q.User) if err != nil { return err } q.SID, err = r.ReadInt32(1, false, q.SID) return err } type UserPrizeInfo struct { ID int64 `json:"id"` Name string `json:"name"` Score int64 `json:"score"` CreateTime int64 `json:"create_time"` Status int32 `json:"status"` Type int32 `json:"type"` IsReal int32 `json:"is_real"` NewScore int64 `json:"new_score"` Account string `json:"account,omitempty"` Code string `json:"code,omitempty"` CommonPrizeType int32 `json:"common_prize_type"` } func (p *UserPrizeInfo) WriteTo(w *taf.Writer) error { return nil } func (p *UserPrizeInfo) ReadFrom(r *taf.Reader) error { var err error if p.ID, err = r.ReadInt64(0, false, p.ID); err != nil { return err } if p.Name, err = r.ReadString(1, false, p.Name); err != nil { return err } if p.Score, err = r.ReadInt64(2, false, p.Score); err != nil { return err } if p.CreateTime, err = r.ReadInt64(3, false, p.CreateTime); err != nil { return err } if p.Status, err = r.ReadInt32(4, false, p.Status); err != nil { return err } if p.Type, err = r.ReadInt32(5, false, p.Type); err != nil { return err } if p.IsReal, err = r.ReadInt32(6, false, p.IsReal); err != nil { return err } if p.NewScore, err = r.ReadInt64(7, false, p.NewScore); err != nil { return err } if p.Account, err = r.ReadString(8, false, p.Account); err != nil { return err } if p.Code, err = r.ReadString(9, false, p.Code); err != nil { return err } p.CommonPrizeType, err = r.ReadInt32(10, false, p.CommonPrizeType) return err } type GetUserPrizeRecordsResp struct { Status int32 `json:"status"` Msg string `json:"msg"` Records []UserPrizeInfo `json:"records"` } func (r *GetUserPrizeRecordsResp) WriteTo(w *taf.Writer) error { return nil } func (r *GetUserPrizeRecordsResp) ReadFrom(rd *taf.Reader) error { var err error if r.Status, err = rd.ReadInt32(0, false, r.Status); err != nil { return err } if r.Msg, err = rd.ReadString(1, false, r.Msg); err != nil { return err } items, err := rd.ReadListStruct(2, false, func() taf.Unmarshaler { return &UserPrizeInfo{} }) if err != nil { return err } r.Records = make([]UserPrizeInfo, 0, len(items)) for _, item := range items { if record, ok := item.(*UserPrizeInfo); ok { r.Records = append(r.Records, *record) } } return nil } type ScoreExchangePrizeReq struct { User ActivityUserID SID int32 PID int32 IP string ClientEnv map[string]string Source string IsRole int32 } func (q *ScoreExchangePrizeReq) WriteTo(w *taf.Writer) error { if err := w.WriteStruct(0, &q.User); err != nil { return err } if err := w.WriteInt32(1, int64(q.SID)); err != nil { return err } if err := w.WriteInt32(2, int64(q.PID)); err != nil { return err } if err := w.WriteString(3, q.IP); err != nil { return err } if err := w.WriteMapStringString(4, q.ClientEnv); err != nil { return err } if err := w.WriteString(5, q.Source); err != nil { return err } if q.IsRole == 0 { q.IsRole = 1 } return w.WriteInt32(6, int64(q.IsRole)) } func (q *ScoreExchangePrizeReq) ReadFrom(r *taf.Reader) error { _, err := r.ReadStruct(0, false, &q.User) if err != nil { return err } if q.SID, err = r.ReadInt32(1, false, q.SID); err != nil { return err } if q.PID, err = r.ReadInt32(2, false, q.PID); err != nil { return err } if q.IP, err = r.ReadString(3, false, q.IP); err != nil { return err } if q.ClientEnv, err = r.ReadMapStringString(4, false); err != nil { return err } if q.Source, err = r.ReadString(5, false, q.Source); err != nil { return err } q.IsRole, err = r.ReadInt32(6, false, q.IsRole) return err } type ExchangeInfo struct { PID int32 `json:"pid"` ExchangeScore int64 `json:"exchange_score"` Desc string `json:"desc"` } func (e *ExchangeInfo) WriteTo(w *taf.Writer) error { return nil } func (e *ExchangeInfo) ReadFrom(r *taf.Reader) error { var err error if e.PID, err = r.ReadInt32(1, false, e.PID); err != nil { return err } if e.ExchangeScore, err = r.ReadInt64(2, false, e.ExchangeScore); err != nil { return err } e.Desc, err = r.ReadString(3, false, e.Desc) return err } type ActPreCondition struct { ConditionType int32 `json:"condition_type"` ConditionParams map[string]string `json:"condition_params,omitempty"` Tip string `json:"tip,omitempty"` JumpURL string `json:"jump_url,omitempty"` ButtonDesc string `json:"button_desc,omitempty"` } func (c *ActPreCondition) WriteTo(w *taf.Writer) error { return nil } func (c *ActPreCondition) ReadFrom(r *taf.Reader) error { var err error if c.ConditionType, err = r.ReadInt32(0, false, c.ConditionType); err != nil { return err } if c.ConditionParams, err = r.ReadMapStringString(1, false); err != nil { return err } if c.Tip, err = r.ReadString(2, false, c.Tip); err != nil { return err } if c.JumpURL, err = r.ReadString(3, false, c.JumpURL); err != nil { return err } c.ButtonDesc, err = r.ReadString(4, false, c.ButtonDesc) return err } type ScoreExchangePrizeResp struct { Status int32 `json:"status"` Msg string `json:"msg"` OrderID string `json:"order_id,omitempty"` ExchangeInfo ExchangeInfo `json:"exchange_info"` ActPreCondition ActPreCondition `json:"act_pre_condition"` } func (r *ScoreExchangePrizeResp) WriteTo(w *taf.Writer) error { return nil } func (r *ScoreExchangePrizeResp) ReadFrom(rd *taf.Reader) error { var err error if r.Status, err = rd.ReadInt32(0, false, r.Status); err != nil { return err } if r.Msg, err = rd.ReadString(1, false, r.Msg); err != nil { return err } if r.OrderID, err = rd.ReadString(3, false, r.OrderID); err != nil { return err } if _, err = rd.ReadStruct(4, false, &r.ExchangeInfo); err != nil { return err } _, err = rd.ReadStruct(5, false, &r.ActPreCondition) return err } func (r ScoreExchangePrizeResp) Success() bool { return r.Status == 200 && (r.Msg == "" || strings.Contains(r.Msg, "成功")) }