Discord implementation and client abstraction

Signed-off-by: jolheiser <john.olheiser@gmail.com>
pull/1/head
jolheiser 2022-01-20 11:42:15 -06:00
parent ef6f3a9afc
commit 63da75ada0
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
2 changed files with 127 additions and 85 deletions

129
client.go
View File

@ -1,30 +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
channel string
discord *discordgo.Session
channelID string
minecraft *bot.Client
serverIP string
}
func (c *Client) Run() error {
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.channel, msg.Text)
_, 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)
}
}

83
main.go
View File

@ -1,23 +1,13 @@
package main
import (
"bufio"
"flag"
"github.com/bwmarrin/discordgo"
"os"
"os/signal"
"strings"
"github.com/Tnze/go-mc/bot"
"github.com/Tnze/go-mc/bot/basic"
_ "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/peterbourgon/ff/v3"
"github.com/peterbourgon/ff/v3/fftoml"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"os"
)
func main() {
@ -43,77 +33,10 @@ func main() {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
minecraft := bot.NewClient()
basic.NewPlayer(minecraft, basic.DefaultSettings)
auth, err := yggdrasil.Authenticate(*emailFlag, *passwordFlag)
client, err := NewClient(*emailFlag, *passwordFlag, *ipFlag, *discordFlag)
if err != nil {
log.Fatal().Err(err).Msg("")
}
minecraft.Auth.UUID, minecraft.Auth.Name = auth.SelectedProfile()
minecraft.Auth.AsTk = auth.AccessToken()
var discord *discordgo.Session
if *discordFlag != "" {
discord, err = discordgo.New("Bot " + *discordFlag)
if err != nil {
log.Fatal().Err(err).Msg("")
}
// TODO discord.Application("@me")
}
client := &Client{
minecraft: minecraft,
discord: discord,
}
basic.EventsListener{
GameStart: func() error {
sendChat(minecraft, "/afk")
return nil
},
ChatMsg: client.onChatMsg,
}.Attach(minecraft)
err = minecraft.JoinServer(*ipFlag)
if err != nil {
log.Fatal().Err(err).Msg("")
}
log.Info().Msg("Login success")
go onChatSend(minecraft)
go func() {
for {
err := minecraft.HandleGame()
if err != nil {
log.Err(err).Msg("")
}
}
}()
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt, os.Kill)
<-ch
}
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()
}