go_dreamfactory/modules/robot/robot.go
2023-08-25 12:04:26 +08:00

225 lines
6.4 KiB
Go

package robot
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/utils"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/nacos-group/nacos-sdk-go/util"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
)
type Robot struct {
Client
index int32 //编号
account, serverId string
curreq string //当前请求
await chan *MessageResp
modules map[core.M_Modules]IModuleRobot
pipeline []string //执行流水线
}
func (this *Robot) Account() string {
return this.account
}
func (this *Robot) ServerId() string {
return this.serverId
}
func (this *Robot) GetModule(module core.M_Modules) IModuleRobot {
return this.modules[module]
}
//初始化
func (this *Robot) Init(addr string, client IClient) (err error) {
this.Client.Init(addr, client)
this.await = make(chan *MessageResp)
this.modules = make(map[core.M_Modules]IModuleRobot)
this.modules[comm.ModuleUser] = new(ModuleRobot_User)
this.modules[comm.ModuleSys] = new(ModuleRobot_Sys)
this.modules[comm.ModuleHero] = new(ModuleRobot_Hero)
this.modules[comm.ModuleEquipment] = new(ModuleRobot_Equipment)
this.modules[comm.ModuleItems] = new(ModuleRobot_Item)
this.modules[comm.ModuleWtask] = new(ModuleRobot_WTask)
this.modules[comm.ModulePractice] = new(ModuleRobot_Practice)
this.modules[comm.ModuleMainline] = new(ModuleRobot_MainLine)
this.modules[comm.ModuleArena] = new(ModuleRobot_Arena)
this.modules[comm.ModulePagoda] = new(ModuleRobot_Pagoda)
for _, v := range this.modules {
v.Init()
}
go this.run()
return
}
//接收消息
func (this *Robot) Receive(msg *pb.UserMessage) (err error) {
var (
msgpath string
message proto.Message
module IModuleRobot
ok bool
)
msgpath = fmt.Sprintf("%s.%s", msg.MainType, msg.SubType)
if msgpath == "gateway.heartbeat" { //心跳 屏蔽掉
return
}
// log.Debug("[机器人 Resp]", log.Field{Key: "Account", Value: this.account}, log.Field{Key: "message", Value: msgpath})
//序列化用户消息对象
if message, err = msg.Data.UnmarshalNew(); err != nil {
log.Errorf("[Robot Receive] UserMessage:%s Unmarshal err:%v", msgpath, err)
return err
}
if msgpath == "notify.errornotify" { //错误通知
resp := message.(*pb.NotifyErrorNotifyPush)
reqpath := fmt.Sprintf("%s.%s", resp.ReqMainType, resp.ReqSubType)
if reqpath == this.curreq { //收到回应
this.await <- &MessageResp{
resp: nil,
errdata: resp.Err,
}
}
return
}
if module, ok = this.modules[core.M_Modules(msg.MainType)]; ok {
module.Receive(this, msg.SubType, message)
} else {
// log.Errorf("[Robot Receive] no register module:%s", msg.MainType)
return
}
if msgpath == this.curreq { //收到回应
this.await <- &MessageResp{
resp: message,
errdata: nil,
}
}
return
}
func (this *Robot) WriteMsg(msg *pb.UserMessage) (err error) {
msg.Sec = this.buildSecStr()
return this.Client.WriteMsg(msg)
}
//发送消息
func (this *Robot) SendMessage(mtype, stype string, msg proto.Message) (resp proto.Message, errdata *pb.ErrorData) {
var (
messageresp *MessageResp
err error
)
// stime := time.Now()
data, _ := anypb.New(msg)
message := &pb.UserMessage{
MainType: mtype,
SubType: stype,
Data: data,
}
if err = this.WriteMsg(message); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ClientError,
Title: pb.ErrorCode_ClientError.String(),
Message: err.Error(),
}
return
}
if mtype != "gateway" {
this.curreq = fmt.Sprintf("%s.%s", mtype, stype)
messageresp = <-this.await //等待回应
resp = messageresp.resp
errdata = messageresp.errdata
// log.Debug("[机器人 Message]", log.Field{Key: "t", Value: time.Since(stime).Milliseconds()}, log.Field{Key: "Account", Value: this.account}, log.Field{Key: "message", Value: fmt.Sprintf("%s.%s", mtype, stype)}, log.Field{Key: "resp", Value: errdata == nil})
}
return
}
//发送消息
func (this *Robot) SendTaskMessage(task, comdi int32, mtype, stype string, msg proto.Message) (resp proto.Message, errdata *pb.ErrorData) {
var (
messageresp *MessageResp
err error
)
stime := time.Now()
data, _ := anypb.New(msg)
message := &pb.UserMessage{
MainType: mtype,
SubType: stype,
Data: data,
}
if err = this.WriteMsg(message); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ClientError,
Title: pb.ErrorCode_ClientError.String(),
Message: err.Error(),
}
return
}
if mtype != "gateway" {
this.curreq = fmt.Sprintf("%s.%s", mtype, stype)
messageresp = <-this.await //等待回应
resp = messageresp.resp
errdata = messageresp.errdata
log.Debug("[机器人 Message]", log.Field{Key: "t", Value: time.Since(stime).Milliseconds()}, log.Field{Key: "Account", Value: this.account}, log.Field{Key: "Task", Value: fmt.Sprintf("[%d-%d]", task, comdi)}, log.Field{Key: "message", Value: fmt.Sprintf("%s.%s", mtype, stype)}, log.Field{Key: "errdata", Value: errdata == nil})
}
return
}
func (this *Robot) buildSecStr() string {
jsonByte, _ := jsoniter.Marshal(&SecBuild{
Account: this.account,
ServerId: this.serverId,
TimeStamp: time.Now().Unix(),
})
jsonBase64 := utils.Base64Encode(jsonByte)
// log.Printf("client base64:%s", jsonBase64)
clientMd5key := util.Md5(jsonBase64)
// log.Printf("client md5:%s", clientMd5key)
return fmt.Sprintf("CE:%s%s", clientMd5key, jsonBase64)
}
func (this *Robot) Heartbeat() {
this.SendMessage("gateway", "heartbeat", &pb.GatewayHeartbeatReq{})
}
func (this *Robot) OnClose() {
log.Debug("[机器人 End]", log.Field{Key: "Account", Value: this.account})
}
func (this *Robot) DoTask(taskconf *cfg.GameWorldTaskData, condconf *cfg.GameBuriedCondiData, moduleStr core.M_Modules) (err error) {
var (
ok bool
module IModuleRobot
)
if module, ok = this.modules[moduleStr]; ok {
err = module.DoTask(this, taskconf, condconf)
} else {
err = fmt.Errorf("no fund module:%s", moduleStr)
return
}
return
}
//运行
func (this *Robot) run() {
var (
module IModuleRobot
err error
)
for _, v := range this.pipeline {
module = this.modules[core.M_Modules(v)]
if err = module.DoPipeline(this); err != nil {
log.Debug("[机器人 执行异常]", log.Field{Key: "Account", Value: this.account}, log.Field{Key: "module", Value: v}, log.Field{Key: "err", Value: err.Error()})
break
}
}
this.Close()
}