diff --git a/conf/demo_config.yaml b/conf/demo_config.yaml index 448de5d..a939662 100644 --- a/conf/demo_config.yaml +++ b/conf/demo_config.yaml @@ -15,6 +15,7 @@ Wskey: # 填空默认禁用wskey转换 需要的填true IsAddFriend: #填写true或者false false Lim: #填写1-N 代表限制次数 Tyt: #填写1-N 代表推一推需要的互助值,默认为8 +Later: #延时防止黑IP自己设置 默认60 不怕黑的改为1即可 单位是秒 theme: static: ./static master: diff --git a/controllers/login.go b/controllers/login.go index 33ba7b4..871fd0e 100644 --- a/controllers/login.go +++ b/controllers/login.go @@ -210,15 +210,13 @@ func init() { jd_token := k.(string) vv := v.([]interface{}) if len(vv) >= 2 { - //cookie := vv[0].(string) - //okl_token := vv[1].(string) + cookie := vv[0].(string) + okl_token := vv[1].(string) bot := vv[2].(string) uid := vv[3].(int) gid := vv[4].(int) // fmt.Println(jd_token, cookie, okl_token) - result, ck := CheckLogin(models.QQuery{ - Code: 0, - }, jd_token) + result, ck := CheckLogin(jd_token, cookie, okl_token) // fmt.Println(result) switch result { case "成功": @@ -301,28 +299,40 @@ func (c *LoginController) Query() { } } -func CheckLogin(q models.QQuery, token string) (string, *models.JdCookie) { - //state := time.Now().Unix() - req := httplib.Post("https://api.kukuqaq.com/jd/cookie") - req.Param("sig", q.Data.QqLoginQrcode.Sig) - req.Param("type", string(1)) +func CheckLogin(token, cookie, okl_token string) (string, *models.JdCookie) { + state := time.Now().Unix() + req := httplib.Post( + fmt.Sprintf(`https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=%s&ou_state=0&okl_token=%s`, + token, + okl_token, + ), + ) + req.Header("Referer", fmt.Sprintf(`https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=%d&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport`, + state), + ) + req.Header("Cookie", cookie) + req.Header("Connection", "Keep-Alive") + req.Header("Content-Type", "application/x-www-form-urlencoded; Charset=UTF-8") + req.Header("Accept", "application/json, text/plain, */*") + req.Header("User-Agent", jdua()) + req.Header("Host", "plogin.m.jd.com") - req.Param("redirectUrl", q.Data.RedirectURL) - req.Param("state", q.Data.State) - req.Param("tempCookie", q.Data.TempCookie) - req.Param("lSid", q.Data.LSid) + req.Param("lang", "chs") + req.Param("appid", "300") + req.Param("returnurl", fmt.Sprintf("https://wqlogin2.jd.com/passport/LoginRedirect?state=%d&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action", state)) + req.Param("source", "wq_passport") rsp, err := req.Response() if err != nil { return "", nil //err.Error() } data, err := ioutil.ReadAll(rsp.Body) - sth := StepThree1{} + sth := StepThree{} err = json.Unmarshal(data, &sth) if err != nil { return "", nil //err.Error() } - switch sth.Code { + switch sth.Errcode { case 0: cookies := strings.Join(rsp.Header.Values("Set-Cookie"), " ") pt_key := FetchJdCookieValue("pt_key", cookies) @@ -355,19 +365,19 @@ func CheckLogin(q models.QQuery, token string) (string, *models.JdCookie) { }() JdCookieRunners.Store(token, []interface{}{pt_pin}) return "成功", &ck - case 500: //Token无效,请退出重试 + case 19: //Token无效,请退出重试 JdCookieRunners.Delete(token) return sth.Message, nil - //case 21: //Token不存在,请退出重试 - // JdCookieRunners.Delete(token) - // return sth.Message, nil - //case 176: //授权登录未确认 - // return sth.Message, nil - //case 258: //务异常,请稍后重试 - // return "", nil - //case 264: //出错了,请退出重试 - // // JdCookieRunners.Delete(token) - // // return sth.Message, nil + case 21: //Token不存在,请退出重试 + JdCookieRunners.Delete(token) + return sth.Message, nil + case 176: //授权登录未确认 + return sth.Message, nil + case 258: //务异常,请稍后重试 + return "", nil + case 264: //出错了,请退出重试 + // JdCookieRunners.Delete(token) + // return sth.Message, nil default: JdCookieRunners.Delete(token) // fmt.Println(sth) diff --git a/models/available.go b/models/available.go index 2d54770..6bb7e6f 100644 --- a/models/available.go +++ b/models/available.go @@ -123,7 +123,7 @@ func initCookie() { cks := GetJdCookies() //l := len(cks) for i := range cks { - time.Sleep(time.Second * time.Duration(60)) + time.Sleep(time.Second * time.Duration(Config.Later)) if cks[i].Available == True && !CookieOK(&cks[i]) { logs.Info("开始禁用") cks[i].OutPool() @@ -243,10 +243,10 @@ func CookieOK(ck *JdCookie) bool { } ui := &UserInfoResult{} if nil != json.Unmarshal(data, ui) { - if !Config.IFC { - (&JdCookie{}).Push("第一个接口失效,切换到第二个接口,可能黑IP") - Config.IFC = true - } + //if !Config.IFC { + // (&JdCookie{}).Push("第一个接口失效,切换到第二个接口,可能黑IP,会导致NickName获取失败,可能会自行恢复。") + // Config.IFC = true + //} b2 := av2(cookie) if b2 == false { if ck.Available == True { @@ -298,10 +298,10 @@ func CookieOK(ck *JdCookie) bool { return true } } - if Config.IFC { - (&JdCookie{}).Push("第一个接口恢复,切换回第一接口,恭喜你IP洗白白了") - Config.IFC = false - } + //if Config.IFC { + // (&JdCookie{}).Push("第一个接口恢复,切换回第一接口,恭喜你IP洗白白了") + // Config.IFC = false + //} switch ui.Retcode { case "1001": //ck.BeanNum if ui.Msg == "not login" { @@ -370,7 +370,7 @@ func CookieOK(ck *JdCookie) bool { } return true } - (&JdCookie{}).Push("第一个接口失效,切换到第二个接口,可能黑IP") + //(&JdCookie{}).Push("第一个接口失效,切换到第二个接口,可能黑IP") return av2(cookie) } @@ -393,7 +393,10 @@ func av2(cookie string) bool { } else if strings.Contains(data, "nickname") { return true } else { - (&JdCookie{}).Push("第二个接口失效,可能黑IP") + if !Config.IFC { + (&JdCookie{}).Push("全部接口都失效,现已无法检测,可能黑IP,会导致NickName获取失败,可能会自行恢复。") + Config.IFC = true + } return true } return !strings.Contains(data, "login") diff --git a/models/bot.go b/models/bot.go index e639781..19b6171 100644 --- a/models/bot.go +++ b/models/bot.go @@ -119,9 +119,9 @@ var handleMessage = func(msgs ...interface{}) interface{} { if err != nil { logs.Error(err) } - if strings.Contains(rsp, "错误") { + if strings.Contains(rsp, "fake_") { logs.Error("wskey错误") - sender.Reply(fmt.Sprintf("wskey错误")) + sender.Reply(fmt.Sprintf("wskey错误 除京东APP皆不可用")) } else { ptKey := FetchJdCookieValue("pt_key", rsp) ptPin := FetchJdCookieValue("pt_pin", rsp) @@ -197,7 +197,10 @@ var handleMessage = func(msgs ...interface{}) interface{} { } RemCoin(sender.UserID, 8) sender.Reply(fmt.Sprintf("推一推即将开始,已扣除%d个互助值", Config.Tyt)) + } else { + sender.Reply(fmt.Sprintf("推一推即将开始,已扣除%d个互助值,管理员通道", Config.Tyt)) } + runTask(&Task{Path: "jd_tyt.js", Envs: []Env{ {Name: "tytpacketId", Value: ss[1]}, }}, sender) diff --git a/models/command.go b/models/command.go index feae5d4..107dcd6 100644 --- a/models/command.go +++ b/models/command.go @@ -1,13 +1,11 @@ package models import ( - "encoding/base64" - "encoding/json" "errors" "fmt" "github.com/beego/beego/v2/client/httplib" "github.com/beego/beego/v2/core/logs" - "io/ioutil" + "github.com/beego/beego/v2/server/web" "regexp" "strings" "time" @@ -142,28 +140,42 @@ var codeSignals = []CodeSignal{ { Command: []string{"qrcode", "扫码", "二维码", "scan"}, Handle: func(sender *Sender) interface{} { - rsp, err := httplib.Post("https://api.kukuqaq.com/jd/qrcode").Response() + url := fmt.Sprintf("http://127.0.0.1:%d/api/login/qrcode.png?tp=%s&uid=%d&gid=%d", web.BConfig.Listen.HTTPPort, sender.Type, sender.UserID, sender.ChatID) + if sender.Type == "tgg" { + url += fmt.Sprintf("&mid=%v&unm=%v", sender.MessageID, sender.Username) + } + rsp, err := httplib.Get(url).Response() if err != nil { return nil } - body, err1 := ioutil.ReadAll(rsp.Body) - if err1 == nil { - fmt.Println(string(body)) - } - s := &QQuery{} - if len(body) > 0 { - json.Unmarshal(body, &s) - } - logs.Info(s.Data.QqLoginQrcode.Bytes) - ddd, _ := base64.StdEncoding.DecodeString(s.Data.QqLoginQrcode.Bytes) //成图片文件并把文件写入到buffer - err2 := ioutil.WriteFile("./output.jpg", ddd, 0666) //buffer输出到jpg文件中(不做处理,直接写到文件) - if err2 != nil { - logs.Error(err2) - } - //ddd, _ := base64.StdEncoding.DecodeString("data:image/png;base64,"+s.Data.QqLoginQrcode.Bytes) - return "data:image/png;base64," + s.Data.QqLoginQrcode.Bytes + return rsp }, }, + //{ + // Command: []string{"qrcode", "扫码", "二维码", "scan"}, + // Handle: func(sender *Sender) interface{} { + // rsp, err := httplib.Post("https://api.kukuqaq.com/jd/qrcode").Response() + // if err != nil { + // return nil + // } + // body, err1 := ioutil.ReadAll(rsp.Body) + // if err1 == nil { + // fmt.Println(string(body)) + // } + // s := &QQuery{} + // if len(body) > 0 { + // json.Unmarshal(body, &s) + // } + // logs.Info(s.Data.QqLoginQrcode.Bytes) + // ddd, _ := base64.StdEncoding.DecodeString(s.Data.QqLoginQrcode.Bytes) //成图片文件并把文件写入到buffer + // err2 := ioutil.WriteFile("./output.jpg", ddd, 0666) //buffer输出到jpg文件中(不做处理,直接写到文件) + // if err2 != nil { + // logs.Error(err2) + // } + // //ddd, _ := base64.StdEncoding.DecodeString("data:image/png;base64,"+s.Data.QqLoginQrcode.Bytes) + // return "data:image/png;base64," + s.Data.QqLoginQrcode.Bytes + // }, + //}, { Command: []string{"sign", "打卡", "签到"}, Handle: func(sender *Sender) interface{} { @@ -380,6 +392,21 @@ var codeSignals = []CodeSignal{ return "已取消管理员" }, }, + { + Command: []string{"QQ转账"}, + Admin: true, + Handle: func(sender *Sender) interface{} { + qq := Int(sender.Contents[0]) + logs.Info(qq) + if len(sender.Contents) > 1 { + //sender.Contents = sender.Contents[1:] + logs.Info(sender.Contents[1:]) + AdddCoin(qq, Int(sender.Contents[1])) + sender.Reply(fmt.Sprintf("%d已增加%d枚互助值。", qq, Int(sender.Contents[1]))) + } + return nil + }, + }, /* { Command: []string{"我要钱", "给点钱", "我干", "给我钱", "给我", "我要"}, @@ -963,7 +990,7 @@ var codeSignals = []CodeSignal{ return nil }, }, - { + { Command: []string{"导出wsk"}, Admin: true, Handle: func(sender *Sender) interface{} { diff --git a/models/config.go b/models/config.go index f3f7eab..1d9b54a 100644 --- a/models/config.go +++ b/models/config.go @@ -43,6 +43,7 @@ type Yaml struct { Lim int `yaml:"Lim"` Tyt int `yaml:"Tyt"` IFC bool `yaml:"IFC"` + Later int `yaml:"Later"` Node string Npm string Python string @@ -108,6 +109,9 @@ func initConfig() { if Config.Tyt == 0 { Config.Tyt = 8 } + if Config.Later == 0 { + Config.Later = 60 + } if Config.Database == "" { Config.Database = ExecPath + "/.xdd.db" } diff --git a/models/container.go b/models/container.go index 4d13e8b..4c3a632 100644 --- a/models/container.go +++ b/models/container.go @@ -60,9 +60,9 @@ func initContainer() { version, err := GetQlVersion(Config.Containers[i].Address) if err == nil { if Config.Containers[i].getToken() == nil { - logs.Info("青龙" + version + "登录成功") + logs.Info("青龙" + version + "通道登录成功") } else { - logs.Warn("青龙" + version + "登录失败") + logs.Warn("青龙" + version + "通道登录失败") } Config.Containers[i].Type = "ql" Config.Containers[i].Version = version @@ -116,7 +116,7 @@ func initContainer() { func (c *Container) write(cks []JdCookie) error { switch c.Type { case "ql": - if c.Version == "2.9" || c.Version == "2.8" { + if c.Version == "openapi" { if len(c.Delete) > 0 { c.request("/api/envs", DELETE, fmt.Sprintf(`[%s]`, strings.Join(c.Delete, ","))) } @@ -241,7 +241,7 @@ func (c *Container) read() error { c.Available = true switch c.Type { case "ql": - if c.Version == "2.9" || c.Version == "2.8" { + if c.Version == "openapi" { type AutoGenerated struct { Code int `json:"code"` Data []struct { @@ -355,35 +355,13 @@ func (c *Container) read() error { func (c *Container) getToken() error { version, err := GetQlVersion(c.Address) logs.Debug(err) - if version == "2.9" { - token, err := getSqlToken(c.Address) - if err != nil { - logs.Error(err) + if version == "openapi" { + token := &Token{} + err, b2 := getT(c, token) + if b2 { + c.Token = token.Token } - getT(c, token) - c.Token = token.Token - //if token == nil { - // err2, done := getT(c, token) - // if done { - // return err2 - // } - //} else { - // logs.Info("缓存token") - // h, _ := time.ParseDuration("-624h") - // tZero := time.Now().Add(h) - // logs.Info(tZero) - // logs.Info(token.Expiration) - // t_ := token.Expiration.Sub(tZero) - // if t_ < 0 { - // err2, done := getT(c, token) - // if done { - // return err2 - // } - // } else { - // logs.Info("获取缓存成功") - // c.Token = token.Token - // } - //} + return err } else { req := httplib.Post(c.Address + "/api/login") req.Header("Content-Type", "application/json;charset=UTF-8") @@ -418,7 +396,6 @@ func getT(c *Container, token *Token) (error, bool) { zero, _ := time.ParseInLocation("2006-01-02", time.Now().Local().Format("2006-01-02"), time.Local) token.Expiration = zero token.Address = c.Address - setSqlToken(token) logs.Info(c.Token + token.Expiration.String()) } else { return err, true @@ -432,7 +409,7 @@ func (c *Container) request(ss ...string) ([]byte, error) { if s == GET || s == POST || s == PUT || s == DELETE { method = s } else if strings.Contains(s, "/api/") { - if c.Version == "2.9" { + if c.Version == "openapi" { api = strings.ReplaceAll(s, "api", "open") } else { api = s @@ -491,14 +468,10 @@ func GetQlVersion(address string) (string, error) { } v := "" //logs.Info(data) - if strings.Contains(data, "v2.8") { - v = "2.8" - } else if strings.Contains(data, "v2.2") { - v = "2.2" - } else if strings.Contains(data, "v2.9") { - v = "2.9" + if strings.Contains(data, "v2.2") { + v = "api" } else { - v = "2.9" + v = "openapi" } return v, nil } diff --git a/models/db.go b/models/db.go index 3b33382..6b6ac72 100644 --- a/models/db.go +++ b/models/db.go @@ -321,17 +321,3 @@ func CheckIn(pin, key string) int { } return 2 } - -func setSqlToken(token *Token) error { - tx := db.Begin() - if err := tx.Create(token).Error; err != nil { - tx.Rollback() - return err - } - return tx.Commit().Error -} - -func getSqlToken(address string) (*Token, error) { - token := &Token{} - return token, db.Where(Address+" = ?", address).Order("expiration desc").First(token).Error -} diff --git a/models/version.go b/models/version.go index 567d9c2..1106a09 100644 --- a/models/version.go +++ b/models/version.go @@ -11,8 +11,8 @@ import ( "github.com/beego/beego/v2/core/logs" ) -var version = "20211002" -var describe = "国庆版本" +var version = "20211011" +var describe = "最终稳定版" var AppName = "xdd" var pname = regexp.MustCompile(`/([^/\s]+)`).FindStringSubmatch(os.Args[0])[1] diff --git a/readme.md b/readme.md index 92b571c..ba8cdbd 100644 --- a/readme.md +++ b/readme.md @@ -2,11 +2,33 @@ ## 注意事项 - 1. master:的值即为密码,后面不可带注释,全匹配方可登录,也不要pt_pin 可自定义 - 2. 2.9+版本需要配置 cid和secret 在青龙里面系统设置,添加应用后配置 + 1. master:的值即为密码,后面不可带注释,全匹配方可登录,也不要pt_pin 可自定义 + 2. 2.9+版本需要配置 cid和secret 在青龙里面系统设置,添加应用后配置 + +# 支持作者 + +就当是支持支持作者更新吧 谢谢各位了。 几毛钱的包愿意就当支持我了 每天都可以领一次 建议保存到本地 辛苦了 不愿意也没事 几块钱的大家可以去买瓶水喝 + + + +1.jpg2.jpg # 更新日志 +## 10-11 + +- 适配V2.8+版本包括即将来的3.0版本都适配了 = - 基本你们能用到黄了把 +- 修复了QQ转账功能 + +## 10-07 + +- 新增延时设置,怕黑号调高,不怕的调低 + +## 10-04 + +- 新增QQ转账功能 格式 QQ转账 QQ 钱 例如 QQ转账 7647 100 +- 各位大老爷支持支持作者吧 谢谢啦 + ## 10-03 - 修复空pin可导入问题 @@ -123,6 +145,32 @@ fix 重大BUG修复,解决以下几个问题, 以及大大小小的模块作者 +# 安装教程 + +xdd-plus安装教程 +第一步:下载go +cd /usr/local && wget https://golang.google.cn/dl/go1.16.7.linux-amd64.tar.gz -O go1.16.7.linux-amd64.tar.gz +第二步:解压go +tar -xvzf go1.16.7.linux-amd64.tar.gz +第三步:设置环境变量 +vi /etc/profile +将文本复制到最后一行 +export GO111MODULE=on +export GOPROXY=https://goproxy.cn +export GOROOT=/usr/local/go +export GOPATH=/usr/local/go/path +export PATH=$PATH:$GOROOT/bin:$GOPATH/bin +第五步:先按 esc +然后输入 :wq +保存文件后 +source /etc/profile +第六步:检查go安装 +go env +第七步:拉xdd-plus的库 +cd ~ && git clone https://ghproxy.com/https://github.com/764763903a/xdd-plus.git +第八步:编译xdd-plus +cd /root/xdd-plus && go build + # 常见问题 编码问题参考 diff --git a/scripts/jd_dyj_help.js b/scripts/jd_dyj_help.js index 043ec3e..2108e60 100644 --- a/scripts/jd_dyj_help.js +++ b/scripts/jd_dyj_help.js @@ -42,7 +42,7 @@ let tools = [] data = await openRedEnvelopeInteract({redEnvelopeId: helps[0].redEnvelopeId,inviter: helps[0].markedPin, helpType:"1"}) errMsg = data?.data?.helpResult?.errMsg if(errMsg){ - console.log(`${tool.id}->${helps[0].id} ${errMsg}`) + // console.log(`${tool.id}->${helps[0].id} ${errMsg}`) if(errMsg.indexOf("成功提现")!=-1){ console.log(errMsg) helps.shift() diff --git a/static/hb.jpg b/static/hb.jpg new file mode 100644 index 0000000..8c42a32 Binary files /dev/null and b/static/hb.jpg differ diff --git a/static/zfb.jpg b/static/zfb.jpg new file mode 100644 index 0000000..8166b16 Binary files /dev/null and b/static/zfb.jpg differ