go_dreamfactory/modules/rtask/module.go
2023-03-10 16:50:09 +08:00

588 lines
18 KiB
Go

// package 随机任务
// 随机任务
// 赵长远
package rtask
import (
"context"
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/base"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db"
"go_dreamfactory/utils"
"github.com/pkg/errors"
)
var _ comm.IRtask = (*ModuleRtask)(nil)
// 限定条件
type rtaskCondi struct {
condId int32 //任务条件配置ID
verify verifyHandle //校验任务条件
find condiFindHandle //检索任务条件
update updateDataHandle //更新任务数据
}
type verifyHandle func(uid string, cfg *cfg.GameRdtaskCondiData) (bool, error)
type condiFindHandle func(cfg *cfg.GameRdtaskCondiData, vals ...int32) (int32, error)
type updateDataHandle func(uid string, cfg *cfg.GameRdtaskCondiData, vals ...int32) error
type ModuleRtask struct {
modules.ModuleBase
service base.IRPCXService
modelRtask *ModelRtask
modelRtaskRecord *ModelRtaskRecord
api *apiComp
configure *configureComp
handleMap map[int32]*rtaskCondi //任务校验处理器
}
func NewModule() core.IModule {
return &ModuleRtask{
handleMap: make(map[int32]*rtaskCondi),
}
}
func (this *ModuleRtask) GetType() core.M_Modules {
return comm.ModuleRtask
}
func (this *ModuleRtask) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
err = this.ModuleBase.Init(service, module, options)
this.service = service.(base.IRPCXService)
this.initRtaskVerifyHandle()
return
}
func (this *ModuleRtask) Start() (err error) {
err = this.ModuleBase.Start()
this.service.RegisterFunctionName(string(comm.Rpc_ModuleRtaskSendTask), this.Rpc_ModuleRtaskSendTask)
return
}
func (this *ModuleRtask) OnInstallComp() {
this.ModuleBase.OnInstallComp()
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
this.modelRtask = this.RegisterComp(new(ModelRtask)).(*ModelRtask)
this.modelRtaskRecord = this.RegisterComp(new(ModelRtaskRecord)).(*ModelRtaskRecord)
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
}
func (this *ModuleRtask) registerVerifyHandle(condiId int32, condi *rtaskCondi) {
if _, ok := this.handleMap[condiId]; !ok {
this.handleMap[condiId] = condi
}
}
// 条件校验初始
func (this *ModuleRtask) initRtaskVerifyHandle() {
conf, err := this.configure.getRtaskCondiCfg()
if err != nil {
return
}
for _, v := range conf.GetDataList() {
if typeCfg, err := this.configure.getRtaskTypeById(v.Id); err == nil {
if typeCfg != nil {
switch comm.TaskType(typeCfg.Type) {
case comm.Rtype1:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verfiyRtype1,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype2:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype2,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype3:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype3,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype4:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype4,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype5:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype5,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype6:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype6,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype8:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verfiyRtype8,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype9:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verfiyRtype9,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype10:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verfiyRtype10,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype11, comm.Rtype84, comm.Rtype85:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.lessEqualFirstParam,
verify: this.modelRtaskRecord.verifyFirstGreatEqualParam,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype18:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.greatEqualFirstParam,
verify: this.modelRtaskRecord.verifyFirstGreatEqualParam,
update: this.modelRtaskRecord.addUpdate,
})
case comm.Rtype7, comm.Rtype12, comm.Rtype13, comm.Rtype14, comm.Rtype15,
comm.Rtype19, comm.Rtype21, comm.Rtype24,
comm.Rtype26, comm.Rtype27, comm.Rtype28, comm.Rtype38,
comm.Rtype39, comm.Rtype50, comm.Rtype51, comm.Rtype53,
comm.Rtype54, comm.Rtype57, comm.Rtype58, comm.Rtype60,
comm.Rtype62, comm.Rtype64, comm.Rtype69, comm.Rtype72, comm.Rtype88, comm.Rtype104,
comm.Rtype96, comm.Rtype105, comm.Rtype128, comm.Rtype130, comm.Rtype131,
comm.Rtype141, comm.Rtype142, comm.Rtype143, comm.Rtype144, comm.Rtype145, comm.Rtype146,
comm.Rtype147, comm.Rtype149, comm.Rtype153, comm.Rtype154, comm.Rtype155, comm.Rtype156:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.lessEqualFirstParam,
verify: this.modelRtaskRecord.verifyFirstGreatEqualParam,
update: this.modelRtaskRecord.addUpdate,
})
case comm.Rtype20:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype20,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype22, comm.Rtype109:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtaskRecord.verifyFirstEqualParam,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype63:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalFirstParam,
verify: this.modelRtask.verifyRtype63,
update: this.modelRtaskRecord.addUpdate,
})
case comm.Rtype16, comm.Rtype17,
comm.Rtype35, comm.Rtype44,
comm.Rtype59, comm.Rtype61, comm.Rtype70:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.equalParams,
verify: this.modelRtaskRecord.verifyFromDb,
update: this.modelRtaskRecord.overrideUpdate,
})
case comm.Rtype23, comm.Rtype25, comm.Rtype29, comm.Rtype30, comm.Rtype31,
comm.Rtype32, comm.Rtype33, comm.Rtype34, comm.Rtype36,
comm.Rtype37, comm.Rtype40, comm.Rtype41,
comm.Rtype42, comm.Rtype43, comm.Rtype45,
comm.Rtype46, comm.Rtype47, comm.Rtype48, comm.Rtype49,
comm.Rtype52, comm.Rtype55, comm.Rtype56,
comm.Rtype65, comm.Rtype66, comm.Rtype67, comm.Rtype68, comm.Rtype140:
this.registerVerifyHandle(v.Id, &rtaskCondi{
find: this.modelRtaskRecord.lessThanParams,
verify: this.modelRtaskRecord.verifyFromDb,
update: this.modelRtaskRecord.addUpdate,
})
default:
log.Warnf("rtaskType[%v] not register", typeCfg.Type)
}
}
}
}
}
// 处理触发的任务
func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType comm.TaskType, params ...int32) (code pb.ErrorCode) {
uid := session.GetUserId()
var condis []*rtaskCondi
if this.IsCross() {
//随机任务
if _, err := this.service.AcrossClusterRpcGo(
context.Background(),
session.GetServiecTag(),
comm.Service_Worker,
string(comm.Rpc_ModuleRtaskSendTask),
pb.RPCRTaskReq{Uid: uid, TaskType: int32(rtaskType), Param: params},
nil); err != nil {
this.Errorln(err)
}
return
}
for _, codiConf := range this.configure.getRtaskCondis(int32(rtaskType)) {
v, ok := this.handleMap[codiConf.Id]
if !ok {
this.Warn("未注册事件处理器",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condiId", Value: codiConf.Id},
)
code = pb.ErrorCode_RtaskCondiNoFound
return
}
if v.find == nil {
this.Warn("未设置find Handle",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condiId", Value: codiConf.Id},
)
return
}
if condiId, _ := v.find(codiConf, params...); condiId != 0 {
v.condId = codiConf.Id
condis = append(condis, v)
}
}
// update
for _, v := range condis {
conf, err := this.configure.getRtaskTypeById(v.condId)
if err != nil {
log.Errorf("get condId conf err:%v", err)
code = pb.ErrorCode_RtaskCondiNoFound
return
}
if v.update != nil {
if err := v.update(uid, conf, params...); err != nil {
log.Errorf("update task:%v", err)
code = pb.ErrorCode_DBError
}
}
//任务完成则推送
if code := this.CheckCondi(uid, conf.Id); code == pb.ErrorCode_Success {
module, err := this.service.GetModule(comm.ModuleWorldtask)
if err == nil {
go func() {
defer func() {
if r := recover(); r != nil {
log.Errorf("[worldtask ] err:%v ", r)
}
}()
if worldtask, ok := module.(comm.IWorldtask); ok {
if err := worldtask.TaskcondNotify(session, conf.Id); err != nil {
log.Error("任务条件达成通知",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condId", Value: conf.Id},
log.Field{Key: "err", Value: err.Error()},
)
}
}
}()
}
userModule, err := this.service.GetModule(comm.ModuleUser)
if err == nil {
go func() {
defer func() { //程序异常 收集异常信息传递给前端显示
if r := recover(); r != nil {
log.Errorf("[sociatytask ] err:%v ", r)
}
}()
// 公会
if user, ok := userModule.(comm.IUser); ok {
ex, err := user.GetUserExpand(uid)
if err == nil && ex.SociatyId != "" {
sociatyModule, err := this.service.GetModule(comm.ModuleSociaty)
if err != nil {
return
}
if sociaty, ok := sociatyModule.(comm.ISociaty); ok {
if err2 := sociaty.TaskcondNotify(uid, ex.SociatyId, conf.Id); err2 != nil {
log.Error("公会任务条件达成通知",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "sociatyId", Value: ex.SociatyId},
log.Field{Key: "condId", Value: conf.Id},
log.Field{Key: "err", Value: err2.Error()},
)
}
this.processOneTask(session, comm.Rtype156, 1)
// if module, err := this.service.GetModule(comm.ModuleRtask); err == nil {
// if iRtask, ok := module.(comm.IRtask); ok {
// iRtask.SendToRtask(session, comm.Rtype156, 1)
// }
// }
}
}
}
}()
}
}
}
return
}
// Deprecated
func (this *ModuleRtask) SendToRtask(session comm.IUserSession, rtaskType comm.TaskType, params ...int32) (code pb.ErrorCode) {
uid := session.GetUserId()
if this.IsCross() {
//随机任务
if _, err := this.service.AcrossClusterRpcGo(
context.Background(),
session.GetServiecTag(),
comm.Service_Worker,
string(comm.Rpc_ModuleRtaskSendTask),
pb.RPCRTaskReq{Uid: uid, TaskType: int32(rtaskType), Param: params},
nil); err != nil {
this.Errorln(err)
}
return
}
// this.Debug("任务事件触发",
// log.Field{Key: "uid", Value: uid},
// log.Field{Key: "taskType", Value: rtaskType},
// log.Field{Key: "params", Value: params},
// )
var (
condis []*rtaskCondi
)
for _, codiConf := range this.configure.getRtaskCondis(int32(rtaskType)) {
v, ok := this.handleMap[codiConf.Id]
if !ok {
this.Warn("未注册事件处理器",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condiId", Value: codiConf.Id},
)
code = pb.ErrorCode_RtaskCondiNoFound
return
}
if v.find == nil {
this.Warn("未设置find Handle",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condiId", Value: codiConf.Id},
)
return
}
if condiId, _ := v.find(codiConf, params...); condiId != 0 {
v.condId = codiConf.Id
condis = append(condis, v)
}
}
// update
for _, v := range condis {
conf, err := this.configure.getRtaskTypeById(v.condId)
if err != nil {
log.Errorf("get condId conf err:%v", err)
code = pb.ErrorCode_RtaskCondiNoFound
return
}
if v.update != nil {
if err := v.update(uid, conf, params...); err != nil {
log.Errorf("update task:%v", err)
code = pb.ErrorCode_DBError
}
}
//任务完成则推送
if code := this.CheckCondi(uid, conf.Id); code == pb.ErrorCode_Success {
module, err := this.service.GetModule(comm.ModuleWorldtask)
if err == nil {
go func() {
defer func() {
if r := recover(); r != nil {
log.Errorf("[worldtask ] err:%v ", r)
}
}()
// 世界任务
if worldtask, ok := module.(comm.IWorldtask); ok {
if err := worldtask.TaskcondNotify(session, conf.Id); err != nil {
var customErr = new(comm.CustomError)
if errors.As(err, &customErr) {
notifyErr := &pb.NotifyErrorNotifyPush{
ReqMainType: string(comm.ModuleWorldtask),
ReqSubType: "finish",
Message: "",
}
if customErr.Code == pb.ErrorCode_WorldtaskLvNotEnough {
notifyErr.Code = pb.ErrorCode_WorldtaskLvNotEnough
session.SendMsg(string(comm.ModuleWorldtask), "finish", notifyErr)
} else if customErr.Code == pb.ErrorCode_UserSessionNobeing {
notifyErr.Code = pb.ErrorCode_UserSessionNobeing
session.SendMsg(string(comm.ModuleWorldtask), "finish", notifyErr)
} else {
log.Error("任务条件达成通知",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "condId", Value: conf.Id},
log.Field{Key: "err", Value: err.Error()},
)
}
}
}
}
}()
}
userModule, err := this.service.GetModule(comm.ModuleUser)
if err == nil {
go func() {
defer func() { //程序异常 收集异常信息传递给前端显示
if r := recover(); r != nil {
log.Errorf("[sociatytask ] err:%v ", r)
}
}()
// 公会
if user, ok := userModule.(comm.IUser); ok {
ex, err := user.GetUserExpand(session.GetUserId())
if err == nil && ex.SociatyId != "" {
sociatyModule, err := this.service.GetModule(comm.ModuleSociaty)
if err != nil {
return
}
if sociaty, ok := sociatyModule.(comm.ISociaty); ok {
if err2 := sociaty.TaskcondNotify(uid, ex.SociatyId, conf.Id); err2 != nil {
log.Error("公会任务条件达成通知",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "sociatyId", Value: ex.SociatyId},
log.Field{Key: "condId", Value: conf.Id},
log.Field{Key: "err", Value: err2.Error()},
)
}
if module, err := this.service.GetModule(comm.ModuleRtask); err == nil {
if iRtask, ok := module.(comm.IRtask); ok {
iRtask.SendToRtask(session, comm.Rtype156, 1)
}
}
}
}
}
}()
}
}
}
return
}
func (this *ModuleRtask) TriggerTask(uid string, taskParams ...*comm.TaskParam) {
session, ok := this.GetUserSession(uid)
if !ok {
return
}
for _, tp := range taskParams {
if code := this.processOneTask(session, tp.TT, tp.Params...); code != pb.ErrorCode_Success {
this.Debug("任务处理",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "taskType", Value: tp.TT},
log.Field{Key: "params", Value: tp.Params})
}
session.Push()
comm.PuttaskParam(tp)
}
return
}
// 任务条件校验
func (this *ModuleRtask) CheckCondi(uid string, condiId int32) (code pb.ErrorCode) {
if _, ok := this.modelRtask.checkCondi(uid, condiId); !ok {
code = pb.ErrorCode_RtaskCondiNoReach
}
return
}
func (this *ModuleRtask) RemoveCondi(uid string, condiId int32) (err error) {
dr := this.modelRtaskRecord.getRecord(uid)
if dr != nil && dr.Vals != nil {
delete(dr.Vals, condiId)
}
return
}
// 获取玩家任务条件记录
func (this *ModuleRtask) GetCondiData(uid string) *pb.DBRtaskRecord {
return this.modelRtaskRecord.getRecord(uid)
}
// 远程条件校验
func (this *ModuleRtask) RemoteCheckCondi(uid string, condiId int32, rsp *pb.DBRtaskRecord) error {
if rsp == nil {
return errors.New("pb.DBRtaskRecord is not instance")
}
sid, _, ok := utils.UIdSplit(uid)
if !ok {
return errors.New("sid split error")
}
conn, err := db.ServerDBConn(sid)
if err != nil {
return err
}
model := db.NewDBModel(comm.TableRtaskRecord, 0, conn)
if err := model.Get(uid, rsp); err != nil {
return err
}
return nil
}
func (this *ModuleRtask) ChangeCondi(uid string, data map[int32]*pb.RtaskData) error {
if len(data) > 0 {
update := map[string]interface{}{
"vals": data,
}
return this.modelRtaskRecord.Change(uid, update)
}
return nil
}
// 接收区服worker发起的秘境事件
func (this *ModuleRtask) Rpc_ModuleRtaskSendTask(ctx context.Context, args *pb.RPCRTaskReq, reply *pb.EmptyResp) (err error) {
this.Debug("Rpc_ModuleRtaskSendTask",
log.Field{Key: "args", Value: args.String()},
)
if args.Uid == "" {
err = errors.New("参数异常!")
return
}
if this.IsCross() {
err = errors.New("环境错误 此处为跨服环境!")
return
}
if session, ok := this.GetUserSession(args.Uid); !ok {
err = fmt.Errorf("未查询到用户:%s在线信息!", args.Uid)
return
} else {
this.processOneTask(session, comm.TaskType(args.TaskType), args.Param...)
session.Push()
}
return
}