From 2a9cb41ec6a2ab4bb8058ba54e7d5e78365967d9 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 20 Jan 2022 17:45:34 +0000 Subject: [PATCH] discord impl (#1) Reviewed-on: https://git.jojodev.com/Minecraft/afk/pulls/1 Co-authored-by: jolheiser Co-committed-by: jolheiser --- client.go | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 7 +++ main.go | 76 ++-------------------------- 4 files changed, 161 insertions(+), 72 deletions(-) create mode 100644 client.go diff --git a/client.go b/client.go new file mode 100644 index 0000000..9a4bbb0 --- /dev/null +++ b/client.go @@ -0,0 +1,149 @@ +package main + +import ( + "bufio" + "errors" + "github.com/Tnze/go-mc/bot" + "github.com/Tnze/go-mc/bot/basic" + "github.com/Tnze/go-mc/chat" + "github.com/Tnze/go-mc/data/packetid" + "github.com/Tnze/go-mc/net/packet" + "github.com/Tnze/go-mc/yggdrasil" + "github.com/bwmarrin/discordgo" + "github.com/google/uuid" + "github.com/rs/zerolog/log" + "io" + "os" + "strings" + "time" +) + +type Client struct { + discord *discordgo.Session + channelID string + + minecraft *bot.Client + serverIP string +} + +func NewClient(email, password, serverIP, discordToken string) (*Client, error) { + c := &Client{ + serverIP: serverIP, + } + if err := c.setupMinecraft(email, password); err != nil { + return nil, err + } + if discordToken != "" { + if err := c.setupDiscord(discordToken); err != nil { + return nil, err + } + } + return c, nil +} + +func (c *Client) Run() { + go c.onChatSend() + c.handleGame() +} + +func (c *Client) handleGame() { + for { + err := c.minecraft.JoinServer(c.serverIP) + if err != nil { + log.Err(err).Msg("") + <-time.After(time.Minute * 5) + return + } + log.Info().Msg("Login success") + + for { + err := c.minecraft.HandleGame() + if err != nil { + log.Err(err).Msg("") + if errors.Is(err, io.EOF) { + <-time.After(time.Minute * 5) + break + } + } + } + } +} + +func (c *Client) sendChat(msg string) { + if err := c.minecraft.Conn.WritePacket(packet.Marshal( + packetid.ServerboundChat, + packet.String(msg), + )); err != nil { + log.Err(err).Msg("") + } +} + +func (c *Client) onChatMsg(msg chat.Message, _ byte, _ uuid.UUID) error { + if c.discord != nil { + _, err := c.discord.ChannelMessageSend(c.channelID, msg.ClearString()) + return err + } + log.Info().Msg(msg.String()) + return nil +} + +func (c *Client) setupDiscord(token string) error { + var err error + c.discord, err = discordgo.New("Bot " + token) + if err != nil { + return err + } + info, err := c.discord.Application("@me") + if err != nil { + return err + } + ch, err := c.discord.UserChannelCreate(info.Owner.ID) + if err != nil { + return err + } + c.channelID = ch.ID + + c.discord.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) { + if m.Author.Bot || m.ChannelID != c.channelID { + return + } + c.sendChat(m.Content) + }) + + return c.discord.Open() +} + +func (c *Client) setupMinecraft(email, password string) error { + c.minecraft = bot.NewClient() + basic.NewPlayer(c.minecraft, basic.DefaultSettings) + + auth, err := yggdrasil.Authenticate(email, password) + if err != nil { + return err + } + + c.minecraft.Auth.UUID, c.minecraft.Auth.Name = auth.SelectedProfile() + c.minecraft.Auth.AsTk = auth.AccessToken() + + basic.EventsListener{ + GameStart: func() error { + <-time.After(time.Second * 5) + c.sendChat("/afk") + return nil + }, + ChatMsg: c.onChatMsg, + }.Attach(c.minecraft) + + return nil +} + +func (c *Client) onChatSend() { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + msg := scanner.Text() + if strings.TrimSpace(msg) == "" { + continue + } + c.sendChat(msg) + } +} diff --git a/go.mod b/go.mod index e427bb1..6c1d214 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/Tnze/go-mc v1.17.2-0.20220104152428-c724909cd711 + github.com/bwmarrin/discordgo v0.23.2 // indirect github.com/google/uuid v1.3.0 github.com/pelletier/go-toml v1.9.4 // indirect github.com/peterbourgon/ff/v3 v3.1.2 diff --git a/go.sum b/go.sum index 95b9e32..dde8e9e 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Tnze/go-mc v1.17.2-0.20220104152428-c724909cd711 h1:xPIWCcvFbKNGiexDlaQgfbeZKIst53JqyLr0yOehruE= github.com/Tnze/go-mc v1.17.2-0.20220104152428-c724909cd711/go.mod h1:t0AI38F1BEmmy8/uLhr9RCOUeDbBj3oUNQH9akjzMc0= +github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4= +github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/iancoleman/strcase v0.1.3/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -20,8 +24,10 @@ github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 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/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -36,6 +42,7 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= diff --git a/main.go b/main.go index 559cdfe..6847ce2 100644 --- a/main.go +++ b/main.go @@ -1,24 +1,13 @@ package main import ( - "bufio" "flag" - "os" - "os/signal" - "strings" - - "github.com/Tnze/go-mc/bot" - "github.com/Tnze/go-mc/bot/basic" - "github.com/Tnze/go-mc/chat" _ "github.com/Tnze/go-mc/data/lang/en-us" - "github.com/Tnze/go-mc/data/packetid" - "github.com/Tnze/go-mc/net/packet" - "github.com/Tnze/go-mc/yggdrasil" - "github.com/google/uuid" "github.com/peterbourgon/ff/v3" "github.com/peterbourgon/ff/v3/fftoml" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "os" ) func main() { @@ -29,6 +18,7 @@ func main() { emailFlag := fs.String("email", "", "Login Email") passwordFlag := fs.String("password", "", "Login Password") ipFlag := fs.String("ip", "", "Server IP") + discordFlag := fs.String("discord", "", "Discord bot token") debugFlag := fs.Bool("debug", false, "Debug Logging") if err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarPrefix("AFK"), @@ -43,68 +33,10 @@ func main() { zerolog.SetGlobalLevel(zerolog.DebugLevel) } - client := bot.NewClient() - basic.NewPlayer(client, basic.DefaultSettings) - - auth, err := yggdrasil.Authenticate(*emailFlag, *passwordFlag) + client, err := NewClient(*emailFlag, *passwordFlag, *ipFlag, *discordFlag) if err != nil { log.Fatal().Err(err).Msg("") } - client.Auth.UUID, client.Auth.Name = auth.SelectedProfile() - client.Auth.AsTk = auth.AccessToken() - - err = client.JoinServer(*ipFlag) - if err != nil { - log.Fatal().Err(err).Msg("") - } - log.Info().Msg("Login success") - - basic.EventsListener{ - GameStart: func() error { - sendChat(client, "/afk") - return nil - }, - ChatMsg: onChatMsg, - }.Attach(client) - - go onChatSend(client) - - go func() { - for { - err := client.HandleGame() - if err != nil { - log.Err(err).Msg("") - } - } - }() - - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt, os.Kill) - <-ch -} - -func onChatMsg(c chat.Message, _ byte, _ uuid.UUID) error { - log.Info().Msg(c.String()) - return nil -} - -func onChatSend(c *bot.Client) { - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - msg := scanner.Text() - if strings.TrimSpace(msg) == "" { - continue - } - sendChat(c, msg) - } -} - -func sendChat(c *bot.Client, msg string) { - if err := c.Conn.WritePacket(packet.Marshal( - packetid.ServerboundChat, - packet.String(msg), - )); err != nil { - log.Err(err).Msg("") - } + client.Run() }