mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-08 11:12:29 +08:00
154 lines
3.9 KiB
Go
154 lines
3.9 KiB
Go
package game
|
|
|
|
import (
|
|
"hk4e/gs/model"
|
|
"hk4e/logger"
|
|
"hk4e/protocol/proto"
|
|
"strings"
|
|
)
|
|
|
|
type CommandFunc func(string, []string)
|
|
|
|
type Command struct {
|
|
Name string // 命令前缀
|
|
Args []string // 命令参数
|
|
}
|
|
|
|
type CommandManager struct {
|
|
system *model.Player // 机器人 目前负责收发命令 以及 大世界
|
|
commandFuncRouter map[string]CommandFunc // 记录命令处理函数
|
|
commandTextInput chan string // 传输要处理的命令文本
|
|
|
|
gameManager *GameManager
|
|
}
|
|
|
|
// NewCommandManager 新建命令管理器
|
|
func NewCommandManager(g *GameManager) *CommandManager {
|
|
r := new(CommandManager)
|
|
|
|
// 创建一个公共的开放世界的AI
|
|
g.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0)
|
|
r.system = g.userManager.GetOnlineUser(1)
|
|
// 开放大世界
|
|
r.system.SceneLoadState = model.SceneEnterDone
|
|
r.system.DbState = model.DbNormal
|
|
g.worldManager.InitBigWorld(r.system)
|
|
|
|
// 初始化
|
|
r.commandTextInput = make(chan string, 1000)
|
|
r.InitRouter() // 初始化路由
|
|
|
|
// 处理传入的命令
|
|
go r.HandleCommand()
|
|
|
|
r.gameManager = g
|
|
return r
|
|
}
|
|
|
|
// InitRouter 初始化命令路由
|
|
func (c *CommandManager) InitRouter() {
|
|
c.commandFuncRouter = make(map[string]CommandFunc)
|
|
c.RegisterRouter("awa", c.FuncAwA)
|
|
}
|
|
|
|
// RegisterRouter 注册命令路由
|
|
func (c *CommandManager) RegisterRouter(cmdName string, cmdFunc CommandFunc) {
|
|
c.commandFuncRouter[cmdName] = cmdFunc
|
|
}
|
|
|
|
func (c *CommandManager) FuncAwA(cmd string, args []string) {
|
|
logger.LOG.Info("awa命令执行啦, name: %v, args: %v", cmd, args)
|
|
}
|
|
|
|
// InputCommand 输入要处理的命令
|
|
func (c *CommandManager) InputCommand(text string) {
|
|
// 机器人不会读命令所以写到了 PrivateChatReq
|
|
|
|
// 输入的命令将在其他协程中处理
|
|
c.commandTextInput <- text
|
|
}
|
|
|
|
// GetFriendList 获取包含系统的玩家好友列表
|
|
func (c *CommandManager) GetFriendList(friendList map[uint32]bool) map[uint32]bool {
|
|
// 可能还有更好的方法实现这功能
|
|
// 但我想不出来awa
|
|
|
|
// 临时好友列表
|
|
tempFriendList := make(map[uint32]bool, len(friendList))
|
|
// 复制玩家的好友列表
|
|
for userId, b := range friendList {
|
|
tempFriendList[userId] = b
|
|
}
|
|
// 添加系统
|
|
tempFriendList[c.system.PlayerID] = true
|
|
|
|
return tempFriendList
|
|
}
|
|
|
|
// HandleCommand 处理命令
|
|
func (c *CommandManager) HandleCommand() {
|
|
// 处理传入 commandTextInput 的所有命令文本
|
|
// 为了避免主协程阻塞搞了个channel
|
|
|
|
for {
|
|
// 取出要处理的命令文本
|
|
text := <-c.commandTextInput
|
|
|
|
// 读取并创建命令
|
|
cmd := c.NewCommand(text)
|
|
if cmd == nil {
|
|
logger.LOG.Error("handle command is nil, text: %v", text)
|
|
continue
|
|
}
|
|
|
|
// 执行命令
|
|
c.ExecCommand(cmd)
|
|
}
|
|
}
|
|
|
|
// NewCommand 创建命令结构
|
|
func (c *CommandManager) NewCommand(text string) *Command {
|
|
// 命令必须以 / 为开头
|
|
if !strings.HasPrefix(text, "/") {
|
|
return nil
|
|
}
|
|
// 将开头的 / 去掉
|
|
text = text[1:]
|
|
|
|
// 分割出命令的每个参数
|
|
cmdSplit := strings.Split(text, " ")
|
|
|
|
// 分割出来啥也没有可能是个空的字符串
|
|
// 处理个寂寞直接return
|
|
if len(cmdSplit) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// 首个参数必是命令名
|
|
cmdName := cmdSplit[0]
|
|
// 命令名后当然是命令的参数喽
|
|
cmdArgs := cmdSplit[1:]
|
|
|
|
return &Command{cmdName, cmdArgs}
|
|
}
|
|
|
|
// ExecCommand 执行命令
|
|
func (c *CommandManager) ExecCommand(cmd *Command) {
|
|
// 理论上执行前已经校验过不会出现nil 但以免万一
|
|
if cmd == nil {
|
|
logger.LOG.Error("exec command is nil")
|
|
return
|
|
}
|
|
|
|
// 判断命令名是否注册
|
|
cmdFunc, ok := c.commandFuncRouter[cmd.Name]
|
|
if !ok {
|
|
logger.LOG.Error("exec command not exist, name: %v", cmd.Name)
|
|
return
|
|
}
|
|
|
|
logger.LOG.Debug("command start, name: %v args: %v", cmd.Name, cmd.Args)
|
|
cmdFunc(cmd.Name, cmd.Args) // 执行命令
|
|
logger.LOG.Debug("command done, name: %v args: %v", cmd.Name, cmd.Args)
|
|
}
|