474 lines
11 KiB
Go
474 lines
11 KiB
Go
package dispatch
|
|
|
|
import (
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
"go_dreamfactory/utils"
|
|
|
|
"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
|
|
}
|
|
|
|
// 初始玩家公告
|
|
// Deprecated
|
|
func (this *modelDispatch) initDispatch(uid string, dispatch *pb.DBDispatch) *pb.Noticeboard {
|
|
tasks, err := this.taskRandom(uid, dispatch)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if len(tasks) == 0 {
|
|
return nil
|
|
}
|
|
|
|
freeCount := this.module.configure.GetGlobalConf().DispatchFreecheck
|
|
ticketCount := this.module.configure.GetGlobalConf().DispatchNumoftimes
|
|
dis := &pb.DBDispatch{
|
|
Uid: uid,
|
|
Ticket: ticketCount,
|
|
Nb: &pb.Noticeboard{
|
|
Lv: 1, //公告初始升级
|
|
FreeCount: freeCount,
|
|
Tasks: tasks,
|
|
CreateTime: configure.Now().Unix(),
|
|
},
|
|
}
|
|
|
|
if err := this.Add(uid, dis); err != nil {
|
|
return nil
|
|
}
|
|
|
|
return dis.Nb
|
|
}
|
|
|
|
// 获取派遣数据
|
|
func (this *modelDispatch) getDBDispatch(uid string) (dis *pb.DBDispatch) {
|
|
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
|
|
}
|
|
|
|
// 获取任务权重数据
|
|
func (this *modelDispatch) getTasksWeight(uid string, noticeLv int32) []int32 {
|
|
dispatch := this.getDBDispatch(uid)
|
|
if dispatch == nil {
|
|
return []int32{}
|
|
}
|
|
|
|
if dispatch.Nb == nil {
|
|
return []int32{}
|
|
}
|
|
|
|
conf, err := this.module.configure.getDispatchLvConf(noticeLv)
|
|
if err != nil || conf == nil {
|
|
this.module.Error("配置不存在", log.Field{Key: "error", Value: err})
|
|
return []int32{}
|
|
}
|
|
|
|
items := make([]*comm.WeightItem, 0)
|
|
for i, v := range conf.Probability {
|
|
items = append(items, &comm.WeightItem{Id: (i + 1), Weight: int(v)})
|
|
}
|
|
|
|
wr := comm.NewWeightedRandom(items)
|
|
//任务类型
|
|
var taskType int
|
|
if c := wr.Pick(); c != nil {
|
|
taskType = c.Id.(int)
|
|
}
|
|
|
|
confList := this.module.configure.getDispatchListConf()
|
|
var tIds []int32
|
|
for _, v := range confList {
|
|
if int(v.Type) == taskType {
|
|
tIds = append(tIds, v.Id)
|
|
}
|
|
}
|
|
|
|
return tIds
|
|
}
|
|
|
|
// 随机任务
|
|
func (this *modelDispatch) taskRandom(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, err error) {
|
|
if dispatch.Nb.Lv == 0 {
|
|
dispatch.Nb.Lv = 1
|
|
}
|
|
|
|
conf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv)
|
|
if err != nil || conf == nil {
|
|
return nil, err
|
|
}
|
|
|
|
var items []*comm.WeightItem
|
|
for i, v := range conf.Probability {
|
|
items = append(items, &comm.WeightItem{Id: (i + 1), Weight: int(v)})
|
|
}
|
|
|
|
wr := comm.NewWeightedRandom(items)
|
|
//任务类型
|
|
var taskType int
|
|
if c := wr.Pick(); c != nil {
|
|
taskType = c.Id.(int)
|
|
}
|
|
|
|
confList := this.module.configure.getDispatchListConf()
|
|
var tIds []int32
|
|
for _, v := range confList {
|
|
if int(v.Type) == taskType {
|
|
tIds = append(tIds, v.Id)
|
|
}
|
|
}
|
|
|
|
//判断随机数量
|
|
var n int
|
|
n = len(dispatch.Nb.Tasks)
|
|
|
|
if n == 0 {
|
|
//随机6个任务
|
|
ids := utils.RandomNumbers(1, len(tIds), 6)
|
|
for _, id := range ids {
|
|
taskConf, err := this.module.configure.getDispatchTaskConf(int32(id))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
//公告持续截至时间
|
|
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
|
|
tasks = append(tasks, &pb.DispatchTask{
|
|
TaskId: int32(id),
|
|
Duration: duration,
|
|
})
|
|
}
|
|
} else {
|
|
tasks = dispatch.Nb.Tasks
|
|
var randCount int
|
|
for i := 0; i < len(tasks); i++ {
|
|
//只随机未接取的任务
|
|
if tasks[i].Status == 0 {
|
|
//删除
|
|
tasks = append(tasks[:i], tasks[i+1:]...)
|
|
i--
|
|
randCount++
|
|
} else {
|
|
tasks = append(tasks, tasks[i])
|
|
}
|
|
}
|
|
//追加随机
|
|
for i := 0; i < randCount; i++ {
|
|
task := this.addRandomTask(uid, dispatch)
|
|
if task != nil {
|
|
tasks = append(tasks, task)
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (this *modelDispatch) addRandomTask(uid string, dispatch *pb.DBDispatch) *pb.DispatchTask {
|
|
randomTaskIds := this.getTasksWeight(uid, dispatch.Nb.Lv)
|
|
if len(randomTaskIds) == 0 {
|
|
return nil
|
|
}
|
|
//追加一条随机任务
|
|
ids := utils.RandomNumbers(1, len(randomTaskIds), 1)
|
|
if len(ids) <= 0 {
|
|
return nil
|
|
}
|
|
taskId := ids[0]
|
|
taskConf, err := this.module.configure.getDispatchTaskConf(int32(taskId))
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
//公告持续截至时间
|
|
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
|
|
return &pb.DispatchTask{
|
|
TaskId: int32(taskId),
|
|
Duration: duration,
|
|
}
|
|
|
|
}
|
|
|
|
// 替换指定的已完成任务
|
|
func (this *modelDispatch) replaceTask(uid string, taskId int32, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, oldTask *pb.DispatchTask) {
|
|
tasks = dispatch.Nb.Tasks
|
|
var randCount int
|
|
for i := 0; i < len(tasks); i++ {
|
|
//替换状态是完成的任务
|
|
if tasks[i].Status == 2 {
|
|
if taskId != tasks[i].TaskId {
|
|
continue
|
|
}
|
|
oldTask = tasks[i]
|
|
//删除
|
|
tasks = append(tasks[:i], tasks[i+1:]...)
|
|
i--
|
|
randCount++
|
|
break
|
|
}
|
|
}
|
|
if randCount > 0 {
|
|
task := this.addRandomTask(uid, dispatch)
|
|
if task != nil {
|
|
tasks = append(tasks, task)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 替换所有完成的任务
|
|
func (this *modelDispatch) replaceFinishedTask(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, oldtasks []*pb.DispatchTask) {
|
|
var randCount int
|
|
tmp := dispatch.Nb.Tasks
|
|
for i := 0; i < len(tmp); i++ {
|
|
//替换状态是完成的任务
|
|
if tmp[i].Status == 2 {
|
|
//删除
|
|
oldtasks = append(oldtasks, tmp[i])
|
|
dispatch.Nb.Tasks = append(dispatch.Nb.Tasks[:i], dispatch.Nb.Tasks[i+1:]...)
|
|
i--
|
|
randCount++
|
|
} else {
|
|
tasks = append(tasks, tmp[i])
|
|
}
|
|
}
|
|
|
|
for i := 0; i < randCount; i++ {
|
|
task := this.addRandomTask(uid, dispatch)
|
|
if task != nil {
|
|
tasks = append(tasks, task)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 验证英雄的条件
|
|
func (this *modelDispatch) validHeroCond(uid string, taskId int32, heroId string) (ok1, ok2 bool, err error) {
|
|
//校验英雄是否已被派遣
|
|
dispatch := this.getDBDispatch(uid)
|
|
if dispatch == nil {
|
|
return
|
|
}
|
|
|
|
for _, v := range dispatch.Nb.Tasks {
|
|
for _, h := range v.HeroIds {
|
|
if h == heroId {
|
|
err = comm.NewCustomError(pb.ErrorCode_DispatchHeroAssigned)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
//taskConf
|
|
gd, err := this.module.configure.getDispatchTaskConf(taskId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
//获取英雄信息
|
|
hero, code := this.module.ModuleHero.GetHeroByObjID(uid, heroId)
|
|
|
|
if code == pb.ErrorCode_Success && hero != nil {
|
|
for _, v := range gd.Taskreq {
|
|
switch v.Key {
|
|
case 1: //校验英雄的基础条件
|
|
if hero.Lv >= v.Param {
|
|
ok1 = true
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, v := range gd.Taskreqex {
|
|
switch v.Key {
|
|
case 2: //校验英雄的额外要求
|
|
if hero.Star >= v.Param {
|
|
ok2 = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 派遣
|
|
func (this *modelDispatch) dispatch(uid string, taskId int32, heroIds []string, disp *pb.DBDispatch) error {
|
|
var flag bool //额外条件是否满足
|
|
for _, heroId := range heroIds {
|
|
if ok1, ok2, err := this.validHeroCond(uid, taskId, heroId); err == nil {
|
|
if !ok1 {
|
|
return comm.NewCustomError(pb.ErrorCode_DispatchHeroNoReached) //基础条件未满足
|
|
}
|
|
if ok2 {
|
|
flag = true
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, v := range disp.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": disp.Nb,
|
|
"ticket": disp.Ticket - 1,
|
|
}
|
|
if err := this.Change(uid, 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.TaskCount >= conf.Upgrade {
|
|
//判断是否有下一等级
|
|
nextConf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv + 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if nextConf != nil {
|
|
dispatch.Nb.Lv++
|
|
dispatch.Nb.TaskCount = 0
|
|
}
|
|
}
|
|
//累计任务数
|
|
dispatch.Nb.TaskCount++
|
|
dispatch.Nb.WeekCount++
|
|
}
|
|
}
|
|
|
|
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++
|
|
}
|
|
}
|
|
}
|
|
|
|
this.module.Debug("随机数量:", log.Field{Key: "count", Value: randCount})
|
|
count := len(dispatch.Nb.Tasks)
|
|
if count < 6 {
|
|
randCount = 6 - count
|
|
}
|
|
for i := 0; i < randCount; i++ {
|
|
task := this.addRandomTask(uid, dispatch)
|
|
if task != nil {
|
|
dispatch.Nb.Tasks = append(dispatch.Nb.Tasks, task)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|