go_dreamfactory/modules/task/model_task.go
2022-12-19 10:13:12 +08:00

510 lines
12 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.Status == 1 && v.Received == 0 {
return true, nil
}
}
} else if taskTag == comm.TASK_WEEKLY {
for _, v := range task.WeekList {
if v.Status == 1 && v.Received == 0 {
return true, nil
}
}
}
return false, nil
}
//获取玩家任务列表
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
})
dr := this.moduleTask.ModuleRtask.GetCondiData(uid)
if dr == nil {
return nil
}
// 筛选出指定tag的任务
if taskTag == comm.TASK_DAILY {
for _, v := range task.DayList {
if p, ok := dr.Vals[v.TypeId]; ok {
if len(p.Data) > 0 {
v.Progress = p.Data[0]
}
}
}
} else if taskTag == comm.TASK_WEEKLY {
for _, v := range task.WeekList {
if p, ok := dr.Vals[v.TypeId]; ok {
if len(p.Data) > 0 {
v.Progress = p.Data[0]
}
}
}
}
// 当前玩家成就任务
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)
}
}
}
}
}
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 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
}
//更改用户任务
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.Fields{"uid": uid, "params": 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.Fields{"uid": uid, "taskTag": 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.Fields{"uid": 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.Fields{"uid": 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.Fields{"uid": uid})
}
update["weekList"] = make([]*pb.TaskData, 0)
}
if err := this.moduleTask.modelTask.Change(uid, update); err != nil {
this.moduleTask.Error("清空任务数据", log.Fields{"uid": 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.Fields{"uid": tl.Uid, "任务ID": 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.Fields{"uid": tl.Uid, "任务ID": conf.Key, "事件ID": conf.TypeId, "progress": update["progress"], "status": 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
}