package main
/**
* 羊了个羊小程序通关脚本
*
* max := 10000 // 通关次数
* concurrency = 20 // 控制并发量
* param.Set("t", "") // 登录token-自行抓包获取(必须设置)
*
* @author thinklxr
*/
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"sync"
"time"
)
type Limit struct {
number int
channel chan struct{}
}
// Limit struct 初始化
func New(number int) *Limit {
return &Limit{
number: number,
channel: make(chan struct{}, number),
}
}
// Run 方法:创建有限的 go f 函数的 goroutine
func (limit *Limit) Run(f func()) {
limit.channel <- struct{}{}
go func() {
f()
<-limit.channel
}()
}
// WaitGroup 对象内部有一个计数器,从0开始
// 有三个方法:Add(), Done(), Wait() 用来控制计数器的数量
var wg = sync.WaitGroup{}
const (
concurrency = 20 // 控制并发量
)
func main() {
start := time.Now()
limit := New(concurrency) // New Limit 控制并发量
// 接口请求URL
apiUrl := "https://cat-match.easygame2021.com/sheep/v1/game/game_over"
max := 50000 // 通关次数
// 初始化参数
param := url.Values{}
param.Set("rank_score", "1")
param.Set("rank_state", "1")
param.Set("rank_time", "888")
param.Set("rank_role", "1")
param.Set("skin", "1")
param.Set("t", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTQ1OTQxNzIsIm5iZiI6MTY2MzQ5MTk3MiwiaWF0IjoxNjYzNDkwMTcyLCJqdGkiOiJDTTpjYXRfbWF0Y2g6bHQxMjM0NTYiLCJvcGVuX2lkIjoiIiwidWlkIjo5NjgzMjMzMSwiZGVidWciOiIiLCJsYW5nIjoiIn0.XpajPZ-_9lTC-yYLpVQYi1rXz_9sgy5WYUEJQi3Q07k")
for i := 0; i < max; i++ {
wg.Add(1)
value := i
goFunc := func() {
fmt.Printf("start func: %d\n", value)
data, err := Get(apiUrl, param)
if err != nil {
fmt.Println(err)
return
}
// 其它逻辑代码...
fmt.Println(string(data))
wg.Done()
}
limit.Run(goFunc)
}
// 阻塞代码防止退出
wg.Wait()
fmt.Printf("耗时: %fs", time.Now().Sub(start).Seconds())
}
// Get 方式发起网络请求
func Get(apiURL string, params url.Values) (rs []byte, err error) {
var Url *url.URL
Url, err = url.Parse(apiURL)
if err != nil {
fmt.Printf("解析url错误:\r\n%v", err)
return nil, err
}
//如果参数中有中文参数,这个方法会进行URLEncode
Url.RawQuery = params.Encode()
resp, err := http.Get(Url.String())
if err != nil {
fmt.Println("err:", err)
return nil, err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}