961 lines
28 KiB
Go
961 lines
28 KiB
Go
package modules
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"go_dreamfactory/comm"
|
||
"go_dreamfactory/lego/base"
|
||
"go_dreamfactory/lego/core"
|
||
"go_dreamfactory/lego/core/cbase"
|
||
"time"
|
||
|
||
"go_dreamfactory/lego/sys/log"
|
||
"go_dreamfactory/pb"
|
||
cfg "go_dreamfactory/sys/configure/structs"
|
||
"go_dreamfactory/sys/db"
|
||
|
||
"google.golang.org/protobuf/proto"
|
||
"google.golang.org/protobuf/types/known/anypb"
|
||
)
|
||
|
||
/*
|
||
基础业务模块实现 封装一些通用的接口提供给业务模块使用
|
||
*/
|
||
type ModuleBase struct {
|
||
cbase.ModuleBase
|
||
module core.IModule
|
||
service base.IRPCXService
|
||
options IOptions
|
||
scomp comm.ISC_GateRouteComp //网关服务组件
|
||
userlog *modelUserLog //用户日志
|
||
//常用的一些通用模块 在底层注册好
|
||
ModuleSys comm.ISys //系统
|
||
ModuleUser comm.IUser //用户模块
|
||
ModuleItems comm.IItems //道具背包模块
|
||
ModuleHero comm.IHero //英雄模块
|
||
ModuleEquipment comm.IEquipment //装备模块
|
||
ModuleFriend comm.IFriend //好友
|
||
ModuleSociaty comm.ISociaty //公会
|
||
ModulePrivilege comm.IPrivilege // 月卡
|
||
ModuleSmithy comm.ISmithy //铁匠铺
|
||
ModulePractice comm.IPractice //练功房
|
||
ModuleTools comm.ITools //工具类 获取一些通用配置
|
||
ModuleBuried comm.IBuried //触发埋点中心
|
||
ModuleMail comm.Imail //邮件
|
||
ModuleActivity comm.IActivity //活动模块
|
||
ModuleUiGame comm.IUiGame //
|
||
ModuleDragon comm.IDragon //
|
||
ModuleEntertain comm.IEntertainment //
|
||
}
|
||
|
||
// 重构模块配置对象
|
||
func (this *ModuleBase) NewOptions() (options core.IModuleOptions) {
|
||
return new(Options)
|
||
}
|
||
|
||
// 模块初始化接口
|
||
func (this *ModuleBase) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
||
this.service = service.(base.IRPCXService)
|
||
this.module = module
|
||
this.options = options.(IOptions)
|
||
this.options.GetLog().SetName("module." + string(module.GetType()))
|
||
if err = this.ModuleBase.Init(service, module, options); err != nil {
|
||
return
|
||
}
|
||
return
|
||
}
|
||
func (this *ModuleBase) OnInstallComp() {
|
||
this.ModuleBase.OnInstallComp()
|
||
this.userlog = this.RegisterComp(new(modelUserLog)).(*modelUserLog)
|
||
}
|
||
|
||
// 模块启动接口
|
||
func (this *ModuleBase) Start() (err error) {
|
||
if err = this.ModuleBase.Start(); err != nil {
|
||
return
|
||
}
|
||
var comp core.IServiceComp
|
||
//注册远程路由
|
||
if comp, err = this.service.GetComp(comm.SC_ServiceGateRouteComp); err != nil {
|
||
return
|
||
}
|
||
this.scomp = comp.(comm.ISC_GateRouteComp)
|
||
var module core.IModule
|
||
if module, err = this.service.GetModule(comm.ModuleUser); err != nil {
|
||
return
|
||
}
|
||
|
||
this.ModuleUser = module.(comm.IUser)
|
||
if module, err = this.service.GetModule(comm.ModuleItems); err != nil {
|
||
return
|
||
}
|
||
this.ModuleItems = module.(comm.IItems)
|
||
if module, err = this.service.GetModule(comm.ModuleHero); err != nil {
|
||
return
|
||
}
|
||
this.ModuleHero = module.(comm.IHero)
|
||
if module, err = this.service.GetModule(comm.ModuleEquipment); err != nil {
|
||
return
|
||
}
|
||
this.ModuleEquipment = module.(comm.IEquipment)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleFriend); err != nil {
|
||
return
|
||
}
|
||
this.ModuleFriend = module.(comm.IFriend)
|
||
|
||
// if module, err = this.service.GetModule(comm.ModuleRtask); err != nil {
|
||
// return
|
||
// }
|
||
// this.ModuleRtask = module.(comm.IRtask)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleSys); err != nil {
|
||
return
|
||
}
|
||
this.ModuleSys = module.(comm.ISys)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleSociaty); err != nil {
|
||
return
|
||
}
|
||
this.ModuleSociaty = module.(comm.ISociaty)
|
||
|
||
if module, err = this.service.GetModule(comm.ModulePrivilege); err != nil {
|
||
return
|
||
}
|
||
this.ModulePrivilege = module.(comm.IPrivilege)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleSmithy); err != nil {
|
||
return
|
||
}
|
||
this.ModuleSmithy = module.(comm.ISmithy)
|
||
if module, err = this.service.GetModule(comm.ModulePractice); err != nil {
|
||
return
|
||
}
|
||
this.ModulePractice = module.(comm.IPractice)
|
||
if module, err = this.service.GetModule(comm.ModuleTools); err != nil {
|
||
return
|
||
}
|
||
this.ModuleTools = module.(comm.ITools)
|
||
if module, err = this.service.GetModule(comm.ModuleBuried); err != nil {
|
||
return
|
||
}
|
||
this.ModuleBuried = module.(comm.IBuried)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleMail); err != nil {
|
||
return
|
||
}
|
||
this.ModuleMail = module.(comm.Imail)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleActivity); err != nil {
|
||
return
|
||
}
|
||
this.ModuleActivity = module.(comm.IActivity)
|
||
|
||
if module, err = this.service.GetModule(comm.ModulePuzzle); err != nil {
|
||
return
|
||
}
|
||
this.ModuleUiGame = module.(comm.IUiGame)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleDragon); err != nil {
|
||
return
|
||
}
|
||
this.ModuleDragon = module.(comm.IDragon)
|
||
|
||
if module, err = this.service.GetModule(comm.ModuleEntertainment); err != nil {
|
||
return
|
||
}
|
||
this.ModuleEntertain = module.(comm.IEntertainment)
|
||
return
|
||
}
|
||
|
||
// 判断当前环境是本服还还是跨服
|
||
func (this *ModuleBase) IsCross() bool {
|
||
return db.IsCross()
|
||
}
|
||
|
||
// 获取跨服标签
|
||
func (this *ModuleBase) GetCrossTag() string {
|
||
return db.CrossTag()
|
||
}
|
||
|
||
func (this *ModuleBase) GetUserSession(uid string) (session comm.IUserSession, ok bool) {
|
||
var udata *pb.CacheUser
|
||
if udata = this.ModuleUser.GetUserSession(uid); udata == nil {
|
||
session = this.scomp.GetUserSession(&pb.CacheUser{Uid: uid})
|
||
ok = false
|
||
return
|
||
}
|
||
session = this.scomp.GetUserSession(udata)
|
||
ok = true
|
||
return
|
||
}
|
||
|
||
func (this *ModuleBase) PutUserSession(session comm.IUserSession) {
|
||
session.Reset()
|
||
this.scomp.PutUserSession(session)
|
||
return
|
||
}
|
||
|
||
// 向指定用户发送消息
|
||
func (this *ModuleBase) SendMsgToUser(mainType, subType string, msg proto.Message, uid string) (err error) {
|
||
user := this.ModuleUser.GetUserSession(uid)
|
||
if user == nil {
|
||
err = fmt.Errorf("user:%v on found", uid)
|
||
return
|
||
}
|
||
session := this.scomp.GetUserSession(user)
|
||
session.SendMsg(mainType, subType, msg)
|
||
err = session.Push()
|
||
this.PutUserSession(session)
|
||
return
|
||
}
|
||
|
||
// 向多个用户发送消息
|
||
func (this *ModuleBase) SendMsgToUsers(mainType, subType string, msg proto.Message, uids ...string) (err error) {
|
||
var (
|
||
users []*pb.CacheUser
|
||
gateways map[string]map[string][]string = make(map[string]map[string][]string)
|
||
cluster map[string][]string = make(map[string][]string)
|
||
gateway []string
|
||
ok bool
|
||
)
|
||
users = this.ModuleUser.GetUserSessions(uids)
|
||
for _, v := range users {
|
||
if cluster, ok = gateways[v.ServiceTag]; !ok {
|
||
cluster = make(map[string][]string)
|
||
gateways[v.ServiceTag] = cluster
|
||
}
|
||
if gateway, ok = cluster[v.GatewayServiceId]; !ok {
|
||
gateway = make([]string, 0)
|
||
cluster[v.GatewayServiceId] = gateway
|
||
}
|
||
cluster[v.GatewayServiceId] = append(cluster[v.GatewayServiceId], v.SessionId)
|
||
}
|
||
data, _ := anypb.New(msg)
|
||
for k, v := range gateways {
|
||
for k1, v1 := range v {
|
||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5) //
|
||
if _, err = this.service.AcrossClusterRpcGo(ctx, k, fmt.Sprintf("%s/%s", comm.Service_Gateway, k1), string(comm.Rpc_GatewaySendBatchMsg), &pb.BatchMessageReq{
|
||
UserSessionIds: v1,
|
||
MainType: mainType,
|
||
SubType: subType,
|
||
Data: data,
|
||
}, nil); err != nil {
|
||
log.Errorf("SendMsgToUsers:%s.%s->%s.%s err:%v", k1, k, mainType, subType, err)
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 向多个用户发送消息
|
||
func (this *ModuleBase) SendMsgToCUsers(mainType, subType string, msg proto.Message, users ...*pb.CacheUser) (err error) {
|
||
var (
|
||
gateways map[string]map[string][]string = make(map[string]map[string][]string)
|
||
cluster map[string][]string = make(map[string][]string)
|
||
gateway []string
|
||
ok bool
|
||
)
|
||
for _, v := range users {
|
||
if cluster, ok = gateways[v.ServiceTag]; !ok {
|
||
cluster = make(map[string][]string)
|
||
gateways[v.ServiceTag] = cluster
|
||
}
|
||
if gateway, ok = cluster[v.GatewayServiceId]; !ok {
|
||
gateway = make([]string, 0)
|
||
cluster[v.GatewayServiceId] = gateway
|
||
}
|
||
cluster[v.GatewayServiceId] = append(cluster[v.GatewayServiceId], v.SessionId)
|
||
}
|
||
data, _ := anypb.New(msg)
|
||
for k, v := range gateways {
|
||
for k1, v1 := range v {
|
||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||
if _, err = this.service.AcrossClusterRpcGo(ctx, k, fmt.Sprintf("%s/%s", comm.Service_Gateway, k1), string(comm.Rpc_GatewaySendBatchMsg), &pb.BatchMessageReq{
|
||
UserSessionIds: v1,
|
||
MainType: mainType,
|
||
SubType: subType,
|
||
Data: data,
|
||
}, nil); err != nil {
|
||
log.Errorf("SendMsgToUsers:%s.%s->%s.%s err:%v", k1, k, mainType, subType, err)
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 向多个用户发送消息
|
||
func (this *ModuleBase) SendMsgToSession(mainType, subType string, msg proto.Message, users ...comm.IUserSession) (err error) {
|
||
var (
|
||
gateways map[string]map[string][]string = make(map[string]map[string][]string)
|
||
cluster map[string][]string = make(map[string][]string)
|
||
gateway []string
|
||
ok bool
|
||
)
|
||
for _, v := range users {
|
||
if cluster, ok = gateways[v.GetServiecTag()]; !ok {
|
||
cluster = make(map[string][]string)
|
||
gateways[v.GetServiecTag()] = cluster
|
||
}
|
||
if gateway, ok = cluster[v.GetGatewayServiceId()]; !ok {
|
||
gateway = make([]string, 0)
|
||
cluster[v.GetGatewayServiceId()] = gateway
|
||
}
|
||
cluster[v.GetGatewayServiceId()] = append(cluster[v.GetGatewayServiceId()], v.GetSessionId())
|
||
}
|
||
data, _ := anypb.New(msg)
|
||
for k, v := range gateways {
|
||
for k1, v1 := range v {
|
||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||
if _, err = this.service.AcrossClusterRpcGo(ctx, k, fmt.Sprintf("%s/%s", comm.Service_Gateway, k1), string(comm.Rpc_GatewaySendBatchMsg), &pb.BatchMessageReq{
|
||
UserSessionIds: v1,
|
||
MainType: mainType,
|
||
SubType: subType,
|
||
Data: data,
|
||
}, nil); err != nil {
|
||
log.Errorf("SendMsgToUsers:%s.%s->%s.%s err:%v", k1, k, mainType, subType, err)
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
func (this *ModuleBase) SendMsgSyncToSession(mainType, subType string, msg proto.Message, users ...comm.IUserSession) (err error) {
|
||
var (
|
||
gateways map[string]map[string][]string = make(map[string]map[string][]string)
|
||
cluster map[string][]string = make(map[string][]string)
|
||
gateway []string
|
||
ok bool
|
||
)
|
||
for _, v := range users {
|
||
if cluster, ok = gateways[v.GetServiecTag()]; !ok {
|
||
cluster = make(map[string][]string)
|
||
gateways[v.GetServiecTag()] = cluster
|
||
}
|
||
if gateway, ok = cluster[v.GetGatewayServiceId()]; !ok {
|
||
gateway = make([]string, 0)
|
||
cluster[v.GetGatewayServiceId()] = gateway
|
||
}
|
||
cluster[v.GetGatewayServiceId()] = append(cluster[v.GetGatewayServiceId()], v.GetSessionId())
|
||
}
|
||
data, _ := anypb.New(msg)
|
||
for k, v := range gateways {
|
||
for k1, v1 := range v {
|
||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||
if err = this.service.AcrossClusterRpcCall(ctx, k, fmt.Sprintf("%s/%s", comm.Service_Gateway, k1), string(comm.Rpc_GatewaySendBatchMsg), &pb.BatchMessageReq{
|
||
UserSessionIds: v1,
|
||
MainType: mainType,
|
||
SubType: subType,
|
||
Data: data,
|
||
}, &pb.RPCMessageReply{}); err != nil { // 同步消息
|
||
log.Errorf("SendMsgToUsers:%s.%s->%s.%s err:%v", k1, k, mainType, subType, err)
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 只校验资源 参数 atn格式
|
||
func (this *ModuleBase) CheckRes(session comm.IUserSession, res []*cfg.Gameatn) (errdata *pb.ErrorData) {
|
||
var (
|
||
items map[string]int32 // 道具背包 批量处理
|
||
attrs map[string]int32 // 属性
|
||
)
|
||
items = make(map[string]int32, 0)
|
||
attrs = make(map[string]int32, 0)
|
||
for _, v := range res {
|
||
switch v.A {
|
||
case comm.AttrType:
|
||
attrs[v.T] = v.N
|
||
case comm.ItemType:
|
||
items[v.T] = v.N
|
||
default:
|
||
this.Error("not found res type", log.Field{Key: "Type", Value: v.A}) // 找不到资源类型
|
||
}
|
||
}
|
||
// 校验数量
|
||
for k, v := range attrs {
|
||
amount := this.ModuleUser.QueryAttributeValue(session.GetUserId(), k)
|
||
if amount < int64(v) {
|
||
errdata = &pb.ErrorData{
|
||
Code: pb.ErrorCode_ResNoEnough,
|
||
Title: pb.ErrorCode_ResNoEnough.ToString(),
|
||
Atn: &pb.UserAssets{A: comm.AttrType, T: k, N: v},
|
||
Message: fmt.Sprintf("资源%v的数量:%v 小于 %v", k, amount, v),
|
||
}
|
||
// this.Warn("资源不足", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "T", Value: k}, log.Field{Key: "N", Value: v})
|
||
return
|
||
}
|
||
}
|
||
for k, v := range items { //校验消费资源是否充足
|
||
amount := int32(this.ModuleItems.QueryItemAmount(session.GetUserId(), k))
|
||
if amount < v {
|
||
errdata = &pb.ErrorData{
|
||
Code: pb.ErrorCode_ResNoEnough,
|
||
Title: pb.ErrorCode_ResNoEnough.ToString(),
|
||
Atn: &pb.UserAssets{A: comm.ItemType, T: k, N: v},
|
||
Message: fmt.Sprintf("道具%v的数量:%v 小于 %v", k, amount, v),
|
||
}
|
||
// this.Warn("道具不足", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "T", Value: k}, log.Field{Key: "N", Value: v})
|
||
return
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// 消耗资源
|
||
func (this *ModuleBase) ConsumeRes(session comm.IUserSession, res []*cfg.Gameatn, bPush bool) (errdata *pb.ErrorData) {
|
||
var (
|
||
items map[string]int32 // 道具背包 批量处理
|
||
attrs map[string]int32 // 属性
|
||
)
|
||
items = make(map[string]int32, 0)
|
||
attrs = make(map[string]int32, 0)
|
||
|
||
for _, v := range res {
|
||
switch v.A {
|
||
case comm.AttrType:
|
||
attrs[v.T] -= v.N
|
||
|
||
case comm.ItemType:
|
||
items[v.T] -= v.N
|
||
default:
|
||
this.Error("not found res type", log.Field{Key: "Type", Value: v.A}) // 找不到资源类型
|
||
}
|
||
}
|
||
// 校验数量
|
||
for k, v := range attrs {
|
||
amount := this.ModuleUser.QueryAttributeValue(session.GetUserId(), k)
|
||
if amount < -int64(v) { // -v 负负得正
|
||
errdata = &pb.ErrorData{
|
||
Code: pb.ErrorCode_ResNoEnough,
|
||
Title: pb.ErrorCode_ResNoEnough.ToString(),
|
||
Atn: &pb.UserAssets{A: comm.AttrType, T: k, N: v},
|
||
Message: fmt.Sprintf("资源%v的数量:%v 小于 %v", k, amount, v),
|
||
}
|
||
this.Warn("资源不足", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "T", Value: k}, log.Field{Key: "N", Value: v})
|
||
return
|
||
}
|
||
}
|
||
for k, v := range items {
|
||
amount := this.ModuleItems.QueryItemAmount(session.GetUserId(), k)
|
||
if int32(amount) < -v {
|
||
errdata = &pb.ErrorData{
|
||
Code: pb.ErrorCode_ResNoEnough,
|
||
Title: pb.ErrorCode_ResNoEnough.ToString(),
|
||
Atn: &pb.UserAssets{A: comm.ItemType, T: k, N: v},
|
||
Message: fmt.Sprintf("道具%v的数量:%v 小于 %v", k, amount, v),
|
||
}
|
||
this.Warn("道具不足", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "T", Value: k}, log.Field{Key: "N", Value: v})
|
||
return
|
||
}
|
||
}
|
||
// 真正消耗
|
||
if len(attrs) > 0 {
|
||
_, errdata = this.ModuleUser.AddAttributeValues(session, attrs, bPush)
|
||
if errdata != nil {
|
||
return
|
||
}
|
||
this.Debug("消耗玩家资源", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "attrs", Value: attrs})
|
||
}
|
||
if len(items) > 0 {
|
||
_, errdata = this.ModuleItems.AddItems(session, items, bPush)
|
||
if errdata != nil {
|
||
return
|
||
}
|
||
this.Debug("消耗玩家资源", log.Field{Key: "uid", Value: session.GetUserId()}, log.Field{Key: "items", Value: items})
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// 发放资源
|
||
func (this *ModuleBase) DispenseRes(session comm.IUserSession, res []*cfg.Gameatn, bPush bool) (errdata *pb.ErrorData) {
|
||
var (
|
||
items map[string]int32 // 道具背包 批量处理
|
||
heros map[string]int32 // 英雄
|
||
attrs map[string]int32 // 属性
|
||
equips map[string]uint32 // 装备
|
||
vip map[string]int32 // vip
|
||
atlas map[string]int32 // 铁匠铺资源
|
||
panda map[string]int32 // 熊猫武馆资源
|
||
mts map[string]int32 // 捕羊大赛资源
|
||
per map[string]int32 // 捕羊大赛资源
|
||
title map[string]int32 // 称号资源
|
||
xxl map[string]int32 // 三消卡片资源
|
||
)
|
||
items = make(map[string]int32, 0)
|
||
heros = make(map[string]int32, 0)
|
||
attrs = make(map[string]int32, 0)
|
||
equips = make(map[string]uint32, 0)
|
||
vip = make(map[string]int32, 0)
|
||
atlas = make(map[string]int32, 0)
|
||
panda = make(map[string]int32, 0)
|
||
mts = make(map[string]int32, 0)
|
||
per = make(map[string]int32, 0)
|
||
title = make(map[string]int32, 0)
|
||
xxl = make(map[string]int32, 0)
|
||
|
||
for _, v := range res {
|
||
switch v.A {
|
||
case comm.AttrType:
|
||
attrs[v.T] += v.N
|
||
case comm.ItemType:
|
||
items[v.T] += v.N
|
||
case comm.HeroType:
|
||
heros[v.T] += v.N
|
||
case comm.EquipmentType:
|
||
if v.N > 0 { // 不允许减少装备
|
||
equips[v.T] += uint32(v.N)
|
||
}
|
||
case comm.VipType:
|
||
vip[v.T] += v.N
|
||
case comm.AtlasType:
|
||
atlas[v.T] = 1
|
||
case comm.PandaType:
|
||
panda[v.T] = 1
|
||
case comm.MountsType:
|
||
mts[v.T] = v.N // N 表示等级
|
||
case comm.PerType:
|
||
per[v.T] = 1
|
||
case comm.TitleType:
|
||
title[v.T] = 1
|
||
case comm.XxlType:
|
||
xxl[v.T] += v.N
|
||
default:
|
||
this.Error("not found res type", log.Field{Key: "Type", Value: v.A}) // 找不到资源类型
|
||
}
|
||
}
|
||
|
||
if len(attrs) > 0 { //用户属性资源
|
||
_, errdata = this.ModuleUser.AddAttributeValues(session, attrs, bPush)
|
||
this.Debugf("发放用户资源: %v errdata: %v", attrs, errdata)
|
||
}
|
||
if len(items) > 0 { //道具资源
|
||
_, errdata = this.ModuleItems.AddItems(session, items, bPush)
|
||
this.Debugf("发放道具资源: %v errdata: %v", items, errdata)
|
||
}
|
||
if len(heros) > 0 { //卡片资源
|
||
_, errdata = this.ModuleHero.CreateRepeatHeros(session, heros, bPush)
|
||
this.Debugf("发放英雄资源: %v errdata: %v", heros, errdata)
|
||
}
|
||
if len(equips) > 0 {
|
||
_, errdata = this.ModuleEquipment.AddNewEquipments(session, equips, bPush)
|
||
this.Debugf("发放装备资源: %v errdata: %v", equips, errdata)
|
||
}
|
||
if len(vip) > 0 { //卡片资源
|
||
for _, v := range vip {
|
||
errdata, _ = this.ModulePrivilege.Delivery(session, v)
|
||
this.Debugf("发放月卡资源: %v errdata: %v", v, errdata)
|
||
}
|
||
}
|
||
if len(atlas) > 0 {
|
||
for k := range atlas {
|
||
this.ModuleSmithy.CheckActivateAtlasCollect(session.GetUserId(), k)
|
||
this.Debugf("发放图鉴资源: %v errdata: %v", k, errdata)
|
||
}
|
||
}
|
||
if len(panda) > 0 {
|
||
errdata = this.ModulePractice.AddItems(session, panda, bPush)
|
||
this.Debugf("发放武馆资源: %v errdata: %v", panda, errdata)
|
||
}
|
||
if len(mts) > 0 {
|
||
if errdata = this.ModuleDragon.CreateDragon(session, mts, bPush); errdata != nil {
|
||
return
|
||
}
|
||
//errdata = this.ModuleParkour.AddMounts(session, mts, bPush)
|
||
this.Debugf("发放捕羊大赛资源: %v errdata: %v", mts, errdata)
|
||
}
|
||
if len(per) > 0 {
|
||
errdata = this.ModuleUser.AddPer(session, per, bPush)
|
||
this.Debugf("发放用户皮肤资源资源: %v errdata: %v", mts, errdata)
|
||
}
|
||
if len(title) > 0 {
|
||
errdata = this.ModuleUser.AddTitle(session, title, bPush)
|
||
this.Debugf("发放用户称号资源资源: %v errdata: %v", mts, errdata)
|
||
}
|
||
if len(xxl) > 0 {
|
||
errdata = this.ModuleEntertain.AddXxlCard(session, xxl, bPush)
|
||
this.Debugf("发放三消卡片资源资源: %v errdata: %v", mts, errdata)
|
||
}
|
||
return
|
||
}
|
||
|
||
// 跨服对象获取数据操作对象
|
||
func (this *ModuleBase) GetDBNodule(session comm.IUserSession, tableName string, expired time.Duration) (model *db.DBModel, err error) {
|
||
var conn *db.DBConn
|
||
if session.GetServiecTag() == this.service.GetTag() {
|
||
if conn, err = db.Local(); err != nil {
|
||
return
|
||
}
|
||
} else {
|
||
if conn, err = db.ServerDBConn(session.GetServiecTag()); err != nil {
|
||
return
|
||
}
|
||
}
|
||
model = db.NewDBModel(tableName, conn)
|
||
return
|
||
}
|
||
|
||
// 跨服对象获取数据操作对象
|
||
func (this *ModuleBase) GetCrossDBModel(tableName string) (model *db.DBModel, err error) {
|
||
var (
|
||
conn *db.DBConn
|
||
)
|
||
if this.IsCross() {
|
||
if conn, err = db.Local(); err != nil {
|
||
return
|
||
}
|
||
} else {
|
||
if conn, err = db.Cross(); err != nil {
|
||
return
|
||
}
|
||
}
|
||
model = db.NewDBModel(tableName, conn)
|
||
return
|
||
}
|
||
|
||
// 跨服对象获取数据操作对象
|
||
func (this *ModuleBase) GetDBModelByUid(uid, tableName string) (model *db.DBModel, err error) {
|
||
var (
|
||
stag string
|
||
conn *db.DBConn
|
||
)
|
||
if stag, err = comm.UidToSTag(uid); err != nil {
|
||
return
|
||
}
|
||
if stag == this.service.GetTag() {
|
||
if conn, err = db.Local(); err != nil {
|
||
return
|
||
}
|
||
} else {
|
||
if conn, err = db.ServerDBConn(stag); err != nil {
|
||
return
|
||
}
|
||
}
|
||
model = db.NewDBModel(tableName, conn)
|
||
return
|
||
}
|
||
|
||
// 日志接口
|
||
func (this *ModuleBase) Debug(msg string, args ...log.Field) {
|
||
this.options.GetLog().Debug(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Info(msg string, args ...log.Field) {
|
||
this.options.GetLog().Info(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Print(msg string, args ...log.Field) {
|
||
this.options.GetLog().Print(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Warn(msg string, args ...log.Field) {
|
||
this.options.GetLog().Warn(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Error(msg string, args ...log.Field) {
|
||
this.options.GetLog().Error(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Panic(msg string, args ...log.Field) {
|
||
this.options.GetLog().Panic(msg, args...)
|
||
}
|
||
func (this *ModuleBase) Fatal(msg string, args ...log.Field) {
|
||
this.options.GetLog().Fatal(msg, args...)
|
||
}
|
||
|
||
func (this *ModuleBase) Debugf(format string, args ...interface{}) {
|
||
this.options.GetLog().Debugf(format, args...)
|
||
}
|
||
func (this *ModuleBase) Infof(format string, args ...interface{}) {
|
||
this.options.GetLog().Infof(format, args...)
|
||
}
|
||
func (this *ModuleBase) Printf(format string, args ...interface{}) {
|
||
this.options.GetLog().Printf(format, args...)
|
||
}
|
||
func (this *ModuleBase) Warnf(format string, args ...interface{}) {
|
||
this.options.GetLog().Warnf(format, args...)
|
||
}
|
||
func (this *ModuleBase) Errorf(format string, args ...interface{}) {
|
||
this.options.GetLog().Errorf(format, args...)
|
||
}
|
||
func (this *ModuleBase) Fatalf(format string, args ...interface{}) {
|
||
this.options.GetLog().Fatalf(format, args...)
|
||
}
|
||
func (this *ModuleBase) Panicf(format string, args ...interface{}) {
|
||
this.options.GetLog().Panicf(format, args...)
|
||
}
|
||
|
||
func (this *ModuleBase) Debugln(args ...interface{}) {
|
||
this.options.GetLog().Debugln(args...)
|
||
}
|
||
func (this *ModuleBase) Infoln(args ...interface{}) {
|
||
this.options.GetLog().Infoln(args...)
|
||
}
|
||
func (this *ModuleBase) Println(args ...interface{}) {
|
||
this.options.GetLog().Println(args...)
|
||
}
|
||
func (this *ModuleBase) Warnln(args ...interface{}) {
|
||
this.options.GetLog().Warnln(args...)
|
||
}
|
||
func (this *ModuleBase) Errorln(args ...interface{}) {
|
||
this.options.GetLog().Errorln(args...)
|
||
}
|
||
func (this *ModuleBase) Fatalln(args ...interface{}) {
|
||
this.options.GetLog().Fatalln(args...)
|
||
}
|
||
func (this *ModuleBase) Panicln(args ...interface{}) {
|
||
this.options.GetLog().Panicln(args...)
|
||
}
|
||
|
||
// 发放资源
|
||
func (this *ModuleBase) DispenseAtno(session comm.IUserSession, res []*cfg.Gameatn, bPush bool) (errdata *pb.ErrorData, atno []*pb.UserAtno) {
|
||
var (
|
||
items map[string]int32 // 道具背包 批量处理
|
||
heros map[string]int32 // 英雄
|
||
attrs map[string]int32 // 属性
|
||
equips map[string]uint32 // 装备
|
||
vip map[string]int32 // vip
|
||
atlas map[string]int32 // 铁匠铺资源
|
||
panda map[string]int32 // 熊猫武馆资源
|
||
mts map[string]int32 // 捕羊大赛资源
|
||
per map[string]int32 // 捕羊大赛资源
|
||
title map[string]int32 // 称号资源
|
||
xxl map[string]int32 // 三消资源
|
||
equipschange []*pb.DB_Equipment
|
||
heroschange []*pb.UserAtno
|
||
itemschange []*pb.UserAtno
|
||
)
|
||
items = make(map[string]int32, 0)
|
||
heros = make(map[string]int32, 0)
|
||
attrs = make(map[string]int32, 0)
|
||
equips = make(map[string]uint32, 0)
|
||
vip = make(map[string]int32, 0)
|
||
atlas = make(map[string]int32, 0)
|
||
panda = make(map[string]int32, 0)
|
||
mts = make(map[string]int32, 0)
|
||
per = make(map[string]int32, 0)
|
||
title = make(map[string]int32, 0)
|
||
xxl = make(map[string]int32, 0)
|
||
|
||
for _, v := range res {
|
||
switch v.A {
|
||
case comm.AttrType:
|
||
attrs[v.T] += v.N
|
||
case comm.ItemType:
|
||
items[v.T] += v.N
|
||
case comm.HeroType:
|
||
heros[v.T] += v.N
|
||
case comm.EquipmentType:
|
||
if v.N > 0 { // 不允许减少装备
|
||
equips[v.T] += uint32(v.N)
|
||
}
|
||
case comm.VipType:
|
||
vip[v.T] += v.N
|
||
case comm.AtlasType:
|
||
atlas[v.T] = 1
|
||
case comm.PandaType:
|
||
panda[v.T] = 1
|
||
case comm.MountsType:
|
||
mts[v.T] += v.N
|
||
case comm.PerType:
|
||
per[v.T] = 1
|
||
case comm.TitleType:
|
||
title[v.T] = 1
|
||
case comm.XxlType:
|
||
xxl[v.T] += v.N
|
||
default:
|
||
this.Error("not found res type", log.Field{Key: "Type", Value: v.A}) // 找不到资源类型
|
||
}
|
||
}
|
||
|
||
if len(attrs) > 0 { //用户属性资源
|
||
if atno, errdata = this.ModuleUser.AddAttributeValues(session, attrs, bPush); errdata != nil {
|
||
return
|
||
}
|
||
|
||
// for k, v := range attrs {
|
||
// atno = append(atno, &pb.UserAtno{
|
||
// A: comm.AttrType,
|
||
// T: k,
|
||
// N: v,
|
||
// })
|
||
// }
|
||
this.Debugf("发放用户资源: %v errdata: %v", attrs, errdata)
|
||
|
||
}
|
||
if len(items) > 0 { //道具资源
|
||
if itemschange, errdata = this.ModuleItems.AddItems(session, items, bPush); errdata != nil {
|
||
return
|
||
}
|
||
atno = append(atno, itemschange...)
|
||
this.Debugf("发放道具资源: %v errdata: %v", items, errdata)
|
||
}
|
||
if len(heros) > 0 { //卡片资源
|
||
if heroschange, errdata = this.ModuleHero.CreateRepeatHeros(session, heros, bPush); errdata != nil {
|
||
return
|
||
}
|
||
atno = append(atno, heroschange...)
|
||
this.Debugf("发放英雄资源: %v errdata: %v", heros, errdata)
|
||
}
|
||
if len(equips) > 0 {
|
||
if equipschange, errdata = this.ModuleEquipment.AddNewEquipments(session, equips, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for _, v := range equipschange {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: "equi",
|
||
T: v.CId,
|
||
N: int32(len(equips)),
|
||
O: v.Id,
|
||
})
|
||
}
|
||
this.Debugf("发放装备资源: %v errdata: %v", equips, errdata)
|
||
}
|
||
if len(vip) > 0 { //卡片资源
|
||
for _, v := range vip {
|
||
errdata, _ = this.ModulePrivilege.Delivery(session, v)
|
||
this.Debugf("发放月卡资源: %v errdata: %v", v, errdata)
|
||
}
|
||
for k, v := range vip {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.VipType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
}
|
||
if len(atlas) > 0 {
|
||
for k := range atlas {
|
||
this.ModuleSmithy.CheckActivateAtlasCollect(session.GetUserId(), k)
|
||
this.Debugf("发放图鉴资源: %v errdata: %v", k, errdata)
|
||
}
|
||
for k, v := range atlas {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.AtlasType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
}
|
||
if len(panda) > 0 {
|
||
if errdata = this.ModulePractice.AddItems(session, panda, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for k, v := range panda {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.PandaType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
this.Debugf("发放武馆资源: %v errdata: %v", panda, errdata)
|
||
}
|
||
if len(mts) > 0 {
|
||
//errdata = this.ModuleParkour.AddMounts(session, mts, bPush)
|
||
if errdata = this.ModuleDragon.CreateDragon(session, mts, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for k, v := range mts {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.MountsType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
this.Debugf("发放捕羊大赛资源: %v errdata: %v", mts, errdata)
|
||
}
|
||
if len(per) > 0 {
|
||
if errdata = this.ModuleUser.AddPer(session, per, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for k, v := range per {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.PerType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
this.Debugf("发放用户皮肤资源资源: %v errdata: %v", per, errdata)
|
||
}
|
||
if len(title) > 0 {
|
||
if errdata = this.ModuleUser.AddTitle(session, title, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for k, v := range title {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.TitleType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
this.Debugf("发放用户称号资源资源: %v errdata: %v", title, errdata)
|
||
}
|
||
|
||
if len(xxl) > 0 {
|
||
if errdata = this.ModuleEntertain.AddXxlCard(session, xxl, bPush); errdata != nil {
|
||
return
|
||
}
|
||
for k, v := range xxl {
|
||
atno = append(atno, &pb.UserAtno{
|
||
A: comm.TitleType,
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
this.Debugf("发放三消卡片资源资源: %v errdata: %v", xxl, errdata)
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// 格式化资源
|
||
func (this *ModuleBase) FormatRes(res []*cfg.Gameatn) (ret []*cfg.Gameatn) {
|
||
var (
|
||
items map[string]int32 // 道具背包 批量处理
|
||
attrs map[string]int32 // 属性
|
||
)
|
||
items = make(map[string]int32, 0)
|
||
attrs = make(map[string]int32, 0)
|
||
|
||
for _, v := range res {
|
||
switch v.A {
|
||
case comm.AttrType:
|
||
attrs[v.T] += v.N
|
||
|
||
case comm.ItemType:
|
||
items[v.T] += v.N
|
||
default:
|
||
this.Error("not found res type", log.Field{Key: "Type", Value: v.A}) // 找不到资源类型
|
||
}
|
||
}
|
||
for k, v := range attrs {
|
||
if v > 0 {
|
||
ret = append(ret, &cfg.Gameatn{
|
||
A: "attr",
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
|
||
}
|
||
for k, v := range items {
|
||
if v > 0 {
|
||
ret = append(ret, &cfg.Gameatn{
|
||
A: "item",
|
||
T: k,
|
||
N: v,
|
||
})
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
//异步调用用户处理流
|
||
func (this *ModuleBase) AsynHandleSession(session comm.IUserSession, handle func(session comm.IUserSession)) {
|
||
handle(session)
|
||
session.Push()
|
||
this.PutUserSession(session)
|
||
}
|
||
|
||
//写用户日志
|
||
func (this *ModuleBase) WriteUserLog(uid string, itype int32, tag string, data interface{}) {
|
||
this.userlog.AddUserLog(uid, itype, tag, data)
|
||
}
|