package mapPlayer 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" nameActor "f1-game/internal/name/actor" nameLocal "f1-game/internal/name/local" nameRedis "f1-game/internal/name/redis" nameRemote "f1-game/internal/name/remote" nameRoute "f1-game/internal/name/route" "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" "f1-game/nodes/map/player/league" "f1-game/nodes/map/player/season" ctime "github.com/cherry-game/cherry/extend/time" cfacade "github.com/cherry-game/cherry/facade" cproto "github.com/cherry-game/cherry/net/proto" ) func (p *actorPlayer) initPlayerLeague() { p.Local().Register(nameLocal.MapPlayer_LeagueCreate, p.leagueCreate) p.Local().Register(nameLocal.MapPlayer_LeagueJoin, p.leagueJoin) p.Local().Register(nameLocal.MapPlayer_LeagueList, p.leagueList) p.Local().Register(nameLocal.MapPlayer_LeagueSearch, p.leagueSearch) p.Local().Register(nameLocal.MapPlayer_LeagueInfo, p.leagueInfo) p.Local().Register(nameLocal.MapPlayer_LeagueNameChange, p.leagueNameChange) p.Local().Register(nameLocal.MapPlayer_LeagueAbbNameChange, p.leagueAbbNameChange) p.Local().Register(nameLocal.MapPlayer_LeagueDiplomacyList, p.leagueDiplomacyList) p.Remote().Register(nameRemote.MapLeague_JoinNotice, p.leagueJoinNotice) p.Remote().Register(nameRemote.MapLeague_QuitNotice, p.leagueQuitNotice) // TODO 未处理 //p.Event().Register(nameEvent.Player_Login, p.onLogin) } // 创建联盟 func (p *actorPlayer) leagueCreate(session *cproto.Session, req *pb.LeagueCreateRequest) { playerTable := db.GetMapPlayerTable(p.playerID) var ( leagueName = req.LeagueName leagueAbbName = req.LeagueAbbName flagBg = req.FlagBg flagIcon = req.FlagIcon ) //判断玩家是否加入联盟 if playerTable.LeagueID > 0 { p.ResponseCode(session, code.LeagueAlreadyJoin) return } // TODO 判断玩家主城等级是否满足 等待后续城建迁移完成处理 // 检测旗帜背景是否合法 flagBgRow, found := data.LeagueFlag.GetByFlagID(flagBg) if !found { p.ResponseCode(session, code.LeagueFlagBgNotExist) return } if flagBgRow.FlagType != enum.League_FlagBg { p.ResponseCode(session, code.LeagueFlagBgError) return } // 检测旗帜图标是否合法 flagIconRow, found := data.LeagueFlag.GetByFlagID(flagIcon) if !found { p.ResponseCode(session, code.LeagueFlagIconNotExist) return } if flagIconRow.FlagType != enum.League_FlagIcon { p.ResponseCode(session, code.LeagueFlagIconError) return } // TODO 暂时从redis获取GameNodeID 后面部队和进入地图流程更新再调整 playerData := redis.Game.GetPlayerData(p.playerID, nameRedis.PlayerGameNodeFields...) if playerData == nil { p.ResponseCode(session, code.DataNotFound) return } // 请求game检测创建联盟需要消耗的金币满足 errCode := actorRemote.GamePlayer.AssetCheck(playerData.GameNodeID, p.playerID, data.Const.LeagueCreateCost) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 尝试创建联盟 leagueID, errCode := mapCall.League.LeagueCreate(p.playerID, leagueName, leagueAbbName, flagBg, flagIcon) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 请求game扣除创建联盟消耗 actorRemote.GamePlayer.AssetSub(playerData.GameNodeID, p.playerID, data.Const.LeagueCreateCost, ao.CreateLeagueCost) // 执行联盟创建通知 p.doLeagueJoinNotice(leagueID, leagueName, false) // 发送联盟创建事件 p.PostEvent(event.NewLeagueCreate(p.playerID, leagueID)) p.ResponseCode(session, code.OK) } // 申请加入联盟 只处理玩家申请加入联盟的流程 func (p *actorPlayer) leagueJoin(session *cproto.Session, req *pb.I64) { var ( leagueID = req.Value playerTable = db.GetMapPlayerTable(p.playerID) ) if leagueID <= 0 { p.ResponseCode(session, code.IllegalArgument) return } if playerTable.LeagueID > 0 { p.ResponseCode(session, code.LeagueAlreadyJoin) return } // 判断退出联盟冷却时间 if data.Const.CheckLeagueQuitCD(playerTable.LeagueQuitTime) { p.ResponseCode(session, code.LeagueQuitCD) return } // 申请加入联盟 errCode := mapCall.League.LeagueJoin(p.playerID, leagueID, playerTable.Facilities.GetFacilityLevel(enum.Facility_MainID)) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } p.ResponseCode(session, code.OK) } // 获取联盟列表 func (p *actorPlayer) leagueList(session *cproto.Session, req *pb.None) { leagueList, errCode := mapCall.League.LeagueList(p.playerID) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } p.Response(session, leagueList) } // 获取联盟外交列表 func (p *actorPlayer) leagueDiplomacyList(session *cproto.Session, _ *pb.None) { var ( diplpmacyReq = &pb.None{} resp = &pb.LeagueDiplomacyInfos{} target = cfacade.NewPath("", nameActor.Map_League) ) errCode := p.CallWait(target, nameRemote.MapLeague_DiplomacyInfos, diplpmacyReq, resp) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } p.Response(session, resp) } // 联盟搜索 func (p *actorPlayer) leagueSearch(session *cproto.Session, req *pb.Str) { keyword := req.Value if len(keyword) < 1 { p.ResponseCode(session, code.IllegalArgument) return } rsp, errCode := mapCall.League.LeagueSearch(keyword) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } if len(rsp.List) < 1 { p.ResponseCode(session, code.LeagueSearchNotExist) return } p.Response(session, rsp) } // 联盟信息 func (p *actorPlayer) leagueInfo(session *cproto.Session, req *pb.I64) { leagueID := req.Value if leagueID < 1 { p.ResponseCode(session, code.IllegalArgument) return } var ( infoReq = &pb.I64{Value: leagueID} resp = &pb.League{} target = cfacade.NewChildPath("", nameActor.Map_League, leagueID) ) errCode := p.CallWait(target, nameRemote.MapLeague_Info, infoReq, resp) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } p.Response(session, resp) } // 联盟名称更改 func (p *actorPlayer) leagueNameChange(session *cproto.Session, req *pb.Str) { playerTable := db.GetMapPlayerTable(p.playerID) leagueID := playerTable.LeagueID if leagueID < 1 { p.ResponseCode(session, code.LeagueNotJoin) return } assets := types.Assets{} assets.Add(data.Const.LeagueChangeNameCost.ID, data.Const.LeagueChangeNameCost.Num) errCode := actorRemote.GamePlayer.AssetCheck(playerTable.GameNodeID, p.playerID, assets) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } var ( changeReq = &pb.LeagueNameChange{ PlayerID: p.playerID, LeagueID: leagueID, NewName: req.Value, } target = cfacade.NewPath("", nameActor.Map_League) ) errCode = p.CallWait(target, nameRemote.MapLeague_NameChange, changeReq, nil) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } actorRemote.GamePlayer.AssetSub(playerTable.GameNodeID, p.playerID, assets, ao.LeagueChangeNameCost) resp := &pb.Str{ Value: req.Value, } p.Response(session, resp) } // 联盟简称更改 func (p *actorPlayer) leagueAbbNameChange(session *cproto.Session, req *pb.Str) { playerTable := db.GetMapPlayerTable(p.playerID) leagueID := playerTable.LeagueID if leagueID < 1 { p.ResponseCode(session, code.LeagueNotJoin) return } assets := types.Assets{} assets.Add(data.Const.LeagueChangeAbbNameCost.ID, data.Const.LeagueChangeAbbNameCost.Num) errCode := actorRemote.GamePlayer.AssetCheck(playerTable.GameNodeID, p.playerID, assets) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } var ( changeReq = &pb.LeagueNameChange{ PlayerID: p.playerID, LeagueID: leagueID, NewName: req.Value, } target = cfacade.NewPath("", nameActor.Map_League) ) errCode = p.CallWait(target, nameRemote.MapLeague_AbbNameChange, changeReq, nil) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 扣除消耗 actorRemote.GamePlayer.AssetSub(playerTable.GameNodeID, p.playerID, assets, ao.LeagueChangeAbbNameCost) resp := &pb.Str{ Value: req.Value, } p.Response(session, resp) } // 加入联盟通知 func (p *actorPlayer) leagueJoinNotice(req *pb.LeagueJoinNotice) int32 { errCode := p.doLeagueJoinNotice(req.LeagueID, req.LeagueName, true) if code.IsFail(errCode) { return errCode } playerTable := db.GetMapPlayerTable(p.playerID) playerTable.CastleResYield.Add(req.CastleConfigIDs...) playerTable.Save2Queue() p.Debug("[leagueJoinNotice] update castle res yield: %v", req.CastleConfigIDs) return code.OK } func (p *actorPlayer) doLeagueJoinNotice(leagueID int64, leagueName string, join bool) int32 { p.Debug("[doLeagueJoinNotice] join league. playerID:%d, leagueID: %d", p.playerID, leagueID) playerTable := db.GetMapPlayerTable(p.playerID) if playerTable.LeagueID > 0 && playerTable.LeagueID != leagueID { p.Debug("[doLeagueJoinNotice] join league fail. playerID:%d, leagueID: %d", p.playerID, leagueID) return code.LeagueAlreadyJoinOther } // 更新玩家所属联盟ID playerTable.LeagueID = leagueID playerTable.Save2Queue() // 创建玩家关联联盟聊天室 target := cfacade.NewChildPath(playerTable.GameNodeID, nameActor.GamePlayer, p.playerID) p.Call(target, nameRemote.Player_ChatRoomUpdate, &pb.PlayerChatRoomUpdate{ ChatType: int32(enum.ChatType_League), ChatID: leagueID, }) session, found := sessions.GetSession(p.playerID) if found { // 更新联盟ID到gate的session league.Service().SetSession(session, playerTable.LeagueID) // 推送联盟信息 mapCall.League.LeagueOnLogin(p.playerID, playerTable.LeagueID) } // 抛事件 p.PostEvent(event.NewLeagueJoin(p.playerID, leagueID, leagueName)) if join { // 发送加入成功邮件 // TODO 暂时往game写 actorRemote.GameMail.Send(playerTable.GameNodeID, &pb.SendMail{ ToPlayerID: p.playerID, TemplateID: constant.MailID_LeagueJoinSuccess, TemplateParams: []string{leagueName}, }) } // 同步声望 mapCall.League.UpdateLeagueMemberPrestige(leagueID, &pb.I64I32{ Key: p.playerID, Value: playerTable.GetPrestige(), }) p.Debug("[doLeagueJoinNotice] join league finish. playerID:%d, leagueID: %d", p.playerID, leagueID) return code.OK } // 退出联盟通知 func (p *actorPlayer) leagueQuitNotice(req *pb.I64) int32 { var ( leagueID = req.Value playerTable = db.GetMapPlayerTable(p.playerID) ) // 防止不同的联盟ID if playerTable.LeagueID != leagueID { return code.LeagueMemberNotExist } // 去掉玩家关联联盟ID playerTable.LeagueID = 0 playerTable.LeagueQuitTime = ctime.Now().ToSecond() // 清空城池资源产量 playerTable.CastleResYield.Clear() playerTable.Save2Queue() session, found := sessions.GetSession(p.playerID) if found { // 更新联盟ID到gate的session league.Service().SetSession(session, 0) } // 退出玩家关联联盟聊天室 target := cfacade.NewChildPath(playerTable.GameNodeID, nameActor.GamePlayer, p.playerID) p.Call(target, nameRemote.Player_ChatRoomUpdate, &pb.PlayerChatRoomUpdate{ ChatType: int32(enum.ChatType_League), ChatID: leagueID, IsExit: true, }) rsp := &pb.I64{ Value: leagueID, } // 推送退出联盟通知 sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_LeagueQuit, rsp) // 抛事件 p.PostEvent(event.NewLeagueQuit(p.playerID, 0)) // TODO 重新随机一个主城位置 //mapCall.Logic.AddMainCity(p.playerID, leagueID, true) // 记录联盟类型的已结算的赛季霸业任务状态 season.Service().LeagueQuitSeasonQuestRecord(p.playerID, leagueID) return code.OK }