package mapLeague import ( actorRemote "f1-game/internal/actor_remote" "f1-game/internal/code" "f1-game/internal/component/redis" "f1-game/internal/constant" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" "f1-game/internal/extend/math" nameLocal "f1-game/internal/name/local" nameRedis "f1-game/internal/name/redis" nameRemote "f1-game/internal/name/remote" "f1-game/internal/pb" "f1-game/internal/sessions" "f1-game/internal/types" ao "f1-game/nodes/game/player/asset/origin" mapCall "f1-game/nodes/map/internal/call" "f1-game/nodes/map/internal/db" dbLeague "f1-game/nodes/map/internal/db/data/league" leagueBase "f1-game/nodes/map/league/base" leagueStorage "f1-game/nodes/map/league/storage" cstring "github.com/cherry-game/cherry/extend/string" cproto "github.com/cherry-game/cherry/net/proto" ) func (p *actorLeague) initStorage() { p.Local().Register(nameLocal.MapLeague_StorageInfo, p.storageInfo) p.Local().Register(nameLocal.MapLeague_RatioUpdate, p.ratioUpdate) p.Local().Register(nameLocal.MapLeague_FundBonus, p.fundBonus) p.Remote().Register(nameRemote.MapLeague_AddRatioAssets, p.addRatioAssets) p.Remote().Register(nameRemote.MapLeague_AddAssets, p.addAssets) } // 获取仓库信息 func (p *actorLeague) storageInfo(session *cproto.Session, _ *pb.None) { mapLeagueStorageTable := db.GetMapLeagueStorageTable(p.leagueID) p.Response(session, mapLeagueStorageTable.Storage.ToProto()) } // 修改资源税率 func (p *actorLeague) ratioUpdate(session *cproto.Session, req *pb.I32I32) { var ( mapLeagueStorageTable = db.GetMapLeagueStorageTable(p.leagueID) currencyID = req.Key // 货币ID ratio = req.Value // 税率值 playerID = sessions.GetPlayerID(session) // 操作的玩家ID ) // 判断是否有权限 if !p.leagueTable.LeagueInfo.IsLeader(playerID) { p.ResponseCode(session, code.LeagueNotLeader) return } // 税率调整次数不足 if mapLeagueStorageTable.Storage.GetRatioRemainAdjustCount(currencyID) < 1 { p.ResponseCode(session, code.LeagueTaxRateNotEnough) return } leagueStorageRow, found := data.LeagueStorage.GetByID(currencyID) if !found { p.ResponseCode(session, code.ConfigNotFound_LeagueStorage) return } // 设值不满足条件 if ratio < leagueStorageRow.MinRate || ratio > leagueStorageRow.MaxRate { p.ResponseCode(session, code.LeagueTaxRateValueError) return } storageRatio, found := mapLeagueStorageTable.Storage.RatioMap.Get(currencyID) if !found { // 没有就new一个 storageRatio = dbLeague.NewStorageRatio(currencyID, leagueStorageRow.InitRate) mapLeagueStorageTable.Storage.RatioMap.Put(currencyID, storageRatio) } // 更新税率,返回旧的税率 oldRatio := storageRatio.UpdateRatio(currencyID, ratio) mapLeagueStorageTable.Save2Queue() leagueLogTable, _ := db.GetMapLeagueLogTable(p.leagueID) // 获取玩家名称 playerName := leagueBase.Service().GetPlayerName(playerID) if currencyID == enum.LeagueItemIDF { leagueLogTable.AddLeagueLog(enum.Log_LeagueFRatioUpdate, playerName, cstring.ToString(oldRatio), cstring.ToString(ratio)) } else { leagueLogTable.AddLeagueLog(enum.Log_LeagueRateUpdate, playerName, cstring.ToString(currencyID), cstring.ToString(oldRatio), cstring.ToString(ratio)) } leagueLogTable.Save2Queue() p.Response(session, storageRatio.ToProto()) } // F币分红 func (p *actorLeague) fundBonus(session *cproto.Session, req *pb.LeagueFundBonus) { var ( mapLeagueStorageTable = db.GetMapLeagueStorageTable(p.leagueID) playerID = sessions.GetPlayerID(session) // 操作者 memberIDList = req.MemberIDList // 成员ID列表 memberNum = int64(len(memberIDList)) // 玩家数量 totalFund = req.TotalFund // 分配的F币数量 ) if totalFund < 1 || memberNum < 1 { p.ResponseCode(session, code.IllegalArgument) return } // 判断是否有权限 if !p.leagueTable.LeagueInfo.IsLeader(playerID) { p.ResponseCode(session, code.LeagueNotLeader) return } leagueStorageRow, found := data.LeagueStorage.GetByID(enum.LeagueItemIDF) if !found { p.ResponseCode(session, code.ConfigNotFound_LeagueStorage) return } // 最小值限制 if totalFund < leagueStorageRow.MinFBonus { p.ResponseCode(session, code.LeagueFundBonusMinValueError) return } // 资源分配次数不足 if mapLeagueStorageTable.Storage.GetFundBonusRemainCount() < 1 { p.ResponseCode(session, code.LeagueFundBonusRemainCountNotEnough) return } // F币不足 if !p.isEnoughOne(enum.LeagueItemIDF, totalFund) { p.ResponseCode(session, code.LeagueFundBonusCountNotEnough) return } leaugeMemberTable, _ := db.GetMapLeagueMemberTable(p.leagueID) for _, sendPlayerID := range memberIDList { // 检查请求的公会成员ID是否存在 if _, found := leaugeMemberTable.GetLeagueMember(sendPlayerID); !found { p.ResponseCode(session, code.LeagueMemberNotExist) return } } // 把余数部分去掉,不扣除了 remainderCount := totalFund % memberNum if remainderCount > 0 { totalFund = totalFund - remainderCount } // 平均F币数量 averageVal := totalFund / memberNum if averageVal < 1 { p.ResponseCode(session, code.LeagueFundBonusMinValueError) return } // 加上盟主的ID totalPlayerIDList := types.NewList(memberIDList...) totalPlayerIDList.Add(playerID) playerDataMap := redis.Game.GetPlayerDataMap(totalPlayerIDList, nameRedis.PlayerBaseFields...) if len(playerDataMap) == 0 { p.ResponseCode(session, code.DataNotFound) return } // 调整次数 mapLeagueStorageTable.Storage.UpdateFundBonusCount() // 扣除F币 cost := types.Assets{} cost.Add(enum.ItemIDF, totalFund) p.subAssets(cost) var ( // 记录发放的成员名称列表 playerNameList []string // 分配的F币 rewards = types.Assets{} ) rewards.Add(enum.ItemIDF, averageVal) for _, sendPlayerID := range memberIDList { // 累计分配数量 member, found := leaugeMemberTable.GetLeagueMember(sendPlayerID) if !found { continue } // 记录成员每周分配的F币数量 member.RecordWeeklyFund(averageVal) playerData, found := playerDataMap[sendPlayerID] if !found { continue } // 发送邮件 actorRemote.GameMail.SendMail(playerData.GameNodeID, sendPlayerID, constant.MailID_LeagueFund, rewards, nil) // 记录发放的成员 sendPlayerName := cstring.ToString(sendPlayerID) if found { sendPlayerName = playerData.PlayerName } playerNameList = append(playerNameList, sendPlayerName) } mapLeagueStorageTable.Save2Queue() leaugeMemberTable.Save2Queue() // 获取玩家名称 playerName := playerDataMap[playerID].PlayerName leagueLogTable, _ := db.GetMapLeagueLogTable(p.leagueID) // TODO F币消耗日志模板需要增加 leagueLogTable.AddLeagueLog(enum.Log_LeagueFundBonus, playerName, cstring.ToString(totalFund), cstring.ToString(playerNameList)) leagueLogTable.Save2Queue() rsp := &pb.I32I64{ Key: mapLeagueStorageTable.Storage.GetFundBonusRemainCount(), Value: mapLeagueStorageTable.Storage.GetFundBonusCount(), } p.Response(session, rsp) } // 增加联盟税收获取的资源 func (p *actorLeague) addRatioAssets(req *pb.AddAssets) { var ( mapLeagueStorageTable = db.GetMapLeagueStorageTable(p.leagueID) playerID = req.PlayerID // 交税玩家ID assets = req.Assets origin = req.Origin eventAssets = types.Assets{} ) leagueLogTable, _ := db.GetMapLeagueLogTable(p.leagueID) playerData := leagueBase.Service().GetPlayerData(playerID) // TODO 收集每次应该只有一种资源,先预留多种资源的处理 for _, asset := range assets { if !enum.IsMapCurrency(asset.Id) { p.Warn("addRatioAssets not league currency : %v", asset) continue } // 获取联盟资源ID leaugeItemID, found := enum.GetLeagueRatioItemID(asset.Id) if !found { p.Warn("addRatioAssets not league currency : %v", asset) continue } // 获取联盟资源当前税率 ratio := mapLeagueStorageTable.Storage.GetRatio(leaugeItemID) if ratio == 0 { p.Warn("addRatioAssets ratio is 0 : %v", asset) continue } // 向上取整计算需要交的税 leagueNum := math.Ceil[float64, int64](float64(asset.Num) * float64(ratio) / constant.PctBase) // 增加联盟资源 p.addAsset(leaugeItemID, leagueNum) // 玩家交完税后的数量 asset.Num = asset.Num - leagueNum playerAsset := types.Assets{} playerAsset.Add(asset.Id, asset.Num) mapCall.Player.AddAssets(playerID, playerAsset, ao.Get(origin)) // F币日志处理 if asset.Id == enum.LeagueItemIDF { leagueLogTable.AddLeagueLog(enum.Log_LeagueCollectResourceF, playerData.PlayerName, cstring.ToString(asset.Num), cstring.ToString(leagueNum)) continue } // 其他资源日志处理 leagueLogTable.AddLeagueLog(enum.Log_LeagueCollectResource, playerData.PlayerName, cstring.ToString(asset.Id), cstring.ToString(asset.Num), cstring.ToString(leagueNum)) eventAssets.Add(asset.Id, asset.Num) } leagueLogTable.Save2Queue() // 发送玩家采集事件 p.PostEvent(event.NewPlayerResGather(playerID, eventAssets)) } // 检查联盟资源 单个 func (p *actorLeague) isEnoughOne(currencyID int32, count int64) bool { assets := types.Assets{} assets.Add(currencyID, count) return p.isEnough(assets) } // 检查联盟资源 func (p *actorLeague) isEnough(assets types.Assets) bool { mapLeagueStorageTable := db.GetMapLeagueStorageTable(p.leagueID) for _, asset := range assets { if !enum.IsLeagueCurrency(asset.ID) { p.Warn("isEnough not league currency : %v", asset) continue } if mapLeagueStorageTable.Storage.CurrencyMap.GetEntity(asset.ID).Num < asset.Num { return false } } return true } // 增加联盟货币 单个 func (p *actorLeague) addAsset(currencyID int32, count int64) { if !enum.IsLeagueCurrency(currencyID) { p.Warn("addAsset not league currencyID: %v, count: %v", currencyID, count) return } mapLeagueStorageTable := db.GetMapLeagueStorageTable(p.leagueID) mapLeagueStorageTable.Storage.CurrencyMap.Increase(currencyID, count) mapLeagueStorageTable.Save2Queue() } // 增加联盟货币 多个 func (p *actorLeague) addAssets(req *pb.AddAssets) { retAssets := types.Assets{} for _, asset := range req.Assets { if !enum.IsLeagueCurrency(asset.Id) { p.Warn("addAssets not league currency : %v", asset) continue } retAssets.Add(asset.Id, asset.Num) } leagueStorage.Service().AddAssets(p.leagueTable, retAssets) } // 扣除联盟资源 func (p *actorLeague) subAssets(assets types.Assets) int32 { if !p.isEnough(assets) { p.Warn("subAssets not enough : %v", assets) return code.ItemNotEnough } mapLeagueStorageTable := db.GetMapLeagueStorageTable(p.leagueID) subAssets := types.Assets{} for _, asset := range assets { if !enum.IsLeagueCurrency(asset.ID) { p.Warn("subAssets not league currency : %v", asset) continue } mapLeagueStorageTable.Storage.CurrencyMap.Decrease(asset.ID, asset.Num) subAssets.AddAsset(asset) } mapLeagueStorageTable.Save2Queue() p.Debug("subAssets: %v", subAssets) return code.OK }