no message
This commit is contained in:
parent
025dbd8691
commit
e8c4f4489f
|
@ -8,6 +8,12 @@ import (
|
|||
"mongo.games.com/goserver/core/logger"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
ItemId int32 // 物品ID
|
||||
ItemNum int64 // 物品数量
|
||||
ObtainTime int64 //获取的时间
|
||||
}
|
||||
|
||||
type BagInfo struct {
|
||||
BagId bson.ObjectId `bson:"_id"`
|
||||
SnId int32 //玩家账号直接在这里生成
|
||||
|
@ -19,20 +25,11 @@ type BagInfo struct {
|
|||
GainWay int32 `bson:"-"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
ItemId int32 // 物品ID
|
||||
ItemNum int64 // 物品数量
|
||||
ObtainTime int64 //获取的时间
|
||||
}
|
||||
type GetBagInfoArgs struct {
|
||||
Plt string
|
||||
SnId int32
|
||||
}
|
||||
|
||||
func NewBagInfo(sid int32, plt string) *BagInfo {
|
||||
return &BagInfo{BagId: bson.NewObjectId(), SnId: sid, Platform: plt, BagItem: make(map[int32]*Item)}
|
||||
}
|
||||
|
||||
func GetBagInfo(sid int32, plt string) (*BagInfo, error) {
|
||||
if rpcCli == nil {
|
||||
return nil, ErrRPClientNoConn
|
||||
|
@ -76,18 +73,6 @@ func SaveDBBagItem(args *BagInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func SaveToDelBackupBagItem(args *BagInfo) error {
|
||||
if rpcCli == nil {
|
||||
return ErrRPClientNoConn
|
||||
}
|
||||
ret := false
|
||||
err := rpcCli.CallWithTimeout("BagSvc.UpdateBag", args, &ret, time.Second*30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AddItemParam struct {
|
||||
Platform string
|
||||
SnId int32
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"mongo.games.com/goserver/core/basic"
|
||||
"mongo.games.com/goserver/core/i18n"
|
||||
"mongo.games.com/goserver/core/logger"
|
||||
"mongo.games.com/goserver/core/module"
|
||||
"mongo.games.com/goserver/core/task"
|
||||
|
||||
"mongo.games.com/game/common"
|
||||
|
@ -24,10 +23,22 @@ import (
|
|||
"mongo.games.com/game/worldsrv/internal"
|
||||
)
|
||||
|
||||
func init() {
|
||||
module.RegisteModule(BagMgrSingleton, time.Second, 0)
|
||||
internal.RegisterPlayerLoad(BagMgrSingleton)
|
||||
const (
|
||||
BagItemMax int32 = 200
|
||||
)
|
||||
|
||||
// 道具功能 Function
|
||||
const (
|
||||
ItemCanUse = iota //可以使用
|
||||
ItemCanGive //可以赠送
|
||||
ItemCanSell //可以出售
|
||||
ItemCanExchange //可以兑换
|
||||
ItemCanFen //可以分解
|
||||
ItemMax
|
||||
)
|
||||
|
||||
func init() {
|
||||
internal.RegisterPlayerLoad(BagMgrSingleton)
|
||||
BagMgrSingleton.AddOnChangeFuncs(func(param *model.ChangeItemParam) {
|
||||
p := PlayerMgrSington.GetPlayerBySnId(param.SnId)
|
||||
if p == nil {
|
||||
|
@ -138,20 +149,6 @@ func init() {
|
|||
})
|
||||
}
|
||||
|
||||
const (
|
||||
BagItemMax int32 = 200
|
||||
)
|
||||
|
||||
// 道具功能 Function
|
||||
const (
|
||||
ItemCanUse = iota //可以使用
|
||||
ItemCanGive //可以赠送
|
||||
ItemCanSell //可以出售
|
||||
ItemCanExchange //可以兑换
|
||||
ItemCanFen //可以分解
|
||||
ItemMax
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
ItemId int32 // 物品ID
|
||||
ItemNum int64 // 物品数量
|
||||
|
@ -186,11 +183,7 @@ func NewBagInfo(platform string, snid int32) *BagInfo {
|
|||
}
|
||||
}
|
||||
|
||||
// BagMgrSingleton 背包管理器
|
||||
var BagMgrSingleton = &BagMgr{
|
||||
PlayerBag: make(map[int32]*BagInfo),
|
||||
}
|
||||
|
||||
// BagMgr 玩家背包
|
||||
type BagMgr struct {
|
||||
PlayerBag map[int32]*BagInfo // snid:背包
|
||||
|
||||
|
@ -198,20 +191,241 @@ type BagMgr struct {
|
|||
onChangeFuncs []func(param *model.ChangeItemParam)
|
||||
}
|
||||
|
||||
func (this *BagMgr) ModuleName() string {
|
||||
return "BagMgr"
|
||||
// BagMgrSingleton 背包管理器
|
||||
var BagMgrSingleton = &BagMgr{
|
||||
PlayerBag: make(map[int32]*BagInfo),
|
||||
}
|
||||
|
||||
func (this *BagMgr) Init() {
|
||||
// ============================================================================
|
||||
// implement IPlayerLoad
|
||||
//=============================================================================
|
||||
|
||||
type LoadData struct {
|
||||
BagInfo *model.BagInfo
|
||||
}
|
||||
|
||||
func (this *BagMgr) Update() {
|
||||
func (this *BagMgr) Load(platform string, snid int32, player any) *internal.PlayerLoadReplay {
|
||||
// 加载道具
|
||||
bagInfo, err := model.GetBagInfo(snid, platform)
|
||||
if err != nil {
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) Shutdown() {
|
||||
module.UnregisteModule(this)
|
||||
// 对账时间戳初始化
|
||||
if bagInfo.Ts == 0 {
|
||||
bagInfo.Ts = time.Now().UnixNano()
|
||||
}
|
||||
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: &LoadData{
|
||||
BagInfo: bagInfo,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) Callback(player any, ret *internal.PlayerLoadReplay) {
|
||||
if ret == nil || ret.Data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, ok := ret.Data.(*LoadData)
|
||||
if !ok || data == nil || data.BagInfo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 背包数据
|
||||
newBagInfo := NewBagInfo(ret.Platform, ret.Snid)
|
||||
newBagInfo.Ts = data.BagInfo.Ts
|
||||
for k, bi := range data.BagInfo.BagItem {
|
||||
item := srvdata.GameItemMgr.Get(ret.Platform, bi.ItemId)
|
||||
if item != nil {
|
||||
if bi.ItemNum > 0 {
|
||||
newBagInfo.BagItem[k] = &Item{
|
||||
ItemId: bi.ItemId,
|
||||
ItemNum: bi.ItemNum,
|
||||
ObtainTime: bi.ObtainTime,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.Logger.Error("InitBagInfo err: item is nil. ItemId:", bi.ItemId)
|
||||
}
|
||||
}
|
||||
this.PlayerBag[ret.Snid] = newBagInfo
|
||||
}
|
||||
|
||||
type LoadAfterData struct {
|
||||
GameID []int32
|
||||
ItemLogs []*model.ItemLog
|
||||
StarTs, EndTs int64
|
||||
}
|
||||
|
||||
func (this *BagMgr) LoadAfter(platform string, snid int32) *internal.PlayerLoadReplay {
|
||||
var err error
|
||||
// 查询最近游戏
|
||||
gameID := model.GetRecentGame(platform, snid)
|
||||
|
||||
// 道具变更记录
|
||||
endTs := time.Now().UnixNano()
|
||||
var itemLogs []*model.ItemLog
|
||||
itemLogs, err = model.GetItemLog(platform, snid, this.PlayerBag[snid].Ts)
|
||||
if err != nil {
|
||||
logger.Logger.Errorf("LoadAfter GetItemLog err: %v", err)
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: nil,
|
||||
Data: &LoadAfterData{
|
||||
GameID: gameID,
|
||||
ItemLogs: itemLogs,
|
||||
StarTs: this.PlayerBag[snid].Ts,
|
||||
EndTs: endTs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) CallbackAfter(ret *internal.PlayerLoadReplay) {
|
||||
if ret == nil {
|
||||
return
|
||||
}
|
||||
if ret.Err != nil {
|
||||
logger.Logger.Error("BagMgr LoadAfter err:", ret.Err)
|
||||
return
|
||||
}
|
||||
|
||||
param, ok := ret.Data.(*LoadAfterData)
|
||||
if !ok {
|
||||
logger.Logger.Errorf("BagMgr LoadAfter BUGE 1")
|
||||
return
|
||||
}
|
||||
|
||||
p := PlayerMgrSington.GetPlayerBySnId(ret.Snid)
|
||||
if p == nil {
|
||||
logger.Logger.Errorf("BagMgr LoadAfter BUGE 2")
|
||||
return
|
||||
}
|
||||
|
||||
// 最近游戏
|
||||
p.GameID = param.GameID
|
||||
|
||||
// 道具变更记录
|
||||
bagInfo := this.PlayerBag[p.SnId]
|
||||
if bagInfo != nil {
|
||||
changeItems := make(map[int32]struct{})
|
||||
for _, v := range param.ItemLogs {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if v.Ts > param.StarTs && v.Ts <= param.EndTs {
|
||||
bagInfo.dirty = true
|
||||
num := v.Count
|
||||
if v.LogType == 1 {
|
||||
num = -num
|
||||
}
|
||||
if v.Ts > bagInfo.Ts {
|
||||
bagInfo.Ts = v.Ts
|
||||
}
|
||||
if v.Offline == 0 {
|
||||
// 在线数据恢复
|
||||
logger.Logger.Tracef("道具恢复 SnId:%v Item:%+v", p.SnId, *v)
|
||||
if _, ok := bagInfo.BagItem[v.ItemId]; !ok {
|
||||
bagInfo.BagItem[v.ItemId] = &Item{
|
||||
ItemId: v.ItemId,
|
||||
ItemNum: 0,
|
||||
ObtainTime: v.CreateTs,
|
||||
}
|
||||
}
|
||||
bagInfo.BagItem[v.ItemId].ItemNum += num
|
||||
changeItems[v.ItemId] = struct{}{}
|
||||
} else {
|
||||
// 离线时的变更
|
||||
logger.Logger.Tracef("处理离线道具变化 SnId:%v Item:%v", p.SnId, *v)
|
||||
this.OnChangeFuncs(&model.ChangeItemParam{
|
||||
SnId: p.SnId,
|
||||
ItemId: v.ItemId,
|
||||
ItemNum: num,
|
||||
GainWay: v.TypeId,
|
||||
RoomConfigId: v.RoomConfigId,
|
||||
GameId: v.GameId,
|
||||
GameFreeId: v.GameFreeId,
|
||||
Cost: v.Cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.SyncBagData(p.SnId, maps.Keys(changeItems)...)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) Save(platform string, snid int32, isSync, force bool) {
|
||||
bagInfo := this.GetBagInfo(snid)
|
||||
if bagInfo == nil {
|
||||
return
|
||||
}
|
||||
if !bagInfo.dirty && !force {
|
||||
return
|
||||
}
|
||||
logger.Logger.Tracef("SaveBagData: %+v", *bagInfo)
|
||||
|
||||
var err error
|
||||
f := func() {
|
||||
newBagInfo := &model.BagInfo{
|
||||
SnId: bagInfo.SnId,
|
||||
Platform: bagInfo.Platform,
|
||||
Ts: bagInfo.Ts,
|
||||
BagItem: make(map[int32]*model.Item),
|
||||
}
|
||||
for _, v := range bagInfo.BagItem {
|
||||
newBagInfo.BagItem[v.ItemId] = &model.Item{ItemId: v.ItemId, ItemNum: v.ItemNum, ObtainTime: v.ObtainTime}
|
||||
}
|
||||
err = model.UpBagItem(newBagInfo)
|
||||
}
|
||||
|
||||
cf := func() {
|
||||
if err == nil && this.PlayerBag[snid] != nil {
|
||||
this.PlayerBag[snid].dirty = false
|
||||
}
|
||||
}
|
||||
|
||||
if isSync {
|
||||
f()
|
||||
cf()
|
||||
return
|
||||
}
|
||||
|
||||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||||
f()
|
||||
return nil
|
||||
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
||||
cf()
|
||||
})).StartByExecutor(fmt.Sprintf("Player%v", snid))
|
||||
}
|
||||
|
||||
func (this *BagMgr) Release(platform string, snid int32) {
|
||||
delete(this.PlayerBag, snid)
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// other functions
|
||||
//============================================================================
|
||||
|
||||
// AddOnChangeFuncs 添加道具变更监听
|
||||
func (this *BagMgr) AddOnChangeFuncs(f ...func(param *model.ChangeItemParam)) {
|
||||
this.onChangeFuncs = append(this.onChangeFuncs, f...)
|
||||
}
|
||||
|
@ -706,7 +920,7 @@ func (this *BagMgr) VerifyUpJybInfo(p *Player, args *model.VerifyUpJybInfoArgs)
|
|||
}), "VerifyUpJybInfo").Start()
|
||||
}
|
||||
|
||||
// 兑换话费卡
|
||||
// ItemExchangeCard 兑换话费卡
|
||||
func (this *BagMgr) ItemExchangeCard(p *Player, itemId int32, money, cardType int32, logId string) bool {
|
||||
// 兑换码奖品
|
||||
var err error
|
||||
|
@ -799,226 +1013,3 @@ func (this *BagMgr) ItemExchangeCard(p *Player, itemId int32, money, cardType in
|
|||
}), fmt.Sprintf("ItemExChange%d", p.SnId)).Start()
|
||||
return true
|
||||
}
|
||||
|
||||
// ========================implement IPlayerLoad ==============================
|
||||
|
||||
type LoadData struct {
|
||||
BagInfo *model.BagInfo
|
||||
}
|
||||
|
||||
func (this *BagMgr) Load(platform string, snid int32, player any) *internal.PlayerLoadReplay {
|
||||
// 加载道具
|
||||
bagInfo, err := model.GetBagInfo(snid, platform)
|
||||
if err != nil {
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// 对账时间戳初始化
|
||||
if bagInfo.Ts == 0 {
|
||||
bagInfo.Ts = time.Now().UnixNano()
|
||||
}
|
||||
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: &LoadData{
|
||||
BagInfo: bagInfo,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) Callback(player any, ret *internal.PlayerLoadReplay) {
|
||||
if ret == nil || ret.Data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, ok := ret.Data.(*LoadData)
|
||||
if !ok || data == nil || data.BagInfo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 背包数据
|
||||
newBagInfo := NewBagInfo(ret.Platform, ret.Snid)
|
||||
newBagInfo.Ts = data.BagInfo.Ts
|
||||
for k, bi := range data.BagInfo.BagItem {
|
||||
item := srvdata.GameItemMgr.Get(ret.Platform, bi.ItemId)
|
||||
if item != nil {
|
||||
if bi.ItemNum > 0 {
|
||||
newBagInfo.BagItem[k] = &Item{
|
||||
ItemId: bi.ItemId,
|
||||
ItemNum: bi.ItemNum,
|
||||
ObtainTime: bi.ObtainTime,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.Logger.Error("InitBagInfo err: item is nil. ItemId:", bi.ItemId)
|
||||
}
|
||||
}
|
||||
this.PlayerBag[ret.Snid] = newBagInfo
|
||||
}
|
||||
|
||||
type LoadAfterData struct {
|
||||
GameID []int32
|
||||
ItemLogs []*model.ItemLog
|
||||
StarTs, EndTs int64
|
||||
}
|
||||
|
||||
func (this *BagMgr) LoadAfter(platform string, snid int32) *internal.PlayerLoadReplay {
|
||||
var err error
|
||||
// 查询最近游戏
|
||||
gameID := model.GetRecentGame(platform, snid)
|
||||
|
||||
// 道具变更记录
|
||||
endTs := time.Now().UnixNano()
|
||||
var itemLogs []*model.ItemLog
|
||||
itemLogs, err = model.GetItemLog(platform, snid, this.PlayerBag[snid].Ts)
|
||||
if err != nil {
|
||||
logger.Logger.Errorf("LoadAfter GetItemLog err: %v", err)
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: err,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
return &internal.PlayerLoadReplay{
|
||||
Platform: platform,
|
||||
Snid: snid,
|
||||
Err: nil,
|
||||
Data: &LoadAfterData{
|
||||
GameID: gameID,
|
||||
ItemLogs: itemLogs,
|
||||
StarTs: this.PlayerBag[snid].Ts,
|
||||
EndTs: endTs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) CallbackAfter(ret *internal.PlayerLoadReplay) {
|
||||
if ret == nil {
|
||||
return
|
||||
}
|
||||
if ret.Err != nil {
|
||||
logger.Logger.Error("BagMgr LoadAfter err:", ret.Err)
|
||||
return
|
||||
}
|
||||
|
||||
param, ok := ret.Data.(*LoadAfterData)
|
||||
if !ok {
|
||||
logger.Logger.Errorf("BagMgr LoadAfter BUGE 1")
|
||||
return
|
||||
}
|
||||
|
||||
p := PlayerMgrSington.GetPlayerBySnId(ret.Snid)
|
||||
if p == nil {
|
||||
logger.Logger.Errorf("BagMgr LoadAfter BUGE 2")
|
||||
return
|
||||
}
|
||||
|
||||
// 最近游戏
|
||||
p.GameID = param.GameID
|
||||
|
||||
// 道具变更记录
|
||||
bagInfo := this.PlayerBag[p.SnId]
|
||||
if bagInfo != nil {
|
||||
changeItems := make(map[int32]struct{})
|
||||
for _, v := range param.ItemLogs {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if v.Ts > param.StarTs && v.Ts <= param.EndTs {
|
||||
bagInfo.dirty = true
|
||||
num := v.Count
|
||||
if v.LogType == 1 {
|
||||
num = -num
|
||||
}
|
||||
if v.Ts > bagInfo.Ts {
|
||||
bagInfo.Ts = v.Ts
|
||||
}
|
||||
if v.Offline == 0 {
|
||||
// 在线数据恢复
|
||||
logger.Logger.Tracef("道具恢复 SnId:%v Item:%+v", p.SnId, *v)
|
||||
if _, ok := bagInfo.BagItem[v.ItemId]; !ok {
|
||||
bagInfo.BagItem[v.ItemId] = &Item{
|
||||
ItemId: v.ItemId,
|
||||
ItemNum: 0,
|
||||
ObtainTime: v.CreateTs,
|
||||
}
|
||||
}
|
||||
bagInfo.BagItem[v.ItemId].ItemNum += num
|
||||
changeItems[v.ItemId] = struct{}{}
|
||||
} else {
|
||||
// 离线时的变更
|
||||
logger.Logger.Tracef("处理离线道具变化 SnId:%v Item:%v", p.SnId, *v)
|
||||
this.OnChangeFuncs(&model.ChangeItemParam{
|
||||
SnId: p.SnId,
|
||||
ItemId: v.ItemId,
|
||||
ItemNum: num,
|
||||
GainWay: v.TypeId,
|
||||
RoomConfigId: v.RoomConfigId,
|
||||
GameId: v.GameId,
|
||||
GameFreeId: v.GameFreeId,
|
||||
Cost: v.Cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.SyncBagData(p.SnId, maps.Keys(changeItems)...)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *BagMgr) Save(platform string, snid int32, isSync, force bool) {
|
||||
bagInfo := this.GetBagInfo(snid)
|
||||
if bagInfo == nil {
|
||||
return
|
||||
}
|
||||
if !bagInfo.dirty && !force {
|
||||
return
|
||||
}
|
||||
logger.Logger.Tracef("SaveBagData: %+v", *bagInfo)
|
||||
|
||||
var err error
|
||||
f := func() {
|
||||
newBagInfo := &model.BagInfo{
|
||||
SnId: bagInfo.SnId,
|
||||
Platform: bagInfo.Platform,
|
||||
Ts: bagInfo.Ts,
|
||||
BagItem: make(map[int32]*model.Item),
|
||||
}
|
||||
for _, v := range bagInfo.BagItem {
|
||||
newBagInfo.BagItem[v.ItemId] = &model.Item{ItemId: v.ItemId, ItemNum: v.ItemNum, ObtainTime: v.ObtainTime}
|
||||
}
|
||||
err = model.UpBagItem(newBagInfo)
|
||||
}
|
||||
|
||||
cf := func() {
|
||||
if err == nil && this.PlayerBag[snid] != nil {
|
||||
this.PlayerBag[snid].dirty = false
|
||||
}
|
||||
}
|
||||
|
||||
if isSync {
|
||||
f()
|
||||
cf()
|
||||
return
|
||||
}
|
||||
|
||||
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
||||
f()
|
||||
return nil
|
||||
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
||||
cf()
|
||||
})).StartByExecutor(fmt.Sprintf("Player%v", snid))
|
||||
}
|
||||
|
||||
func (this *BagMgr) Release(platform string, snid int32) {
|
||||
delete(this.PlayerBag, snid)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue