├── 111.PNG ├── config.json ├── README.md └── main.go /111.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryGOTry/go-Tubi/HEAD/111.PNG -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "action":"login", 3 | "username": "", 4 | "password": "", 5 | "questionid": 0, 6 | "answer": "", 7 | "serverkey": "" 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go-Tubi 2 | Golang写的土司自动签到程序(Server酱推送,检测是否成功,没成功一小时后再执行) 3 | 4 | ## 说明 5 | 又是造轮子的一天. 6 | 7 | 根据大佬的操作,不用修改标准库也可以带cookie进行post发包了!!!!!!!! 果然还是自己太菜了。 8 | 9 | 10 | ## config.json说明 11 | ``` 12 | { 13 | "action":"login", //不可修改 14 | "Username": "", //登录账号 15 | "password": "", // 登录密码,不加密 16 | "questionid": 0, //安全问题id 17 | "answer": "", //安全问题答案 18 | "serverkey": "" //server酱的key,不要推送的话,不填写就好了 19 | } 20 | //问题id 21 | //# 0 = 没有安全提问 22 | //# 1 = 母亲的名字 23 | //# 2 = 爷爷的名字 24 | //# 3 = 父亲出生的城市 25 | //# 4 = 您其中一位老师的名字 26 | //# 5 = 您个人计算机的型号 27 | //# 6 = 您最喜欢的餐馆名称 28 | //# 7 = 驾驶执照的最后四位数字 29 | 30 | ``` 31 | --- 32 | ### 如何编译 33 | ``` 34 | Linux: 35 | SET CGO_ENABLED=0 36 | SET GOOS=linux 37 | SET GOARCH=amd64 38 | go build -ldflags "-s -w" -o Tubi_linux_x64 main.go 39 | 40 | windows: 41 | SET CGO_ENABLED=0 42 | SET GOOS=windows 43 | SET GOARCH=amd64 44 | go build -ldflags "-s -w" -o Tubi_x64.exe main.go 45 | ``` 46 | ### 可以直接下载编译好的文件,修改config.json里的配置就可以了。 47 | 太菜了. 48 | 49 | ![运行截图](https://github.com/TRYblog/go-Tubi/blob/main/111.PNG "go-Tubi") 50 | 51 | ## 关于作者 52 | 一个菜鸟. 53 | [个人博客](https://www.nctry.com) 54 | 55 | ## 时间 56 | 2021/02/22 57 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/json" 6 | "fmt" 7 | "github.com/tidwall/gjson" 8 | "io/ioutil" 9 | "net/http" 10 | "net/http/cookiejar" 11 | "net/url" 12 | "os" 13 | "time" 14 | ) 15 | 16 | type Userinfo struct { 17 | Action string `json:"action"` //类型 18 | Username string `json:"username"` //账号 19 | Password string `json:"password"` //密码 20 | Questionid int `json:"questionid"` //登录问题 21 | Answer string `json:"answer"` //登录答案 22 | Serverkey string `json:"serverkey"` 23 | Signsubmit string `json:"signsubmit"` 24 | Formhash string `json:"formhash"` 25 | Cookie string 26 | } 27 | 28 | func T00ls_Go(u *Userinfo) *Userinfo { 29 | jar, err := cookiejar.New(nil) 30 | client := &http.Client{ 31 | Jar: jar, 32 | } 33 | skey := u.Serverkey 34 | md5passwd := md5.Sum([]byte(u.Password)) //将密码进行md5加密 35 | u.Password = fmt.Sprintf("%x", md5passwd) 36 | want := url.Values{ 37 | "action": {u.Action}, 38 | "username": {u.Username}, 39 | "password": {u.Password}, 40 | "answer": {u.Answer}, 41 | } 42 | //fmt.Println(want) 43 | want.Add("questionid", fmt.Sprintf("%v", u.Questionid)) 44 | request, err := client.PostForm("https://www.t00ls.net/login.json", 45 | want) 46 | if err != nil || request.Status != "200 OK" { 47 | fmt.Println("[info] 土司好像挂了") 48 | Sendmsg(u.Serverkey, "土司好像挂了,一小时后会尝试重新打卡."+fmt.Sprintf("%d", time.Now().Unix())) 49 | time.Sleep(1 * time.Hour) //延时一小时,再执行签到。 50 | T00ls_Go(u) 51 | } 52 | //fmt.Println(request.Body.Read(b)) 53 | defer request.Body.Close() 54 | body, err := ioutil.ReadAll(request.Body) 55 | if err != nil { 56 | fmt.Println(err) 57 | } 58 | c := request.Cookies() 59 | var sid *http.Cookie = c[0] 60 | var ck *http.Cookie = c[2] 61 | status := fmt.Sprintf("%s", gjson.Get(string(body), "status")) 62 | formhash := fmt.Sprintf("%s", gjson.Get(string(body), "formhash")) 63 | if status != "success" { 64 | fmt.Println("[info] 登录失败!") 65 | } 66 | fmt.Println("[info] 登录成功!") 67 | h := &Userinfo{} 68 | h.Formhash = formhash 69 | h.Signsubmit = "true" 70 | h.Cookie = fmt.Sprintf("%s", ck) + fmt.Sprintf("%s", sid) 71 | h.Serverkey = skey 72 | Sign(h, client) //签到 73 | return h //登录成功返回hash 74 | } 75 | func Sign(h *Userinfo, client *http.Client) { //签到函数 76 | want := url.Values{ 77 | "signsubmit": {h.Signsubmit}, 78 | "formhash": {h.Formhash}, 79 | } 80 | request, err := client.PostForm("https://www.t00ls.net/ajax-sign.json", want) 81 | if err != nil || request.Status != "200 OK" { 82 | fmt.Println("[info] 土司好像挂了") 83 | } 84 | //fmt.Println(request.Body.Read(b)) 85 | defer request.Body.Close() 86 | body, err := ioutil.ReadAll(request.Body) 87 | if err != nil { 88 | fmt.Println(err) 89 | } 90 | //fmt.Println(string(body)) 91 | status := fmt.Sprintf("%s", gjson.Get(string(body), "status")) 92 | message := fmt.Sprintf("%s", gjson.Get(string(body), "message")) 93 | if status == "success" { 94 | fmt.Println("[info] 签到成功!") 95 | Sendmsg(h.Serverkey, "签到成功!"+fmt.Sprintf("%d", time.Now().Unix())) 96 | } else if message == "alreadysign" { 97 | fmt.Println("[info] 当前账号已签到!") 98 | Sendmsg(h.Serverkey, "当前账号已签到!"+fmt.Sprintf("%d", time.Now().Unix())) 99 | } else { 100 | fmt.Println("[info] 签到失败~") 101 | } 102 | } 103 | func Sendmsg(key string, msg string) { 104 | //server酱发送信息 105 | url1 := "https://sc.ftqq.com/" + key + ".send?text=" + url.QueryEscape(msg) 106 | 107 | resp, err := http.Get(url1) 108 | if err != nil { 109 | fmt.Println(err) 110 | } 111 | defer resp.Body.Close() 112 | body, err := ioutil.ReadAll(resp.Body) 113 | if err != nil { 114 | // handle error 115 | } 116 | errmsg := fmt.Sprintf("%s", gjson.Get(string(body), "errmsg")) 117 | //fmt.Println(string(body)) 118 | if errmsg == "success" { 119 | fmt.Println("[info] 信息推送成功!") 120 | } else { 121 | fmt.Println("[info] 信息推送失败!") 122 | } 123 | 124 | } 125 | 126 | func main() { 127 | if len(os.Args) < 2 { 128 | fmt.Println("[info] 请输入配置文件地址,运行案例:Tubi.exe config.json (不行的话,请加绝对路径)") 129 | } else { 130 | filename := os.Args[1] 131 | file, _ := os.Open(filename) 132 | defer file.Close() 133 | decoder := json.NewDecoder(file) 134 | conf := &Userinfo{} 135 | err := decoder.Decode(&conf) 136 | if err != nil { 137 | fmt.Println("Error:", err) 138 | } 139 | if conf.Action != "login" { 140 | fmt.Println("[info] Action配置必须是login!") 141 | os.Exit(1) 142 | } else if conf.Username == "" || conf.Password == "" || conf.Answer == "" { 143 | fmt.Println("[info] 请认证填写config.json配置文件~") 144 | } else { 145 | fmt.Println("[info] 配置读取成功! by: Try") 146 | fmt.Println("[info] By T00ls.Net;") 147 | T00ls_Go(conf) //开始执行 148 | } 149 | } 150 | } 151 | --------------------------------------------------------------------------------