├── sample.toml ├── .gitignore ├── go.mod ├── helper ├── win-toast.go ├── win-run.go ├── token.go ├── config.go ├── logger.go ├── win-process.go ├── helper.go └── leigod-api.go ├── README.md ├── LICENSE ├── main.go └── go.sum /sample.toml: -------------------------------------------------------------------------------- 1 | username = "" # 雷神加速器账号 2 | password = "" # 雷神加速器密码 3 | games = "TslGame,SoTGame" ## 绝地求生,盗贼之海 进程名 不需要.exe -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | leigodhelper.exe* 2 | logs 3 | cache 4 | *debug* 5 | .vscode 6 | leigodhelper.zip 7 | local.toml 8 | config.toml -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module leigodhelper 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 7 | github.com/kardianos/service v1.2.2 8 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect 9 | github.com/spf13/viper v1.7.1 10 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /helper/win-toast.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "github.com/go-toast/toast" 5 | ) 6 | 7 | func Notify(msg string) { 8 | Logger.Println(msg) 9 | notification := toast.Notification{ 10 | AppID: "Microsoft.Windows.Shell.RunDialog", 11 | Title: "加速器助手", 12 | Message: msg, 13 | } 14 | err := notification.Push() 15 | if err != nil { 16 | Logger.Println(err) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /helper/win-run.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "os/exec" 5 | "syscall" 6 | ) 7 | 8 | func runApps(apps ...string) error { 9 | // 启动 10 | for _, app := range apps { 11 | cmd := exec.Command("cmd", "/c", app) 12 | cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 13 | err := cmd.Start() 14 | if err != nil { 15 | Logger.Println(err) 16 | return err 17 | } 18 | Logger.Println("start", app) 19 | } 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /helper/token.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "encoding/json" 5 | "io/fs" 6 | "os" 7 | "time" 8 | ) 9 | 10 | type LeigodToken struct { 11 | AccountToken string 12 | ExpireTime time.Time 13 | } 14 | 15 | var Token *LeigodToken 16 | 17 | var filename = "cache/token.cache" 18 | 19 | func (a *LeigodApi) SaveToken() { 20 | buf, err := json.Marshal(a.Token) 21 | if err != nil { 22 | Logger.Println(err) 23 | return 24 | } 25 | os.Mkdir("cache", os.ModeDir) 26 | err = os.WriteFile(filename, buf, fs.ModePerm) 27 | if err != nil { 28 | Logger.Println(err) 29 | } 30 | } 31 | 32 | func (a *LeigodApi) LoadToken() { 33 | buf, _ := os.ReadFile(filename) 34 | json.Unmarshal(buf, &a.Token) 35 | } 36 | -------------------------------------------------------------------------------- /helper/config.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/spf13/viper" 7 | ) 8 | 9 | type Config struct { 10 | Username string `mapstructure:"username"` 11 | Password string `mapstructure:"password"` 12 | Games string `mapstructure:"games"` 13 | } 14 | 15 | var config Config 16 | 17 | func LoadConfig(configPath string) (*Config, error) { 18 | viper.SetConfigName("config") 19 | viper.SetConfigType("toml") 20 | viper.AddConfigPath(".") 21 | if configPath != "" { 22 | if strings.Contains(configPath, ".") { 23 | viper.SetConfigFile(configPath) 24 | } else { 25 | viper.SetConfigName(configPath) 26 | } 27 | } 28 | 29 | err := viper.ReadInConfig() 30 | if err != nil { 31 | return nil, err 32 | } 33 | err = viper.Unmarshal(&config) 34 | if err != nil { 35 | return nil, err 36 | } 37 | config.Games = strings.ReplaceAll(config.Games, ",", ",") 38 | return &config, nil 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 雷神加速器自动暂停工具 2 | 3 | ### 编译 4 | - 下载并安装Go https://golang.google.cn/dl/go1.16.4.windows-amd64.msi 5 | - 在powershell中 cd到根目录执行下面两条命令 6 | - $env:GOPROXY="https://goproxy.cn,direct" 7 | - go build -ldflags "-H windowsgui" 8 | 9 | 10 | ### 申明 11 | 12 | - 本工具仅适用于交流学习,不得用作商业用途 13 | - 如果本项目可能侵犯您的权益,请及时联系我删除,邮箱: yixinin@outlook.com 14 | - 本项目只有源码,没有可执行文件,任何形式的文件传播均与本项目及账号无关 15 | 16 | ### 特性 17 | 18 | - 退出游戏时自动暂停加速器 19 | - 电脑关机时自动暂停加速器 20 | - 长时间没有运行游戏时暂停加速器(每1小时检测一次) 21 | 22 | 23 | ### 使用说明 24 | 25 | #### 填写config.toml 26 | - 将雷神账号密码填写在username,password 27 | - 将需要监听的游戏进程名(不要.exe)填写在games, 以英文逗号分隔(默认监听pubg,盗贼之海。) 28 | #### 安装 29 | - 将config.toml 和 leigodhelper.exe 放置在目录leigodhelper 30 | - 编辑config.toml, 填入 username,password,games 31 | - 用管理员身份打开powershell/cmd 执行以下命令 32 | ``` 33 | cd leigodhelper 34 | ./leigodhelper.exe install 35 | ``` 36 | - leigodhelper service会自动启动 37 | - 编辑config.toml会自动生效 38 | - 安装路径为C:\Program Files\LeigodHelper 39 | 40 | ### 卸载 41 | - 用管理员身份打开powershell/cmd 42 | - ./leigodhelper.exe remove -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 yixinin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /helper/logger.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "syscall" 10 | "time" 11 | ) 12 | 13 | var Logger *Log 14 | 15 | func InitLogger() { 16 | var dir = `C:\Program Files\LeigodHelper` 17 | cmd := exec.Command("powershell", "rm", filepath.Join(dir, "logs/leigodhelper.log.*")) 18 | cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 19 | cmd.Run() 20 | 21 | os.Rename(filepath.Join(dir, "logs/leigodhelper.log"), fmt.Sprintf(filepath.Join(dir, "logs/leigodhelper.log.%s"), time.Now().Format("0102150405"))) 22 | os.Mkdir(filepath.Join(dir, "logs"), os.ModeDir) 23 | f, err := os.OpenFile(filepath.Join(dir, "logs/leigodhelper.log"), os.O_CREATE|os.O_RDWR, 0644) 24 | if err != nil { 25 | log.Println(err) 26 | return 27 | } 28 | logger := log.New(f, "", log.Llongfile) 29 | 30 | Logger = &Log{ 31 | f: f, 32 | logger: logger, 33 | } 34 | } 35 | 36 | type Log struct { 37 | f *os.File 38 | logger *log.Logger 39 | } 40 | 41 | func (l *Log) Close() { 42 | if l != nil { 43 | l.f.Close() 44 | } 45 | } 46 | 47 | func (l *Log) Println(args ...interface{}) { 48 | args = append([]interface{}{time.Now()}, args...) 49 | l.logger.Println(args...) 50 | } 51 | func (l *Log) Printf(f string, args ...interface{}) { 52 | args = append([]interface{}{time.Now()}, args...) 53 | l.logger.Printf("%s "+f, args...) 54 | } 55 | -------------------------------------------------------------------------------- /helper/win-process.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "strings" 5 | "syscall" 6 | "unsafe" 7 | ) 8 | 9 | type ulong int32 10 | type ulong_ptr uintptr 11 | 12 | type PROCESSENTRY32 struct { 13 | dwSize ulong 14 | cntUsage ulong 15 | th32ProcessID ulong 16 | th32DefaultHeapID ulong_ptr 17 | th32ModuleID ulong 18 | cntThreads ulong 19 | th32ParentProcessID ulong 20 | pcPriClassBase ulong 21 | dwFlags ulong 22 | szExeFile [260]byte 23 | } 24 | 25 | func getProcess() (m map[string]byte) { 26 | m = make(map[string]byte, 100) 27 | kernel32 := syscall.NewLazyDLL("kernel32.dll") 28 | CreateToolhelp32Snapshot := kernel32.NewProc("CreateToolhelp32Snapshot") 29 | pHandle, _, _ := CreateToolhelp32Snapshot.Call(uintptr(0x2), uintptr(0x0)) 30 | if int(pHandle) == -1 { 31 | return 32 | } 33 | defer func() { 34 | CloseHandle := kernel32.NewProc("CloseHandle") 35 | _, _, _ = CloseHandle.Call(pHandle) 36 | }() 37 | Process32Next := kernel32.NewProc("Process32Next") 38 | for { 39 | var proc PROCESSENTRY32 40 | proc.dwSize = ulong(unsafe.Sizeof(proc)) 41 | if rt, _, _ := Process32Next.Call(uintptr(pHandle), uintptr(unsafe.Pointer(&proc))); int(rt) == 1 { 42 | v := strings.TrimSpace(string(proc.szExeFile[0:])) 43 | var i = strings.Index(v, ".exe") 44 | if i > 0 { 45 | name := v[:i] 46 | name = NormalizeProcessName(name) 47 | m[name]++ 48 | } 49 | } else { 50 | break 51 | } 52 | } 53 | return m 54 | } 55 | 56 | func NormalizeProcessName(src string) string { 57 | var dst = make([]byte, 0, len(src)) 58 | for _, b := range []byte(src) { 59 | if isLetter(b) || b == '_' { 60 | dst = append(dst, b) 61 | } 62 | } 63 | return string(dst) 64 | } 65 | 66 | func isLetter(b byte) bool { 67 | if b >= 'a' && b <= 'z' { 68 | return true 69 | } 70 | if b >= 'A' && b <= 'Z' { 71 | return true 72 | } 73 | return false 74 | } 75 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "leigodhelper/helper" 8 | "log" 9 | "os" 10 | "os/exec" 11 | "path/filepath" 12 | "sync" 13 | "time" 14 | 15 | "github.com/kardianos/service" 16 | ) 17 | 18 | const InstallPath = `C:\Program Files\LeigodHelper` 19 | 20 | func main() { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | var msg = fmt.Sprintf("leigod helper exited with error:\nerror: %+v", r) 24 | helper.Notify(msg) 25 | helper.Logger.Println(msg) 26 | return 27 | } 28 | }() 29 | svcConfig := &service.Config{ 30 | Name: "LeigodHelper", 31 | DisplayName: "LeigodHelper", 32 | Description: "Leigod game helper service", 33 | WorkingDirectory: `C:\Program Files\LeigodHelper`, 34 | } 35 | 36 | prg := &program{} 37 | s, err := service.New(prg, svcConfig) 38 | if err != nil { 39 | helper.Notify(err.Error()) 40 | return 41 | } 42 | if len(os.Args) > 1 { 43 | if os.Args[1] == "install" { 44 | os.MkdirAll(InstallPath, 0644) 45 | { 46 | src, err := os.Open(os.Args[0]) 47 | if err != nil { 48 | panic(err) 49 | } 50 | defer src.Close() 51 | dst, err := os.Create(InstallPath + "/leigodhelper.exe") 52 | if err != nil { 53 | panic(err) 54 | } 55 | _, err = io.Copy(dst, src) 56 | if err != nil { 57 | panic(err) 58 | } 59 | defer src.Close() 60 | } 61 | { 62 | src, err := os.Open(filepath.Dir(os.Args[0]) + "/config.toml") 63 | if err != nil { 64 | panic(err) 65 | } 66 | dst, err := os.Create(InstallPath + "/config.toml") 67 | if err != nil { 68 | panic(err) 69 | } 70 | _, err = io.Copy(dst, src) 71 | if err != nil { 72 | panic(err) 73 | } 74 | } 75 | 76 | // start service 77 | s.Install() 78 | log.Println("Install service success!") 79 | err = exec.Command("net", "start", "LeigodHelper").Run() 80 | if err != nil { 81 | log.Println("start service error: ", err) 82 | } 83 | return 84 | } 85 | 86 | if os.Args[1] == "remove" { 87 | err = exec.Command("net", "stop", "LeigodHelper").Run() 88 | if err != nil { 89 | log.Println("stop service error: ", err) 90 | } 91 | s.Uninstall() 92 | time.Sleep(time.Second) 93 | err := os.RemoveAll(InstallPath) 94 | if err != nil { 95 | log.Println("remove files error: ", err) 96 | } 97 | log.Println("Remove service success!") 98 | return 99 | } 100 | } 101 | 102 | // Call svc.Run to start your program/service. 103 | if err := s.Run(); err != nil { 104 | log.Fatal(err) 105 | } 106 | } 107 | 108 | // program implements svc.Service 109 | type program struct { 110 | cancel context.CancelFunc 111 | wg sync.WaitGroup 112 | } 113 | 114 | func (p *program) Start(srv service.Service) error { 115 | c, err := helper.LoadConfig(`C:\Program Files\LeigodHelper\config.toml`) 116 | if err != nil { 117 | helper.Notify(err.Error()) 118 | return nil 119 | } 120 | helper.InitLogger() 121 | ctx, cancel := context.WithCancel(context.Background()) 122 | p.cancel = cancel 123 | var h = helper.NewHelper(c) 124 | p.wg.Add(1) 125 | go func() { 126 | h.Run(ctx) 127 | p.wg.Done() 128 | }() 129 | helper.Logger.Println("Starting...") 130 | return nil 131 | } 132 | 133 | func (p *program) Stop(srv service.Service) error { 134 | // The Stop method is invoked by stopping the Windows service, or by pressing Ctrl+C on the console. 135 | // This method may block, but it's a good idea to finish quickly or your process may be killed by 136 | // Windows during a shutdown/reboot. As a general rule you shouldn't rely on graceful shutdown. 137 | if p.cancel != nil { 138 | p.cancel() 139 | } 140 | helper.Logger.Println("Waiting graceful stop...") 141 | p.wg.Wait() 142 | helper.Logger.Println("Stopped") 143 | helper.Logger.Close() 144 | return nil 145 | } 146 | -------------------------------------------------------------------------------- /helper/helper.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | var ( 11 | lastTryPauseTime int64 12 | ) 13 | 14 | type Helper struct { 15 | api LeigodApi 16 | games map[string]bool 17 | 18 | GameStatus Status 19 | LeigodStatus Status 20 | 21 | tm *time.Timer 22 | tmSet bool 23 | } 24 | 25 | type Status string 26 | 27 | const ( 28 | Unknown Status = "" 29 | Stop Status = "stop" 30 | Running Status = "running" 31 | ) 32 | 33 | func NewHelper(c *Config) Helper { 34 | var games = make(map[string]bool) 35 | for _, v := range strings.Split(c.Games, ",") { 36 | name := NormalizeProcessName(strings.TrimSpace(v)) 37 | games[name] = true 38 | } 39 | 40 | h := Helper{ 41 | api: LeigodApi{ 42 | username: c.Username, 43 | password: c.Password, 44 | }, 45 | games: games, 46 | tm: time.NewTimer(time.Second), 47 | } 48 | h.tm.Stop() 49 | return h 50 | } 51 | 52 | func (h *Helper) Run(ctx context.Context) { 53 | var exitCh = make(chan string) 54 | Logger.Println("start watch games:", config.Games) 55 | go h.loop(ctx, exitCh) 56 | for { 57 | select { 58 | case <-ctx.Done(): 59 | Logger.Printf("recv exit signal, try pause") 60 | h.Pause() 61 | return 62 | case msg := <-exitCh: 63 | Logger.Printf("check paniced, try pause", msg) 64 | h.Pause() 65 | return 66 | case <-h.tm.C: 67 | h.Pause() 68 | h.tmSet = false 69 | } 70 | } 71 | } 72 | 73 | func (h *Helper) Update(leigodOK, gameOK bool) { 74 | h.GameStatus = Stop 75 | if gameOK { 76 | h.GameStatus = Running 77 | if h.tmSet { 78 | Logger.Println("game running, pause canced!") 79 | h.tm.Stop() 80 | h.tmSet = false 81 | return 82 | } 83 | } 84 | if leigodOK { 85 | if !gameOK && !h.tmSet { 86 | Logger.Println("will pause 10minute later...") 87 | if h.LeigodStatus == Running { 88 | Notify("no game running, will pause 10minutes later.") 89 | } 90 | h.tm.Reset(10 * time.Minute) 91 | h.tmSet = true 92 | } 93 | return 94 | } else { 95 | if h.LeigodStatus == Running { 96 | if !gameOK && !h.tmSet { 97 | Logger.Println("will pause 10minute later...") 98 | if h.LeigodStatus == Running { 99 | Notify("no game running, will pause 10minutes later.") 100 | } 101 | h.tm.Reset(10 * time.Minute) 102 | h.tmSet = true 103 | } 104 | } 105 | } 106 | } 107 | 108 | func (h *Helper) loop(ctx context.Context, exitCh chan string) { 109 | defer func() { 110 | if r := recover(); r != nil { 111 | exitCh <- fmt.Sprintf("paniced ! \n err: %+v", recover()) 112 | } 113 | }() 114 | tk := time.NewTicker(10 * time.Second) 115 | defer tk.Stop() 116 | 117 | ttk := time.NewTicker(time.Hour) 118 | defer ttk.Stop() 119 | 120 | for { 121 | select { 122 | case <-ctx.Done(): 123 | return 124 | case <-tk.C: 125 | c, _ := LoadConfig(`C:\Program Files\LeigodHelper\config.toml`) 126 | if c != nil { 127 | var games = make(map[string]bool) 128 | var adds = make([]string, 0) 129 | var dels = make([]string, 0) 130 | for _, v := range strings.Split(c.Games, ",") { 131 | name := NormalizeProcessName(strings.TrimSpace(v)) 132 | games[name] = true 133 | 134 | if _, ok := h.games[name]; !ok { 135 | adds = append(adds, name) 136 | } 137 | } 138 | for k := range h.games { 139 | if _, ok := games[k]; !ok { 140 | dels = append(dels, k) 141 | } 142 | } 143 | if len(adds) != 0 { 144 | Logger.Println("add wathcing games:", dels) 145 | } 146 | if len(dels) != 0 { 147 | Logger.Println("del wathcing games:", dels) 148 | } 149 | if c.Password != "" && c.Password != h.api.password { 150 | Logger.Println("update password") 151 | h.api.password = c.Password 152 | } 153 | if c.Username != "" && c.Username != h.api.username { 154 | Logger.Println("update username to", c.Username) 155 | h.api.username = c.Username 156 | } 157 | 158 | h.games = games 159 | } 160 | leigodOk, gameOK := hasGameRunning("leigod", h.games) 161 | h.Update(leigodOk, gameOK) 162 | case <-ttk.C: 163 | // force check 164 | _, gameOK := hasGameRunning("leigod", h.games) 165 | if !gameOK { 166 | h.Pause() 167 | } 168 | } 169 | } 170 | } 171 | 172 | // 检测游戏是否运行中 173 | func hasGameRunning(name string, games map[string]bool) (leigodOK, gameOK bool) { 174 | var ps = getProcess() 175 | if _, leigodOK = ps[name]; !leigodOK { 176 | return 177 | } 178 | for k := range games { 179 | if _, ok := ps[k]; ok { 180 | gameOK = true 181 | break 182 | } 183 | } 184 | return 185 | } 186 | 187 | func (h *Helper) Pause(finnal ...bool) error { 188 | lastTryPauseTime = time.Now().Unix() 189 | // 获取暂停状态 190 | paused, err := h.api.IsPause() 191 | if err == ErrorNotLogin { 192 | if err := h.Relogin(); err != nil { 193 | return err 194 | } 195 | if len(finnal) > 0 { 196 | return nil 197 | } 198 | return h.Pause(true) 199 | } else { 200 | if err != nil { 201 | return err 202 | } 203 | } 204 | if !paused { 205 | h.LeigodStatus = Running 206 | err := h.api.Pause() 207 | if err == ErrorNotLogin { 208 | if err := h.Relogin(); err != nil { 209 | return err 210 | } 211 | if len(finnal) > 0 { 212 | return nil 213 | } 214 | return h.Pause(true) 215 | } else { 216 | if err != nil { 217 | return err 218 | } 219 | } 220 | 221 | Notify("no game running, stop timing.") 222 | h.LeigodStatus = Stop 223 | return nil 224 | } 225 | h.LeigodStatus = Stop 226 | Logger.Println("already paused!, nothing todo.") 227 | return nil 228 | } 229 | 230 | func (h *Helper) Relogin() error { 231 | err := h.api.Login() 232 | if err != nil { 233 | return err 234 | } 235 | return nil 236 | } 237 | -------------------------------------------------------------------------------- /helper/leigod-api.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "bytes" 5 | "crypto/md5" 6 | "encoding/hex" 7 | "encoding/json" 8 | "errors" 9 | "fmt" 10 | "io" 11 | "net/http" 12 | "time" 13 | ) 14 | 15 | const ( 16 | CodeNotLogin = 400006 17 | TimeLayout = "2006-01-02 15:04:05" 18 | 19 | UserAgent = "Mozilla/5.0 (Linux; Android 9; MIX 2 Build/PKQ1.190118.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045521 Mobile Safari/537.36 MMWEBID/2679 MicroMessenger/8.0.1.1841(0x2800015D) Process/tools WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64" 20 | ) 21 | 22 | var ErrorNotLogin = errors.New("not login") 23 | 24 | type Ack struct { 25 | Code int `json:"code"` 26 | Message string `json:"msg"` 27 | Data interface{} `json:"data"` 28 | } 29 | 30 | type LoginReq struct { 31 | Lang string `json:"lang"` 32 | CountryCode int `json:"country_code"` 33 | Code string `json:"code"` 34 | SrcChannel string `json:"src_channel"` 35 | UserType string `json:"user_type"` 36 | Password string `json:"password"` 37 | Username string `json:"username"` 38 | } 39 | 40 | type LoginAck struct { 41 | Code int `json:"code"` 42 | Message string `json:"msg"` 43 | Data struct { 44 | LoginInfo struct { 45 | AccountToken string `json:"account_token"` 46 | ExpiryTime string `json:"expiry_time"` 47 | } `json:"login_info"` 48 | } `json:"data"` 49 | } 50 | 51 | type LeigodApi struct { 52 | username, password string 53 | Token LeigodToken 54 | } 55 | 56 | func NewApi(username, password string) LeigodApi { 57 | api := LeigodApi{ 58 | username: username, 59 | password: password, 60 | } 61 | api.LoadToken() 62 | return api 63 | } 64 | 65 | func (a *LeigodApi) GetToken() string { 66 | if a.Token.ExpireTime.Before(time.Now()) || a.Token.AccountToken == "" { 67 | if err := a.Login(); err != nil { 68 | Logger.Println(err) 69 | return "" 70 | } 71 | } 72 | return a.Token.AccountToken 73 | } 74 | 75 | func (a *LeigodApi) Login() error { 76 | var url = "https://webapi.nn.com/wap/login/bind" 77 | var req = LoginReq{ 78 | Lang: "zh_CN", 79 | CountryCode: 86, 80 | SrcChannel: "guanwang", 81 | UserType: "0", 82 | Username: a.username, 83 | Password: MD5(a.password), 84 | } 85 | var ack LoginAck 86 | err := a.leigodHttpPost(url, req, &ack) 87 | if err != nil { 88 | return err 89 | } 90 | if ack.Code != 0 { 91 | return fmt.Errorf("%s", ack.Message) 92 | } 93 | expireTime, _ := time.ParseInLocation(TimeLayout, ack.Data.LoginInfo.ExpiryTime, time.Local) 94 | a.Token.AccountToken = ack.Data.LoginInfo.AccountToken 95 | a.Token.ExpireTime = expireTime 96 | a.SaveToken() 97 | return nil 98 | } 99 | 100 | func MD5(str string) string { 101 | h := md5.New() 102 | h.Write([]byte(str)) 103 | return hex.EncodeToString(h.Sum(nil)) 104 | } 105 | 106 | type PauseReq struct { 107 | AccountToken string `json:"account_token"` 108 | Lang string `json:"lang"` 109 | } 110 | 111 | type PauseAck struct { 112 | Code int `json:"code"` 113 | Data []interface{} `json:"data"` 114 | Message string `json:"msg"` 115 | } 116 | 117 | func (a *LeigodApi) Pause() error { 118 | var url = "https://webapi.nn.com/api/user/pause" 119 | var req = PauseReq{ 120 | Lang: "zh_CN", 121 | AccountToken: a.GetToken(), 122 | } 123 | var ack PauseAck 124 | err := a.leigodHttpPost(url, req, &ack) 125 | if err != nil { 126 | return err 127 | } 128 | if ack.Code != 0 { 129 | return fmt.Errorf("code:%d, msg:%s, data:%+v", ack.Code, ack.Message, ack.Data) 130 | } 131 | return nil 132 | } 133 | 134 | type UserInfoReq struct { 135 | AccountToken string `json:"account_token"` 136 | Lang string `json:"lang"` 137 | } 138 | 139 | type UserInfoAck struct { 140 | Code int `json:"code"` 141 | Message string `json:"msg"` 142 | Data struct { 143 | PauseStatusId int `json:"pause_status_id"` // 0表示未暂停 144 | } `json:"data"` 145 | } 146 | 147 | func (a *LeigodApi) IsPause() (bool, error) { 148 | var url = "https://webapi.nn.com/api/user/info" 149 | var req = UserInfoReq{ 150 | Lang: "zh_CN", 151 | AccountToken: a.GetToken(), 152 | } 153 | var ack UserInfoAck 154 | err := a.leigodHttpPost(url, req, &ack) 155 | if err != nil { 156 | return false, err 157 | } 158 | if ack.Code != 0 { 159 | return false, fmt.Errorf("code:%d, msg:%s", ack.Code, ack.Message) 160 | } 161 | return ack.Data.PauseStatusId != 0, nil 162 | } 163 | 164 | func (a *LeigodApi) leigodHttpPost(url string, req, ackBody interface{}) error { 165 | reqBuf, err := json.Marshal(req) 166 | if err != nil { 167 | return err 168 | } 169 | r, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqBuf)) 170 | if err != nil { 171 | return err 172 | } 173 | a.setHeader(r) 174 | resp, err := http.DefaultClient.Do(r) 175 | if err != nil { 176 | return err 177 | } 178 | defer resp.Body.Close() 179 | buf, err := io.ReadAll(resp.Body) 180 | if err != nil { 181 | return err 182 | } 183 | // Logger.Printf("http post: url=%s, req=%+v, ack=%s \n", url, req, string(buf)) 184 | var ack Ack 185 | err = json.Unmarshal(buf, &ack) 186 | if err != nil { 187 | return err 188 | } 189 | if ack.Code == 0 { 190 | err = json.Unmarshal(buf, ackBody) 191 | Logger.Printf("http post: url=%s, req=%s, ack=%+v \n", url, string(reqBuf), ackBody) 192 | return err 193 | } 194 | if ack.Code == CodeNotLogin { 195 | return ErrorNotLogin 196 | } 197 | Logger.Printf("http post: url=%s, req=%s, ack=%+v \n", url, string(reqBuf), ack) 198 | return fmt.Errorf("code:%d, msg:%s", ack.Code, ack.Message) 199 | } 200 | 201 | func (a *LeigodApi) setHeader(r *http.Request) { 202 | var headers = map[string]string{ 203 | "Origin": "https://jiasu.nn.com/", 204 | "User-Agent": UserAgent, 205 | "Sec-Fetch-Mode": "cors", 206 | "X-Requested-With": "com.tencent.mm", 207 | "Sec-Fetch-Site": "same-site", 208 | "Referer": "https://jiasu.nn.com/m/mpause.html?region_code=1&language=zh_CN&platform=4", 209 | } 210 | for k, v := range headers { 211 | r.Header.Set(k, v) 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 9 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 10 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 11 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 12 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 13 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 14 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 15 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 16 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 17 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 18 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 19 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 20 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 21 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 22 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 23 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 24 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 25 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 26 | github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 27 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 28 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 29 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 30 | github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 31 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 32 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 33 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 34 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 35 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 36 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 37 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 38 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 39 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 40 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 41 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 42 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 43 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 44 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 45 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 46 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 47 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 48 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= 49 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= 50 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 51 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 52 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 53 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 54 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 55 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 56 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 57 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 58 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 59 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 60 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 61 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 62 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 63 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 64 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 65 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 66 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 67 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 68 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 69 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 70 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 71 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 72 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 73 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 74 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 75 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 76 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 77 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 78 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 79 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 80 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 81 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 82 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 83 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 84 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 85 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 86 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 87 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 88 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 89 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 90 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 91 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 92 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 93 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 94 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 95 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 96 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 97 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 98 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 99 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 100 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 101 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 102 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 103 | github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= 104 | github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= 105 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 106 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 107 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 108 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 109 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 110 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 111 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 112 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 113 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 114 | github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= 115 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 116 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 117 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 118 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 119 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 120 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 121 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 122 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 123 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 124 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 125 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 126 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= 127 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 128 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 129 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 130 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 131 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= 132 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= 133 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 134 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 135 | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= 136 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 137 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 138 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 139 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 140 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 141 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 142 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 143 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 144 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 145 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 146 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 147 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 148 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 149 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 150 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 151 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 152 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 153 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 154 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 155 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 156 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 157 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 158 | github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= 159 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 160 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 161 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 162 | github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= 163 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 164 | github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= 165 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 166 | github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= 167 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 168 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 169 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 170 | github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= 171 | github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 172 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 173 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 174 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 175 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 176 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 177 | github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= 178 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 179 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 180 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 181 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 182 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 183 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 184 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 185 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 186 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 187 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 188 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 189 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 190 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 191 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 192 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 193 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 194 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 195 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 196 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 197 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 198 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 199 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 200 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 201 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 202 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 203 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 204 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 205 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 206 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 207 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 208 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 209 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 210 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 211 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 212 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 213 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 214 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 215 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 216 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 217 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 218 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 219 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 220 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 221 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 222 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 223 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 224 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 225 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 226 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 227 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 228 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 229 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 230 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 231 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 232 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 233 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 234 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 235 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 236 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 237 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 238 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 239 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 240 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 241 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 242 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 243 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 244 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 245 | golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 246 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= 247 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 248 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 249 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 250 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 251 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 252 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 253 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 254 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 255 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 256 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 257 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 258 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 259 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 260 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 261 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 262 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 263 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 264 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 265 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 266 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 267 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 268 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 269 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 270 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 271 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 272 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 273 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 274 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 275 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 276 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 277 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 278 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 279 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 280 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 281 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 282 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 283 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 284 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 285 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 286 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 287 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 288 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 289 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 290 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 291 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 292 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 293 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 294 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 295 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 296 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 297 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 298 | gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= 299 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 300 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 301 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 302 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 303 | gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= 304 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 305 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 306 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 307 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 308 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 309 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 310 | --------------------------------------------------------------------------------