commit b4dc5896e51e1fdc9244c725386acf1d263adef0 Author: Russia9 Date: Fri Apr 8 19:35:38 2022 +0300 Init diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cad9c83 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.idea/ +*.iml +.env +data/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cad9c83 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml +.env +data/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..d475b64 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,25 @@ +stages: + - build + +services: + - docker:20.10.12-dind + +variables: + TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest + TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA + +build: + image: docker:20.10.12 + stage: build + + before_script: + # Login to GitLab Registry + - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY + # Pull last image to use cache + - docker pull "$TAG_LATEST" || true + script: + # Build Image + - docker build --cache-from "$TAG_LATEST" -t $TAG_COMMIT -t $TAG_LATEST . + # Push to GitLab Registry + - docker push $TAG_COMMIT + - docker push $TAG_LATEST diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..68c981a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.18 + +# Set app workdir +WORKDIR /go/src/app + +# Copy dependencies list +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy application sources +COPY . . + +# Build app +RUN go build -o app . + +# Run app +CMD ["./app"] diff --git a/assets/layout.yml b/assets/layout.yml new file mode 100644 index 0000000..66cd615 --- /dev/null +++ b/assets/layout.yml @@ -0,0 +1,13 @@ +settings: + token_env: TELEGRAM_TOKEN + parse_mode: html + locales_dir: assets/locales + +buttons: + rules_accept: + unique: rules_accept + text: ✅ Принять + +markups: + rules: + - [ rules_accept ] \ No newline at end of file diff --git a/assets/locales/ru.yml b/assets/locales/ru.yml new file mode 100644 index 0000000..69810dd --- /dev/null +++ b/assets/locales/ru.yml @@ -0,0 +1,2 @@ +rules: | + ⚠️Внимание! При использовании бота ваш аккаунт в Telegram и игровой профиль могут быть заблокированы в любой момент. Разработчик не несет ответственности за эти баны. diff --git a/bot/bot.go b/bot/bot.go new file mode 100644 index 0000000..2de2763 --- /dev/null +++ b/bot/bot.go @@ -0,0 +1,9 @@ +package bot + +import ( + "gopkg.in/tucnak/telebot.v3" + "gopkg.in/tucnak/telebot.v3/layout" +) + +var Bot *telebot.Bot +var Layout *layout.Layout diff --git a/bot/handlers/add.go b/bot/handlers/add.go new file mode 100644 index 0000000..49c383d --- /dev/null +++ b/bot/handlers/add.go @@ -0,0 +1,27 @@ +package handlers + +import ( + "context" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" +) + +func Add(ctx telebot.Context) error { + //return ctx.Send(bot.Layout.Text(ctx, "rules"), bot.Layout.Markup(ctx, "rules")) + + err := storage.SetState(context.Background(), ctx.Sender().ID, "phone") + if err != nil { + return err + } + + return ctx.Send("Введите номер телефона:") +} + +func Accept(ctx telebot.Context) error { + err := storage.SetState(context.Background(), ctx.Sender().ID, "phone") + if err != nil { + return err + } + + return ctx.Edit("Введите номер телефона:") +} diff --git a/bot/handlers/code.go b/bot/handlers/code.go new file mode 100644 index 0000000..5bbf7b3 --- /dev/null +++ b/bot/handlers/code.go @@ -0,0 +1,105 @@ +package handlers + +import ( + "bytes" + "context" + "errors" + "github.com/gotd/td/session" + "github.com/gotd/td/telegram" + "github.com/gotd/td/telegram/auth" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" + "muskrat/types" + "muskrat/userbot" + "os" + "regexp" + "strconv" + "strings" + "time" +) + +func Code(ctx telebot.Context, metadata []string) error { + if !regexp.MustCompile("^\\d \\d \\d \\d \\d$").MatchString(ctx.Text()) { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return ctx.Send("Неправильный формат кода. Научись читать пж") + } + + sess := storage.Registration[ctx.Sender().ID] + if len(sess) == 0 { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return List(ctx) + } + + s := session.StorageMemory{} + err := s.StoreSession(context.Background(), sess) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return err + } + + appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID")) + if err != nil { + return err + } + client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{ + SessionStorage: &s, + }) + + err = client.Run(context.Background(), func(c context.Context) error { + _, err = client.Auth().SignIn(c, metadata[0], strings.ReplaceAll(ctx.Text(), " ", ""), metadata[1]) + if errors.Is(err, auth.ErrPasswordAuthNeeded) { + b := new(bytes.Buffer) + err = s.Dump(b) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return err + } + if len(storage.Registration) == 0 { + storage.Registration = make(map[int64][]byte) + } + storage.Registration[ctx.Sender().ID] = b.Bytes() + storage.SetState(context.Background(), ctx.Sender().ID, "password") + return ctx.Send("Введите пароль 2fa:") + } else if err != nil { + return err + } + + self, err := client.Self(context.Background()) + if err != nil { + return err + } + + // Success + account := &types.Account{ + ID: self.ID, + User: ctx.Sender().ID, + Session: storage.Registration[ctx.Sender().ID], + } + err = storage.DB.Create(account).Error + if err != nil { + return ctx.Send("Аккаунт с таким ID уже есть в боте") + } + + if len(userbot.Userbots) == 0 { + userbot.Userbots = make(map[int64]*userbot.Userbot) + } + if userbot.Userbots[account.ID] != nil { + userbot.Userbots[account.ID].Stop() + delete(userbot.Userbots, account.ID) + } + ubot := &userbot.Userbot{ + Account: account, + } + go ubot.Start(c) + userbot.Userbots[account.ID] = ubot + + time.Sleep(time.Second * 2) + + delete(storage.Registration, ctx.Sender().ID) + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + + return ctx.Send("Успешный логин" + self.FirstName + " " + self.LastName) + }) + + return err +} diff --git a/bot/handlers/delete.go b/bot/handlers/delete.go new file mode 100644 index 0000000..81d0d4a --- /dev/null +++ b/bot/handlers/delete.go @@ -0,0 +1,92 @@ +package handlers + +import ( + "fmt" + "github.com/rs/zerolog/log" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" + "muskrat/types" + "muskrat/userbot" + "strconv" + "strings" +) + +func Delete(ctx telebot.Context) error { + accounts := make([]types.Account, 0) + storage.DB.Find(&accounts, "\"user\" = ?", strconv.FormatInt(ctx.Sender().ID, 10)) + + if len(accounts) == 0 { + return ctx.Send("Чтобы добавить аккаунт, /add") + } + + markup := &telebot.ReplyMarkup{} + rows := make([]telebot.Row, 0) + + for _, account := range accounts { + rows = append(rows, markup.Row(markup.Data(fmt.Sprintf("%s %s %d", account.Corp, account.Name, account.Level), "delete", strconv.FormatInt(account.ID, 10)))) + } + + markup.Inline(rows...) + + return ctx.Send("Удалить аккаунт:", markup) +} + +func AdminDelete(ctx telebot.Context) error { + if ctx.Sender().ID != 784726544 && ctx.Sender().ID != 709800052 { + return nil + } + + params := strings.Split(ctx.Text(), " ") + if len(params) != 2 { + return ctx.Send("Неправильный формат") + } + + id, err := strconv.ParseInt(params[1], 10, 64) + if err != nil { + return err + } + + if userbot.Userbots[id].Account == nil { + return nil + } + + account := userbot.Userbots[id].Account + + err = userbot.Userbots[id].Stop() + if err != nil { + log.Warn().Err(err).Send() + } + + delete(userbot.Userbots, id) + storage.DB.Unscoped().Delete(&account) + + return ctx.Send("Успешно удалено") +} + +func DeleteButton(ctx telebot.Context) error { + data := strings.Split(ctx.Data(), "|") + if len(data) != 1 { + return nil + } + + id, err := strconv.ParseInt(data[0], 10, 64) + if err != nil { + return err + } + + if userbot.Userbots[id].Account == nil { + return nil + } + + account := userbot.Userbots[id].Account + + err = userbot.Userbots[id].Stop() + if err != nil { + log.Warn().Err(err).Send() + } + + delete(userbot.Userbots, id) + storage.DB.Unscoped().Delete(&account) + + return ctx.Send("Успешно удалено") +} diff --git a/bot/handlers/list.go b/bot/handlers/list.go new file mode 100644 index 0000000..a8e9a1e --- /dev/null +++ b/bot/handlers/list.go @@ -0,0 +1,247 @@ +package handlers + +import ( + "context" + "fmt" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" + "muskrat/types" + "muskrat/userbot" + "muskrat/utils" + "regexp" + "strconv" + "strings" +) + +func List(ctx telebot.Context) error { + accounts := make([]types.Account, 0) + storage.DB.Find(&accounts, "\"user\" = ?", strconv.FormatInt(ctx.Sender().ID, 10)) + + if len(accounts) == 0 { + return ctx.Send("Чтобы добавить аккаунт, /add") + } + + markup := &telebot.ReplyMarkup{} + rows := make([]telebot.Row, 0) + + for _, account := range accounts { + rows = append(rows, markup.Row(markup.Data(fmt.Sprintf("%s %s %d", account.Corp, account.Name, account.Level), "account", strconv.FormatInt(account.ID, 10)))) + } + + markup.Inline(rows...) + + return ctx.Send("Список аккаунтов:", markup) +} + +func Account(ctx telebot.Context) error { + if len(ctx.Data()) == 0 { + return ctx.Delete() + } + + var account types.Account + storage.DB.First(&account, strings.Split(ctx.Data(), "|")[0]) + + markup := &telebot.ReplyMarkup{} + + id := strconv.FormatInt(account.ID, 10) + + markup.Inline( + markup.Row( + markup.Data(fmt.Sprintf("Еда: %s", utils.BoolEmoji(account.Eat)), "edit", id, "eat"), + markup.Data(fmt.Sprintf("Еда на 200: %s", utils.BoolEmoji(account.Eat200)), "edit", id, "eat_200"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Команда еды: %s", account.EatCommand), "edit", id, "eat_command"), + markup.Data(fmt.Sprintf("Шанс на еду: %d", account.EatChance), "edit", id, "eat_chance"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Лвлап: %s", utils.BoolEmoji(account.Levelup)), "edit", id, "levelup"), + markup.Data(fmt.Sprintf("Скилл: %s", utils.BoolLevelup(account.LevelupSkill)), "edit", id, "levelup_skill"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Пины: %s", utils.BoolEmoji(account.Pin)), "edit", id, "pin"), + markup.Data(fmt.Sprintf("Чат: %d", account.PinChat), "edit", id, "pin_chat"), + markup.Data(fmt.Sprintf("Пауза: %.1f", account.PinDelay), "edit", id, "pin_delay"), + markup.Data(fmt.Sprintf("Шанс: %d", account.PinChance), "edit", id, "pin_chance"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Репорты: %s", utils.BoolEmoji(account.Report)), "edit", id, "report"), + markup.Data(fmt.Sprintf("Чат: %d", account.ReportChat), "edit", id, "report_chat"), + markup.Data(fmt.Sprintf("Пауза: %.1f", account.ReportDelay), "edit", id, "report_delay"), + markup.Data(fmt.Sprintf("Шанс: %d", account.ReportChance), "edit", id, "report_chance"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Мобы: %s", utils.BoolEmoji(account.Mob)), "edit", id, "mob"), + markup.Data(fmt.Sprintf("Пауза: %.1f", account.MobDelay), "edit", id, "mob_delay"), + markup.Data(fmt.Sprintf("Шанс: %d", account.MobChance), "edit", id, "mob_chance"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Акула: %s", utils.BoolEmoji(account.Shark)), "edit", id, "shark"), + markup.Data(fmt.Sprintf("Пауза: %.1f", account.SharkDelay), "edit", id, "shark_delay"), + markup.Data(fmt.Sprintf("Команда: %s", utils.SharkEmoji(account.SharkTeam)), "edit", id, "shark_team"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Сон: %s", utils.BoolEmoji(account.Sleep)), "edit", id, "sleep"), + markup.Data(fmt.Sprintf("Сон в отеле? %s", utils.BoolEmoji(account.SleepHotel)), "edit", id, "sleep_hotel"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Слив моты: %s", utils.BoolEmoji(account.Motivation)), "edit", id, "motivation"), + markup.Data(fmt.Sprintf("Слив по кд: %s", utils.BoolEmoji(account.MotivationKD)), "edit", id, "motivation_kd"), + ), + markup.Row( + markup.Data(fmt.Sprintf("Команда для слива: %s", account.MotivationCommand), "edit", id, "motivation_command"), + ), + ) + + return ctx.EditOrSend(fmt.Sprintf("Аккаунт %s %s:", account.Corp, account.Name), markup) +} + +func Edit(ctx telebot.Context) error { + data := strings.Split(ctx.Data(), "|") + if len(data) != 2 { + return nil + } + + id, err := strconv.ParseInt(data[0], 10, 64) + if err != nil { + return err + } + + if userbot.Userbots[id].Account == nil { + return nil + } + + account := userbot.Userbots[id].Account + + switch data[1] { + case "eat": + account.Eat = !account.Eat + case "eat_200": + account.Eat200 = !account.Eat200 + case "levelup": + account.Levelup = !account.Levelup + case "levelup_skill": + account.LevelupSkill = !account.LevelupSkill + case "pin": + account.Pin = !account.Pin + case "report": + account.Report = !account.Report + case "mob": + account.Mob = !account.Mob + case "shark": + account.Shark = !account.Shark + case "shark_team": + account.SharkTeam = !account.SharkTeam + case "sleep": + account.Sleep = !account.Sleep + case "sleep_hotel": + account.SleepHotel = !account.SleepHotel + case "motivation": + account.Motivation = !account.Motivation + case "motivation_kd": + account.MotivationKD = !account.MotivationKD + default: + err = storage.SetState(context.Background(), ctx.Sender().ID, "edit", data...) + if err != nil { + return err + } + return ctx.Send(fmt.Sprintf("Введите значение %s:", data[1])) + } + + userbot.Userbots[id].Account = account + storage.DB.Save(&account) + + return Account(ctx) +} + +func EditInput(ctx telebot.Context, data []string) error { + defer storage.ClearState(context.Background(), ctx.Sender().ID) + + if len(data) != 2 { + return nil + } + + id, err := strconv.ParseInt(data[0], 10, 64) + if err != nil { + return err + } + + if userbot.Userbots[id] == nil { + return nil + } + + account := userbot.Userbots[id].Account + + switch data[1] { + case "eat_command": + if !regexp.MustCompile("/.*").MatchString(ctx.Text()) { + return ctx.Send("Неправильный формат") + } + account.EatCommand = ctx.Text() + case "eat_chance": + account.EatChance, err = strconv.Atoi(ctx.Text()) + if err != nil { + return ctx.Send("Неправильный формат") + } + + case "pin_chat": + account.PinChat, err = strconv.ParseInt(ctx.Text(), 10, 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + case "pin_delay": + account.PinDelay, err = strconv.ParseFloat(ctx.Text(), 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + case "pin_chance": + account.PinChance, err = strconv.Atoi(ctx.Text()) + if err != nil { + return ctx.Send("Неправильный формат") + } + + case "report_chat": + account.ReportChat, err = strconv.ParseInt(ctx.Text(), 10, 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + case "report_delay": + account.ReportDelay, err = strconv.ParseFloat(ctx.Text(), 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + case "report_chance": + account.ReportChance, err = strconv.Atoi(ctx.Text()) + if err != nil { + return ctx.Send("Неправильный формат") + } + + case "mob_delay": + account.MobDelay, err = strconv.ParseFloat(ctx.Text(), 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + case "mob_chance": + account.MobChance, err = strconv.Atoi(ctx.Text()) + if err != nil { + return ctx.Send("Неправильный формат") + } + + case "shark_delay": + account.SharkDelay, err = strconv.ParseFloat(ctx.Text(), 64) + if err != nil { + return ctx.Send("Неправильный формат") + } + + case "motivation_command": + if !regexp.MustCompile("/.*").MatchString(ctx.Text()) { + return ctx.Send("Неправильный формат") + } + account.MotivationCommand = ctx.Text() + } + + userbot.Userbots[id].Account = account + storage.DB.Save(&account) + + return ctx.Send("Изменено") +} diff --git a/bot/handlers/password.go b/bot/handlers/password.go new file mode 100644 index 0000000..50697b1 --- /dev/null +++ b/bot/handlers/password.go @@ -0,0 +1,88 @@ +package handlers + +import ( + "context" + "github.com/gotd/td/session" + "github.com/gotd/td/telegram" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" + "muskrat/types" + "muskrat/userbot" + "os" + "strconv" + "time" +) + +func Password(ctx telebot.Context, metadata []string) error { + sess := storage.Registration[ctx.Sender().ID] + if len(sess) == 0 { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return List(ctx) + } + + s := session.StorageMemory{} + err := s.StoreSession(context.Background(), sess) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return err + } + + appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID")) + if err != nil { + return err + } + client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{ + SessionStorage: &s, + }) + + err = client.Run(context.Background(), func(c context.Context) error { + _, err = client.Auth().Password(context.Background(), ctx.Text()) + if err != nil { + return err + } + + // Success + self, err := client.Self(context.Background()) + if err != nil { + return err + } + + // Success + account := &types.Account{ + ID: self.ID, + User: ctx.Sender().ID, + Session: storage.Registration[ctx.Sender().ID], + } + err = storage.DB.Create(account).Error + if err != nil { + return ctx.Send("Аккаунт с таким ID уже есть в боте") + } + + if len(userbot.Userbots) == 0 { + userbot.Userbots = make(map[int64]*userbot.Userbot) + } + if userbot.Userbots[account.ID] != nil { + userbot.Userbots[account.ID].Stop() + delete(userbot.Userbots, account.ID) + } + ubot := &userbot.Userbot{ + Account: account, + } + go ubot.Start(c) + userbot.Userbots[account.ID] = ubot + + time.Sleep(time.Second * 2) + + delete(storage.Registration, ctx.Sender().ID) + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return ctx.Send("Успешный логин" + self.FirstName + " " + self.LastName) + }) + + if err != nil { + delete(storage.Registration, ctx.Sender().ID) + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return ctx.Send("Неправильный пароль") + } + + return err +} diff --git a/bot/handlers/phone.go b/bot/handlers/phone.go new file mode 100644 index 0000000..cf6fe14 --- /dev/null +++ b/bot/handlers/phone.go @@ -0,0 +1,63 @@ +package handlers + +import ( + "bytes" + "context" + "github.com/gotd/td/session" + "github.com/gotd/td/telegram" + "github.com/gotd/td/telegram/auth" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" + "os" + "regexp" + "strconv" +) + +func Phone(ctx telebot.Context) error { + if !regexp.MustCompile("^[+]?[(]?[0-9]{3}[)]?[-\\s.]?[0-9]{3}[-\\s.]?[0-9]{4,8}$").MatchString(ctx.Text()) { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return List(ctx) + } + + s := session.StorageMemory{} + appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID")) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return err + } + client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{ + SessionStorage: &s, + }) + + err = client.Run(context.Background(), func(c context.Context) error { + code, err := client.Auth().SendCode(c, ctx.Text(), auth.SendCodeOptions{}) + if err != nil { + return err + } + + err = storage.SetState(context.Background(), ctx.Sender().ID, "code", ctx.Text(), code.PhoneCodeHash) + if err != nil { + return err + } + + return nil + }) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return List(ctx) + } + + b := new(bytes.Buffer) + err = s.Dump(b) + if err != nil { + _ = storage.ClearState(context.Background(), ctx.Sender().ID) + return err + } + + if len(storage.Registration) == 0 { + storage.Registration = make(map[int64][]byte) + } + storage.Registration[ctx.Sender().ID] = b.Bytes() + + return ctx.Send("Введите код из личных сообщений в формате 1 2 3 4 5:") +} diff --git a/bot/handlers/router.go b/bot/handlers/router.go new file mode 100644 index 0000000..01f226d --- /dev/null +++ b/bot/handlers/router.go @@ -0,0 +1,27 @@ +package handlers + +import ( + "context" + "gopkg.in/tucnak/telebot.v3" + "muskrat/storage" +) + +func Router(ctx telebot.Context) error { + state, metadata, err := storage.GetState(context.Background(), ctx.Sender().ID) + if err != nil { + return err + } + + switch state { + case "phone": + return Phone(ctx) + case "code": + return Code(ctx, metadata) + case "password": + return Password(ctx, metadata) + case "edit": + return EditInput(ctx, metadata) + } + + return List(ctx) +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..31fca0b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.3" + +services: + redis: + image: redis:6.2.5 + restart: always + ports: + - "127.0.0.1:6380:6379" + + postgres: + image: postgres:14.1 + restart: always + env_file: ".env" + ports: + - "127.0.0.1:5432:5432" + volumes: + - ./data:/var/lib/postgresql/data + + muskrat: + build: . + restart: always + env_file: ".env" + depends_on: + - redis + - postgres diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..76ec505 --- /dev/null +++ b/go.mod @@ -0,0 +1,57 @@ +module muskrat + +go 1.18 + +require ( + github.com/go-co-op/gocron v1.13.0 + github.com/go-redis/redis/v8 v8.11.5 + github.com/gotd/td v0.56.0 + github.com/rs/zerolog v1.26.1 + gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee + gorm.io/driver/postgres v1.3.4 + gorm.io/gorm v1.23.4 +) + +require ( + github.com/cenkalti/backoff/v4 v4.1.2 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/go-faster/errors v0.5.0 // indirect + github.com/go-faster/jx v0.34.0 // indirect + github.com/go-faster/xor v0.3.0 // indirect + github.com/goccy/go-yaml v1.9.5 // indirect + github.com/gotd/ige v0.2.2 // indirect + github.com/gotd/neo v0.1.5 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.11.0 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.2.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgtype v1.10.0 // indirect + github.com/jackc/pgx/v4 v4.15.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/segmentio/asm v1.1.3 // indirect + github.com/spf13/cast v1.4.1 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect + golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + nhooyr.io/websocket v1.8.7 // indirect + rsc.io/qr v0.2.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c64df52 --- /dev/null +++ b/go.sum @@ -0,0 +1,429 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-co-op/gocron v1.11.0 h1:ujOMubCpGcTxnnR/9vJIPIEpgwuAjbueAYqJRNr+nHg= +github.com/go-co-op/gocron v1.11.0/go.mod h1:qtlsoMpHlSdIZ3E/xuZzrrAbeX3u5JtPvWf2TcdutU0= +github.com/go-co-op/gocron v1.13.0 h1:BjkuNImPy5NuIPEifhWItFG7pYyr27cyjS6BN9w/D4c= +github.com/go-co-op/gocron v1.13.0/go.mod h1:GD5EIEly1YNW+LovFVx5dzbYVcIc8544K99D8UVRpGo= +github.com/go-faster/errors v0.5.0 h1:hS/zHFJ2Vb14jcupq5J9tk05XW+PFTmySOkDRByHBo4= +github.com/go-faster/errors v0.5.0/go.mod h1:/9SNBcg2ESJTYztBFEiM5Np6ns85BtPNMJd8lFTiFwk= +github.com/go-faster/jx v0.32.0 h1:AVAtgZ1FefKWMfD69DUIAQBV4ypXwHhFjh1ln9WAEEw= +github.com/go-faster/jx v0.32.0/go.mod h1:T561ezgn74siJgc+QzZzoGHokGBKxV6WZugVyfw+68c= +github.com/go-faster/jx v0.34.0 h1:4V/7G+v6S7MNRihCrMXqKgiZLLVs57Qv9HqAJ8zprtg= +github.com/go-faster/jx v0.34.0/go.mod h1:FdJhlaqQP+Drk7zHphPa6fF0Lg19rc6eh6dOugjpEFI= +github.com/go-faster/xor v0.3.0 h1:tc0bdVe31Wj999e5rEj7K3DhHyQNp2VydYyLFj3YSN8= +github.com/go-faster/xor v0.3.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= +github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-yaml v1.9.1/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/goccy/go-yaml v1.9.5 h1:Eh/+3uk9kLxG4koCX6lRMAPS1OaMSAi+FJcya0INdB0= +github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gotd/ige v0.2.2 h1:XQ9dJZwBfDnOGSTxKXBGP4gMud3Qku2ekScRjDWWfEk= +github.com/gotd/ige v0.2.2/go.mod h1:tuCRb+Y5Y3eNTo3ypIfNpQ4MFjrnONiL2jN2AKZXmb0= +github.com/gotd/neo v0.1.5 h1:oj0iQfMbGClP8xI59x7fE/uHoTJD7NZH9oV1WNuPukQ= +github.com/gotd/neo v0.1.5/go.mod h1:9A2a4bn9zL6FADufBdt7tZt+WMhvZoc5gWXihOPoiBQ= +github.com/gotd/td v0.55.2 h1:pxd4LgSnWODqRx1uQ79GgTjHMSRVnFO3YaKHWWSljF8= +github.com/gotd/td v0.55.2/go.mod h1:L3N+aEIojKkN7vjqnijFSMbwCSr+m5wpSyFZdxTCMA0= +github.com/gotd/td v0.56.0 h1:SlpVIxKbEhNzQ83lbkbBB0uS1QONCP+K1EE0YQOAHJU= +github.com/gotd/td v0.56.0/go.mod h1:wILjug50hgK8UkPwGcYRGQ6+7TYX5Uuf2yU873umgvM= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8= +github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.11.0 h1:HiHArx4yFbwl91X3qqIHtUFoiIfLNJXCQRsnzkiwwaQ= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.9.1 h1:MJc2s0MFS8C3ok1wQTdQxWuXQcB6+HwAm5x1CzW7mf0= +github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.10.0 h1:ILnBWrRMSXGczYvmkYD6PsYyVFUNLTnIUJHHDLmqk38= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8= +github.com/jackc/pgx/v4 v4.14.1 h1:71oo1KAGI6mXhLiTMn6iDFcp3e7+zon/capWjl2OEFU= +github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M= +github.com/jackc/pgx/v4 v4.15.0 h1:B7dTkXsdILD3MF987WGGCcg+tvLW6bZJdEcqVFeU//w= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds= +github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= +github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.20.0 h1:N4oPlghZwYG55MlU6LXk/Zp00FVNE9X9wrYO8CEs4lc= +go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8= +golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 h1:EN5+DfgmRMvRUrMGERW2gQl3Vc+Z7ZMnI/xdEpPSf0c= +golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 h1:QyVthZKMsyaQwBTJE04jdNN0Pp5Fn9Qga0mrgxyERQM= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee h1:0jS8G549Rie2L+BvXC+O+HPVyC+8gq3SpR/p2sJSfqg= +gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee/go.mod h1:1XHg/CpPZtstsm3WY57h1T4X/EQquwOgllQl/TjjgqI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To= +gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs= +gorm.io/driver/postgres v1.3.4 h1:evZ7plF+Bp+Lr1mO5NdPvd6M/N98XtwHixGB+y7fdEQ= +gorm.io/driver/postgres v1.3.4/go.mod h1:y0vEuInFKJtijuSGu9e5bs5hzzSzPK+LancpKpvbRBw= +gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU= +gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg= +gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= +rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= diff --git a/main.go b/main.go new file mode 100644 index 0000000..b2752f2 --- /dev/null +++ b/main.go @@ -0,0 +1,130 @@ +package main + +import ( + "context" + "github.com/go-redis/redis/v8" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "gopkg.in/tucnak/telebot.v3" + "gopkg.in/tucnak/telebot.v3/layout" + "gorm.io/driver/postgres" + "gorm.io/gorm" + "muskrat/bot" + "muskrat/bot/handlers" + "muskrat/storage" + "muskrat/types" + "muskrat/userbot" + "os" + "strconv" + "time" +) + +func main() { + // Log settings + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + pretty, err := strconv.ParseBool(os.Getenv("LOG_PRETTY")) + if err != nil { + pretty = false + } + if pretty { + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + } + switch os.Getenv("LOG_LEVEL") { + case "DISABLED": + zerolog.SetGlobalLevel(zerolog.Disabled) + case "PANIC": + zerolog.SetGlobalLevel(zerolog.PanicLevel) + case "FATAL": + zerolog.SetGlobalLevel(zerolog.FatalLevel) + case "ERROR": + zerolog.SetGlobalLevel(zerolog.ErrorLevel) + case "WARN": + zerolog.SetGlobalLevel(zerolog.WarnLevel) + case "DEBUG": + zerolog.SetGlobalLevel(zerolog.DebugLevel) + case "TRACE": + zerolog.SetGlobalLevel(zerolog.TraceLevel) + default: + zerolog.SetGlobalLevel(zerolog.InfoLevel) + } + + // Postgres + storage.DB, err = gorm.Open(postgres.Open(os.Getenv("POSTGRES_DSN")), &gorm.Config{}) + if err != nil { + log.Fatal().Err(err).Send() + } + // Connection pools + db, err := storage.DB.DB() + if err != nil { + log.Fatal().Err(err).Send() + } + db.SetMaxIdleConns(10) + db.SetMaxOpenConns(100) + db.SetConnMaxLifetime(time.Hour) + + err = storage.DB.AutoMigrate(&types.Account{}) + if err != nil { + log.Fatal().Err(err).Send() + } + + // Redis + redisURI, err := redis.ParseURL(os.Getenv("REDIS_URI")) + if err != nil { + log.Fatal().Str("module", "redis").Err(err).Send() + } + storage.Redis = redis.NewClient(redisURI) + defer storage.Redis.Close() + err = storage.Redis.Ping(context.TODO()).Err() + if err != nil { + log.Fatal().Str("module", "redis").Err(err).Send() + } + + // Userbots + accounts := make([]types.Account, 0) + storage.DB.Find(&accounts) + + userbot.Userbots = make(map[int64]*userbot.Userbot) + + for _, account := range accounts { + current := account + + userbot.Userbots[account.ID] = &userbot.Userbot{ + Account: ¤t, + } + + err = userbot.Userbots[account.ID].Start(context.Background()) + if err != nil { + storage.DB.Unscoped().Delete(¤t) + userbot.Userbots[account.ID].Stop() + delete(userbot.Userbots, account.ID) + } + } + + // Layout + bot.Layout, err = layout.New("assets/layout.yml") + if err != nil { + log.Fatal().Str("module", "bot").Err(err).Send() + } + + // Bot + bot.Bot, err = telebot.NewBot(bot.Layout.Settings()) + if err != nil { + log.Fatal().Str("module", "bot").Err(err).Send() + } + + // Middlewares + bot.Bot.Use(bot.Layout.Middleware("ru")) + + // Handlers + bot.Bot.Handle("/add", handlers.Add) + bot.Bot.Handle("/delete", handlers.Delete) + bot.Bot.Handle("/adel", handlers.AdminDelete) + bot.Bot.Handle("\frules_accept", handlers.Accept) + bot.Bot.Handle("\faccount", handlers.Account) + bot.Bot.Handle("\fedit", handlers.Edit) + bot.Bot.Handle("\fdelete", handlers.DeleteButton) + + bot.Bot.Handle(telebot.OnText, handlers.Router) + + bot.Bot.Start() +} diff --git a/storage/storage.go b/storage/storage.go new file mode 100644 index 0000000..08f8d84 --- /dev/null +++ b/storage/storage.go @@ -0,0 +1,35 @@ +package storage + +import ( + "context" + "github.com/go-redis/redis/v8" + "gorm.io/gorm" + "strconv" + "strings" +) + +var DB *gorm.DB +var Redis *redis.Client +var Registration map[int64][]byte + +func SetState(ctx context.Context, id int64, state string, metadata ...string) error { + for _, current := range metadata { + state += "|" + current + } + return Redis.Set(ctx, strconv.FormatInt(id, 10), state, 0).Err() +} + +func GetState(ctx context.Context, id int64) (string, []string, error) { + cursor := Redis.Get(ctx, strconv.FormatInt(id, 10)) + if cursor.Err() == redis.Nil { + return "", make([]string, 0), nil + } else if cursor.Err() != nil { + return "", nil, cursor.Err() + } + result := strings.Split(cursor.Val(), "|") + return result[0], result[1:], nil +} + +func ClearState(ctx context.Context, id int64) error { + return Redis.Del(ctx, strconv.FormatInt(id, 10)).Err() +} diff --git a/types/account.go b/types/account.go new file mode 100644 index 0000000..e7860e5 --- /dev/null +++ b/types/account.go @@ -0,0 +1,54 @@ +package types + +import ( + "gorm.io/gorm" +) + +type Account struct { + ID int64 `json:"id"` + User int64 `json:"user"` + Session []byte `json:"session"` + + Name string `json:"name"` + Corp string `json:"corp"` + Level int `json:"level"` + + Eat bool `json:"eat"` + Eat200 bool `json:"eat_200"` + EatCommand string `json:"eat_command" gorm:"default:/eat"` + EatChance int `json:"eat_chance" gorm:"default:100"` + + Levelup bool `json:"levelup"` + LevelupSkill bool `json:"levelup_skill"` + + Pin bool `json:"pin"` + PinChat int64 `json:"pin_chat"` + PinDelay float64 `json:"pin_delay" gorm:"default:5"` + PinChance int `json:"pin_chance" gorm:"default:100"` + + Report bool `json:"report"` + ReportChat int64 `json:"report_chat"` + ReportChatAccessHash int64 `json:"report_chat_access_hash"` + ReportDelay float64 `json:"report_delay" gorm:"default:5"` + ReportChance int `json:"report_chance" gorm:"default:100"` + + Mob bool `json:"mob"` + MobDelay float64 `json:"mob_delay" gorm:"default:10"` + MobChance int `json:"mob_chance" gorm:"default:30"` + + Sleep bool `json:"sleep"` + SleepHotel bool `json:"sleep_hotel" gorm:"default:true"` + + Stock bool `json:"stock"` + StockCorp string `json:"stock_corp"` + + Shark bool `json:"shark"` + SharkDelay float64 `json:"shark_delay" gorm:"default:1200"` + SharkTeam bool `json:"shark_team"` + + Motivation bool `json:"motivation" gorm:"default:true"` + MotivationKD bool `json:"motivation_kd"` + MotivationCommand string `json:"motivation_command" gorm:"default:/harvest"` + + gorm.Model +} diff --git a/userbot/bot.go b/userbot/bot.go new file mode 100644 index 0000000..03f57db --- /dev/null +++ b/userbot/bot.go @@ -0,0 +1,468 @@ +package userbot + +import ( + "context" + "fmt" + "github.com/go-co-op/gocron" + "github.com/gotd/td/session" + "github.com/gotd/td/telegram" + "github.com/gotd/td/telegram/message" + "github.com/gotd/td/tg" + "github.com/rs/zerolog/log" + "math/rand" + "muskrat/storage" + "muskrat/types" + "os" + "regexp" + "strconv" + "strings" + "time" +) + +type Userbot struct { + Account *types.Account + Client *telegram.Client + Sender *message.Sender + SW *message.RequestBuilder + Closed bool + Scheduler *gocron.Scheduler +} + +var Userbots map[int64]*Userbot + +func (b *Userbot) Start(ctx context.Context) error { + // Session + st := session.StorageMemory{} + err := st.StoreSession(ctx, b.Account.Session) + if err != nil { + return err + } + + // Dispatcher + dp := tg.NewUpdateDispatcher() + dp.OnNewChannelMessage(func(c context.Context, e tg.Entities, u *tg.UpdateNewChannelMessage) error { + m, ok := u.Message.(*tg.Message) + if !ok { + return nil + } + + from, ok := m.FromID.(*tg.PeerUser) + if !ok { + return nil + } + + peer, ok := m.PeerID.(*tg.PeerChannel) + if !ok { + return nil + } + + reportChatID := int64(0) + pinChatID := int64(0) + if len(strconv.FormatInt(b.Account.ReportChat, 10)) > 4 { + reportChatID, _ = strconv.ParseInt(strconv.FormatInt(b.Account.ReportChat, 10)[4:], 10, 64) + } + if len(strconv.FormatInt(b.Account.PinChat, 10)) > 4 { + pinChatID, _ = strconv.ParseInt(strconv.FormatInt(b.Account.PinChat, 10)[4:], 10, 64) + } + + if (peer.ChannelID == b.Account.PinChat || peer.ChannelID == pinChatID) && b.Account.Pin && rand.Intn(100) <= b.Account.PinChance { + if from.UserID == 376592453 { // Pin + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*b.Account.PinDelay) * time.Minute) + + r := regexp.MustCompile("(⚔В атаку на |🛡Все в защиту - )([^a-zA-Z]+)") + + if !r.MatchString(m.Message) { + return nil + } + + _, err = b.SW.Text(context.Background(), r.FindAllStringSubmatch(m.Message, -1)[0][2]) + if err != nil { + fmt.Println(err) + } + + markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup) + if !ok { + return nil + } + + callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback) + if !ok { + return nil + } + + _, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + Data: callback.Data, + }) + if err != nil { + fmt.Println(err, "pin") + } + + _, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{ + Channel: &tg.InputChannelFromMessage{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + ChannelID: peer.ChannelID, + }, + MaxID: m.ID, + }) + if err != nil { + fmt.Println(err) + } + } + + if from.UserID == 1714476897 || from.UserID == 1806724130 || from.UserID == 613165445 || from.UserID == 739073438 || from.UserID == 629902813 { + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*b.Account.PinDelay) * time.Minute) + + markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup) + if !ok { + return nil + } + + callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback) + if !ok { + return nil + } + + _, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + Data: callback.Data, + }) + if err != nil { + fmt.Println(err) + } + + _, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{ + Channel: &tg.InputChannelFromMessage{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + ChannelID: peer.ChannelID, + }, + MaxID: m.ID, + }) + if err != nil { + fmt.Println(err) + } + } + } + + if peer.ChannelID == 1109615116 { // Main Chat + if from.UserID == 376592453 { // Informator + if strings.HasPrefix(m.Message, "⚔️В любом мире есть противники. 🐮Быки и 🐻Медведи") { // Shark + if b.Account.Shark { + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*b.Account.SharkDelay+2) * time.Minute) + + markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup) + if !ok { + return nil + } + + button := 0 + if b.Account.SharkTeam { + button = 1 + } + + callback, ok := markup.Rows[0].Buttons[button].(*tg.KeyboardButtonCallback) + if !ok { + return nil + } + + _, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + Data: callback.Data, + }) + if err != nil { + fmt.Println(err) + } + + _, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{ + Channel: &tg.InputChannelFromMessage{ + Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash}, + MsgID: m.ID, + ChannelID: peer.ChannelID, + }, + MaxID: m.ID, + }) + if err != nil { + fmt.Println(err) + } + } + } + } + } + + if peer.ChannelID == b.Account.ReportChat || peer.ChannelID == reportChatID { // Update access hash + if b.Account.ReportChatAccessHash != e.Channels[peer.ChannelID].AccessHash { + b.Account.ReportChatAccessHash = e.Channels[peer.ChannelID].AccessHash + storage.DB.Save(b.Account) + } + } + + return nil + }) + + dp.OnNewMessage(func(c context.Context, e tg.Entities, u *tg.UpdateNewMessage) error { + m, ok := u.Message.(*tg.Message) + if !ok { + return nil + } + + peer, ok := m.PeerID.(*tg.PeerUser) + if !ok { + return nil + } + + if peer.UserID == 227859379 { // StartupWarsBot + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*5+2) * time.Second) + + if regexp.MustCompile("🎚(\\d+)").MatchString(m.Message) { // Update Profile + self, err := b.Client.Self(context.Background()) + if err != nil { + return err + } + + b.Account.Name = self.FirstName + " " + self.LastName + b.Account.Level, err = strconv.Atoi(regexp.MustCompile("🎚(\\d+)").FindAllStringSubmatch(m.Message, -1)[0][1]) + b.Account.Corp = regexp.MustCompile("\\((.)[^)]+\\)").FindAllStringSubmatch(m.Message, -1)[0][1] + + storage.DB.Save(b.Account) + } + + if _, ok = m.Media.(*tg.MessageMediaDocument); (ok || strings.HasPrefix(m.Message, "Ты достиг нового уровня.")) && b.Account.Levelup { // Levelup + _, err = b.SW.Text(context.Background(), "/levelup") + if err != nil { + return err + } + + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*5) * time.Second) + + if b.Account.LevelupSkill { + _, err = b.SW.Text(context.Background(), "+1 🔨Практика") + if err != nil { + return err + } + + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*5+5) * time.Second) + + _, err = b.SW.Text(context.Background(), "+1 🐿Хитрость") + if err != nil { + return err + } + } else { + _, err = b.SW.Text(context.Background(), "+1 🎓Теория") + if err != nil { + return err + } + + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*5+5) * time.Second) + + _, err = b.SW.Text(context.Background(), "+1 🐢Мудрость") + if err != nil { + return err + } + } + } + + if b.Account.Eat { // Eat + if regexp.MustCompile("🔋Выносливость на нуле").MatchString(m.Message) { + _, err = b.SW.Text(context.Background(), "/to_eat") + if err != nil { + return err + } + } + + if regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").MatchString(m.Message) && !strings.HasPrefix(m.Message, "🍴Меню") { + data := regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").FindAllStringSubmatch(m.Message, -1) + if len(data[0]) >= 2 { + stamina, err := strconv.Atoi(data[0][1]) + if err != nil { + return err + } + + if b.Account.Eat200 { + if stamina < 200 { + _, err = b.SW.Text(context.Background(), "/to_eat") + if err != nil { + return err + } + } + } else { + if stamina < 100 { + _, err = b.SW.Text(context.Background(), "/to_eat") + if err != nil { + return err + } + } + } + } + } + + if strings.HasPrefix(m.Message, "🍴Меню") { + data := regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").FindAllStringSubmatch(m.Message, -1) + if len(data[0]) >= 2 { + stamina, err := strconv.Atoi(data[0][1]) + if err != nil { + return err + } + + if b.Account.Eat200 { + if stamina < 200 { + _, err = b.SW.Text(context.Background(), b.Account.EatCommand) + if err != nil { + return err + } + } + } else { + if stamina < 100 { + _, err = b.SW.Text(context.Background(), b.Account.EatCommand) + if err != nil { + return err + } + } + } + } + } + } + + if strings.Contains(m.Message, "Твои результаты в битве") && b.Account.Report { // Forward Report + rand.Seed(time.Now().UnixNano()) + _, err = b.Client.API().MessagesForwardMessages(context.Background(), &tg.MessagesForwardMessagesRequest{ + FromPeer: &tg.InputPeerUser{UserID: 227859379}, + ID: []int{m.ID}, + ToPeer: &tg.InputPeerChannel{ChannelID: b.Account.ReportChat, AccessHash: b.Account.ReportChatAccessHash}, + RandomID: []int64{rand.Int63()}, + }) + if err != nil { + return err + } + } + + if strings.Contains(m.Message, "Опа, тебя начал грабить") && b.Account.Sleep { + markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup) + if !ok { + return nil + } + + callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback) + if !ok { + return nil + } + + _, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{ + Peer: &tg.InputPeerUser{UserID: peer.UserID, AccessHash: e.Users[peer.UserID].AccessHash}, + MsgID: m.ID, + Data: callback.Data, + }) + if err != nil { + return err + } + } + + if strings.Contains(m.Message, b.Account.MotivationCommand) && b.Account.MotivationCommand != "" && b.Account.MotivationKD && b.Account.Motivation { + builder := b.Sender.Resolve("@StartupWarsBot") + if builder != nil { + _, err := builder.Text(context.Background(), b.Account.MotivationCommand) + if err != nil { + log.Error().Err(err) + } + } + } + + // TODO: Sleep + // TODO: Mobs + } + + return nil + }) + + // Telegram Client + appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID")) + if err != nil { + return err + } + + b.Client = telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{ + SessionStorage: &st, + UpdateHandler: &dp, + }) + + go func() { + err = b.Client.Run(context.Background(), func(c context.Context) error { + if err != nil { + return err + } + + // Create Sender + b.Sender = message.NewSender(b.Client.API()) + b.SW = b.Sender.Resolve("@StartupWarsBot") + if b.SW == nil { + fmt.Println("no startupwars") + return err + } + + _, err = b.SW.Text(context.Background(), "/compact") + if err != nil { + return err + } + + // Scheduler + location, err := time.LoadLocation("Europe/Moscow") + if err != nil { + return err + } + + b.Scheduler = gocron.NewScheduler(location) + + _, err = b.Scheduler.Every(30).Minutes().Do(MotivationTask(b)) + if err != nil { + return err + } + _, err = b.Scheduler.Cron("45 9-21/3 * * *").Do(EatTask(b)) + if err != nil { + return err + } + _, err = b.Scheduler.Cron("15 10-22/3 * * *").Do(EatTask(b)) + if err != nil { + return err + } + _, err = b.Scheduler.Cron("1 10-22/3 * * *").Do(ReportTask(b)) + if err != nil { + return err + } + _, err = b.Scheduler.Cron("0 1 * * *").Do(ProfileTask(b)) + if err != nil { + return err + } + + b.Scheduler.StartAsync() + + for !b.Closed { + time.Sleep(time.Second) + } + return nil + }) + if err != nil { + fmt.Println(err) + } + }() + + return nil +} + +func (b *Userbot) Stop() error { + b.Closed = true + if b.Scheduler != nil { + b.Scheduler.Stop() + } + return nil +} diff --git a/userbot/eat.go b/userbot/eat.go new file mode 100644 index 0000000..6d467ec --- /dev/null +++ b/userbot/eat.go @@ -0,0 +1,22 @@ +package userbot + +import ( + "context" + "github.com/rs/zerolog/log" + "math/rand" + "time" +) + +func EatTask(b *Userbot) func() { + return func() { + rand.Seed(time.Now().UnixNano()) + + if b.Account.Eat && rand.Intn(100) <= b.Account.EatChance { + _, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/to_eat") + if err != nil { + log.Error().Err(err) + return + } + } + } +} diff --git a/userbot/motivation.go b/userbot/motivation.go new file mode 100644 index 0000000..c9e3489 --- /dev/null +++ b/userbot/motivation.go @@ -0,0 +1,26 @@ +package userbot + +import ( + "context" + "github.com/rs/zerolog/log" + "math/rand" + "time" +) + +func MotivationTask(b *Userbot) func() { + return func() { + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*20) * time.Minute) + + if b.Account.Motivation { + builder := b.Sender.Resolve("@StartupWarsBot") + if builder != nil { + _, err := builder.Text(context.Background(), b.Account.MotivationCommand) + if err != nil { + log.Error().Err(err) + return + } + } + } + } +} diff --git a/userbot/profile.go b/userbot/profile.go new file mode 100644 index 0000000..3c0f99c --- /dev/null +++ b/userbot/profile.go @@ -0,0 +1,22 @@ +package userbot + +import ( + "context" + "github.com/rs/zerolog/log" + "math/rand" + "time" +) + +func ProfileTask(b *Userbot) func() { + return func() { + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*40) * time.Minute) + + _, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/compact") + if err != nil { + log.Error().Err(err) + return + } + + } +} diff --git a/userbot/report.go b/userbot/report.go new file mode 100644 index 0000000..7fa7dba --- /dev/null +++ b/userbot/report.go @@ -0,0 +1,23 @@ +package userbot + +import ( + "context" + "github.com/rs/zerolog/log" + "math/rand" + "time" +) + +func ReportTask(b *Userbot) func() { + return func() { + rand.Seed(time.Now().UnixNano()) + time.Sleep(time.Duration(rand.Float64()*b.Account.ReportDelay) * time.Minute) + + if b.Account.Report && rand.Intn(100) <= b.Account.ReportChance { + _, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/battle") + if err != nil { + log.Error().Err(err) + return + } + } + } +} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..d16ce88 --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,21 @@ +package utils + +func BoolEmoji(a bool) string { + if a { + return "✅" + } + return "🚫" +} +func SharkEmoji(a bool) string { + if a { + return "🐮" + } + return "🐻" +} + +func BoolLevelup(a bool) string { + if a { + return "⚔" + } + return "🛡" +}