package mapLeague import ( "f1-game/internal/code" "f1-game/internal/component/redis" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" nameActor "f1-game/internal/name/actor" nameRedis "f1-game/internal/name/redis" nameRemote "f1-game/internal/name/remote" "f1-game/internal/pb" "f1-game/internal/sessions" "f1-game/nodes/map/internal/db" mapFacade "f1-game/nodes/map/internal/facade" leagueBase "f1-game/nodes/map/league/base" "strings" "unicode" cstring "github.com/cherry-game/cherry/extend/string" cutils "github.com/cherry-game/cherry/extend/utils" cfacade "github.com/cherry-game/cherry/facade" clog "github.com/cherry-game/cherry/logger" cactor "github.com/cherry-game/cherry/net/actor" ) type ( actor struct { cactor.Base leagueIDs []int64 } ) func Init(app cfacade.IApplication, leagueTables map[int64]*db.MapLeagueTable) { actor := NewActor() app.ActorSystem().CreateActor(actor.AliasID(), actor) for leagueID := range leagueTables { actor.leagueIDs = append(actor.leagueIDs, leagueID) } } func NewActor() *actor { return &actor{} } func (p *actor) AliasID() string { return nameActor.Map_League } func (p *actor) OnInit() { p.Remote().Register(nameRemote.MapLeague_List, p.leagueList) p.Remote().Register(nameRemote.MapLeague_Search, p.leagueSearch) p.Remote().Register(nameRemote.MapLeague_Create, p.leagueCreate) p.Remote().Register(nameRemote.MapLeague_DiplomacyInfos, p.diplomacyInfos) p.Remote().Register(nameRemote.MapLeague_NameChange, p.leagueNameChange) p.Remote().Register(nameRemote.MapLeague_AbbNameChange, p.leagueAbbNameChange) } func (p *actor) OnLocalReceived(m *cfacade.Message) (bool, bool) { leagueID := m.Session.GetString(sessions.LeagueID) if cstring.IsBlank(leagueID) { clog.Warnf("[OnLocalReceived] league not found. m = %+v", m) return false, false } if child, found := p.Child().Get(leagueID); found { child.PostLocal(m) } return false, false } func (p *actor) OnRemoteReceived(m *cfacade.Message) (bool, bool) { if m.TargetPath().IsParent() { // 不拦截父actor的remote消息 return true, false } childID := m.TargetPath().ChildID leagueID, ok := cstring.ToInt64(childID) if !ok { return false, false } if _, found := db.GetMapLeagueTable(leagueID); !found { clog.Warnf("league table not found. [leagueID = %d, target = %s]", leagueID, m.Target) return false, false } return true, false } func (p *actor) OnFindChild(m *cfacade.Message) (cfacade.IActor, bool) { childID := m.TargetPath().ChildID leagueID, ok := cstring.ToInt64(childID) if !ok { return nil, false } childLeague := newActorLeague(leagueID) childActor, err := p.Child().Create(childID, &childLeague) if err != nil { return nil, false } clog.Debugf("[actor] create child. actorID = %s, targetPath = %v", childActor.ActorID(), m.TargetPath(), ) return childActor, true } // create 创建联盟 func (p *actor) leagueCreate(req *pb.CreateLeague) (*pb.I64, int32) { var ( playerID = req.PlayerID leagueName = req.LeagueName leagueAbbName = req.LeagueAbbName flagBg = req.FlagBg flagIcon = req.FlagIcon ) if playerID < 1 { return nil, code.IllegalArgument } // 检测联盟名称是否合法 errCode := p.CheckLeagueName(leagueName) if code.IsFail(errCode) { return nil, errCode } // 检测简称是否合法 errCode = p.CheckLeagueAbbName(leagueAbbName) if code.IsFail(errCode) { return nil, errCode } // 获取盟主职位ID leaderJobID := data.LeagueJob.GetLeaderJobID() if leaderJobID <= 0 { return nil, code.LeagueJobNotExist } leagueID := redis.GUID.NewLeagueID() leagueTable := db.NewMapLeagueTable(leagueID) // 联盟创建完成 leagueTable.LeagueInfo.LeagueCreateFinish(playerID, leagueName, leagueAbbName, flagBg, flagIcon) leagueTable.Save2Queue() // 初始化联盟数据 db.InitMapLeagueTables(leagueID) // 模块初始化 mapFacade.LeagueServiceOnInit(leagueTable) //获取联盟成员列表 leagueMemberTable, _ := db.GetMapLeagueMemberTable(leagueID) leagueMemberTable.LeagueMember.LeagueJoin(playerID) // 设置盟主职位&权限 leagueMemberTable.SetLeagueMemberJob(leaderJobID, playerID) leagueMemberTable.SetLeagueJobPermission(leaderJobID, enum.LeaguePermissionss) leagueMemberTable.Save2Queue() // 更新联盟信息到redis updateLeagueInfo2Redis(leagueTable, leagueMemberTable, playerID) // 保存联盟ID p.leagueIDs = append(p.leagueIDs, leagueID) // 写入创建日志 var ( leagueLogTable, _ = db.GetMapLeagueLogTable(leagueID) playerName = cstring.ToString(playerID) ) playerData := redis.Game.GetPlayerData(playerID, nameRedis.PlayerBaseFields...) if playerData != nil { playerName = playerData.PlayerName } leagueLogTable.AddLeagueLog(enum.Log_LeagueCreate, playerName) // 抛事件 p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague())) // 同步声望排行榜 leagueBase.Service().SyncLeaguePrestigeRank(leagueTable, leagueMemberTable) resp := &pb.I64{Value: leagueID} return resp, code.OK } // 获取联盟列表 func (p *actor) leagueList(req *pb.I64) (*pb.LeagueList, int32) { var ( playerID = req.Value leagueList = []*pb.LeagueSearch{} ) for _, leagueID := range p.leagueIDs { leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { clog.Warnf("[leagueList]league not found. leagueID = %d", leagueID) continue } leagueList = append(leagueList, leagueTable.ToLeagueSearchProto(playerID)) } rsp := &pb.LeagueList{ Total: int32(len(leagueList)), List: leagueList, } return rsp, code.OK } // 模糊搜索联盟 func (p *actor) leagueSearch(req *pb.Str) (*pb.LeagueList, int32) { var ( keyword = strings.ToLower(req.Value) id = int64(0) ) if cutils.IsNumeric(keyword) { id, _ = cstring.ToInt64(keyword) } leagueList := []*pb.LeagueSearch{} for _, leagueID := range p.leagueIDs { leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { clog.Warnf("[leagueSearch]league not found. leagueID = %d", leagueID) continue } if keyword == "" || leagueTable.LeagueID == id || strings.Contains(strings.ToLower(leagueTable.LeagueInfo.LeagueName), keyword) || strings.Contains(strings.ToLower(leagueTable.LeagueInfo.LeagueAbbName), keyword) { leagueList = append(leagueList, leagueTable.ToLeagueSearchProto(0)) } } rsp := &pb.LeagueList{ Total: int32(len(leagueList)), List: leagueList, } return rsp, code.OK } // 获取联盟外交列表 func (p *actor) diplomacyInfos(req *pb.None) (*pb.LeagueDiplomacyInfos, int32) { infos := &pb.LeagueDiplomacyInfos{} for _, leagueID := range p.leagueIDs { leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { clog.Warnf("[leagueList]league not found. leagueID = %d", leagueID) continue } infos.List = append(infos.List, leagueTable.ToLeagueDiplomacyProto()) } return infos, code.OK } // 联盟名称变更 func (p *actor) leagueNameChange(req *pb.LeagueNameChange) int32 { var ( playerID = req.PlayerID leagueID = req.LeagueID newLeagueName = req.NewName ) // 获取联盟数据 leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { return code.LeagueNotExist } leagueMemberTable, found := db.GetMapLeagueMemberTable(leagueID) if !found { return code.LeagueMembersEmpty } oldLeagueName := leagueTable.LeagueInfo.LeagueName if ok := leagueMemberTable.LeagueMember.CheckPermission(playerID, enum.League_Permission_Diplomacy); !ok { return code.LeaguePermissionDenied } // 判断当前名称是否一致 if newLeagueName == oldLeagueName { return code.LeagueNameNotChange } // 判断是否重名 errCode := p.CheckLeagueName(newLeagueName) if code.IsFail(errCode) { return errCode } // 更新名称 leagueTable.LeagueInfo.LeagueName = newLeagueName leagueTable.Save2Queue() memberIDList := leagueMemberTable.LeagueMember.GetLeagueMemberIDs() updateLeagueInfo2Redis(leagueTable, leagueMemberTable, memberIDList...) // 抛事件 p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague())) return code.OK } // 更新成员的联盟信息,联盟名称,简称,职位 func updateLeagueInfo2Redis(leagueTable *db.MapLeagueTable, leagueMemberTable *db.MapLeagueMemberTable, memberIDList ...int64) { if len(memberIDList) <= 0 { return } var playerLeagueInfoList []*pb.PlayerLeagueInfo for _, memberID := range memberIDList { playerLeagueInfoList = append(playerLeagueInfoList, &pb.PlayerLeagueInfo{ PlayerID: memberID, LeagueID: leagueTable.LeagueID, LeagueName: leagueTable.LeagueInfo.LeagueName, LeagueAbbName: leagueTable.LeagueInfo.LeagueAbbName, LeagueJob: leagueMemberTable.LeagueMember.GetLeagueMemberJob(memberID), }) } redis.Game.UpdatePlayerDataLeagueInfo(playerLeagueInfoList...) } // 联盟简称变更 func (p *actor) leagueAbbNameChange(req *pb.LeagueNameChange) int32 { var ( playerID = req.PlayerID leagueID = req.LeagueID newLeagueAbbName = req.NewName ) // 获取联盟数据 leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { return code.LeagueNotExist } leagueMemberTable, found := db.GetMapLeagueMemberTable(leagueID) if !found { return code.LeagueMembersEmpty } oldLeagueAbbName := leagueTable.LeagueInfo.LeagueAbbName if ok := leagueMemberTable.LeagueMember.CheckPermission(playerID, enum.League_Permission_Diplomacy); !ok { return code.LeaguePermissionDenied } // 判断当前简称是否一致 if newLeagueAbbName == oldLeagueAbbName { return code.LeagueNameNotChange } // 判断是否重名 errCode := p.CheckLeagueAbbName(newLeagueAbbName) if code.IsFail(errCode) { return errCode } // 更新名称 leagueTable.LeagueInfo.LeagueAbbName = newLeagueAbbName leagueTable.Save2Queue() memberIDList := leagueMemberTable.LeagueMember.GetLeagueMemberIDs() updateLeagueInfo2Redis(leagueTable, leagueMemberTable, memberIDList...) // 抛事件 p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague())) return code.OK } // 检测联盟名称是否可用 func (p *actor) CheckLeagueName(leagueName string) int32 { //检测联盟名称长度是否符合 ok := data.Const.CheckLeagueNameLen(leagueName) if !ok { return code.LeagueNameLimit } //判断是否包含特殊符号 只能是字符、数字和中文 if errCode := hasSpecialCharsForLeagueName(leagueName); code.IsFail(errCode) { return errCode } // 判断联盟名称是否存在 for _, leagueID := range p.leagueIDs { leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { continue } if leagueTable.LeagueInfo.LeagueName == leagueName { return code.LeagueNameExist } } return code.OK } // 检测联盟简称是否可用 func (p *actor) CheckLeagueAbbName(leagueAbbName string) int32 { ok := data.Const.CheckLeagueAbbNameLen(leagueAbbName) if !ok { return code.LeagueAbbNameLimit } //判断是否包含特殊符号 只能是字符和数字 TODO 现在暂时一样 if errCode := hasSpecialCharsForLeagueAbbName(leagueAbbName); code.IsFail(errCode) { return errCode } // 判断联盟名称是否存在 for _, leagueID := range p.leagueIDs { leagueTable, found := db.GetMapLeagueTable(leagueID) if !found { continue } if leagueTable.LeagueInfo.LeagueAbbName == leagueAbbName { return code.LeagueAbbNameExist } } return code.OK } func hasSpecialCharsForLeagueName(leagueName string) int32 { for _, r := range leagueName { //判断是否为字母、数字 或者 汉字 if !(unicode.IsLetter(r) || unicode.IsNumber(r) || unicode.In(r, unicode.Han)) { return code.LeagueNameHasSpecial } } return code.OK } func hasSpecialCharsForLeagueAbbName(leagueAbbName string) int32 { for _, r := range leagueAbbName { //判断是否为字母、数字 或者 汉字 if !(unicode.IsLetter(r) || unicode.IsNumber(r)) { return code.LeagueNameHasSpecial } } return code.OK }