550 lines
14 KiB
Go
550 lines
14 KiB
Go
package task
|
|
|
|
import (
|
|
"fmt"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
event_v2 "go_dreamfactory/lego/sys/event/v2"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"sort"
|
|
|
|
"github.com/pkg/errors"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
|
)
|
|
|
|
type ModelTask struct {
|
|
modules.MCompModel
|
|
moduleTask *ModuleTask
|
|
EventApp *event_v2.App
|
|
}
|
|
|
|
func (this *ModelTask) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
|
this.TableName = comm.TableTask
|
|
err = this.MCompModel.Init(service, module, comp, options)
|
|
this.moduleTask = module.(*ModuleTask)
|
|
this.EventApp = event_v2.NewApp()
|
|
this.EventApp.Listen(comm.EventTaskChanged, this.doTaskHandle)
|
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
|
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
|
|
})
|
|
return
|
|
}
|
|
|
|
// 查询完成的且未领取的任务 发现未领取返回true
|
|
func (this *ModelTask) noReceiveTask(uid string, taskTag comm.TaskTag) (bool, error) {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
this.moduleTask.Errorf("getTaskList err %v", err)
|
|
return false, err
|
|
}
|
|
if taskTag == comm.TASK_DAILY {
|
|
for _, v := range task.DayList {
|
|
if v.Received == 0 {
|
|
return true, nil
|
|
}
|
|
}
|
|
} else if taskTag == comm.TASK_WEEKLY {
|
|
for _, v := range task.WeekList {
|
|
if v.Received == 0 {
|
|
return true, nil
|
|
}
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (this *ModelTask) checkTaskStatus(uid string, list []*pb.TaskData) []*pb.TaskData {
|
|
// 待校验的条件ID
|
|
condIds := []int32{}
|
|
for _, v := range list {
|
|
condIds = append(condIds, v.TypeId)
|
|
}
|
|
|
|
conds, err := this.moduleTask.ModuleBuried.CheckCondition(uid, condIds...)
|
|
if err != nil {
|
|
this.moduleTask.Error(err.Error())
|
|
return nil
|
|
}
|
|
|
|
for _, v := range list {
|
|
for _, cond := range conds {
|
|
if v.TypeId == cond.Conid {
|
|
v.Cond = cond
|
|
}
|
|
}
|
|
}
|
|
|
|
return list
|
|
}
|
|
|
|
// 获取玩家任务列表
|
|
func (this *ModelTask) getTaskListByTag(uid string, taskTag comm.TaskTag) *pb.DBTask {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
this.moduleTask.Errorf("getTaskList err %v", err)
|
|
return nil
|
|
}
|
|
|
|
if task == nil {
|
|
return nil
|
|
}
|
|
|
|
// 排序
|
|
sort.SliceStable(task.DayList, func(i, j int) bool {
|
|
return task.DayList[i].Sort < task.DayList[j].Sort
|
|
})
|
|
sort.SliceStable(task.WeekList, func(i, j int) bool {
|
|
return task.WeekList[i].Sort < task.WeekList[j].Sort
|
|
})
|
|
|
|
update := map[string]interface{}{}
|
|
var dataList []*pb.TaskData
|
|
if taskTag == comm.TASK_DAILY {
|
|
dataList = task.DayList
|
|
} else if taskTag == comm.TASK_WEEKLY {
|
|
dataList = task.WeekList
|
|
}
|
|
|
|
dataList = this.checkTaskStatus(uid, dataList)
|
|
|
|
if taskTag == comm.TASK_DAILY {
|
|
update["dayList"] = dataList
|
|
} else if taskTag == comm.TASK_WEEKLY {
|
|
update["weekList"] = dataList
|
|
}
|
|
|
|
if err := this.moduleTask.modelTask.Change(uid, update); err != nil {
|
|
this.moduleTask.Error("change err", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
|
|
// 当前玩家成就任务
|
|
getCurTask := func(taskId int32) *pb.TaskData {
|
|
for _, v := range task.AchieveList {
|
|
if v.TaskId == taskId {
|
|
return v
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 判断上个成就任务领取了才显示最后一个任务
|
|
isReceived := func(taskId int32) bool {
|
|
if preCnf := this.moduleTask.configure.getPreTask(taskId); preCnf != nil {
|
|
if preTask := getCurTask(preCnf.Key); preTask != nil {
|
|
if preTask.Received == 1 {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 成就列表
|
|
var achieveList []*pb.TaskData
|
|
|
|
if taskTag == comm.TASK_ACHIEVE {
|
|
for _, v := range task.AchieveList {
|
|
if curTask := this.moduleTask.configure.getTaskById(v.TaskId); curTask != nil {
|
|
if v.Received == 0 {
|
|
isFirst := this.moduleTask.configure.isFirstTask(curTask.Key)
|
|
if curTask.IdAfter == 0 && isFirst { //未领取和没有下个连续任务的
|
|
achieveList = append(achieveList, v)
|
|
continue
|
|
}
|
|
|
|
if isFirst && curTask.IdAfter != 0 { //连续任务的第一个任务
|
|
next := this.moduleTask.configure.getTaskById(curTask.IdAfter)
|
|
if next != nil && v.Received == 0 {
|
|
achieveList = append(achieveList, v)
|
|
}
|
|
} else {
|
|
if isReceived(curTask.Key) {
|
|
achieveList = append(achieveList, v)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
achieveList = this.checkTaskStatus(uid, achieveList)
|
|
|
|
update["achieveList"] = achieveList
|
|
if err := this.moduleTask.modelTask.Change(uid, update); err != nil {
|
|
log.Error("err", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
|
|
task.AchieveList = achieveList
|
|
}
|
|
|
|
return task
|
|
}
|
|
|
|
// 获取用户任务
|
|
func (this *ModelTask) getTaskById(uid string, taskTag comm.TaskTag, taskId int32) *pb.DBTask {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
this.moduleTask.Errorf("getTaskById err %v", err)
|
|
return nil
|
|
}
|
|
|
|
if task != nil {
|
|
if taskTag == comm.TASK_DAILY {
|
|
for _, v := range task.DayList {
|
|
if v.TaskId == taskId {
|
|
task.DayList = append(task.DayList, v)
|
|
}
|
|
}
|
|
} else if taskTag == comm.TASK_WEEKLY {
|
|
for _, v := range task.WeekList {
|
|
if v.TaskId == taskId {
|
|
task.WeekList = append(task.WeekList, v)
|
|
}
|
|
}
|
|
} else if taskTag == comm.TASK_ACHIEVE {
|
|
for _, v := range task.AchieveList {
|
|
if v.TaskId == taskId {
|
|
task.AchieveList = append(task.AchieveList, v)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return task
|
|
}
|
|
|
|
// 初始化任务
|
|
func (this *ModelTask) initTask(uid string, taskTag comm.TaskTag) error {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
objId := primitive.NewObjectID().Hex()
|
|
task = &pb.DBTask{
|
|
Uid: uid,
|
|
Id: objId,
|
|
}
|
|
if err := this.Add(uid, task); err != nil {
|
|
this.moduleTask.Errorf("initTask addlists err %v", err)
|
|
return err
|
|
}
|
|
} else {
|
|
this.moduleTask.Errorf("getTaskList err %v", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
data := this.moduleTask.configure.getTaskByTag(int32(taskTag))
|
|
update := map[string]interface{}{}
|
|
for _, cnf := range data {
|
|
t := &pb.TaskData{
|
|
Tag: cnf.IdTag,
|
|
TypeId: cnf.TypeId,
|
|
TaskId: cnf.Key,
|
|
Active: cnf.Active,
|
|
Sort: cnf.IdList,
|
|
}
|
|
if taskTag == comm.TASK_DAILY {
|
|
task.DayList = append(task.DayList, t)
|
|
update["dayList"] = task.DayList
|
|
} else if taskTag == comm.TASK_WEEKLY {
|
|
task.WeekList = append(task.WeekList, t)
|
|
update["weekList"] = task.WeekList
|
|
} else if taskTag == comm.TASK_ACHIEVE {
|
|
task.AchieveList = append(task.AchieveList, t)
|
|
update["achieveList"] = task.AchieveList
|
|
}
|
|
}
|
|
|
|
if len(update) > 0 {
|
|
if err := this.Change(uid, update); err != nil {
|
|
this.moduleTask.Errorf("initTask err %v", err)
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 查询用户任务
|
|
func (this *ModelTask) getUserTask(uid string, taskId int32) *pb.DBTask {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
this.moduleTask.Errorf("getTaskList err %v", err)
|
|
return nil
|
|
}
|
|
return task
|
|
}
|
|
|
|
// 获取已完成的(日、周)任务
|
|
// func (this *ModelTask) getFinishTasks(uid string, taskTag comm.TaskTag) (list []*pb.TaskData) {
|
|
// task := this.getTaskListByTag(uid, taskTag)
|
|
// if taskTag == comm.TASK_DAILY {
|
|
// for _, v := range task.DayList {
|
|
// if v.Status == 1 {
|
|
// list = append(list, v)
|
|
// }
|
|
// }
|
|
// } else if taskTag == comm.TASK_WEEKLY {
|
|
// for _, v := range task.WeekList {
|
|
// if v.Status == 1 {
|
|
// list = append(list, v)
|
|
// }
|
|
// }
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// 获取待处理的(日、周)任务
|
|
func (this *ModelTask) getUnFinishTasks(uid string, taskId int32) (list []*pb.TaskData) {
|
|
task := &pb.DBTask{}
|
|
if err := this.Get(uid, task); err != nil {
|
|
this.moduleTask.Errorf("getTaskById err %v", err)
|
|
return nil
|
|
}
|
|
|
|
if task != nil {
|
|
for _, v := range task.DayList {
|
|
if v.TaskId == taskId && v.Status == 0 {
|
|
list = append(list, v)
|
|
}
|
|
}
|
|
|
|
for _, v := range task.WeekList {
|
|
if v.TaskId == taskId && v.Status == 0 {
|
|
list = append(list, v)
|
|
}
|
|
}
|
|
|
|
for _, v := range task.AchieveList {
|
|
if v.TaskId == taskId && v.Status == 0 {
|
|
list = append(list, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 检查任务状态 返回等待处理的任务
|
|
func (this *ModelTask) checkTask(uid string, taskId int32) (*pb.TaskData, bool) {
|
|
taskList := this.getUnFinishTasks(uid, taskId)
|
|
for _, v := range taskList {
|
|
if taskId == v.TaskId {
|
|
return v, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
// 更改用户任务
|
|
// Deprecated
|
|
func (this *ModelTask) modifyUserTask(uid string, taskId int32, data map[string]interface{}) error {
|
|
var task *pb.DBTask
|
|
if err := this.GetList(uid, &task); err != nil {
|
|
this.moduleTask.Errorf("getTaskById err %v", err)
|
|
return nil
|
|
}
|
|
var err error
|
|
for _, v := range task.DayList {
|
|
if v.TaskId == taskId {
|
|
// v.Progress = data["progress"].(int32)
|
|
v.Status = data["status"].(int32)
|
|
}
|
|
}
|
|
day_update := map[string]interface{}{
|
|
"dayList": task.DayList,
|
|
}
|
|
err = this.Change(uid, day_update)
|
|
|
|
for _, v := range task.WeekList {
|
|
if v.TaskId == taskId {
|
|
// v.Progress = data["progress"].(int32)
|
|
v.Status = data["status"].(int32)
|
|
}
|
|
}
|
|
week_update := map[string]interface{}{
|
|
"weekList": task.WeekList,
|
|
}
|
|
err = this.Change(uid, week_update)
|
|
|
|
for _, v := range task.AchieveList {
|
|
if v.TaskId == taskId {
|
|
// v.Progress = data["progress"].(int32)
|
|
v.Status = data["status"].(int32)
|
|
}
|
|
}
|
|
achieve_update := map[string]interface{}{
|
|
"achieveList": task.AchieveList,
|
|
}
|
|
err = this.Change(uid, achieve_update)
|
|
|
|
return err
|
|
}
|
|
|
|
// 清空任务
|
|
func (this *ModelTask) clearTask(uid string, taskTag ...comm.TaskTag) {
|
|
if len(taskTag) == 0 {
|
|
this.moduleTask.Error("TaskTag参数缺失",
|
|
log.Field{Key: "uid", Value: uid},
|
|
log.Field{Key: "params", Value: taskTag},
|
|
)
|
|
return
|
|
}
|
|
var task *pb.DBTask
|
|
if err := this.GetList(uid, &task); err != nil {
|
|
this.moduleTask.Errorf("getTaskById err %v", err)
|
|
return
|
|
}
|
|
|
|
if task == nil {
|
|
this.moduleTask.Error("任务数据空",
|
|
log.Field{Key: "uid", Value: uid},
|
|
log.Field{Key: "taskTag", Value: taskTag},
|
|
)
|
|
return
|
|
}
|
|
|
|
dr := this.moduleTask.ModuleRtask.GetCondiData(uid)
|
|
|
|
update := map[string]interface{}{}
|
|
if taskTag[0] == comm.TASK_DAILY {
|
|
for _, v := range task.DayList {
|
|
//删除任务条件数据
|
|
if dr != nil && dr.Vals != nil {
|
|
delete(dr.Vals, v.TypeId)
|
|
}
|
|
}
|
|
if err := this.moduleTask.ModuleRtask.ChangeCondi(uid, dr.Vals); err != nil {
|
|
this.moduleTask.Error("更新任务条件数据", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
update["dayList"] = make([]*pb.TaskData, 0)
|
|
} else if taskTag[0] == comm.TASK_WEEKLY {
|
|
for _, v := range task.WeekList {
|
|
//删除任务条件数据
|
|
if dr != nil && dr.Vals != nil {
|
|
delete(dr.Vals, v.TypeId)
|
|
}
|
|
}
|
|
if err := this.moduleTask.ModuleRtask.ChangeCondi(uid, dr.Vals); err != nil {
|
|
this.moduleTask.Error("更新任务条件数据", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
update["weekList"] = make([]*pb.TaskData, 0)
|
|
} else if taskTag[0] == comm.TASK_ACHIEVE {
|
|
for _, v := range task.AchieveList {
|
|
//删除任务条件数据
|
|
if dr != nil && dr.Vals != nil {
|
|
delete(dr.Vals, v.TypeId)
|
|
}
|
|
}
|
|
if err := this.moduleTask.ModuleRtask.ChangeCondi(uid, dr.Vals); err != nil {
|
|
this.moduleTask.Error("更新任务条件数据", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
update["weekList"] = make([]*pb.TaskData, 0)
|
|
}
|
|
|
|
if err := this.moduleTask.modelTask.Change(uid, update); err != nil {
|
|
this.moduleTask.Error("清空任务数据", log.Field{Key: "uid", Value: uid})
|
|
}
|
|
|
|
}
|
|
|
|
// 任务处理
|
|
func (this *ModelTask) doTaskHandle(event interface{}, next func(event interface{})) {
|
|
tl := event.(*TaskListen)
|
|
|
|
data, err := this.moduleTask.configure.getTasks(int32(tl.TaskType))
|
|
if err != nil {
|
|
this.moduleTask.Errorf("taskHandle err %v", err)
|
|
return
|
|
}
|
|
|
|
// 获取玩家的任务条件数据
|
|
dr := this.moduleTask.ModuleRtask.GetCondiData(tl.Uid)
|
|
if dr == nil {
|
|
return
|
|
}
|
|
|
|
// 遍历事件列表
|
|
for _, conf := range data {
|
|
// 从任务条件中查找
|
|
ret, ok := dr.Vals[conf.TypeId]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
task, ok := this.checkTask(tl.Uid, conf.Key)
|
|
if !ok {
|
|
this.moduleTask.Debug("任务已完成", log.Field{Key: "uid", Value: tl.Uid}, log.Field{Key: "任务ID", Value: conf.Key})
|
|
continue
|
|
}
|
|
|
|
var (
|
|
progress int32
|
|
update map[string]interface{}
|
|
)
|
|
|
|
if code := this.moduleTask.ModuleRtask.CheckCondi(tl.Uid, conf.TypeId); code == pb.ErrorCode_Success {
|
|
// update data
|
|
if ret != nil && len(ret.Data) > 0 {
|
|
progress = ret.Data[0]
|
|
}
|
|
update = map[string]interface{}{
|
|
"progress": progress,
|
|
"status": 1,
|
|
}
|
|
} else {
|
|
if ret != nil && len(ret.Data) > 0 {
|
|
progress = ret.Data[0]
|
|
}
|
|
update = map[string]interface{}{
|
|
"progress": progress,
|
|
}
|
|
}
|
|
if err = this.modifyUserTask(tl.Uid, task.TaskId, update); err != nil {
|
|
return
|
|
}
|
|
this.moduleTask.Debug("更新任务",
|
|
log.Field{Key: "uid", Value: tl.Uid}, log.Field{Key: "任务ID", Value: conf.Key},
|
|
log.Field{Key: "事件ID", Value: conf.TypeId}, log.Field{Key: "progress", Value: update["progress"]},
|
|
log.Field{Key: "status", Value: update["status"]},
|
|
)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 更新活跃度
|
|
func (this *ModelTask) updateActive(uid string, cfgId int32) error {
|
|
// 更新活跃度
|
|
de, err := this.moduleTask.ModuleUser.GetUserExpand(uid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
conf := this.moduleTask.configure.getTaskById(cfgId)
|
|
if conf == nil {
|
|
return errors.New(fmt.Sprintf("%v config nil", cfgId))
|
|
}
|
|
|
|
switch conf.IdTag {
|
|
case int32(comm.TASK_DAILY):
|
|
de.Activeday += conf.Active
|
|
case int32(comm.TASK_WEEKLY):
|
|
de.Activeweek += conf.Active
|
|
}
|
|
|
|
update := map[string]interface{}{
|
|
"activeday": de.Activeday,
|
|
"activeweek": de.Activeweek,
|
|
}
|
|
|
|
return this.moduleTask.ModuleUser.ChangeUserExpand(uid, update)
|
|
}
|
|
|
|
type TaskListen struct {
|
|
event_v2.Event
|
|
Uid string
|
|
TaskType comm.TaskType
|
|
}
|