You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

468 lines
13 KiB

package userbot
import (
"context"
"fmt"
"gitea.russia9.dev/russia9/muskrat/storage"
"gitea.russia9.dev/russia9/muskrat/types"
"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"
"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
}