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 if cond.State == pb.BuriedItemFinishState_buried_finish { v.Status = 1 } } } } 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 == nil { // // 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 }