494 lines
14 KiB
Go
494 lines
14 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"
|
||
"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, 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.Rtype51,
|
||
comm.Rtype125, comm.Rtype126, comm.Rtype127, comm.Rtype187:
|
||
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.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.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.Rtype96, comm.Rtype98, comm.Rtype99,
|
||
comm.Rtype104, 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.Rtype188:
|
||
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.Rtype76, comm.Rtype79,
|
||
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.Rtype73, comm.Rtype77, comm.Rtype80, comm.Rtype83:
|
||
handle := &rtaskCondHandle{
|
||
condId: v.Id,
|
||
verify: this.modelRtaskRecord.verifyThirdGreatEqualParam,
|
||
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, record *pb.DBRtaskRecord, rtaskType comm.TaskType, params ...int32) (condIds []int32, code pb.ErrorCode) {
|
||
uid := session.GetUserId()
|
||
handles := this.getHandle(rtaskType)
|
||
|
||
// update
|
||
for _, handle := range handles {
|
||
conf, err := this.configure.getRtaskTypeById(handle.condId)
|
||
if err != nil {
|
||
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, conf, params...)
|
||
}
|
||
|
||
if !ok {
|
||
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)
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
type RPCRtaskReq struct {
|
||
Uid string
|
||
TaskParams []*comm.TaskParam
|
||
}
|
||
|
||
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})
|
||
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()
|
||
|
||
if this.IsCross() {
|
||
//随机任务
|
||
if _, err := this.service.AcrossClusterRpcGo(
|
||
context.Background(),
|
||
session.GetServiecTag(),
|
||
comm.Service_Worker,
|
||
string(comm.Rpc_ModuleRtaskSendTask),
|
||
&RPCRtaskReq{Uid: uid, TaskParams: taskParams},
|
||
nil); err != nil {
|
||
log.Errorln(err)
|
||
}
|
||
return
|
||
}
|
||
|
||
this.processTasks(session, taskParams...)
|
||
|
||
session.Push()
|
||
this.PutUserSession(session)
|
||
return
|
||
}
|
||
|
||
func (this *ModuleRtask) processTasks(session comm.IUserSession, taskParams ...*comm.TaskParam) {
|
||
uid := session.GetUserId()
|
||
record := this.modelRtaskRecord.getRecord(uid)
|
||
var condIds []int32
|
||
for _, tp := range taskParams {
|
||
ids, _ := this.processOneTask(session, record, tp.TT, tp.Params...)
|
||
condIds = append(condIds, ids...)
|
||
comm.PuttaskParam(tp)
|
||
}
|
||
|
||
update := map[string]interface{}{
|
||
"vals": record.Vals,
|
||
}
|
||
|
||
this.modelRtaskRecord.Change(uid, update)
|
||
|
||
//去重
|
||
condIds = removeDuplicate(condIds)
|
||
//带通知的condIds
|
||
var condIdsForNotify []int32
|
||
for _, condId := range condIds {
|
||
r, _ := record.Vals[condId]
|
||
conf, _ := this.configure.getRtaskTypeById(condId)
|
||
if r.Data[0] >= conf.Data1 {
|
||
condIdsForNotify = append(condIdsForNotify, condId)
|
||
|
||
}
|
||
}
|
||
|
||
if len(condIdsForNotify) == 0 {
|
||
return
|
||
}
|
||
//通知世界任务模块
|
||
module, err := this.service.GetModule(comm.ModuleWorldtask)
|
||
if err == nil {
|
||
//世界任务
|
||
if worldtask, ok := module.(comm.IWorldtask); ok {
|
||
if err := worldtask.TaskCondFinishNotify(session, condIdsForNotify); err != nil {
|
||
}
|
||
}
|
||
}
|
||
// 通知公会任务模块
|
||
sociatyModule, err := this.service.GetModule(comm.ModuleSociaty)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if sociaty, ok := sociatyModule.(comm.ISociaty); ok {
|
||
if err2 := sociaty.TaskcondNotify(uid, condIds); err2 != nil {
|
||
}
|
||
}
|
||
}
|
||
|
||
// 任务条件校验
|
||
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) (cids []int32) {
|
||
record := this.modelRtaskRecord.getRecord(uid)
|
||
if record == nil {
|
||
return
|
||
}
|
||
|
||
for _, condId := range condiIds {
|
||
if r, ok := record.Vals[condId]; ok {
|
||
conf, err := this.configure.getRtaskTypeById(condId)
|
||
if err != nil || conf == nil {
|
||
errors.Errorf("conf not found condiID: %v", condId)
|
||
return
|
||
}
|
||
if r.Data[0] > conf.Data1 {
|
||
cids = append(cids, 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 *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.processTasks(session, args.TaskParams...)
|
||
session.Push()
|
||
}
|
||
return
|
||
}
|