This commit is contained in:
meixiongfeng 2023-08-23 17:23:16 +08:00
commit 322d0130c7
11 changed files with 846 additions and 90 deletions

View File

@ -103,6 +103,7 @@ const (
ModuleStoryLine core.M_Modules = "storyline" //剧情活动 ModuleStoryLine core.M_Modules = "storyline" //剧情活动
ModulePushgiftbag core.M_Modules = "pushgiftbag" //推送礼包 ModulePushgiftbag core.M_Modules = "pushgiftbag" //推送礼包
ModulePuzzle core.M_Modules = "uigame" //小游戏 ModulePuzzle core.M_Modules = "uigame" //小游戏
ModuleRobot core.M_Modules = "robot" //压测机器人
) )
// 数据表名定义处 // 数据表名定义处
@ -646,49 +647,50 @@ const (
// 随机任务类型 // 随机任务类型
const ( const (
Rtype1 TaskType = 1 //英雄指定 Rtype20001 TaskType = 20001 //对话埋点 前端主动完成
Rtype2 TaskType = 2 //主线之内触发了剧情Id Rtype1 TaskType = 1 //英雄指定
Rtype3 TaskType = 3 //每日任务 Rtype2 TaskType = 2 //主线之内触发了剧情Id
Rtype4 TaskType = 4 //指定英雄的等级限制 Rtype3 TaskType = 3 //每日任务
Rtype5 TaskType = 5 //指定英雄的装备数量 Rtype4 TaskType = 4 //指定英雄的等级限制
Rtype6 TaskType = 6 //指定英雄的星级 Rtype5 TaskType = 5 //指定英雄的装备数量
Rtype7 TaskType = 7 //日常登录一次 Rtype6 TaskType = 6 //指定英雄的星级
Rtype8 TaskType = 8 //累计登陆xx天 Rtype7 TaskType = 7 //日常登录一次
Rtype9 TaskType = 9 //连续登陆xx天 Rtype8 TaskType = 8 //累计登陆xx天
Rtype10 TaskType = 10 //拥有xx个好友 Rtype9 TaskType = 9 //连续登陆xx天
Rtype11 TaskType = 11 //赠送X次友情点 Rtype10 TaskType = 10 //拥有xx个好友
Rtype12 TaskType = 12 //使用好友助战英雄xx次 Rtype11 TaskType = 11 //赠送X次友情点
Rtype13 TaskType = 13 //更换X次助战英雄 Rtype12 TaskType = 12 //使用好友助战英雄xx次
Rtype14 TaskType = 14 //累计xx次普通招募 Rtype13 TaskType = 13 //更换X次助战英雄
Rtype15 TaskType = 15 //累计xx次阵营招募 Rtype14 TaskType = 14 //累计xx次普通招募
Rtype16 TaskType = 16 //招募获得xx品质英雄xx个 Rtype15 TaskType = 15 //累计xx次阵营招募
Rtype17 TaskType = 17 //普通招募十连获得xx个以上xx星英雄 Rtype16 TaskType = 16 //招募获得xx品质英雄xx个
Rtype18 TaskType = 18 //xx次普通招募 Rtype17 TaskType = 17 //普通招募十连获得xx个以上xx星英雄
Rtype19 TaskType = 19 //xx次阵营招募 Rtype18 TaskType = 18 //xx次普通招募
Rtype20 TaskType = 20 //用户等级达到xx级 Rtype19 TaskType = 19 //xx次阵营招募
Rtype21 TaskType = 21 //英雄合成xx次 Rtype20 TaskType = 20 //用户等级达到xx级
Rtype22 TaskType = 22 //合成xx英雄 Rtype21 TaskType = 21 //英雄合成xx次
Rtype23 TaskType = 23 //拥有xx个xx星级的xx等级英雄 Rtype22 TaskType = 22 //合成xx英雄
Rtype24 TaskType = 24 //为任意英雄提升xx次等级 Rtype23 TaskType = 23 //拥有xx个xx星级的xx等级英雄
Rtype25 TaskType = 25 //xx名xx英雄升至xx星 Rtype24 TaskType = 24 //为任意英雄提升xx次等级
Rtype26 TaskType = 26 //xx名英雄从三星升四星 Rtype25 TaskType = 25 //xx名xx英雄升至xx星
Rtype27 TaskType = 27 //xx名英雄从四星升五星 Rtype26 TaskType = 26 //xx名英雄从三星升四星
Rtype28 TaskType = 28 //xx名英雄从五星升六星 Rtype27 TaskType = 27 //xx名英雄从四星升五星
Rtype29 TaskType = 29 //拥有xx个xx级及以上的【xx】英雄 Rtype28 TaskType = 28 //xx名英雄从五星升六星
Rtype30 TaskType = 30 //获得xx个品质为xx的英雄 Rtype29 TaskType = 29 //拥有xx个xx级及以上的【xx】英雄
Rtype31 TaskType = 31 //获得xx个品质为xx以上的英雄 Rtype30 TaskType = 30 //获得xx个品质为xx的英雄
Rtype32 TaskType = 32 //xx个品质为xx的英雄升到xx级 Rtype31 TaskType = 31 //获得xx个品质为xx以上的英雄
Rtype33 TaskType = 33 //xx个品质为xx以及以上英雄升到xx级 Rtype32 TaskType = 32 //xx个品质为xx的英雄升到xx级
Rtype34 TaskType = 34 //xx个英雄觉醒达到xx阶段 Rtype33 TaskType = 33 //xx个品质为xx以及以上英雄升到xx级
Rtype35 TaskType = 35 //xx英雄觉醒达到xx阶段 Rtype34 TaskType = 34 //xx个英雄觉醒达到xx阶段
Rtype36 TaskType = 36 //xx位xx品质xx职业英雄xx阵营觉醒达到xx阶段检查满级满共鸣满觉醒的英雄数量每有一个进度+1 Rtype35 TaskType = 35 //xx英雄觉醒达到xx阶段
Rtype37 TaskType = 37 //xx名xx品质英雄 Rtype36 TaskType = 36 //xx位xx品质xx职业英雄xx阵营觉醒达到xx阶段检查满级满共鸣满觉醒的英雄数量每有一个进度+1
Rtype38 TaskType = 38 //xx英雄满级 Rtype37 TaskType = 37 //xx名xx品质英雄
Rtype39 TaskType = 39 //累计英雄共鸣xx次 Rtype38 TaskType = 38 //xx英雄满级
Rtype40 TaskType = 40 //将xx个英雄共鸣xx次 Rtype39 TaskType = 39 //累计英雄共鸣xx次
Rtype41 TaskType = 41 //任意一名英雄穿戴xx件xx星级的装备 Rtype40 TaskType = 40 //将xx个英雄共鸣xx次
Rtype42 TaskType = 42 //任意一名英雄穿戴xx件xx等级的装备 Rtype41 TaskType = 41 //任意一名英雄穿戴xx件xx星级的装备
Rtype43 TaskType = 43 //将xx件装备强化至xx级 Rtype42 TaskType = 42 //任意一名英雄穿戴xx件xx等级的装备
Rtype43 TaskType = 43 //将xx件装备强化至xx级
// Rtype44 TaskType = 44 //任意装备强化到xx级 合并到43 // Rtype44 TaskType = 44 //任意装备强化到xx级 合并到43
Rtype45 TaskType = 45 //将xx件xx星【xx】套装装备强化至xx级 Rtype45 TaskType = 45 //将xx件xx星【xx】套装装备强化至xx级
Rtype46 TaskType = 46 //为xx名英雄穿戴完整xx星【xx】套装装备 Rtype46 TaskType = 46 //为xx名英雄穿戴完整xx星【xx】套装装备

View File

@ -1,22 +1,42 @@
package robot package robot
import ( import (
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
) )
type Client struct { type Client struct {
sessionId string client IClient
uId string wsConn *websocket.Conn
wsConn *websocket.Conn writeChan chan []byte
state int32 //状态 0 关闭 1 运行 2 关闭中 state int32 //状态 0 关闭 1 运行 2 关闭中
closeSignal chan bool closeSignal chan bool
wg sync.WaitGroup wg sync.WaitGroup
account, sid string
}
func (this *Client) Init(addr string, client IClient) (err error) {
var (
comm *websocket.Conn
)
if comm, _, err = websocket.DefaultDialer.Dial(addr, nil); err != nil {
return
}
this.client = client
this.state = 1
this.writeChan = make(chan []byte, 2)
this.closeSignal = make(chan bool)
this.wsConn = comm
this.wg.Add(2)
go this.readLoop()
go this.writeLoop()
return
} }
func (this *Client) readLoop() { func (this *Client) readLoop() {
@ -29,24 +49,56 @@ func (this *Client) readLoop() {
locp: locp:
for { for {
if _, data, err = this.wsConn.ReadMessage(); err != nil { if _, data, err = this.wsConn.ReadMessage(); err != nil {
log.Errorf("agent:%s uId:%s ReadMessage err:%v", this.sessionId, this.uId, err) go this.client.Close()
go this.Close()
break locp break locp
} }
if err = proto.Unmarshal(data, msg); err != nil { if err = proto.Unmarshal(data, msg); err != nil {
log.Errorf("agent:%s uId:%s Unmarshal err:%v", this.sessionId, this.uId, err) go this.client.Close()
go this.Close()
break locp break locp
} else { } else {
// this.gateway.Debugf("----------2 agent:%s uId:%s MainType:%s SubType:%s ", this.sessionId, this.uId, msg.MainType, msg.SubType) // this.gateway.Debugf("----------2 agent:%s uId:%s MainType:%s SubType:%s ", this.sessionId, this.uId, msg.MainType, msg.SubType)
if err = this.messageDistribution(msg); err != nil { this.client.Receive(msg)
break locp
}
} }
} }
log.Debugf("agent:%s uId:%s readLoop end!", this.sessionId, this.uId) }
func (this *Client) writeLoop() {
defer this.wg.Done()
var (
err error
timer *time.Ticker
)
timer = time.NewTicker(time.Second * 30)
locp:
for {
select {
case <-this.closeSignal:
break locp
case msg, ok := <-this.writeChan:
if ok {
if err = this.wsConn.WriteMessage(websocket.BinaryMessage, msg); err != nil {
go this.client.Close()
}
} else {
go this.client.Close()
}
case <-timer.C:
this.client.Heartbeat()
}
}
}
func (this *Client) WriteMsg(msg *pb.UserMessage) (err error) {
if atomic.LoadInt32(&this.state) != 1 {
return
}
var (
data []byte
)
if data, err = proto.Marshal(msg); err == nil {
this.writeChan <- data
}
return
} }
// 外部代用关闭 // 外部代用关闭
@ -58,10 +110,26 @@ func (this *Client) Close() {
this.closeSignal <- true this.closeSignal <- true
this.wg.Wait() this.wg.Wait()
atomic.StoreInt32(&this.state, 0) atomic.StoreInt32(&this.state, 0)
this.client.OnClose()
} }
// 分发用户消息 // 分发用户消息
func (this *Client) messageDistribution(msg *pb.UserMessage) (err error) { func (this *Client) Receive(msg *pb.UserMessage) (err error) {
return return
} }
func (this *Client) SendMessage(mtype, stype string, msg proto.Message) (err error) {
data, _ := anypb.New(msg)
message := &pb.UserMessage{
MainType: mtype,
SubType: stype,
Data: data,
}
err = this.WriteMsg(message)
return
}
func (this *Client) Heartbeat() {
}

View File

@ -0,0 +1,75 @@
package robot
import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
)
const (
gameWorldTask = "game_worldtask.json"
gameWorldtaskBattle = "game_worldbattle.json"
game_buriedcondi = "game_buriedcondi.json"
// gameWorldAll = "game_worldall.json"
// gameburiedCond = "game_buriedcondi.json"
// gamerdtasknpc = "game_rdtasknpc.json"
// gamesearchitemall = "game_searchitemall.json"
// gamesearchitembox = "game_searchitembox.json"
// game_worlddeal = "game_worlddeal.json"
// game_worldrd = "game_worldrd.json"
)
type configureComp struct {
cbase.ModuleCompBase
module *RobotModule
}
func (this *configureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
err = this.ModuleCompBase.Init(service, module, comp, options)
this.module = module.(*RobotModule)
configure.RegisterConfigure(gameWorldTask, cfg.NewGameWorldTask, nil)
configure.RegisterConfigure(gameWorldtaskBattle, cfg.NewGameWorldBattle, nil)
configure.RegisterConfigure(game_buriedcondi, cfg.NewGameBuriedCondi, nil)
return
}
//获取任务配置
func (this *configureComp) getGameWorldTaskData(tid int32) (conf *cfg.GameWorldTaskData, err error) {
var (
v interface{}
ok bool
)
if v, err = configure.GetConfigure(gameWorldTask); err != nil {
return
} else {
if conf, ok = v.(*cfg.GameWorldTask).GetDataMap()[tid]; !ok {
err = comm.NewNotFoundConfErr(string(this.module.GetType()), gameWorldTask, tid)
log.Errorf("err:%v", err)
return
}
}
return
}
//获取战斗配置
func (this *configureComp) getGameWorldBattleData(confId int32) (conf *cfg.GameWorldBattleData, err error) {
var (
v interface{}
ok bool
)
if v, err = configure.GetConfigure(gameWorldtaskBattle); err != nil {
return
} else {
if conf, ok = v.(*cfg.GameWorldBattle).GetDataMap()[confId]; !ok {
err = comm.NewNotFoundConfErr(string(this.module.GetType()), gameWorldtaskBattle, confId)
log.Errorf("err:%v", err)
return
}
}
return
}

48
modules/robot/core.go Normal file
View File

@ -0,0 +1,48 @@
package robot
import (
"go_dreamfactory/lego/core"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"google.golang.org/protobuf/proto"
)
//客户端端
type IClient interface {
Init(addr string, client IClient) (err error)
Heartbeat()
Receive(msg *pb.UserMessage) (err error)
WriteMsg(msg *pb.UserMessage) (err error)
SendMessage(mtype, stype string, msg proto.Message) (err error)
Close()
OnClose()
}
//机器人
type IRobot interface {
IClient
Account() string
ServerId() string
SetData(key string, data interface{})
GetData(key string) interface{}
DoTask(taskconf *cfg.GameWorldTaskData, condconf *cfg.GameBuriedCondiData, module core.M_Modules) (err error)
}
//机器人模块
type IModuleRobot interface {
//接收到回应和推送消息
Receive(robot IRobot, stype string, message proto.Message) (err error)
//错误码接收
ErrReceive(robot IRobot, stype string, code pb.ErrorCode) (err error)
//执行流水线任务
DoPipeline(robot IRobot) (err error)
//执行任务
DoTask(robot IRobot, taskconf *cfg.GameWorldTaskData, condconf *cfg.GameBuriedCondiData) (err error)
}
type SecBuild struct {
Account string `json:"account"`
ServerId string `json:"serverId"`
TimeStamp int64 `json:"timestamp"`
}

View File

@ -4,7 +4,7 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/lego/base" "go_dreamfactory/lego/base"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/lego/core/cbase"
) )
/* /*
@ -13,34 +13,43 @@ import (
开发:李伟 开发:李伟
*/ */
func NewModule() core.IModule { func NewModule() core.IModule {
m := new(Reddot) m := new(RobotModule)
return m return m
} }
type Reddot struct { type RobotModule struct {
modules.ModuleBase cbase.ModuleBase
service base.IRPCXService options *Options
service base.IRPCXService
robotmgr *robotmgrComp
configure *configureComp
} }
// 模块名 // 模块名
func (this *Reddot) GetType() core.M_Modules { func (this *RobotModule) GetType() core.M_Modules {
return comm.ModuleReddot return comm.ModuleRobot
}
// 重构模块配置对象
func (this *RobotModule) NewOptions() (options core.IModuleOptions) {
return new(Options)
} }
// 模块初始化接口 注册用户创建角色事件 // 模块初始化接口 注册用户创建角色事件
func (this *Reddot) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) { func (this *RobotModule) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
err = this.ModuleBase.Init(service, module, options) err = this.ModuleBase.Init(service, module, options)
this.options = options.(*Options)
this.service = service.(base.IRPCXService) this.service = service.(base.IRPCXService)
return return
} }
func (this *Reddot) Start() (err error) { func (this *RobotModule) Start() (err error) {
err = this.ModuleBase.Start() err = this.ModuleBase.Start()
return return
} }
// 装备组件 // 装备组件
func (this *Reddot) OnInstallComp() { func (this *RobotModule) OnInstallComp() {
this.ModuleBase.OnInstallComp() this.ModuleBase.OnInstallComp()
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
this.robotmgr = this.RegisterComp(new(robotmgrComp)).(*robotmgrComp)
} }

View File

@ -0,0 +1,66 @@
package robot
import (
"fmt"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"google.golang.org/protobuf/proto"
)
//用户模块 机器人
type ModuleRobot_User struct {
}
//接收到消息
func (this *ModuleRobot_User) Receive(robot IRobot, stype string, message proto.Message) (err error) {
switch stype {
case "login":
resp := message.(*pb.UserLoginResp)
robot.SetData("user", resp.Data)
robot.SetData("userex", resp.Ex)
break
case "create":
// resp := message.(*pb.UserCreateResp)
break
}
return
}
//接收到消息
func (this *ModuleRobot_User) ErrReceive(robot IRobot, stype string, code pb.ErrorCode) (err error) {
switch stype {
case "login":
err = fmt.Errorf("登录错误:%d", code)
break
case "create":
break
}
return
}
//机器人执行流
func (this *ModuleRobot_User) DoPipeline(robot IRobot) (err error) {
//登录
if err = robot.SendMessage("user", "login", &pb.UserLoginReq{
Account: robot.Account(),
Sid: robot.ServerId(),
}); err != nil {
return
}
//创角
if err = robot.SendMessage("user", "create", &pb.UserCreateReq{
NickName: robot.Account(),
Figure: 100,
Gender: 1,
}); err != nil {
return
}
return
}
//做任务
func (this *ModuleRobot_User) DoTask(robot IRobot, taskconf *cfg.GameWorldTaskData, condconf *cfg.GameBuriedCondiData) (err error) {
return
}

View File

@ -0,0 +1,238 @@
package robot
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
"google.golang.org/protobuf/proto"
)
//用户模块 机器人
type ModuleRobot_WTask struct {
info *pb.DBWTask
progress []*pb.DBWTaskItem //任务进度
}
//接收到消息
func (this *ModuleRobot_WTask) Receive(robot IRobot, stype string, message proto.Message) (err error) {
switch stype {
case "info":
resp := message.(*pb.WTaskInfoResp)
this.info = resp.Info
this.progress = resp.Accepts
break
case "accept":
resp := message.(*pb.WTaskAcceptResp)
this.progress = resp.Accepts
if this.info != nil {
this.info.Activations = resp.Activations
this.info.Accepts = make([]int32, 0)
for _, v := range this.progress {
this.info.Accepts = append(this.info.Accepts, v.Tid)
}
}
break
case "completecondi":
resp := message.(*pb.WTaskCompleteCondiResp)
for i, v := range this.progress {
if v.Tid == resp.TaskId {
this.progress[i] = resp.Progress
break
}
}
break
case "finish":
resp := message.(*pb.WTaskFinishResp)
for i, v := range this.info.Accepts {
if v == resp.Tid {
this.info.Accepts = append(this.info.Accepts[0:i], this.info.Accepts[i+1:]...)
}
}
break
case "activationschange":
resp := message.(*pb.WTaskActivationsChangePush)
if this.info != nil {
this.info.Activations = resp.Activations
}
break
case "acceptchange":
resp := message.(*pb.WTaskAcceptChangePush)
this.progress = resp.Accepts
if this.info != nil {
this.info.Accepts = make([]int32, 0)
for _, v := range this.progress {
this.info.Accepts = append(this.info.Accepts, v.Tid)
}
}
break
}
return
}
//接收到消息
func (this *ModuleRobot_WTask) ErrReceive(robot IRobot, stype string, code pb.ErrorCode) (err error) {
switch stype {
case "info":
err = fmt.Errorf("信息获取:%d", code)
break
}
return
}
//机器人执行流
func (this *ModuleRobot_WTask) DoPipeline(robot IRobot) (err error) {
//获取任务列表
if err = robot.SendMessage("wtask", "info", &pb.WTaskInfoReq{}); err != nil {
return
}
var (
tconf *cfg.GameWorldTaskData
cconf *cfg.GameBuriedCondiData
module core.M_Modules
)
locp:
for {
//寻找可做任务
tconf = this.findtask()
if tconf == nil {
break locp
}
if this.checkaccept(tconf) { //是否需要接收任务
if err = robot.SendMessage("wtask", "accept", &pb.WTaskAcceptReq{Tid: tconf.Key}); err != nil {
return
}
continue
}
//找到能做的任务
cconf, err = this.findconlds(tconf)
if err != nil {
break locp
}
//有问完成的子任务
if cconf != nil {
switch comm.TaskType(cconf.Type) {
case comm.Rtype1:
module = comm.ModuleHero
case comm.Rtype20001:
module = comm.ModuleWtask
default:
log.Error("[Robot DoTask]", log.Field{Key: "ctype", Value: cconf.Type}, log.Field{Key: "conld", Value: cconf.Id}, log.Field{Key: "err", Value: "Not Achieved !"})
break locp
}
if err = robot.DoTask(tconf, cconf, module); err != nil {
log.Error("[Robot DoTask]", log.Field{Key: "task", Value: tconf.Key}, log.Field{Key: "conld", Value: cconf.Id}, log.Field{Key: "err", Value: err.Error()})
break locp
}
continue
} else { //任务已完成直接完成
if err = robot.SendMessage("wtask", "finish", &pb.WTaskFinishReq{Tid: tconf.Key}); err != nil {
return
}
}
}
return
}
//做任务
func (this *ModuleRobot_WTask) DoTask(robot IRobot, taskconf *cfg.GameWorldTaskData, condconf *cfg.GameBuriedCondiData) (err error) {
switch comm.TaskType(condconf.Type) {
case comm.Rtype20001:
if err = robot.SendMessage("wtask", "completecondi", &pb.WTaskCompleteCondiReq{TaskId: taskconf.Key, CondiId: condconf.Id}); err != nil {
return
}
break
}
return
}
func (this *ModuleRobot_WTask) findtask() (conf *cfg.GameWorldTaskData) {
var (
confs []*cfg.GameWorldTaskData
err error
)
for _, v := range this.info.Accepts {
if conf, err = this.getGameWorldTaskData(v); err != nil {
log.Error("[Robot 世界任务配置未找到]", log.Field{Key: "task", Value: v}, log.Field{Key: "err", Value: err.Error()})
}
if conf.Des == 2 { //优先找到主线任务
return
}
confs = append(confs, conf)
}
for _, v := range this.info.Activations { //可接取任务列表
if conf, err = this.getGameWorldTaskData(v); err != nil {
log.Error("[Robot 世界任务配置未找到]", log.Field{Key: "task", Value: v}, log.Field{Key: "err", Value: err.Error()})
}
if conf.Des == 2 { //优先找到主线任务
return
}
}
return
}
func (this *ModuleRobot_WTask) findconlds(conf *cfg.GameWorldTaskData) (cconf *cfg.GameBuriedCondiData, err error) {
for _, tp := range this.progress {
if tp.Tid == conf.Key {
for _, v := range tp.Conlds {
if v.State == pb.BuriedItemFinishState_buried_unfinish { //未完成
if cconf, err = this.getburiedcondidata(v.Conid); err != nil {
log.Error("[Robot 埋点任务配置未找到]", log.Field{Key: "conld", Value: v.Conid}, log.Field{Key: "err", Value: err.Error()})
return
}
return
}
}
}
}
return
}
func (this *ModuleRobot_WTask) checkaccept(conf *cfg.GameWorldTaskData) bool {
for _, v := range this.info.Accepts {
if v == conf.Key {
return false
}
}
return true
}
//获取任务配置
func (this *ModuleRobot_WTask) getGameWorldTaskData(tid int32) (conf *cfg.GameWorldTaskData, err error) {
var (
v interface{}
ok bool
)
if v, err = configure.GetConfigure(gameWorldTask); err != nil {
return
} else {
if conf, ok = v.(*cfg.GameWorldTask).GetDataMap()[tid]; !ok {
err = comm.NewNotFoundConfErr("robot", gameWorldTask, tid)
return
}
}
return
}
// 读取条件任务id配置
func (this *ModuleRobot_WTask) getburiedcondidata(cid int32) (conf *cfg.GameBuriedCondiData, err error) {
var (
v interface{}
ok bool
)
if v, err = configure.GetConfigure(game_buriedcondi); err != nil {
return
} else {
if conf, ok = v.(*cfg.GameBuriedCondi).GetDataMap()[cid]; !ok {
err = comm.NewNotFoundConfErr("robot", game_buriedcondi, cid)
return
}
}
return
}

27
modules/robot/options.go Normal file
View File

@ -0,0 +1,27 @@
package robot
import (
"go_dreamfactory/lego/utils/mapstructure"
"go_dreamfactory/modules"
)
type (
Options struct {
modules.Options
ServerAddr string //服务地址
RobotTotalNum int32 //机器人总数
RobotSingleNum int32 //单词机器人进入数量
Intervals int32 //间隔时间 单位秒
Pipeline []string //执行流水线
}
)
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
if settings != nil {
if err = this.Options.LoadConfig(settings); err != nil {
return
}
err = mapstructure.Decode(settings, this)
}
return
}

169
modules/robot/robot.go Normal file
View File

@ -0,0 +1,169 @@
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()
}

View File

@ -0,0 +1,70 @@
package robot
import (
"fmt"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/log"
"time"
)
/*
客户端管理组件
*/
type robotmgrComp struct {
cbase.ModuleCompBase
service core.IService
module *RobotModule
currRobotNum int32
}
//组件初始化接口
func (this *robotmgrComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.ModuleCompBase.Init(service, module, comp, options)
this.module = module.(*RobotModule)
this.service = service
return
}
func (this *robotmgrComp) Start() (err error) {
err = this.ModuleCompBase.Start()
go this.run()
return
}
func (this *robotmgrComp) run() {
timer := time.NewTicker(time.Second)
defer timer.Stop()
locp:
for {
select {
case <-timer.C:
if this.currRobotNum <= this.module.options.RobotSingleNum {
for i := 0; i < int(this.module.options.RobotSingleNum); i++ {
this.createRobot(this.currRobotNum)
this.currRobotNum++
}
} else {
break locp
}
}
}
}
func (this *robotmgrComp) createRobot(index int32) {
var (
robot *Robot
err error
)
robot = &Robot{
index: index,
account: fmt.Sprintf("test%d", index),
serverId: "df01",
pipeline: this.module.options.Pipeline,
}
if err = robot.Init(this.module.options.ServerAddr, robot); err != nil {
log.Errorln(err)
return
}
return
}

View File

@ -2,15 +2,12 @@ package main
import ( import (
"flag" "flag"
"fmt" "go_dreamfactory/modules/robot"
"go_dreamfactory/services" "go_dreamfactory/services"
"go_dreamfactory/sys/db"
"go_dreamfactory/lego" "go_dreamfactory/lego"
"go_dreamfactory/lego/base/rpcx" "go_dreamfactory/lego/base/rpcx"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/cron"
"go_dreamfactory/lego/sys/log"
) )
/* /*
@ -31,7 +28,7 @@ func main() {
s.OnInstallComp( //装备组件 s.OnInstallComp( //装备组件
//services.NewGateRouteComp(), //此服务需要接受用户的消息 需要装备网关组件 //services.NewGateRouteComp(), //此服务需要接受用户的消息 需要装备网关组件
) )
lego.Run(s) //运行模块 lego.Run(s, robot.NewModule()) //运行模块
} }
@ -49,17 +46,4 @@ type Service struct {
// 初始化worker需要的一些系统工具 // 初始化worker需要的一些系统工具
func (this *Service) InitSys() { func (this *Service) InitSys() {
this.ServiceBase.InitSys() this.ServiceBase.InitSys()
//定时系统
if err := cron.OnInit(nil); err != nil {
panic(fmt.Sprintf("init sys.cron err: %s", err.Error()))
} else {
log.Infof("init sys.cron success!")
}
//存储系统
if err := db.OnInit(this.GetSettings().Sys["db"]); err != nil {
panic(fmt.Sprintf("init sys.db err: %s", err.Error()))
} else {
log.Infof("init sys.db success!")
}
} }