diff --git a/conf/demo_config.yaml b/conf/demo_config.yaml index 5d8a682..dccef9e 100644 --- a/conf/demo_config.yaml +++ b/conf/demo_config.yaml @@ -13,6 +13,7 @@ IsHelp: #填写true或者false false IsOldV4: #填写true或者false false是否新版或者旧版V4 ApiToken: #为空默认随机禁用 Wskey: # 填空默认禁用wskey转换 需要的填true +SMSAddress: theme: static: ./static master: diff --git a/controllers/account.go b/controllers/account.go index f0a1e06..848fda1 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -1,6 +1,7 @@ package controllers import ( + "github.com/beego/beego/v2/core/logs" "github.com/cdle/xdd/models" ) @@ -54,6 +55,16 @@ func (c *AccountController) List() { c.ServeJSON() } +func (c *AccountController) GetUserInfo() { + + pin := c.GetString("pin") + cookie, err := models.GetJdCookie(pin) + if err != nil { + logs.Error(err) + } + cookie.Query() +} + func (c *AccountController) CreateOrUpdate() { ps := &models.JdCookie{} c.Validate(ps) diff --git a/main.go b/main.go index aa9fb23..ad147ba 100644 --- a/main.go +++ b/main.go @@ -60,6 +60,7 @@ func main() { web.Router("/api/login/smslogin", &controllers.LoginController{}, "post:SMSLogin") web.Router("/api/account", &controllers.AccountController{}, "get:List") web.Router("/api/account", &controllers.AccountController{}, "post:CreateOrUpdate") + web.Router("/api/account/getUserInfo", &controllers.AccountController{}, "post:GetUserInfo") web.Router("/admin", &controllers.AccountController{}, "get:Admin") web.Router("/admin", &controllers.AccountController{}, "post:Admin") web.Router("/userCenter", &controllers.AccountController{}, "get:UserCenter") diff --git a/models/bot.go b/models/bot.go index 9ca251e..bb6a88a 100644 --- a/models/bot.go +++ b/models/bot.go @@ -135,8 +135,6 @@ var handleMessage = func(msgs ...interface{}) interface{} { } if nck, err := GetJdCookie(ck.PtPin); err == nil { nck.InPool(ck.PtKey) - nck.Update(PtKey, ck.PtKey) - if nck.WsKey == "" || len(nck.WsKey) == 0 { if sender.IsQQ() { ck.Update(QQ, ck.QQ) diff --git a/models/command.go b/models/command.go index 420c4b6..faaf5a8 100644 --- a/models/command.go +++ b/models/command.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/beego/beego/v2/core/logs" "regexp" + "strconv" "strings" "time" @@ -116,6 +117,140 @@ var codeSignals = []CodeSignal{ return Count() }, }, + { + Command: []string{`raw ^(\d{11})$`}, + Handle: func(s *Sender) interface{} { + if num := 5; len(codes) >= num { + return fmt.Sprintf("%v坑位全部在使用中,请排队。", num) + } + id := "qq" + strconv.Itoa(s.UserID) + if _, ok := codes[id]; ok { + return "你已在登录中。" + } + go func() { + c := make(chan string, 1) + codes[id] = c + defer delete(codes, id) + var sess = new(Session) + phone := s.Contents[0] + logs.Info(phone) + s.Reply("请稍后,正在模拟环境...") + if err := sess.Phone(phone); err != nil { + s.Reply(err.Error()) + return + } + send := false + login := false + verify := false + success := false + sms_code := "" + for { + query, _ := sess.query() + if query.PageStatus == "SESSION_EXPIRED" { + s.Reply("登录超时") + return + } + if query.SessionTimeOut == 0 { + if success { + return + } + s.Reply("登录超时") + return + } + if query.CanClickLogin && !login { + s.Reply("正在登录...") + if err := sess.login(phone, sms_code); err != nil { + s.Reply(err.Error()) + return + } + } + if query.PageStatus == "VERIFY_FAILED_MAX" { + s.Reply("验证码错误次数过多,请重新获取。") + return + } + if query.PageStatus == "VERIFY_CODE_MAX" { + s.Reply("对不起,短信验证码请求频繁,请稍后再试。") + return + } + if query.PageStatus == "REQUIRE_VERIFY" && !verify { + verify = true + s.Reply("正在自动验证...") + if err := sess.crackCaptcha(); err != nil { + s.Reply(err.Error()) + return + } + s.Reply("验证通过。") + s.Reply("请输入验证码______") + select { + case sms_code = <-c: + s.Reply("正在提交验证码...") + if err := sess.SmsCode(sms_code); err != nil { + s.Reply(err.Error()) + return + } + s.Reply("验证码提交成功。") + case <-time.After(60 * time.Second): + s.Reply("验证码超时。") + return + + } + } + if query.CanSendAuth && !send { + if err := sess.sendAuthCode(); err != nil { + s.Reply(err.Error()) + return + } + send = true + } + if !query.CanSendAuth && query.AuthCodeCountDown > 0 { + + } + if query.AuthCodeCountDown == -1 && send { + + } + if query.PageStatus == "SUCCESS_CK" && !success { + //Sender <- &Faker{ + // Message: fmt.Sprintf("pt_key=%v;pt_pin=%v;", query.Ck.PtKey, query.Ck.PtPin), + // UserID: s.GetUserID(), + // Type: s.GetImType(), + //} + s.Reply(fmt.Sprintf("登录成功,%v秒后可以登录下一个账号。", query.SessionTimeOut)) + success = true + } + time.Sleep(time.Second) + } + }() + + return nil + }, + }, + { + Command: []string{`raw ^登陆$`}, + Handle: func(s *Sender) interface{} { + if num := 5; len(codes) >= num { + return fmt.Sprintf("%v坑位全部在使用中,请排队(稍后再试)。", num) + } + id := "qq" + strconv.Itoa(s.UserID) + if _, ok := codes[id]; ok { + return "你已在登录中。" + } + s.Reply("你要登上敌方的陆地?") + s.Reply("请输入手机号___________") + return nil + }, + }, + { + Command: []string{`raw ^(\d{6})$`}, + Handle: func(s *Sender) interface{} { + if code, ok := codes["qq"+fmt.Sprint(s.UserID)]; ok { + //code <- s.Get() + logs.Info(code) + } else { + s.Reply("验证码不存在或过期了,请重新登录。") + } + return nil + }, + }, { Command: []string{"sign", "打卡", "签到"}, Handle: func(sender *Sender) interface{} { diff --git a/models/config.go b/models/config.go index 5ea75db..a53b10f 100644 --- a/models/config.go +++ b/models/config.go @@ -38,6 +38,7 @@ type Yaml struct { ApiToken string `yaml:"ApiToken"` Wskey bool `yaml:"Wskey"` TGURL string `yaml:"TGURL"` + SMSAddress string `yaml:"SMSAddress"` Node string Npm string Python string diff --git a/models/sms.go b/models/sms.go new file mode 100644 index 0000000..5b437d6 --- /dev/null +++ b/models/sms.go @@ -0,0 +1,127 @@ +package models + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/beego/beego/v2/client/httplib" + "regexp" + "time" +) + +var codes map[string]chan string + +type Query struct { + Ck struct { + PtPin interface{} `json:"ptPin"` + PtKey interface{} `json:"ptKey"` + Empty bool `json:"empty"` + } `json:"ck"` + PageStatus string `json:"pageStatus"` + AuthCodeCountDown int `json:"authCodeCountDown"` + CanClickLogin bool `json:"canClickLogin"` + CanSendAuth bool `json:"canSendAuth"` + SessionTimeOut int `json:"sessionTimeOut"` + AvailChrome int `json:"availChrome"` +} + +type Session struct { + Value string +} + +func (sess *Session) create() error { + var url = "https://github.com/rubyangxg/jd-qinglong" + if Config.SMSAddress == "" { + return errors.New("未配置服务器地址,仓库地址:" + url) + } + html, _ := httplib.Get(Config.SMSAddress).String() + res := regexp.MustCompile(`value="([\d\w]+)"`).FindStringSubmatch(html) + if len(res) == 0 { + return errors.New("崩了请找作者,仓库地址:https://github.com/rubyangxg/jd-qinglong") + } + sess.Value = res[1] + return nil +} + +func (sess *Session) control(name, value string) error { + req := httplib.Post(Config.SMSAddress + "/control") + req.Param("currId", name) + req.Param("currValue", value) + req.Param("clientSessionId", sess.String()) + _, err := req.String() + // fmt.Println("controll", name, value, rt) + return err +} + +func (sess *Session) login(phone, sms_code string) error { + req := httplib.Post(Config.SMSAddress + "/jdLogin") + req.Param("phone", phone) + req.Param("sms_code", sms_code) + req.Param("clientSessionId", sess.String()) + _, err := req.String() + // fmt.Println(phone, sms_code, rt) + return err +} + +func (sess *Session) sendAuthCode() error { + req := httplib.Get(Config.SMSAddress + "/sendAuthCode?clientSessionId=" + sess.String()) + _, err := req.Response() + return err +} + +func (sess *Session) String() string { + return sess.Value +} + +func (sess *Session) query() (*Query, error) { + query := &Query{} + // fmt.Println(sess.String(), "+++") + data, err := httplib.Get(fmt.Sprintf("%s/getScreen?clientSessionId=%s", Config.SMSAddress, sess.String())).Bytes() + if err != nil { + return nil, err + } + // fmt.Println(string(data)) + err = json.Unmarshal(data, &query) + if err != nil { + return nil, err + } + return query, nil +} + +func (sess *Session) Phone(phone string) error { + err := sess.create() + if err != nil { + return err + } + for { + query, err := sess.query() + if err != nil { + return err + } + if query.PageStatus == "NORMAL" { + break + } + if query.PageStatus == "SESSION_EXPIRED" { + return sess.Phone(phone) + } + time.Sleep(time.Second) + } + err = sess.control("phone", phone) + if err != nil { + return err + } + return nil +} + +func (sess *Session) SmsCode(sms_code string) error { + err := sess.control("sms_code", sms_code) + if err != nil { + return err + } + return nil +} + +func (sess *Session) crackCaptcha() error { + _, err := httplib.Get(fmt.Sprintf("%s/crackCaptcha?clientSessionId=%s", Config.SMSAddress, sess.String())).Response() + return err +}