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 string modules map[core.M_Modules]IModuleRobot datas map[string]interface{} pipeline []string //执行流水线 } func (this *Robot) Account() string { return this.account } func (this *Robot) ServerId() string { return this.serverId } func (this *Robot) SetData(key string, data interface{}) { this.datas[key] = data } func (this *Robot) GetData(key string) interface{} { return this.datas[key] } //初始化 func (this *Robot) Init(addr string, client IClient) (err error) { this.Client.Init(addr, client) this.datas = make(map[string]interface{}) this.await = make(chan string) this.modules = make(map[core.M_Modules]IModuleRobot) this.modules[comm.ModuleUser] = new(ModuleRobot_User) this.modules[comm.ModuleWtask] = new(ModuleRobot_WTask) 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" { //错误通知 req := message.(*pb.NotifyErrorNotifyPush) reqpath := fmt.Sprintf("%s.%s", req.ReqMainType, req.ReqSubType) if module, ok = this.modules[core.M_Modules(req.ReqMainType)]; ok { if err = module.ErrReceive(this, req.ReqSubType, req.Code); err != nil { log.Error("[Robot NotifyErrorNotifyPush]", log.Field{Key: "Account", Value: this.account}, log.Field{Key: "message", Value: reqpath}, log.Field{Key: "err", Value: err.Error()}) return } } if reqpath == this.curreq { //收到回应 this.await <- msgpath } 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 <- msgpath } 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) (err error) { stime := time.Now() data, _ := anypb.New(msg) message := &pb.UserMessage{ MainType: mtype, SubType: stype, Data: data, } err = this.WriteMsg(message) if mtype != "gateway" { this.curreq = fmt.Sprintf("%s.%s", mtype, stype) <-this.await //等待回应 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)}) } 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 ) for _, v := range this.pipeline { module = this.modules[core.M_Modules(v)] module.DoPipeline(this) } this.Close() }