修复跨服任务

This commit is contained in:
wh_zcy 2023-05-12 15:24:22 +08:00
parent 9b7f8f3ffe
commit b633b02b08
6 changed files with 153 additions and 134 deletions

View File

@ -160,6 +160,7 @@ var (
}, },
"dispatch": { "dispatch": {
common.MF(comm.ModuleDispatch, "dispatch"), common.MF(comm.ModuleDispatch, "dispatch"),
common.MF(comm.ModulePractice, "practice"),
}, },
"reputation": { "reputation": {
common.MF(comm.ModuleReputation, "reputation"), common.MF(comm.ModuleReputation, "reputation"),
@ -839,6 +840,13 @@ var (
SubType: "dispatch", SubType: "dispatch",
Enabled: true, Enabled: true,
}, },
common.MF(comm.ModulePractice, "practice"): {
NavLabel: "练功",
Desc: "练功",
MainType: string(comm.ModulePractice),
SubType: "practice",
Enabled: true,
},
// reputation // reputation
string(comm.ModuleReputation): { string(comm.ModuleReputation): {
NavLabel: "声望", NavLabel: "声望",

View File

@ -119,6 +119,7 @@ var (
common.MF(comm.ModuleSmithy, "customer"): &formview.SmithyView{}, common.MF(comm.ModuleSmithy, "customer"): &formview.SmithyView{},
//武馆派遣 //武馆派遣
common.MF(comm.ModuleDispatch, "dispatch"): &formview.DispatchView{}, common.MF(comm.ModuleDispatch, "dispatch"): &formview.DispatchView{},
common.MF(comm.ModulePractice, "practice"): &formview.PracticeView{},
//声望 //声望
common.MF(comm.ModuleReputation, "reputation"): &formview.ReputationView{}, common.MF(comm.ModuleReputation, "reputation"): &formview.ReputationView{},
//旧时光 //旧时光

View File

@ -0,0 +1,51 @@
package formview
import (
"go_dreamfactory/cmd/v2/model"
"go_dreamfactory/cmd/v2/service"
"go_dreamfactory/pb"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
"github.com/sirupsen/logrus"
"github.com/spf13/cast"
)
type PracticeView struct {
BaseformView
}
func (this *PracticeView) CreateView(t *model.TestCase) fyne.CanvasObject {
//英雄ID
heroId := widget.NewEntry()
//位置ID
index := widget.NewEntry()
form := widget.NewForm(
widget.NewFormItem("位置", index),
widget.NewFormItem("英雄", heroId),
)
form.OnSubmit = func() {
if err := service.GetPttService().SendToClient(
t.MainType,
"practice",
&pb.PracticePracticeReq{
Index: cast.ToInt32(index.Text),
Hero: heroId.Text,
},
); err != nil {
logrus.Error(err)
return
}
}
liangongBtn := widget.NewButton("练功", func() {
paiWin := dialog.NewCustom("练功", "关闭", form, this.w)
paiWin.Resize(fyne.NewSize(600, 300))
paiWin.Show()
})
layout := container.NewBorder(container.NewHBox(liangongBtn), nil, nil, nil)
return layout
}

View File

@ -6,8 +6,11 @@ import (
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
"go_dreamfactory/sys/db"
"github.com/pkg/errors" "github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx" "go.mongodb.org/mongo-driver/x/bsonx"
) )
@ -16,7 +19,6 @@ type ModelRtaskRecord struct {
modules.MCompModel modules.MCompModel
moduleRtask *ModuleRtask moduleRtask *ModuleRtask
service core.IService service core.IService
record *pb.DBRtaskRecord
} }
func (this *ModelRtaskRecord) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelRtaskRecord) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
@ -45,10 +47,40 @@ func (this *ModelRtaskRecord) GetVerifyData(uid string, condiId int32) (*pb.Rtas
// 配置表: rdtask_condi // 配置表: rdtask_condi
func (this *ModelRtaskRecord) getRecord(uid string) *pb.DBRtaskRecord { func (this *ModelRtaskRecord) getRecord(uid string) *pb.DBRtaskRecord {
record := &pb.DBRtaskRecord{} record := &pb.DBRtaskRecord{}
if err := this.Get(uid, record); err != nil { if this.moduleRtask.IsCross() {
if err != mongo.ErrNoDocuments { var (
log.Warnf("获取玩家任务条件 uid:%s err:%v", uid, err) stag string
conn *db.DBConn
err error
)
if stag, err = comm.UidToSTag(uid); err != nil {
return nil
}
if stag == this.service.GetTag() {
if conn, err = db.Local(); err != nil {
return nil
}
} else {
if conn, err = db.ServerDBConn(stag); err != nil {
return nil
}
}
model := db.NewDBModel(this.TableName, this.Expired, conn)
if model != nil {
model.Get(uid, record)
}
} else {
if err := this.Get(uid, record); err != nil {
if err == mongo.ErrNoDocuments {
record.Id = primitive.NewObjectID().Hex()
record.Ctime = configure.Now().Unix()
if err := this.Add(uid, record); err != nil {
log.Errorln(err)
return nil
}
}
} }
} }
return record return record
} }

View File

@ -12,15 +12,12 @@ import (
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs" cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db" "go_dreamfactory/sys/db"
"go_dreamfactory/utils" "go_dreamfactory/utils"
"sync" "sync"
"github.com/pkg/errors" "github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
) )
var _ comm.IRtask = (*ModuleRtask)(nil) var _ comm.IRtask = (*ModuleRtask)(nil)
@ -35,7 +32,7 @@ type rtaskCondHandle struct {
type verifyHandle func(uid string, cfg *cfg.GameRdtaskCondiData) (bool, error) type verifyHandle func(uid string, cfg *cfg.GameRdtaskCondiData) (bool, error)
type condiFindHandle func(cfg *cfg.GameRdtaskCondiData, vals ...int32) (int32, error) type condiFindHandle func(cfg *cfg.GameRdtaskCondiData, vals ...int32) (int32, error)
type updateDataHandle func(uid string, cfg *cfg.GameRdtaskCondiData, vals ...int32) error type updateDataHandle func(uid string, record *pb.DBRtaskRecord, cfg *cfg.GameRdtaskCondiData, vals ...int32) error
type ModuleRtask struct { type ModuleRtask struct {
modules.ModuleBase modules.ModuleBase
@ -45,7 +42,6 @@ type ModuleRtask struct {
api *apiComp api *apiComp
configure *configureComp configure *configureComp
handleMap sync.Map //map[int32]*rtaskCondi //任务校验处理器 handleMap sync.Map //map[int32]*rtaskCondi //任务校验处理器
condIds []int32
} }
func NewModule() core.IModule { func NewModule() core.IModule {
@ -270,11 +266,15 @@ func (this *ModuleRtask) getHandle(tt comm.TaskType) (condis []*rtaskCondHandle)
return return
} }
// 处理触发的任务 // 处理触发的任务
func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType comm.TaskType, params ...int32) (code pb.ErrorCode) { func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType comm.TaskType, params ...int32) (code pb.ErrorCode) {
uid := session.GetUserId() uid := session.GetUserId()
var handles []*rtaskCondHandle var (
handles []*rtaskCondHandle
condIds []int32
)
if this.IsCross() { if this.IsCross() {
//随机任务 //随机任务
@ -283,14 +283,17 @@ func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType com
session.GetServiecTag(), session.GetServiecTag(),
comm.Service_Worker, comm.Service_Worker,
string(comm.Rpc_ModuleRtaskSendTask), string(comm.Rpc_ModuleRtaskSendTask),
pb.RPCRTaskReq{Uid: uid, TaskType: int32(rtaskType), Param: params}, &pb.RPCRTaskReq{Uid: uid, TaskType: int32(rtaskType), Param: params},
nil); err != nil { nil); err != nil {
log.Errorln(err) log.Errorln(err)
} }
return return
} }
record := this.modelRtaskRecord.getRecord(uid)
handles = this.getHandle(rtaskType) handles = this.getHandle(rtaskType)
// update // update
for _, handle := range handles { for _, handle := range handles {
conf, err := this.configure.getRtaskTypeById(handle.condId) conf, err := this.configure.getRtaskTypeById(handle.condId)
@ -301,76 +304,29 @@ func (this *ModuleRtask) processOneTask(session comm.IUserSession, rtaskType com
} }
if handle.update != nil { if handle.update != nil {
if err := handle.update(uid, conf, params...); err != nil { if err := handle.update(uid, record, conf, params...); err != nil {
log.Errorf("update task:%v", err) log.Errorf("update task:%v", err)
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
return return
} }
this.condIds = append(this.condIds, conf.Id)
} }
} condIds = append(condIds, handle.condId)
return
}
func (this *ModuleRtask) TriggerTask(uid string, taskParams ...*comm.TaskParam) {
session, ok := this.GetUserSession(uid)
if !ok {
return
}
lock, _ := this.modelRtask.userlock(uid)
err := lock.Lock()
if err != nil {
this.Error("TriggerTask userlock err!", log.Field{Key: "err", Value: err.Error()})
}
defer func() {
this.condIds = []int32{}
lock.Unlock()
}()
record := &pb.DBRtaskRecord{Uid: uid}
if err := this.modelRtaskRecord.Get(uid, record); err != nil {
if err == mongo.ErrNoDocuments {
record.Id = primitive.NewObjectID().Hex()
record.Ctime = configure.Now().Unix()
if err := this.modelRtaskRecord.Add(uid, record); err != nil {
log.Errorln(err)
return
}
}
}
this.modelRtaskRecord.record = record
for _, tp := range taskParams {
this.Debug("任务触发",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "type", Value: tp.TT},
log.Field{Key: "params", Value: tp.Params})
code := this.processOneTask(session, tp.TT, tp.Params...)
if code != pb.ErrorCode_Success {
// this.Error("任务处理", log.Field{Key: "uid", Value: uid}, log.Field{Key: "code", Value: code})
}
comm.PuttaskParam(tp)
} }
update := map[string]interface{}{ update := map[string]interface{}{
"vals": this.modelRtaskRecord.record.Vals, "vals": record.Vals,
} }
this.modelRtaskRecord.Change(uid, update) this.modelRtaskRecord.Change(uid, update)
for _, condId := range this.condIds { for _, condId := range condIds {
//任务完成则推送 if code = this.CheckCondi(uid, condId); code == pb.ErrorCode_Success {
if code := this.CheckCondi(uid, condId); code == pb.ErrorCode_Success {
module, err := this.service.GetModule(comm.ModuleWorldtask) module, err := this.service.GetModule(comm.ModuleWorldtask)
if err == nil { if err == nil {
//世界任务
if worldtask, ok := module.(comm.IWorldtask); ok { if worldtask, ok := module.(comm.IWorldtask); ok {
if err := worldtask.TaskCondFinishNotify(session, condId); err != nil { if err := worldtask.TaskCondFinishNotify(session, condId); err != nil {
log.Error("任务条件达成通知", log.Error("世界任务条件达成通知",
log.Field{Key: "uid", Value: uid}, log.Field{Key: "uid", Value: uid},
log.Field{Key: "condId", Value: condId}, log.Field{Key: "condId", Value: condId},
log.Field{Key: "err", Value: err.Error()}, log.Field{Key: "err", Value: err.Error()},
@ -404,6 +360,35 @@ func (this *ModuleRtask) TriggerTask(uid string, taskParams ...*comm.TaskParam)
} }
} }
} }
return
}
func (this *ModuleRtask) TriggerTask(uid string, taskParams ...*comm.TaskParam) {
session, ok := this.GetUserSession(uid)
if !ok {
return
}
lock, _ := this.modelRtask.userlock(uid)
err := lock.Lock()
if err != nil {
this.Error("TriggerTask userlock err!", log.Field{Key: "err", Value: err.Error()})
}
defer lock.Unlock()
for _, tp := range taskParams {
this.Debug("任务触发",
log.Field{Key: "uid", Value: uid},
log.Field{Key: "type", Value: tp.TT},
log.Field{Key: "params", Value: tp.Params})
code := this.processOneTask(session, tp.TT, tp.Params...)
if code != pb.ErrorCode_Success {
// this.Error("任务处理失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "code", Value: code})
}
comm.PuttaskParam(tp)
}
session.Push() session.Push()
this.PutUserSession(session) this.PutUserSession(session)
@ -472,7 +457,7 @@ type TaskProcessResp struct {
// 接收区服worker发起的秘境事件 // 接收区服worker发起的秘境事件
func (this *ModuleRtask) Rpc_ModuleRtaskSendTask(ctx context.Context, args *pb.RPCRTaskReq, reply *pb.EmptyResp) (err error) { func (this *ModuleRtask) Rpc_ModuleRtaskSendTask(ctx context.Context, args *pb.RPCRTaskReq, reply *pb.EmptyResp) (err error) {
this.Debug("Rpc_ModuleRtaskSendTask", this.Debug("Rpc_ModuleRtaskSendTask",
log.Field{Key: "args", Value: args.String()}, log.Field{Key: "args", Value: args},
) )
if args.Uid == "" { if args.Uid == "" {
err = errors.New("参数异常!") err = errors.New("参数异常!")

View File

@ -8,106 +8,48 @@ import (
) )
// 覆盖更新 // 覆盖更新
func (this *ModelRtaskRecord) overrideUpdate(uid string, cfg *cfg.GameRdtaskCondiData, vals ...int32) (err error) { func (this *ModelRtaskRecord) overrideUpdate(uid string, record *pb.DBRtaskRecord, cfg *cfg.GameRdtaskCondiData, vals ...int32) (err error) {
var paramLen int var paramLen int
if paramLen, err = lenParam(cfg, vals...); err != nil { if paramLen, err = lenParam(cfg, vals...); err != nil {
return err return err
} }
// record := &pb.DBRtaskRecord{Uid: uid} if record.Vals == nil {
// if err := this.Get(uid, record); err != nil { record.Vals = make(map[int32]*pb.RtaskData)
// if err == mongo.ErrNoDocuments {
// record.Id = primitive.NewObjectID().Hex()
// record.Ctime = configure.Now().Unix()
// if err := this.Add(uid, record); err != nil {
// return errors.Wrapf(err, "创建玩家任务记录 err: %v rtype[%v]", uid, cfg.Id)
// }
// } else {
// return errors.Wrapf(err, "获取玩家任务记录 err: %v rtype[%v]", uid, cfg.Id)
// }
// }
if this.record.Vals == nil {
this.record.Vals = make(map[int32]*pb.RtaskData)
} }
if v, ok := this.record.Vals[cfg.Id]; ok { if v, ok := record.Vals[cfg.Id]; ok {
v.Data = hasUpdateData(paramLen, v, vals...) v.Data = hasUpdateData(paramLen, v, vals...)
// if len(v.Data) > 0 {
// update := map[string]interface{}{
// "vals": record.Vals,
// }
// if err = this.Change(uid, update); err != nil {
// this.moduleRtask.Error("更新失败",
// log.Field{Key: "uid", Value: uid},
// log.Field{Key: "update", Value: update})
// return
// }
// }
} else { } else {
data := &pb.RtaskData{ data := &pb.RtaskData{
Rtype: cfg.Type, Rtype: cfg.Type,
Data: toMap(vals...), Data: toMap(vals...),
Timestamp: configure.Now().Unix(), Timestamp: configure.Now().Unix(),
} }
this.record.Vals[cfg.Id] = data record.Vals[cfg.Id] = data
// update := map[string]interface{}{
// "vals": record.Vals,
// }
// if err = this.Change(uid, update); err != nil {
// this.moduleRtask.Error("更新失败",
// log.Field{Key: "uid", Value: uid},
// log.Field{Key: "update", Value: update})
// return
// }
} }
return return
} }
// 累计更新 - 招募等 // 累计更新 - 招募等
func (this *ModelRtaskRecord) addUpdate(uid string, cfg *cfg.GameRdtaskCondiData, vals ...int32) (err error) { func (this *ModelRtaskRecord) addUpdate(uid string, record *pb.DBRtaskRecord, cfg *cfg.GameRdtaskCondiData, vals ...int32) (err error) {
// record := &pb.DBRtaskRecord{Uid: uid} if record.Vals == nil {
// err = this.Get(uid, record) record.Vals = make(map[int32]*pb.RtaskData)
// if err != nil {
// if err == mongo.ErrNoDocuments {
// record.Id = primitive.NewObjectID().Hex()
// record.Ctime = configure.Now().Unix()
// if err := this.Add(uid, record); err != nil {
// return errors.Wrapf(err, "创建玩家任务记录 err: %v rtype[%v]", uid, cfg.Id)
// }
// } else {
// return errors.Wrapf(err, "获取玩家任务记录 err: %v rtype[%v]", uid, cfg.Id)
// }
// }
if this.record.Vals == nil {
this.record.Vals = make(map[int32]*pb.RtaskData)
} }
//查找任务数据 //查找任务数据
if v, ok := this.record.Vals[cfg.Id]; ok { if v, ok := record.Vals[cfg.Id]; ok {
newArr := make([]int32, len(vals)) newArr := make([]int32, len(vals))
copy(newArr, vals) copy(newArr, vals)
srcCount := v.Data[0] srcCount := v.Data[0]
newArr[0] = srcCount + vals[0] newArr[0] = srcCount + vals[0]
v.Data = toMap(newArr...) v.Data = toMap(newArr...)
v.Timestamp = configure.Now().Unix() v.Timestamp = configure.Now().Unix()
// update := map[string]interface{}{
// "vals": record.Vals,
// }
// err = this.Change(uid, update)
} else { } else {
this.record.Vals[cfg.Id] = &pb.RtaskData{ record.Vals[cfg.Id] = &pb.RtaskData{
Data: toMap(vals...), Data: toMap(vals...),
Rtype: cfg.Type, Rtype: cfg.Type,
Timestamp: configure.Now().Unix(), Timestamp: configure.Now().Unix(),
} }
// update := map[string]interface{}{
// "vals": record.Vals,
// }
// err = this.Change(uid, update)
} }
return return
} }