package dispatch import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "go_dreamfactory/modules" "go_dreamfactory/pb" "go_dreamfactory/sys/configure" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/x/bsonx" ) type modelDispatch struct { modules.MCompModel module *Dispatch service core.IService } func (this *modelDispatch) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { err = this.MCompModel.Init(service, module, comp, options) this.TableName = comm.TableDispatch this.module = module.(*Dispatch) this.service = service this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ Keys: bsonx.Doc{{Key: "_id", Value: bsonx.Int32(1)}}, }) return } // 获取派遣数据 func (this *modelDispatch) getDBDispatch(uid string) (dis *pb.DBDispatch, err error) { dis = &pb.DBDispatch{} if err = this.Get(uid, dis); err != nil { if err == mongo.ErrNoDocuments { dis.Uid = uid dis.Nb = &pb.Noticeboard{ Lv: 1, } if err = this.Add(uid, dis); err != nil { return } } return } return } // 获取随机任务ID func (this *modelDispatch) getTasksWeight(dispatch *pb.DBDispatch) int32 { conf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv) if err != nil || conf == nil { this.module.Error("配置不存在", log.Field{Key: "error", Value: err}) return 0 } // 取权重数组下标 i := comm.GetRandW(conf.Probability) // this.module.Debug("随机下标", log.Field{Key: "idx", Value: i}) confList, err := this.module.configure.getDispatchTaskConfByType(int32(i + 1)) var tIds []int32 var weights []int32 for _, v := range confList { weights = append(weights, v.Weight) if v.Completecount == 0 { tIds = append(tIds, v.Id) } else if v.Completecount > 0 { if cc, ok := dispatch.Completecount[v.Id]; ok { if cc < v.Completecount { tIds = append(tIds, v.Id) } } else { tIds = append(tIds, v.Id) } } } idex := comm.GetRandW(weights) // idex := utils.RandomNumbers(0, len(tIds), 1) // if len(idex) == 0 { // return 0 // } return tIds[idex] } // 随机任务 func (this *modelDispatch) taskRandom(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, err error) { if dispatch.Nb.Lv == 0 { dispatch.Nb.Lv = 1 } //判断随机数量 var n int n = len(dispatch.Nb.Tasks) if n == 0 { dispatch.Nb.Tasks = make([]*pb.DispatchTask, 6) //随机任务 for i := 0; i < noticeNum; i++ { dispatch.Nb.Tasks[i] = this.addOneRandomTask(dispatch) } tasks = dispatch.Nb.Tasks } else { for i := 0; i < len(dispatch.Nb.Tasks); i++ { //只随机未接取的任务 if dispatch.Nb.Tasks[i].Status == 0 { // 替换 t := this.addOneRandomTask(dispatch) dispatch.Nb.Tasks[i] = t } } tasks = dispatch.Nb.Tasks } return } func (this *modelDispatch) randomTask(dispatch *pb.DBDispatch, n int) (tasks []*pb.DispatchTask) { total := 0 existmap := make(map[int32]int32) for _, v := range dispatch.Nb.Tasks { if v != nil { existmap[v.TaskId] = v.TaskId } } for total < n { rid := this.getTasksWeight(dispatch) if rid == 0 { return nil } conf, _ := this.module.configure.getDispatchTaskConf(rid) race := comm.GetRandW(conf.Raceweight) + 1 if _, ok := existmap[rid]; !ok { tasks = append(tasks, &pb.DispatchTask{ TaskId: rid, Race: race, }) total++ } } //更新任务持续截至时间 for _, task := range tasks { taskConf, err := this.module.configure.getDispatchTaskConf(task.TaskId) if err != nil { return nil } if task.Duration == 0 { duration := configure.Now().Unix() + int64(taskConf.Taskcd) task.Duration = duration } } return } func (this *modelDispatch) addOneRandomTask(dispatch *pb.DBDispatch) (task *pb.DispatchTask) { tasks := this.randomTask(dispatch, 1) if len(tasks) == 1 { task = tasks[0] } return } func (this *modelDispatch) addRandomTask(dispatch *pb.DBDispatch, n int) (tasks []*pb.DispatchTask) { if n <= 0 { tasks = dispatch.Nb.Tasks return } return this.randomTask(dispatch, n) } // 替换指定的已完成任务 func (this *modelDispatch) replaceTask(uid string, taskId int32, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, oldTask *pb.DispatchTask) { for i := 0; i < len(dispatch.Nb.Tasks); i++ { //替换状态是完成的任务 if dispatch.Nb.Tasks[i].Status == 2 { if taskId != dispatch.Nb.Tasks[i].TaskId { continue } oldTask = dispatch.Nb.Tasks[i] //替换 dispatch.Nb.Tasks[i] = this.addOneRandomTask(dispatch) break } } tasks = dispatch.Nb.Tasks return } // 替换所有完成的任务 func (this *modelDispatch) replaceFinishedTask(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, oldtasks []*pb.DispatchTask) { var randCount int for i := 0; i < len(dispatch.Nb.Tasks); i++ { //替换状态是完成的任务 if dispatch.Nb.Tasks[i].Status == 2 { //删除 oldtasks = append(oldtasks, dispatch.Nb.Tasks[i]) dispatch.Nb.Tasks = append(dispatch.Nb.Tasks[:i], dispatch.Nb.Tasks[i+1:]...) i-- randCount++ } else { tasks = append(tasks, dispatch.Nb.Tasks[i]) } } tasks = append(tasks, this.addRandomTask(dispatch, randCount)...) return } // 验证英雄的条件 func (this *modelDispatch) validHeroCond(uid string, dispatch *pb.DBDispatch, taskId int32, hero *pb.DBHero) (ok1, ok2 bool, err error) { var ( task *pb.DispatchTask ) for _, v := range dispatch.Nb.Tasks { for _, h := range v.HeroIds { if h == hero.Id { err = comm.NewCustomError(pb.ErrorCode_DispatchHeroAssigned) return } } } for _, v := range dispatch.Nb.Tasks { if v.TaskId == taskId { task = v } } if task == nil { err = fmt.Errorf("no fund task:%d", taskId) return } //taskConf gd, err := this.module.configure.getDispatchTaskConf(taskId) if err != nil { return } for _, v := range gd.Taskreq { if v.Key == 1 { if hero.Lv >= v.Param { ok1 = true } else { ok1 = false break } } else if v.Key == 2 { if hero.Star >= v.Param { ok1 = true } else { ok1 = false break } } else if v.Key == 3 { hcfg, err2 := this.module.configure.GetHeroConfig(hero.HeroID) if err2 != nil { return false, false, err2 } if hcfg.Race == v.Param { ok1 = true } else { ok1 = false break } } hcfg, err2 := this.module.configure.GetHeroConfig(hero.HeroID) if err2 != nil { return false, false, err2 } if hcfg.Race == task.Race { ok2 = true } else { ok2 = false } } return } // 派遣 func (this *modelDispatch) dispatch(session comm.IUserSession, info *pb.DBDispatch, taskId int32, heroIds []string) (err error) { var ( flag bool //额外条件是否满足 heros []*pb.DBHero ) if heros, err = this.module.ModuleHero.QueryCrossMultipleHeroinfo(session.GetUserId(), heroIds); err != nil { this.module.Errorln(err) return } for _, hero := range heros { if ok1, ok2, err := this.validHeroCond(session.GetUserId(), info, taskId, hero); err == nil { if !ok1 { return comm.NewCustomError(pb.ErrorCode_DispatchHeroNoReached) //基础条件未满足 } if ok2 { flag = true } } else { return err } } for _, v := range info.Nb.Tasks { if v.TaskId == taskId && v.Status == 0 { v.HeroIds = heroIds if v.Duration <= configure.Now().Unix() { return comm.NewCustomError(pb.ErrorCode_DispatchTaskExpired) } else { if v.LeftTime >= configure.Now().Unix() { v.Status = 2 //任务结束 v.Exaward = flag } else { taskConf, err := this.module.configure.getDispatchTaskConf(v.TaskId) if err != nil { continue } v.Status = 1 //任务进行中 leftTime := configure.Now().Unix() + int64(taskConf.Tasktime) v.LeftTime = leftTime v.Exaward = flag } } } } update := map[string]interface{}{ "nb": info.Nb, } if err := this.Change(session.GetUserId(), update); err != nil { return err } return nil } // 更新免费刷新次数 func (this *modelDispatch) updateFreeCount(uid string, noticeboard *pb.Noticeboard) error { if noticeboard.FreeCount <= 0 { return comm.NewCustomError(pb.ErrorCode_DispatchNoFree) } noticeboard.FreeCount-- update := map[string]interface{}{ "nb": noticeboard, } return this.Change(uid, update) } // 更新刷新次数 func (this *modelDispatch) updateRefreshCount(uid string, noticeboard *pb.Noticeboard) error { noticeboard.RefreshCount++ update := map[string]interface{}{ "nb": noticeboard, } return this.Change(uid, update) } // 更新公告任务 func (this *modelDispatch) updateTasks(uid string, noticeboard *pb.Noticeboard, tasks []*pb.DispatchTask) error { noticeboard.Tasks = tasks update := map[string]interface{}{ "nb": noticeboard, } return this.Change(uid, update) } // 更新公告栏任务 func (this *modelDispatch) updateNotice(uid string, dispatch *pb.DBDispatch) error { var randCount int for i := 0; i < len(dispatch.Nb.Tasks); i++ { if dispatch.Nb.Tasks[i].Status == 1 { if dispatch.Nb.Tasks[i].LeftTime != 0 && dispatch.Nb.Tasks[i].LeftTime <= configure.Now().Unix() { //更改次任务状态为 dispatch.Nb.Tasks[i].Status = 2 //任务结束 dispatch.Nb.Tasks[i].LeftTime = 0 //升级 conf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv) if err != nil || conf == nil { return err } } } if dispatch.Nb.Tasks[i].Status == 0 { //判断到期时间 if dispatch.Nb.Tasks[i].Duration != 0 && dispatch.Nb.Tasks[i].Duration <= configure.Now().Unix() { //删除到期任务 dispatch.Nb.Tasks = append(dispatch.Nb.Tasks[:i], dispatch.Nb.Tasks[i+1:]...) // i-- randCount++ } } } //刷新任务 count := len(dispatch.Nb.Tasks) if count < noticeNum { randCount = noticeNum - count dispatch.Nb.Tasks = append(dispatch.Nb.Tasks, this.addRandomTask(dispatch, randCount)...) } //判断是否有下一等级 nextConf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv + 1) if nextConf != nil { if dispatch.Nb.TaskCount >= nextConf.Upgrade { if err != nil { return err } dispatch.Nb.Lv++ dispatch.Nb.TaskCount = 0 } } return this.updateTasks(uid, dispatch.Nb, dispatch.Nb.Tasks) } // 更新周任务状态 func (this *modelDispatch) updateWeekstatus(uid string, idx int32, noticeboard *pb.Noticeboard) error { noticeboard.WeekReceived = append(noticeboard.WeekReceived, idx) update := map[string]interface{}{ "nb": noticeboard, } return this.Change(uid, update) }