898 lines
26 KiB
Go
898 lines
26 KiB
Go
package buried
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
"go_dreamfactory/sys/db"
|
|
"go_dreamfactory/utils"
|
|
"time"
|
|
)
|
|
|
|
/*
|
|
模块名:用户埋点完成条件触发系统
|
|
模块描述:用户埋点数据中心管理模块
|
|
开发人员:李伟
|
|
*/
|
|
|
|
const moduleName = "埋点统计中心"
|
|
|
|
type Buried struct {
|
|
modules.ModuleBase
|
|
service comm.IService
|
|
wtask comm.IWtask //世界任务
|
|
smithy comm.ISmithy //铁匠朴
|
|
sociaty comm.ISociaty //工会
|
|
api *apiComp
|
|
configure *configureComp
|
|
modelBuried *modelBuried
|
|
}
|
|
|
|
func NewModule() core.IModule {
|
|
return &Buried{}
|
|
}
|
|
|
|
func (this *Buried) GetType() core.M_Modules {
|
|
return comm.ModuleBuried
|
|
}
|
|
|
|
func (this *Buried) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
|
if err = this.ModuleBase.Init(service, module, options); err != nil {
|
|
return
|
|
}
|
|
this.service = service.(comm.IService)
|
|
return
|
|
}
|
|
|
|
func (this *Buried) Start() (err error) {
|
|
if err = this.ModuleBase.Start(); err != nil {
|
|
return
|
|
}
|
|
|
|
var module core.IModule
|
|
if module, err = this.service.GetModule(comm.ModuleWtask); err != nil {
|
|
return
|
|
}
|
|
this.wtask = module.(comm.IWtask)
|
|
if module, err = this.service.GetModule(comm.ModuleSmithy); err != nil {
|
|
return
|
|
}
|
|
this.smithy = module.(comm.ISmithy)
|
|
if module, err = this.service.GetModule(comm.ModuleSociaty); err != nil {
|
|
return
|
|
}
|
|
this.sociaty = module.(comm.ISociaty)
|
|
this.service.RegisterFunctionName(string(comm.Rpc_ModuleBuriedTrigger), this.Rpc_ModuleBuriedTrigger)
|
|
return
|
|
}
|
|
|
|
// 装备组件
|
|
func (this *Buried) OnInstallComp() {
|
|
this.ModuleBase.OnInstallComp()
|
|
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
|
|
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
|
|
this.modelBuried = this.RegisterComp(new(modelBuried)).(*modelBuried)
|
|
}
|
|
|
|
// 跨服埋点触发
|
|
func (this *Buried) Rpc_ModuleBuriedTrigger(ctx context.Context, req *pb.Rpc_ModuleBuriedTriggerReq, reply *pb.Rpc_ModuleBuriedTriggerResp) (err error) {
|
|
this.Debug("跨服埋点触发!", log.Field{Key: "uid", Value: req.UserId}, log.Field{Key: "burieds", Value: req.Burieds})
|
|
session := this.service.GetUserSession()
|
|
session.SetSession(req.Ip, req.UserSessionId, req.ServiceTag, req.GatewayServiceId, req.UserId, req.Group)
|
|
this.trigger(session, req.Burieds...)
|
|
session.Push()
|
|
this.service.PutUserSession(session)
|
|
return
|
|
}
|
|
|
|
//完成任务
|
|
func (this *Buried) CompleteCondition(session comm.IUserSession, condiIds ...int32) (err error) {
|
|
var (
|
|
uid string
|
|
model *buriedModel
|
|
bdatas *pb.DBBuried
|
|
bitem *pb.DBBuriedConItem
|
|
conf *cfg.GameBuriedCondiData
|
|
ok bool
|
|
bdata *pb.DBBuriedItem
|
|
progress []*pb.ConIProgress
|
|
)
|
|
uid = session.GetUserId()
|
|
if model, err = this.modelBuried.getburiedModel(uid); err != nil {
|
|
return
|
|
}
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
return
|
|
}
|
|
this.Debug("完成埋点!", log.Field{Key: "condiIds", Value: condiIds})
|
|
lock, _ := model.userlock(uid)
|
|
err = lock.Lock()
|
|
if err != nil {
|
|
this.Error("埋点分布式锁失效 err!", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
defer lock.Unlock()
|
|
for _, condiId := range condiIds {
|
|
if conf, err = this.configure.getburiedcondidata(condiId); err != nil {
|
|
return
|
|
}
|
|
if bdata, ok = bdatas.Items[conf.Type]; ok {
|
|
ok = false
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Conid == condiId {
|
|
ok = true
|
|
if v1.Finish != pb.BuriedItemFinishState_buried_finish {
|
|
if conf.Ctype == ctype_once { //完成后自动锁定
|
|
v1.State = pb.BuriedItemState_Freeze
|
|
} else if conf.Ctype == ctype_repeat {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_daily {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_weekly {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
}
|
|
v1.Value = conf.Value
|
|
v1.Finish = pb.BuriedItemFinishState_buried_finish
|
|
progress = append(progress, comm.GetBuriedConIProgress(conf, v1))
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
bdata = &pb.DBBuriedItem{
|
|
Btype: conf.Type,
|
|
Condi: make([]*pb.DBBuriedConItem, 0),
|
|
}
|
|
bdatas.Items[conf.Type] = bdata
|
|
}
|
|
if !ok { //未找到 初始化一个
|
|
bitem = &pb.DBBuriedConItem{
|
|
Conid: condiId,
|
|
State: pb.BuriedItemState_Activated,
|
|
Value: conf.Value,
|
|
Statistics: make([]string, 0),
|
|
Timestamp: time.Now().Unix(),
|
|
Finish: pb.BuriedItemFinishState_buried_finish,
|
|
}
|
|
if conf.Ctype == ctype_once { //完成后自动锁定
|
|
bitem.State = pb.BuriedItemState_Freeze
|
|
} else if conf.Ctype == ctype_repeat {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_daily {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_weekly {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
}
|
|
bdata.Condi = append(bdata.Condi, bitem)
|
|
progress = append(progress, comm.GetBuriedConIProgress(conf, bitem))
|
|
}
|
|
}
|
|
|
|
if err = model.updateUserBurieds(uid, bdatas); err != nil {
|
|
this.Error("更新用户埋点数据错误!", log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
session.SendMsg(string(this.GetType()), "change", &pb.BuriedChangePush{Conitems: progress})
|
|
return
|
|
}
|
|
|
|
// 激活数据采集点
|
|
func (this *Buried) ActiveCondition(session comm.IUserSession, condiIds ...int32) (errdata *pb.ErrorData) {
|
|
var (
|
|
uid string
|
|
conf *cfg.GameBuriedCondiData
|
|
bdatas *pb.DBBuried
|
|
model *buriedModel
|
|
bdata *pb.DBBuriedItem
|
|
ok bool
|
|
chanage bool
|
|
err error
|
|
)
|
|
uid = session.GetUserId()
|
|
if model, err = this.modelBuried.getburiedModel(uid); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.String(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
this.Debug("激活埋点!", log.Field{Key: "condiIds", Value: condiIds})
|
|
lock, _ := model.userlock(uid)
|
|
err = lock.Lock()
|
|
if err != nil {
|
|
this.Error("埋点分布式锁失效 err!", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_CacheReadError,
|
|
Title: pb.ErrorCode_CacheReadError.String(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
defer lock.Unlock()
|
|
for _, v := range condiIds {
|
|
if v == 0 {
|
|
continue
|
|
}
|
|
if conf, err = this.configure.getburiedcondidata(v); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_ConfigNoFound,
|
|
Title: pb.ErrorCode_ConfigNoFound.String(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
if conf.Rtype != rtype2 { //非接取任务 不处理
|
|
continue
|
|
}
|
|
if bdatas == nil { //放在后面 可以减少网络io
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Title: pb.ErrorCode_DBError.String(),
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
if bdata, ok = bdatas.Items[conf.Type]; ok {
|
|
ok = false
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Conid == v {
|
|
ok = true
|
|
v1.Value = 0
|
|
v1.Statistics = make([]string, 0)
|
|
v1.Timestamp = time.Now().Unix()
|
|
v1.State = pb.BuriedItemState_Activated
|
|
chanage = true
|
|
break
|
|
}
|
|
}
|
|
|
|
} else {
|
|
bdata = &pb.DBBuriedItem{
|
|
Btype: conf.Type,
|
|
Condi: make([]*pb.DBBuriedConItem, 0),
|
|
}
|
|
bdatas.Items[conf.Type] = bdata
|
|
}
|
|
if !ok {
|
|
bdata.Condi = append(bdata.Condi, &pb.DBBuriedConItem{
|
|
Conid: v,
|
|
State: pb.BuriedItemState_Activated,
|
|
Value: 0,
|
|
Statistics: make([]string, 0),
|
|
Finish: pb.BuriedItemFinishState_buried_unfinish,
|
|
Timestamp: time.Now().Unix(),
|
|
})
|
|
chanage = true
|
|
}
|
|
}
|
|
if chanage {
|
|
err = model.updateUserBurieds(uid, bdatas)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 重置所有对应的子任务 按埋点类型
|
|
func (this *Buried) ResetBuriedByType(session comm.IUserSession, types ...comm.TaskType) (err error) {
|
|
var (
|
|
uid string
|
|
bdatas *pb.DBBuried
|
|
model *buriedModel
|
|
bdata *pb.DBBuriedItem
|
|
ok bool
|
|
chanage bool
|
|
)
|
|
uid = session.GetUserId()
|
|
if model, err = this.modelBuried.getburiedModel(uid); err != nil {
|
|
return
|
|
}
|
|
this.Debug("重置埋点!", log.Field{Key: "types", Value: types})
|
|
lock, _ := this.modelBuried.userlock(uid)
|
|
err = lock.Lock()
|
|
if err != nil {
|
|
this.Error("埋点分布式锁失效 err!", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
defer lock.Unlock()
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
return
|
|
}
|
|
for _, v := range types {
|
|
if bdata, ok = bdatas.Items[int32(v)]; ok {
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Value != 0 && v1.Finish != pb.BuriedItemFinishState_buried_finish {
|
|
v1.Value = 0
|
|
v1.Statistics = make([]string, 0)
|
|
v1.Timestamp = time.Now().Unix()
|
|
v1.State = pb.BuriedItemState_Activated
|
|
chanage = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if chanage {
|
|
err = model.updateUserBurieds(uid, bdatas)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 激活数据采集点
|
|
func (this *Buried) CheckCondition(session comm.IUserSession, condiIds ...int32) (ok bool, condis []*pb.ConIProgress, err error) {
|
|
var (
|
|
uid string
|
|
model *buriedModel
|
|
bdatas *pb.DBBuried
|
|
conf *cfg.GameBuriedCondiData
|
|
bdata *pb.DBBuriedItem
|
|
)
|
|
uid = session.GetUserId()
|
|
if model, err = this.modelBuried.getburiedModel(uid); err != nil {
|
|
return
|
|
}
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
return
|
|
}
|
|
condis = make([]*pb.ConIProgress, 0)
|
|
for _, v := range condiIds {
|
|
if v == 0 {
|
|
continue
|
|
}
|
|
if conf, err = this.configure.getburiedcondidata(v); err != nil {
|
|
return
|
|
}
|
|
if bdata, ok = bdatas.Items[conf.Type]; ok {
|
|
ok = false
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Conid == v {
|
|
ok = true
|
|
//状态等于休眠
|
|
if conf.Ctype == ctype_daily { //日常
|
|
if !utils.IsToday(v1.Timestamp) { //不是同一天 可以重置数据
|
|
v1.State = pb.BuriedItemState_Activated
|
|
v1.Value = 0
|
|
v1.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
} else if conf.Ctype == ctype_weekly { //周常
|
|
if !utils.IsSameWeek(v1.Timestamp) { //不是同一周
|
|
v1.State = pb.BuriedItemState_Activated
|
|
v1.Value = 0
|
|
v1.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
}
|
|
condis = append(condis, &pb.ConIProgress{
|
|
Btype: conf.Type,
|
|
Conid: v1.Conid,
|
|
Value: v1.Value,
|
|
Target: conf.Value,
|
|
State: v1.Finish,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
if !ok { //未找到 初始化一个
|
|
condis = append(condis, &pb.ConIProgress{
|
|
Btype: conf.Type,
|
|
Conid: v,
|
|
Value: 0,
|
|
Target: conf.Value,
|
|
State: pb.BuriedItemFinishState_buried_unfinish,
|
|
})
|
|
}
|
|
ok = true
|
|
for _, v := range condis {
|
|
if v.State == pb.BuriedItemFinishState_buried_unfinish {
|
|
ok = false
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 设置任务完成状态并校验
|
|
func (this *Buried) FinishConditionAndCheck(session comm.IUserSession, finishcondiIds []int32, condiIds ...int32) (condis []*pb.ConIProgress, err error) {
|
|
var (
|
|
uid string
|
|
model *buriedModel
|
|
bdatas *pb.DBBuried
|
|
bitem *pb.DBBuriedConItem
|
|
conf *cfg.GameBuriedCondiData
|
|
ok bool
|
|
chanage bool
|
|
progress []*pb.ConIProgress
|
|
bdata *pb.DBBuriedItem
|
|
)
|
|
uid = session.GetUserId()
|
|
if model, err = this.modelBuried.getburiedModel(uid); err != nil {
|
|
return
|
|
}
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
return
|
|
}
|
|
|
|
this.Debug("完成埋点!", log.Field{Key: "finishcondiIds", Value: finishcondiIds})
|
|
lock, _ := model.userlock(uid)
|
|
err = lock.Lock()
|
|
if err != nil {
|
|
this.Error("埋点分布式锁失效 err!", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
defer lock.Unlock()
|
|
|
|
condis = make([]*pb.ConIProgress, 0)
|
|
for _, v := range finishcondiIds {
|
|
if v == 0 {
|
|
continue
|
|
}
|
|
if conf, err = this.configure.getburiedcondidata(v); err != nil {
|
|
return
|
|
}
|
|
if bdata, ok = bdatas.Items[conf.Type]; ok {
|
|
ok = false
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Conid == v {
|
|
ok = true
|
|
if v1.Finish != pb.BuriedItemFinishState_buried_finish {
|
|
if conf.Ctype == ctype_once { //完成后自动锁定
|
|
v1.State = pb.BuriedItemState_Freeze
|
|
} else if conf.Ctype == ctype_repeat {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_daily {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_weekly {
|
|
v1.State = pb.BuriedItemState_Sleep
|
|
}
|
|
v1.Value = conf.Value
|
|
v1.Finish = pb.BuriedItemFinishState_buried_finish
|
|
chanage = true
|
|
progress = append(progress, comm.GetBuriedConIProgress(conf, v1))
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
bdata = &pb.DBBuriedItem{
|
|
Btype: conf.Type,
|
|
Condi: make([]*pb.DBBuriedConItem, 0),
|
|
}
|
|
bdatas.Items[conf.Type] = bdata
|
|
}
|
|
if !ok { //未找到 初始化一个
|
|
bitem = &pb.DBBuriedConItem{
|
|
Conid: v,
|
|
State: pb.BuriedItemState_Activated,
|
|
Value: conf.Value,
|
|
Statistics: make([]string, 0),
|
|
Timestamp: time.Now().Unix(),
|
|
Finish: pb.BuriedItemFinishState_buried_finish,
|
|
}
|
|
if conf.Ctype == ctype_once { //完成后自动锁定
|
|
bitem.State = pb.BuriedItemState_Freeze
|
|
} else if conf.Ctype == ctype_repeat {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_daily {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if conf.Ctype == ctype_weekly {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
}
|
|
bdata.Condi = append(bdata.Condi, bitem)
|
|
chanage = true
|
|
progress = append(progress, comm.GetBuriedConIProgress(conf, bitem))
|
|
}
|
|
}
|
|
|
|
for _, v := range condiIds {
|
|
if v == 0 {
|
|
continue
|
|
}
|
|
if conf, err = this.configure.getburiedcondidata(v); err != nil {
|
|
return
|
|
}
|
|
if bdata, ok := bdatas.Items[conf.Type]; ok {
|
|
ok = false
|
|
for _, v1 := range bdata.Condi {
|
|
if v1.Conid == v {
|
|
ok = true
|
|
//状态等于休眠
|
|
if conf.Ctype == ctype_daily { //日常
|
|
if !utils.IsToday(v1.Timestamp) { //不是同一天 可以重置数据
|
|
v1.State = pb.BuriedItemState_Activated
|
|
v1.Value = 0
|
|
v1.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
} else if conf.Ctype == ctype_weekly { //周常
|
|
if !utils.IsSameWeek(v1.Timestamp) { //不是同一周
|
|
v1.State = pb.BuriedItemState_Activated
|
|
v1.Value = 0
|
|
v1.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
}
|
|
condis = append(condis, &pb.ConIProgress{
|
|
Btype: conf.Type,
|
|
Conid: v1.Conid,
|
|
Value: v1.Value,
|
|
Target: conf.Value,
|
|
State: v1.Finish,
|
|
})
|
|
}
|
|
}
|
|
if !ok { //未找到 初始化一个
|
|
condis = append(condis, &pb.ConIProgress{
|
|
Btype: conf.Type,
|
|
Conid: v,
|
|
Value: 0,
|
|
Target: conf.Value,
|
|
State: pb.BuriedItemFinishState_buried_unfinish,
|
|
})
|
|
}
|
|
} else { //未找到 初始化一个
|
|
condis = append(condis, &pb.ConIProgress{
|
|
Btype: conf.Type,
|
|
Conid: v,
|
|
Value: 0,
|
|
Target: conf.Value,
|
|
State: pb.BuriedItemFinishState_buried_unfinish,
|
|
})
|
|
}
|
|
}
|
|
|
|
if chanage {
|
|
if err = model.updateUserBurieds(uid, bdatas); err != nil {
|
|
this.Error("更新用户埋点数据错误!", log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
session.SendMsg(string(this.GetType()), "change", &pb.BuriedChangePush{Conitems: progress})
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 触发埋点
|
|
func (this *Buried) TriggerBuried(session comm.IUserSession, burieds ...*pb.BuriedParam) {
|
|
|
|
if db.IsCross() {
|
|
var (
|
|
stag string
|
|
err error
|
|
)
|
|
if stag, err = comm.UidToSTag(session.GetUserId()); err != nil {
|
|
this.Error("远程触发埋点错误!", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
if err = this.service.AcrossClusterRpcCall(
|
|
context.Background(),
|
|
stag,
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleBuriedTrigger),
|
|
pb.Rpc_ModuleBuriedTriggerReq{
|
|
Ip: session.GetIP(),
|
|
UserSessionId: session.GetSessionId(),
|
|
ServiceTag: session.GetServiecTag(),
|
|
GatewayServiceId: session.GetGatewayServiceId(),
|
|
UserId: session.GetUserId(),
|
|
Burieds: burieds,
|
|
},
|
|
nil); err != nil {
|
|
this.Error("远程触发埋点错误!", log.Field{Key: "burieds", Value: burieds}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
} else {
|
|
this.trigger(session, burieds...)
|
|
}
|
|
// session.Push()
|
|
// this.service.PutUserSession(session)
|
|
}
|
|
|
|
func (this *Buried) trigger(session comm.IUserSession, burieds ...*pb.BuriedParam) {
|
|
var (
|
|
model *buriedModel
|
|
pass map[*pb.BuriedParam][]*cfg.GameBuriedCondiData = make(map[*pb.BuriedParam][]*cfg.GameBuriedCondiData)
|
|
bconf *cfg.GameBuriedTypeData
|
|
bdatas *pb.DBBuried
|
|
bdata *pb.DBBuriedItem
|
|
bitem *pb.DBBuriedConItem
|
|
ok bool
|
|
change bool
|
|
changes []*pb.ConIProgress
|
|
notify map[string][]*pb.ConIProgress
|
|
module core.IModule
|
|
nmodule comm.IBuriedUpdateNotify
|
|
err error
|
|
)
|
|
if model, err = this.modelBuried.getburiedModel(session.GetUserId()); err != nil {
|
|
return
|
|
}
|
|
|
|
this.Debug("触发埋点!", log.Field{Key: "burieds", Value: burieds})
|
|
lock, _ := model.userlock(session.GetUserId())
|
|
err = lock.Lock()
|
|
if err != nil {
|
|
this.Error("埋点分布式锁失效 err!", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
defer lock.Unlock()
|
|
|
|
for _, buried := range burieds {
|
|
conds := this.configure.getCondiDatas(buried.TaskType)
|
|
if bconf, err = this.configure.getburiedtypedata(buried.TaskType); err != nil {
|
|
this.Error("未找到目标埋点类型配置", log.Field{Key: "type", Value: buried.TaskType})
|
|
continue
|
|
}
|
|
for _, cond := range conds {
|
|
if this.checkburied(buried, bconf, cond) { //判断此埋点数据是否有效
|
|
if _, ok := pass[buried]; !ok {
|
|
pass[buried] = make([]*cfg.GameBuriedCondiData, 0)
|
|
}
|
|
pass[buried] = append(pass[buried], cond)
|
|
this.Debug("校验通过埋点条件!", log.Field{Key: "埋点id", Value: buried.TaskType}, log.Field{Key: "条件id", Value: cond.Id})
|
|
}
|
|
}
|
|
}
|
|
if len(pass) > 0 {
|
|
if ok, mate := session.GetMate(comm.Session_Buried); ok {
|
|
bdatas = mate.(*pb.DBBuried)
|
|
} else {
|
|
if bdatas, err = model.getSessionBuried(session); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
notify = make(map[string][]*pb.ConIProgress)
|
|
changes = make([]*pb.ConIProgress, 0)
|
|
//处理校验通过埋点数据
|
|
for buried, conds := range pass {
|
|
this.Debug("更新埋点数据", log.Field{Key: "埋点类型", Value: buried.TaskType})
|
|
if bconf, err = this.configure.getburiedtypedata(buried.TaskType); err != nil {
|
|
this.Error("未找到目标埋点类型配置", log.Field{Key: "type", Value: buried.TaskType})
|
|
continue
|
|
}
|
|
if bdata, ok = bdatas.Items[int32(buried.TaskType)]; !ok {
|
|
bdatas.Items[int32(buried.TaskType)] = &pb.DBBuriedItem{
|
|
Btype: int32(buried.TaskType),
|
|
Condi: make([]*pb.DBBuriedConItem, 0),
|
|
}
|
|
bdata = bdatas.Items[int32(buried.TaskType)]
|
|
}
|
|
for _, cond := range conds {
|
|
this.Debug("更新埋点数据", log.Field{Key: "埋点类型", Value: buried.TaskType}, log.Field{Key: "条件类型", Value: cond.Id})
|
|
autoActivated := false
|
|
if cond.Rtype == rtype1 { //创号后入录
|
|
autoActivated = true
|
|
} else if cond.Rtype == rtype2 { //任务接取后才会录入 判断用户埋点数据是否存在 不存在等待任务系统调用接口 ActivationBuried 激活
|
|
autoActivated = false
|
|
} else {
|
|
this.Error("未知的任务类型", log.Field{Key: "埋点类型", Value: buried.TaskType}, log.Field{Key: "条件Id", Value: cond.Id}, log.Field{Key: "条件类型", Value: cond.Rtype})
|
|
continue
|
|
}
|
|
if change, bitem, err = this.updateAndCheckBuried(bconf, bdata, buried, cond, autoActivated); change {
|
|
cp := comm.GetBuriedConIProgress2()
|
|
cp.Btype = bdata.Btype
|
|
cp.Conid = cond.Id
|
|
cp.Value = bitem.Value
|
|
cp.Target = cond.Value
|
|
cp.State = bitem.Finish
|
|
|
|
changes = append(changes, cp)
|
|
if len(cond.Notify) > 0 {
|
|
for _, mname := range cond.Notify {
|
|
if _, ok = notify[mname]; !ok {
|
|
notify[mname] = make([]*pb.ConIProgress, 0)
|
|
}
|
|
notify[mname] = append(notify[mname], cp)
|
|
}
|
|
} else {
|
|
if _, ok = notify[string(comm.ModuleWtask)]; !ok {
|
|
notify[string(comm.ModuleWtask)] = make([]*pb.ConIProgress, 0)
|
|
}
|
|
notify[string(comm.ModuleWtask)] = append(notify[string(comm.ModuleWtask)], cp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(changes) > 0 { //同步数据
|
|
if err = model.updateUserBurieds(session.GetUserId(), bdatas); err != nil {
|
|
this.Error("更新用户埋点数据错误!", log.Field{Key: "err", Value: err.Error()})
|
|
return
|
|
}
|
|
session.SendMsg(string(this.GetType()), "change", &pb.BuriedChangePush{Conitems: changes})
|
|
}
|
|
|
|
if len(notify) > 0 {
|
|
for k, v := range notify {
|
|
if module, err = this.service.GetModule(core.M_Modules(k)); err != nil {
|
|
this.Warn("通知条件变化异常 目标模块未找到!", log.Field{Key: "module", Value: k}, log.Field{Key: "err", Value: err.Error()})
|
|
continue
|
|
}
|
|
if nmodule, ok = module.(comm.IBuriedUpdateNotify); !ok {
|
|
this.Warn("通知条件变化异常 目标模块未实现 IBuriedUpdateNotify 接口 !", log.Field{Key: "module", Value: k})
|
|
continue
|
|
}
|
|
//异步通知指定模块
|
|
nmodule.BuriedsNotify(session, v)
|
|
}
|
|
}
|
|
|
|
//回收
|
|
for _, v := range changes {
|
|
comm.PutburiedConIProgress(v)
|
|
}
|
|
|
|
}
|
|
|
|
// 更新并校验完成
|
|
func (this *Buried) updateAndCheckBuried(bconf *cfg.GameBuriedTypeData, bdata *pb.DBBuriedItem, collec *pb.BuriedParam, cond *cfg.GameBuriedCondiData, autoActivated bool) (chanage bool, bitem *pb.DBBuriedConItem, err error) {
|
|
var (
|
|
ok bool
|
|
)
|
|
|
|
for _, v := range bdata.Condi {
|
|
if v.Conid == cond.Id {
|
|
bitem = v
|
|
ok = true
|
|
break
|
|
}
|
|
}
|
|
if !ok {
|
|
if autoActivated { //自动激活
|
|
bitem = &pb.DBBuriedConItem{
|
|
Conid: cond.Id,
|
|
State: pb.BuriedItemState_Activated,
|
|
Value: 0,
|
|
Statistics: make([]string, 0),
|
|
Timestamp: time.Now().Unix(),
|
|
}
|
|
bdata.Condi = append(bdata.Condi, bitem)
|
|
} else {
|
|
this.Debug("任务需激活才可写入!", log.Field{Key: "埋点Id", Value: bdata.Btype}, log.Field{Key: "条件Id", Value: cond.Id})
|
|
return
|
|
}
|
|
}
|
|
|
|
if bitem.State == pb.BuriedItemState_Inactivated || bitem.State == pb.BuriedItemState_Freeze { //未激活和冻结 不在处理
|
|
this.Debug("检测到任务状态不可写入!", log.Field{Key: "埋点Id", Value: bdata.Btype}, log.Field{Key: "条件Id", Value: bitem.Conid}, log.Field{Key: "State", Value: bitem.State})
|
|
return
|
|
}
|
|
|
|
if bitem.State == pb.BuriedItemState_Sleep && cond.Ctype == ctype_repeat { //完成后自动锁定
|
|
bitem.State = pb.BuriedItemState_Activated
|
|
bitem.Value = 0
|
|
bitem.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
|
|
if cond.Ctype == ctype_daily { //日常
|
|
if !utils.IsToday(bitem.Timestamp) { //不是同一天 可以重置数据
|
|
|
|
bitem.State = pb.BuriedItemState_Activated
|
|
bitem.Value = 0
|
|
bitem.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
} else if cond.Ctype == ctype_weekly { //周常
|
|
if !utils.IsSameWeek(bitem.Timestamp) { //不是同一周
|
|
bitem.State = pb.BuriedItemState_Activated
|
|
bitem.Value = 0
|
|
bitem.Finish = pb.BuriedItemFinishState_buried_unfinish
|
|
}
|
|
}
|
|
|
|
//非激活状态不写入输出
|
|
if bitem.State != pb.BuriedItemState_Activated {
|
|
return
|
|
}
|
|
|
|
switch bconf.Insert { //数据接入方式
|
|
case overlay: //累加数据
|
|
bitem.Value += collec.Value
|
|
chanage = true
|
|
case cover:
|
|
if bitem.Value != collec.Value {
|
|
chanage = true
|
|
}
|
|
bitem.Value = collec.Value
|
|
case statistics:
|
|
ok = true
|
|
for _, v := range bitem.Statistics {
|
|
if v == collec.Statistics { //已统计过
|
|
ok = false
|
|
}
|
|
}
|
|
if ok {
|
|
bitem.Statistics = append(bitem.Statistics, collec.Statistics)
|
|
bitem.Value = int32(len(bitem.Statistics))
|
|
chanage = true
|
|
}
|
|
default:
|
|
err = fmt.Errorf("未知的埋点数据处理类型:%d", bconf.Insert)
|
|
this.Error("未知的埋点数据处理类型!", log.Field{Key: "Insert", Value: bconf.Insert})
|
|
return
|
|
}
|
|
bitem.Timestamp = configure.Now().Unix() //记录最后一次操作时间
|
|
if bitem.Value >= cond.Value { //完成进度
|
|
bitem.Finish = pb.BuriedItemFinishState_buried_finish
|
|
if cond.Ctype == ctype_once { //完成后自动锁定
|
|
bitem.State = pb.BuriedItemState_Freeze
|
|
} else if cond.Ctype == ctype_repeat {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if cond.Ctype == ctype_daily {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
} else if cond.Ctype == ctype_weekly {
|
|
bitem.State = pb.BuriedItemState_Sleep
|
|
}
|
|
} else {
|
|
this.Debug("完成条件未达成!", log.Field{Key: "埋点Id", Value: bdata.Btype}, log.Field{Key: "条件Id", Value: bitem.Conid}, log.Field{Key: "当前进度", Value: bitem.Value}, log.Field{Key: "目标进度", Value: cond.Value})
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 判断埋点数据的有效性
|
|
func (this *Buried) checkburied(buried *pb.BuriedParam, bconf *cfg.GameBuriedTypeData, conf *cfg.GameBuriedCondiData) (efficient bool) {
|
|
if !(len(buried.Filter) == len(conf.Filter) && len(bconf.Filter) == len(conf.Filter)) {
|
|
this.Debug("校验埋点错误!", log.Field{Key: "buried", Value: buried}, log.Field{Key: "conf", Value: conf})
|
|
return
|
|
}
|
|
for i, v := range conf.Filter {
|
|
efficient = false
|
|
value := buried.Filter[i]
|
|
symbol := bconf.Filter[i]
|
|
target := conf.Filter[i]
|
|
switch symbol {
|
|
case eq: //==
|
|
if value == target {
|
|
efficient = true
|
|
}
|
|
case gt: //>
|
|
if value > target {
|
|
efficient = true
|
|
}
|
|
case gte: //>=
|
|
if value >= target {
|
|
efficient = true
|
|
}
|
|
case lt: //<
|
|
if value < target {
|
|
efficient = true
|
|
}
|
|
case lte: //<=
|
|
if value <= target {
|
|
efficient = true
|
|
}
|
|
case ne: //!=
|
|
if value != target {
|
|
efficient = true
|
|
}
|
|
default:
|
|
this.Error("校验埋点配置错误!", log.Field{Key: "不存在的比较符号", Value: v}, log.Field{Key: "buried", Value: buried}, log.Field{Key: "conf", Value: conf})
|
|
return
|
|
}
|
|
|
|
if !efficient { //校验不过
|
|
this.Debug("校验不通!", log.Field{Key: "埋点id", Value: buried.TaskType}, log.Field{Key: "条件id", Value: conf.Id}, log.Field{Key: "判断公式", Value: fmt.Sprintf("%d %s %d", value, symbol, target)})
|
|
return
|
|
}
|
|
}
|
|
efficient = true
|
|
return
|
|
}
|
|
|
|
//获取埋点数据
|
|
func (this *Buried) getburied(session comm.IUserSession) (bdatas *pb.DBBuried, err error) {
|
|
if ok, mate := session.GetMate(comm.Session_Buried); ok {
|
|
bdatas = mate.(*pb.DBBuried)
|
|
return
|
|
} else {
|
|
if bdatas, err = this.modelBuried.getUserBurieds(session.GetUserId()); err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
}
|