feat: support kick
This commit is contained in:
		
							
								
								
									
										16
									
								
								services/mc/defs.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								services/mc/defs.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
package mc
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ErrNotJoined = "not joined"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	EventPlayerJoined = "multiplayer.player.joined"
 | 
			
		||||
	EventPlayerLeft   = "multiplayer.player.left"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	StatusPending = iota
 | 
			
		||||
	StatusNormal
 | 
			
		||||
	StatusBanned
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										89
									
								
								services/mc/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								services/mc/helper.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
package mc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"tg-mc/conf"
 | 
			
		||||
	"tg-mc/models"
 | 
			
		||||
	su "tg-mc/services/utils"
 | 
			
		||||
	"tg-mc/utils"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Tnze/go-mc/chat"
 | 
			
		||||
	"github.com/Tnze/go-mc/data/packetid"
 | 
			
		||||
	"github.com/Tnze/go-mc/net/packet"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetJoinedPlayer(m chat.Message) (userName string, err error) {
 | 
			
		||||
	if m.Translate != "multiplayer.player.joined" && len(m.With) == 0 {
 | 
			
		||||
		return "", errors.New(ErrNotJoined)
 | 
			
		||||
	}
 | 
			
		||||
	userName = m.With[0].Text
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetLeftPlayer(m chat.Message) (userName string, err error) {
 | 
			
		||||
	if m.Translate != "multiplayer.player.left" && len(m.With) == 0 {
 | 
			
		||||
		return "", errors.New(ErrNotJoined)
 | 
			
		||||
	}
 | 
			
		||||
	userName = m.With[0].Text
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func HandleJoinGame(userName string) {
 | 
			
		||||
 | 
			
		||||
	u, err := models.GetUserByMCName(userName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Error("get user name error: ", err)
 | 
			
		||||
	}
 | 
			
		||||
	time.Sleep(3 * time.Second)
 | 
			
		||||
 | 
			
		||||
	switch u.Status {
 | 
			
		||||
	case StatusNormal:
 | 
			
		||||
		SendMsgToPlayer("欢迎回来!", userName)
 | 
			
		||||
	case StatusPending:
 | 
			
		||||
		SendMsgToPlayer("你还没有绑定 Telegram 哦, 5秒后你将会被踢出。请在群组中发送 /bind <你的 MC 用户名> 进行绑定。", userName)
 | 
			
		||||
		time.Sleep(5 * time.Second)
 | 
			
		||||
		kickPlayer(userName)
 | 
			
		||||
	case StatusBanned:
 | 
			
		||||
		SendMsgToPlayer("你已被封禁,如有疑问请联系管理员。", userName)
 | 
			
		||||
	default:
 | 
			
		||||
		SendMsgToPlayer("未知错误,请联系管理员,你将被踢出", userName)
 | 
			
		||||
		time.Sleep(3 * time.Second)
 | 
			
		||||
		kickPlayer(userName)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sendCommand(cmd string) error {
 | 
			
		||||
	var salt int64
 | 
			
		||||
	if err := binary.Read(rand.Reader, binary.BigEndian, &salt); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := conf.Client.Conn.WritePacket(packet.Marshal(
 | 
			
		||||
		packetid.ServerboundChatCommand,
 | 
			
		||||
		packet.String(cmd),
 | 
			
		||||
		packet.Long(time.Now().UnixMilli()),
 | 
			
		||||
		packet.Long(salt),
 | 
			
		||||
		packet.VarInt(0), // signature
 | 
			
		||||
		packet.VarInt(0),
 | 
			
		||||
		packet.NewFixedBitSet(20),
 | 
			
		||||
	))
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func kickPlayer(userName string) error {
 | 
			
		||||
	err := sendCommand("kick " + userName)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CronKick() {
 | 
			
		||||
	utils.CronStart(func() {
 | 
			
		||||
		users := su.GetAlivePlayerList()
 | 
			
		||||
		for _, u := range users {
 | 
			
		||||
			kickPlayer(u)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -13,7 +13,6 @@ import (
 | 
			
		||||
	"github.com/Tnze/go-mc/bot/playerlist"
 | 
			
		||||
	"github.com/Tnze/go-mc/bot/screen"
 | 
			
		||||
	"github.com/Tnze/go-mc/chat"
 | 
			
		||||
	"github.com/Tnze/go-mc/data/item"
 | 
			
		||||
	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
@@ -36,9 +35,8 @@ func Run() error {
 | 
			
		||||
		DisguisedChat:     onDisguisedMsg,
 | 
			
		||||
	})
 | 
			
		||||
	conf.ScreenManager = screen.NewManager(client, screen.EventsListener{
 | 
			
		||||
		Open:    nil,
 | 
			
		||||
		SetSlot: onScreenSlotChange,
 | 
			
		||||
		Close:   nil,
 | 
			
		||||
		Open:  nil,
 | 
			
		||||
		Close: nil,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	err := client.JoinServer(
 | 
			
		||||
@@ -54,16 +52,38 @@ func Run() error {
 | 
			
		||||
	return client.HandleGame()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SendMsg(msg string) error {
 | 
			
		||||
	if err := conf.ChatHandler.SendMessage(msg); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
func SendMsg(msg string) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		err := conf.ChatHandler.SendMessage(msg)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Error("send msg error: ", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SendMsgToPlayer(msg string, playerName string) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		err := sendCommand(fmt.Sprintf("tell %s %s", playerName, msg))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logrus.Error("send msg to player error: ", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func onSystemMsg(msg chat.Message, overlay bool) error {
 | 
			
		||||
	go func() {
 | 
			
		||||
		log.Printf("System: %v", msg)
 | 
			
		||||
		log.Printf("System: %v", msg.String())
 | 
			
		||||
		switch msg.Translate {
 | 
			
		||||
		case EventPlayerJoined:
 | 
			
		||||
			userName, err := GetJoinedPlayer(msg)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logrus.Error("user join error ", err)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			go HandleJoinGame(userName)
 | 
			
		||||
		default:
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		m := tgbotapi.NewMessage(conf.GetBotSettings().GroupID, fmt.Sprintf("%v", msg))
 | 
			
		||||
		conf.Bot.Send(m)
 | 
			
		||||
	}()
 | 
			
		||||
@@ -110,30 +130,14 @@ func onDeath() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func onGameStart() error {
 | 
			
		||||
	log.Println("Game start")
 | 
			
		||||
	go func() {
 | 
			
		||||
		log.Println("Game start")
 | 
			
		||||
		// SendMsgToPlayer("Hello", "test")
 | 
			
		||||
		go CronKick()
 | 
			
		||||
	}()
 | 
			
		||||
	return nil // if err isn't nil, HandleGame() will return it.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func onScreenSlotChange(id, index int) error {
 | 
			
		||||
	if id == -2 {
 | 
			
		||||
		log.Printf("Slot: inventory: %v", conf.ScreenManager.Inventory.Slots[index])
 | 
			
		||||
	} else if id == -1 && index == -1 {
 | 
			
		||||
		log.Printf("Slot: cursor: %v", conf.ScreenManager.Cursor)
 | 
			
		||||
	} else {
 | 
			
		||||
		container, ok := conf.ScreenManager.Screens[id]
 | 
			
		||||
		if ok {
 | 
			
		||||
			// Currently, only inventory container is supported
 | 
			
		||||
			switch container.(type) {
 | 
			
		||||
			case *screen.Inventory:
 | 
			
		||||
				slot := container.(*screen.Inventory).Slots[index]
 | 
			
		||||
				itemInfo := item.ByID[item.ID(slot.ID)]
 | 
			
		||||
				log.Printf("Slot: Screen[%d].Slot[%d]: [%v] * %d | NBT: %v", id, index, itemInfo, slot.Count, slot.NBT)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func onHealthChange(health float32, foodLevel int32, foodSaturation float32) error {
 | 
			
		||||
	log.Printf("Health: %.2f, FoodLevel: %d, FoodSaturation: %.2f", health, foodLevel, foodSaturation)
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user