| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- package storage
- import (
- actorRemote "f1-game/internal/actor_remote"
- capp "f1-game/internal/cherry_app"
- "f1-game/internal/code"
- "f1-game/internal/data"
- "f1-game/internal/enum"
- "f1-game/internal/event"
- facade "f1-game/internal/facade"
- nameRoute "f1-game/internal/name/route"
- "f1-game/internal/pb"
- "f1-game/internal/sessions"
- "f1-game/internal/types"
- assetOrigin "f1-game/nodes/game/player/asset/origin"
- mapCall "f1-game/nodes/map/internal/call"
- "f1-game/nodes/map/internal/db"
- clog "github.com/cherry-game/cherry/logger"
- cproto "github.com/cherry-game/cherry/net/proto"
- )
- var (
- srv = newService()
- )
- func newService() *service {
- instance := &service{}
- instance.load()
- return instance
- }
- func Service() *service {
- return srv
- }
- type service struct {
- facade.PlayerServiceBase[*db.MapPlayerTable]
- }
- func (p *service) load() {
- }
- func (p *service) OnLogin(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
- if session.Contains(sessions.IsNewPlayer) {
- clog.Infof("map storage init: playerID = %d", mapPlayerTable.PlayerID)
- // 初始化资源
- p.AssetAdds(mapPlayerTable.PlayerID, data.Const.PlayerInitCurrencies, assetOrigin.CreatePlayer, false)
- }
- }
- // func (p *service) OnLogined(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
- // }
- // func (p *service) OnLogout(mapPlayerTable *db.MapPlayerTable) {
- // }
- // func (p *service) OnReset(mapPlayerTable *db.MapPlayerTable, time *ctime.CherryTime, byLogin bool) {
- // }
- func (p *service) Push(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(mapPlayerTable.PlayerID)
- proto := mapPlayerStorageTable.Storage.ToProto()
- sessions.PushWithSession(session, nameRoute.PushMapPlayer_StorageList, proto)
- }
- // ChangePush 仓库变更推送
- func (p *service) ChangePush(playerID int64, idList ...int32) {
- if len(idList) < 1 {
- return
- }
- var (
- mapPlayerStorageTable = db.GetMapPlayerStorageTable(playerID)
- rsp = &pb.ItemList{
- Currencies: map[int32]*pb.Currency{},
- }
- )
- for _, id := range idList {
- // 只推送地图里面的资源
- if enum.IsMapCurrency(id) {
- entity := mapPlayerStorageTable.Storage.CurrencyMap.GetEntity(id)
- proto := entity.ToProto()
- rsp.Currencies[entity.ID] = &proto
- }
- }
- if len(rsp.Currencies) < 1 {
- return
- }
- sessions.PushPlayer(playerID, nameRoute.PushMapPlayer_StoragChange, rsp)
- }
- func (p *service) Contain(playerID int64, id int32) int32 {
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- if _, found := data.Item.GetByID(id); !found {
- return code.ConfigNotFound_Item
- }
- if mapPlayerStorageTable.Storage.CurrencyMap.Get(id) < 1 {
- return code.ItemNotEnough
- }
- return code.OK
- }
- func (p *service) isEnough(playerID int64, id int32, num int64) bool {
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- availableNum := mapPlayerStorageTable.Storage.CurrencyMap.Get(id)
- if availableNum < 1 || availableNum < num {
- return false
- }
- return true
- }
- func (p *service) add(playerID int64, id int32, num int64, origin assetOrigin.Origin, save, push bool) (types.Asset, int32) {
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- row, found := data.Item.GetByID(id)
- if !found {
- return types.NoneAsset, code.ConfigNotFound_Item
- }
- if row.ParseType != enum.AssetType_Currency {
- return types.NoneAsset, code.CurrencyTypeError
- }
- if !enum.IsMapCurrency(id) {
- return types.NoneAsset, code.CurrencyTypeError
- }
- if num < 1 {
- return types.NoneAsset, code.ItemNumError
- }
- _, ok := mapPlayerStorageTable.Storage.CurrencyMap.Increase(id, num)
- if !ok {
- return types.NoneAsset, code.ItemNotEnough
- }
- if save {
- mapPlayerStorageTable.Save2Queue()
- }
- if push {
- p.ChangePush(playerID, id)
- }
- returnAsset := types.Asset{
- ID: id,
- Num: num,
- }
- return returnAsset, code.OK
- }
- func (p *service) sub(playerID int64, id int32, num int64, origin assetOrigin.Origin, save, push bool) int32 {
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- if num < 1 {
- return code.ItemNumError
- }
- _, found := data.Item.GetByID(id)
- if !found {
- return code.ConfigNotFound_Item
- }
- // 优先扣除绑定资源,再扣除非绑定资源
- changeAssets, ok := mapPlayerStorageTable.Storage.CurrencyMap.Decrease(id, num)
- if !ok {
- return code.ItemNotEnough
- }
- if save {
- mapPlayerStorageTable.Save2Queue()
- }
- var changeIDList []int32
- for _, asset := range changeAssets {
- changeIDList = append(changeIDList, asset.ID)
- }
- if push {
- p.ChangePush(playerID, changeIDList...)
- }
- return code.OK
- }
- // CheckAutoAdd 检查每几秒资源发放情况
- func (p *service) CheckAutoAdd(playerTable *db.MapPlayerTable, nowSecond int64, isOnline bool) {
- var (
- playerStorageTable = db.GetMapPlayerStorageTable(playerTable.PlayerID)
- itemAddSecond = data.Const.ItemAddSecond
- changePushIDList []int32
- save bool
- )
- for _, itemID := range enum.ItemMaxNumList {
- // 产出的量
- yield := p.GetMapCurrencyYield(playerTable, itemID)
- if yield < 1 {
- continue
- }
- // 只有能产出的时候才初始化 UpdateTime
- if playerStorageTable.Storage.CurrencyMap.CheckInitUpdateTime(itemID, nowSecond) {
- save = true
- }
- if !playerStorageTable.Storage.CurrencyMap.CheckAutoAdd(itemID, nowSecond, yield, itemAddSecond) {
- continue
- }
- save = true
- changePushIDList = append(changePushIDList, itemID)
- if playerStorageTable.Storage.CurrencyMap.IsFull(itemID) {
- actorRemote.GamePlayer.GamePlayerCallSystemMsg(playerTable.GameNodeID, playerTable.PlayerID, enum.ChatMsgType_resourceMax, nil, nil, itemID)
- }
- }
- if save {
- playerStorageTable.Save2Queue()
- }
- if len(changePushIDList) > 0 && isOnline {
- p.ChangePush(playerTable.PlayerID, changePushIDList...)
- }
- }
- // 获取资源总产量
- func (p *service) GetMapCurrencyYield(mapPlayerTable *db.MapPlayerTable, itemIDs ...int32) int64 {
- if len(itemIDs) <= 0 {
- return 0
- }
- var (
- mapResYields = mapPlayerTable.GetAllYield()
- totalYield = int64(0)
- )
- for _, itemID := range itemIDs {
- // 绑定资源
- if attrID, ok := enum.MapItemAttrs[itemID]; ok {
- totalYield += p.calcAssetOutputFinalAttr(mapPlayerTable, attrID)
- }
- // 非绑定资源
- if _, ok := enum.UnBindingResourceMap[itemID]; ok {
- totalYield += mapResYields.GetValue(itemID)
- }
- }
- return totalYield
- }
- func (p *service) IsEnough(playerID int64, id int32, num int64) bool {
- if !enum.IsMapCurrency(id) {
- return true
- }
- if !p.isEnough(playerID, id, num) {
- return false
- }
- return true
- }
- func (p *service) IsAllEnough(playerID int64, assets types.Assets) bool {
- for _, asset := range assets {
- if !enum.IsMapCurrency(asset.ID) {
- continue
- }
- if !p.isEnough(playerID, asset.ID, asset.Num) {
- return false
- }
- }
- return true
- }
- // AssetAdds 增加多个资源,地图和游戏节点分别增加
- func (p *service) AssetAdds(playerID int64, assets types.Assets, ao assetOrigin.Origin, isPush ...bool) (types.Assets, int32) {
- var (
- mapPlayerTable = db.GetMapPlayerTable(playerID)
- mapAssets = types.Assets{}
- mapLeagueAssets = types.Assets{}
- gameAssets = types.Assets{}
- retAssets = types.Assets{}
- )
- // 检查玩家表是否存在
- if mapPlayerTable == nil {
- return retAssets, code.PlayerNotFound
- }
- if len(assets) == 0 {
- return retAssets, code.IllegalArgument
- }
- // TODO 默认推送
- push := true
- if len(isPush) > 0 {
- push = isPush[0]
- }
- // 资源拆解分组,地图的资源和游戏的资源分开处理
- for _, asset := range assets {
- if enum.IsLeagueCurrency(asset.ID) {
- mapLeagueAssets.AddAsset(asset)
- } else if enum.IsMapCurrency(asset.ID) {
- mapAssets.AddAsset(asset)
- } else {
- gameAssets.AddAsset(asset)
- }
- }
- if mapAssets.Len() > 0 {
- for _, asset := range mapAssets {
- retAsset, errCode := p.add(playerID, asset.ID, asset.Num, ao, true, push)
- if code.IsFail(errCode) {
- return retAssets, errCode
- }
- retAssets.AddAsset(&retAsset)
- }
- // 发送获得奖励的系统消息
- actorRemote.GamePlayer.GamePlayerCallSystemMsg(mapPlayerTable.GameNodeID, playerID, enum.ChatMsgType_reward, mapAssets, nil)
- capp.PostEvent(event.NewItemAdd(playerID, mapAssets, ao))
- }
- if mapLeagueAssets.Len() > 0 {
- mapCall.League.MapLeagueAddAssets(playerID, mapPlayerTable.LeagueID, mapLeagueAssets)
- }
- if gameAssets.Len() > 0 {
- retAssetsProto, errCode := actorRemote.GamePlayer.AssetAdd(mapPlayerTable.GameNodeID, playerID, gameAssets, ao)
- if code.IsFail(errCode) {
- return retAssets, errCode
- }
- for _, asset := range retAssetsProto.List {
- retAsset := types.Asset{
- ID: asset.Id,
- Num: asset.Num,
- GUID: asset.Guid,
- }
- retAssets.AddAsset(&retAsset)
- }
- }
- return retAssets, code.OK
- }
- // AssetAddOne 单个资源增加,地图和游戏节点分别增加
- func (p *service) AssetAddOne(playerID int64, id int32, num int64, origin assetOrigin.Origin, isPush ...bool) (types.Assets, int32) {
- assets := types.Assets{
- {
- ID: id,
- Num: num,
- },
- }
- return p.AssetAdds(playerID, assets, origin, isPush...)
- }
- // AssetSubs 扣除多个资源,地图和游戏节点分别扣除
- func (p *service) AssetSubs(playerID int64, assets types.Assets, origin assetOrigin.Origin, isPush ...bool) (types.Assets, int32) {
- var (
- mapAssets = types.Assets{}
- gameAssets = types.Assets{}
- retAssets = types.Assets{}
- )
- if len(assets) == 0 {
- return nil, code.IllegalArgument
- }
- // TODO 默认推送
- push := true
- if len(isPush) > 0 {
- push = isPush[0]
- }
- for _, asset := range assets {
- // 不支持联盟货币消耗
- if enum.IsLeagueCurrency(asset.ID) {
- clog.Warnf("AssetSubs league currency not support, playerID: %d, asset: %+v", playerID, asset)
- return nil, code.LeagueCurrencyNotSupport
- }
- if enum.IsMapCurrency(asset.ID) {
- mapAssets.AddAsset(asset)
- } else {
- gameAssets.AddAsset(asset)
- }
- }
- // 先检查地图这边的资源是否足够
- if !p.IsAllEnough(playerID, mapAssets) {
- return nil, code.CurrencyNotEnough
- }
- if len(gameAssets) > 0 {
- mapPlayerTable := db.GetMapPlayerTable(playerID)
- // 检查玩家表是否存在
- if mapPlayerTable == nil {
- return retAssets, code.PlayerNotFound
- }
- // 发送到游戏节点扣除游戏资源
- retAssetsProto, errCode := actorRemote.GamePlayer.AssetSub(mapPlayerTable.GameNodeID, playerID, gameAssets, origin)
- if code.IsFail(errCode) {
- return nil, errCode
- }
- for _, asset := range retAssetsProto.List {
- retAsset := types.Asset{
- ID: asset.Id,
- Num: asset.Num,
- GUID: asset.Guid,
- }
- retAssets.AddAsset(&retAsset)
- }
- }
- for _, asset := range mapAssets {
- errCode := p.sub(playerID, asset.ID, asset.Num, origin, true, push)
- if code.IsFail(errCode) {
- return nil, errCode
- }
- retAssets.AddAsset(asset)
- }
- return retAssets, code.OK
- }
- // AssetSubOne 单个资源扣除,地图和游戏节点分别扣除
- func (p *service) AssetSubOne(playerID int64, id int32, num int64, origin assetOrigin.Origin, isPush ...bool) (types.Assets, int32) {
- assets := types.Assets{
- {
- ID: id,
- Num: num,
- },
- }
- return p.AssetSubs(playerID, assets, origin, isPush...)
- }
- // Get 获取资源数量
- func (p *service) Get(playerID int64, id int32) int64 {
- if !enum.IsMapCurrency(id) {
- return 0
- }
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- return mapPlayerStorageTable.Storage.CurrencyMap.Get(id)
- }
- // 计算各个模块给资源产出的加成
- // 1,城建
- // 2,VIP
- func (p *service) calcAssetOutputFinalAttr(mapPlayerTable *db.MapPlayerTable, attrID int32) int64 {
- facilityValue := mapPlayerTable.Facilities.Attrs.GetI64(attrID)
- vipValue := int64(0)
- if !mapPlayerTable.Vip.IsExpired {
- vipValue = mapPlayerTable.Vip.Attrs.GetI64(attrID)
- }
- attrValue := facilityValue + vipValue
- return attrValue
- }
|