go_dreamfactory/modules/rtask/module.go
2023-05-25 16:06:47 +08:00

495 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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"
"sync"
"github.com/pkg/errors"
)
var _ comm.IRtask = (*ModuleRtask)(nil)
// 限定条件
type rtaskCondHandle struct {
condId int32 //任务条件配置ID
verify verifyHandle //校验任务条件
update updateDataHandle //更新任务数据
}
// 任务参数校验
type verifyHandle func(uid string, record *pb.DBRtaskRecord, cfg *cfg.GameRdtaskCondiData, params ...int32) (bool, int32, error)
// 任务数据更新
type updateDataHandle func(uid string, record *pb.DBRtaskRecord, cfg *cfg.GameRdtaskCondiData, vals ...int32) error
type ModuleRtask struct {
modules.ModuleBase
service base.IRPCXService
modelRtask *ModelRtask
modelRtaskRecord *ModelRtaskRecord
api *apiComp
configure *configureComp
handleMap sync.Map //map[int32]*rtaskCondi //任务校验处理器
}
func NewModule() core.IModule {
return &ModuleRtask{}
}
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)
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 *rtaskCondHandle) {
this.handleMap.Store(condiId, condi)
}
func (this *ModuleRtask) getHandle(tt comm.TaskType) (handles []*rtaskCondHandle) {
for _, v := range this.configure.getRtaskCondis(int32(tt)) {
switch tt {
// 大于1个参数且第一个参数累计第二个参数等于
case comm.Rtype1, comm.Rtype16, comm.Rtype17, comm.Rtype50, comm.Rtype125, comm.Rtype126, comm.Rtype127:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyMultiEqual,
update: this.modelRtaskRecord.addUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
//两个参数 第一个参数覆盖 第二个参数等于
case comm.Rtype4, comm.Rtype5, comm.Rtype6, comm.Rtype8, comm.Rtype10, comm.Rtype35, comm.Rtype158, comm.Rtype168,
comm.Rtype122, comm.Rtype133:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.veriftyEqualParam, //两个参数 等于
update: this.modelRtaskRecord.overrideUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
// 两个参数 第一个大于等于 第二个等于
case comm.Rtype159, comm.Rtype160, comm.Rtype74, comm.Rtype75:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyMultiEqual, //两个参数 等于
update: this.modelRtaskRecord.overrideUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
// 一个参数且覆盖
case comm.Rtype61, comm.Rtype109, comm.Rtype129, comm.Rtype134:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyFirstEqualParam,
update: this.modelRtaskRecord.overrideUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
// 一个参数且累计
case comm.Rtype7, comm.Rtype12, comm.Rtype13, comm.Rtype14, comm.Rtype15,
comm.Rtype18, comm.Rtype19, comm.Rtype23, comm.Rtype24,
comm.Rtype26, comm.Rtype27, comm.Rtype28, comm.Rtype38,
comm.Rtype39, comm.Rtype47, comm.Rtype51, comm.Rtype53,
comm.Rtype54, comm.Rtype57, comm.Rtype60,
comm.Rtype62, comm.Rtype64, comm.Rtype87, comm.Rtype88, comm.Rtype89, comm.Rtype90,
comm.Rtype91, comm.Rtype92, comm.Rtype94, comm.Rtype95, comm.Rtype97, comm.Rtype104,
comm.Rtype96, comm.Rtype98, comm.Rtype99, comm.Rtype102, comm.Rtype103, comm.Rtype105,
comm.Rtype106, comm.Rtype108, comm.Rtype113, comm.Rtype114, comm.Rtype115, comm.Rtype116,
comm.Rtype117, comm.Rtype118, comm.Rtype119, comm.Rtype120, comm.Rtype121, comm.Rtype123,
comm.Rtype124,
comm.Rtype128, comm.Rtype130, comm.Rtype131, comm.Rtype132, comm.Rtype135,
comm.Rtype141, comm.Rtype142, comm.Rtype143, comm.Rtype144, comm.Rtype145, comm.Rtype146,
comm.Rtype147, comm.Rtype148, comm.Rtype149, comm.Rtype152, comm.Rtype153, comm.Rtype154,
comm.Rtype156, comm.Rtype161, comm.Rtype165, comm.Rtype166, comm.Rtype167,
comm.Rtype171, comm.Rtype172, comm.Rtype173, comm.Rtype175, comm.Rtype177,
comm.Rtype181, comm.Rtype182, comm.Rtype183, comm.Rtype184, comm.Rtype185, comm.Rtype186, comm.Rtype187:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyFirstGreatEqualParam,
update: this.modelRtaskRecord.addUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
//////
case comm.Rtype3:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtask.verifyRtype3,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype9:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtask.verfiyRtype9,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype20:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtask.verifyRtype20,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype138:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtask.verifyRtype138,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
// 多参数 第一个大于等于 其它等于
case comm.Rtype25, comm.Rtype30,
comm.Rtype32, comm.Rtype33, comm.Rtype34, comm.Rtype36,
comm.Rtype37, comm.Rtype40,
comm.Rtype46, comm.Rtype73, comm.Rtype76, comm.Rtype77, comm.Rtype79, comm.Rtype80, comm.Rtype83,
comm.Rtype52, comm.Rtype55, comm.Rtype56, comm.Rtype82,
comm.Rtype65, comm.Rtype66, comm.Rtype67, comm.Rtype68, comm.Rtype70, comm.Rtype140,
comm.Rtype169, comm.Rtype170, comm.Rtype174, comm.Rtype179, comm.Rtype180:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyMultiEqual,
update: this.modelRtaskRecord.addUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype41, comm.Rtype42:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyThirdGreatEqualParam,
update: this.modelRtaskRecord.addUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype43:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtask.verifyRtype43,
update: this.modelRtaskRecord.overrideUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
case comm.Rtype78:
handle := &rtaskCondHandle{
condId: v.Id,
verify: this.modelRtaskRecord.verifyThirdLessEqualParam,
update: this.modelRtaskRecord.overrideUpdate,
}
handles = append(handles, handle)
this.registerVerifyHandle(v.Id, handle)
default:
log.Warnf("rtaskType[%v] handle not register", tt)
}
}
return
}
// 处理触发的任务
func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType comm.TaskType, params ...int32) (code pb.ErrorCode) {
uid := session.GetUserId()
var (
handles []*rtaskCondHandle
condIds []int32
)
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 {
log.Errorln(err)
}
return
}
lock, _ := this.modelRtask.userlock(uid)
err := lock.Lock()
if err != nil {
this.Error("TriggerTask userlock err!", log.Field{Key: "err", Value: err.Error()})
}
defer lock.Unlock()
record := this.modelRtaskRecord.getRecord(uid)
handles = this.getHandle(rtaskType)
// update
for _, handle := range handles {
conf, err := this.configure.getRtaskTypeById(handle.condId)
if err != nil {
log.Debug("任务配置未找到", log.Field{Key: "condId", Value: handle.condId})
code = pb.ErrorCode_RtaskCondiNoFound
return
}
if conf.Data == 1 { //接取
if r, ok := record.Vals[handle.condId]; ok {
if r.Flag == 0 { //非接取
r.Data = make(map[int32]int32)
r.Rtype = conf.Type
} else {
return
}
}
}
if handle.verify != nil {
var (
ok bool
d int32
)
if len(params) == 1 {
ok = true
} else {
ok, d, _ = handle.verify(uid, record, conf, params...)
}
if !ok {
this.Debug("验证失败", log.Field{Key: "uid", Value: uid},
log.Field{Key: "params", Value: params},
log.Field{Key: "conf", Value: conf})
continue
}
if handle.update != nil {
if d > 0 {
params[0] = d
}
if err := handle.update(uid, record, conf, params...); err != nil {
log.Errorf("update task:%v", err)
code = pb.ErrorCode_DBError
return
}
}
condIds = append(condIds, handle.condId)
update := map[string]interface{}{
"vals": record.Vals,
}
this.modelRtaskRecord.Change(uid, update)
}
}
for _, condId := range condIds {
if code = this.CheckCondi(uid, condId, params...); code == pb.ErrorCode_Success {
module, err := this.service.GetModule(comm.ModuleWorldtask)
if err == nil {
//世界任务
if worldtask, ok := module.(comm.IWorldtask); ok {
if err := worldtask.TaskCondFinishNotify(session, condId); err != nil {
// log.Error("世界任务条件达成通知",
// log.Field{Key: "uid", Value: uid},
// log.Field{Key: "condId", Value: condId},
// log.Field{Key: "err", Value: err.Error()},
// )
}
}
}
userModule, err := this.service.GetModule(comm.ModuleUser)
if err == nil {
// 公会
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, condId); err2 != nil {
log.Error("公会任务条件达成通知",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "sociatyId", Value: ex.SociatyId},
log.Field{Key: "condId", Value: condId},
log.Field{Key: "err", Value: err2.Error()},
)
}
this.processOneTask(session, comm.Rtype156, 1)
}
}
}
}
}
}
return
}
func (this *ModuleRtask) TriggerTask(uid string, taskParams ...*comm.TaskParam) {
session, ok := this.GetUserSession(uid)
if !ok {
return
}
this.Debug("任务触发",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "tasks", Value: taskParams})
for _, tp := range taskParams {
// this.Debug("任务触发",
// log.Field{Key: "uid", Value: uid},
// log.Field{Key: "type", Value: tp.TT},
// log.Field{Key: "params", Value: tp.Params})
code := this.processOneTask(session, tp.TT, tp.Params...)
if code != pb.ErrorCode_Success {
// this.Error("任务处理失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "code", Value: code})
}
comm.PuttaskParam(tp)
}
session.Push()
this.PutUserSession(session)
return
}
// 任务条件校验
func (this *ModuleRtask) CheckCondi(uid string, condiId int32, params ...int32) (code pb.ErrorCode) {
record := this.modelRtaskRecord.getRecord(uid)
if record == nil {
code = pb.ErrorCode_DataNotFound
return
}
if len(params) == 0 {
if v, ok := record.Vals[condiId]; ok {
for _, p := range v.Data {
params = append(params, p)
}
}
}
if _, ok := this.modelRtask.checkCondi(uid, condiId, record, params...); !ok {
code = pb.ErrorCode_RtaskCondiNoReach
return
}
return
}
func (this *ModuleRtask) CheckCondis(uid string, condiIds ...int32) (condIds []int32) {
record := this.modelRtaskRecord.getRecord(uid)
if record == nil {
return
}
for _, condId := range condIds {
if _, ok := this.modelRtask.checkCondi(uid, condId, record); ok {
condIds = append(condIds, condId)
}
}
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
}
type TaskProcessResp struct {
CondIds []int32
}
// 接收区服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},
)
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
}