actor.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. package mapLeague
  2. import (
  3. "f1-game/internal/code"
  4. "f1-game/internal/component/redis"
  5. "f1-game/internal/data"
  6. "f1-game/internal/enum"
  7. "f1-game/internal/event"
  8. nameActor "f1-game/internal/name/actor"
  9. nameRedis "f1-game/internal/name/redis"
  10. nameRemote "f1-game/internal/name/remote"
  11. "f1-game/internal/pb"
  12. "f1-game/internal/sessions"
  13. "f1-game/nodes/map/internal/db"
  14. "strings"
  15. "unicode"
  16. cstring "github.com/cherry-game/cherry/extend/string"
  17. cutils "github.com/cherry-game/cherry/extend/utils"
  18. cfacade "github.com/cherry-game/cherry/facade"
  19. clog "github.com/cherry-game/cherry/logger"
  20. "github.com/cherry-game/cherry/net/parser/pomelo"
  21. )
  22. type (
  23. actor struct {
  24. pomelo.ActorBase
  25. leagueIDs []int64
  26. }
  27. )
  28. func Init(app cfacade.IApplication, leagueTables map[int64]*db.MapLeagueTable) {
  29. actor := NewActor()
  30. app.ActorSystem().CreateActor(actor.AliasID(), actor)
  31. for leagueID := range leagueTables {
  32. childActor := newActorLeague(leagueID)
  33. actor.Child().Create(cstring.ToString(leagueID), &childActor)
  34. actor.leagueIDs = append(actor.leagueIDs, leagueID)
  35. }
  36. }
  37. func NewActor() *actor {
  38. return &actor{}
  39. }
  40. func (p *actor) AliasID() string {
  41. return nameActor.Map_League
  42. }
  43. func (p *actor) OnInit() {
  44. p.Remote().Register(nameRemote.MapLeague_List, p.leagueList)
  45. p.Remote().Register(nameRemote.MapLeague_Search, p.leagueSearch)
  46. p.Remote().Register(nameRemote.MapLeague_Create, p.leagueCreate)
  47. p.Remote().Register(nameRemote.MapLeague_DiplomacyInfos, p.diplomacyInfos)
  48. p.Remote().Register(nameRemote.MapLeague_NameChange, p.leagueNameChange)
  49. p.Remote().Register(nameRemote.MapLeague_AbbNameChange, p.leagueAbbNameChange)
  50. }
  51. func (p *actor) OnLocalReceived(m *cfacade.Message) (bool, bool) {
  52. leagueID := m.Session.GetString(sessions.LeagueID)
  53. if cstring.IsBlank(leagueID) {
  54. clog.Warnf("[OnLocalReceived] league not found. m = %+v", m)
  55. p.ResponseCode(m.Session, code.LeagueNotJoin)
  56. return false, false
  57. }
  58. if child, found := p.Child().Get(leagueID); found {
  59. child.PostLocal(m)
  60. } else {
  61. p.ResponseCode(m.Session, code.LeagueNotExist)
  62. }
  63. return false, false
  64. }
  65. func (p *actor) OnRemoteReceived(m *cfacade.Message) (bool, bool) {
  66. if m.TargetPath().IsParent() {
  67. // 不拦截父actor的remote消息
  68. return true, false
  69. }
  70. childID := m.TargetPath().ChildID
  71. leagueID, ok := cstring.ToInt64(childID)
  72. if !ok {
  73. return false, false
  74. }
  75. if _, found := db.GetMapLeagueTable(leagueID); !found {
  76. clog.Warnf("league table not found. [leagueID = %d, target = %s]", leagueID, m.Target)
  77. return false, false
  78. }
  79. return true, false
  80. }
  81. func (p *actor) OnFindChild(m *cfacade.Message) (cfacade.IActor, bool) {
  82. childID := m.TargetPath().ChildID
  83. leagueID, ok := cstring.ToInt64(childID)
  84. if !ok {
  85. return nil, false
  86. }
  87. childLeague := newActorLeague(leagueID)
  88. childActor, err := p.Child().Create(childID, &childLeague)
  89. if err != nil {
  90. return nil, false
  91. }
  92. clog.Debugf("[actor] create child. actorID = %s, targetPath = %v",
  93. childActor.ActorID(),
  94. m.TargetPath(),
  95. )
  96. return childActor, true
  97. }
  98. // create 创建联盟
  99. func (p *actor) leagueCreate(req *pb.CreateLeague) (*pb.I64, int32) {
  100. var (
  101. playerID = req.PlayerID
  102. leagueName = req.LeagueName
  103. leagueAbbName = req.LeagueAbbName
  104. flagBg = req.FlagBg
  105. flagIcon = req.FlagIcon
  106. )
  107. if playerID < 1 {
  108. return nil, code.IllegalArgument
  109. }
  110. // 检测联盟名称是否合法
  111. errCode := p.CheckLeagueName(leagueName)
  112. if code.IsFail(errCode) {
  113. return nil, errCode
  114. }
  115. // 检测简称是否合法
  116. errCode = p.CheckLeagueAbbName(leagueAbbName)
  117. if code.IsFail(errCode) {
  118. return nil, errCode
  119. }
  120. // 获取盟主职位ID
  121. leaderJobID := data.LeagueJob.GetLeaderJobID()
  122. if leaderJobID <= 0 {
  123. return nil, code.LeagueJobNotExist
  124. }
  125. leagueID := redis.GUID.NewLeagueID()
  126. leagueTable := db.NewMapLeagueTable(leagueID)
  127. // 联盟创建完成
  128. leagueTable.LeagueInfo.LeagueCreateFinish(playerID, leagueName, leagueAbbName, flagBg, flagIcon)
  129. leagueTable.Save2Queue()
  130. // 初始化联盟数据
  131. db.InitMapLeagueTables(leagueID)
  132. // 模块初始化
  133. LeagueServiceOnInit(leagueTable)
  134. //获取联盟成员列表
  135. leagueMemberTable, _ := db.GetMapLeagueMemberTable(leagueID)
  136. leagueMemberTable.LeagueMember.LeagueJoin(playerID)
  137. // 设置盟主职位&权限
  138. leagueMemberTable.SetLeagueMemberJob(leaderJobID, playerID)
  139. leagueMemberTable.SetLeagueJobPermission(leaderJobID, enum.LeaguePermissionss)
  140. leagueMemberTable.Save2Queue()
  141. // 更新联盟信息到redis
  142. updateLeagueInfo2Redis(leagueTable, leagueMemberTable, playerID)
  143. // 保存联盟ID
  144. p.leagueIDs = append(p.leagueIDs, leagueID)
  145. // 写入创建日志
  146. var (
  147. leagueLogTable, _ = db.GetMapLeagueLogTable(leagueID)
  148. playerName = cstring.ToString(playerID)
  149. )
  150. playerData := redis.Game.GetPlayerData(playerID, nameRedis.PlayerBaseFields...)
  151. if playerData != nil {
  152. playerName = playerData.PlayerName
  153. }
  154. leagueLogTable.AddLeagueLog(enum.Log_LeagueCreate, playerName)
  155. // 抛事件
  156. p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague()))
  157. resp := &pb.I64{Value: leagueID}
  158. return resp, code.OK
  159. }
  160. // 获取联盟列表
  161. func (p *actor) leagueList(req *pb.I64) (*pb.LeagueList, int32) {
  162. var (
  163. playerID = req.Value
  164. leagueList = []*pb.LeagueSearch{}
  165. )
  166. for _, leagueID := range p.leagueIDs {
  167. leagueTable, found := db.GetMapLeagueTable(leagueID)
  168. if !found {
  169. clog.Warnf("[leagueList]league not found. leagueID = %d", leagueID)
  170. continue
  171. }
  172. leagueList = append(leagueList, leagueTable.ToLeagueSearchProto(playerID))
  173. }
  174. rsp := &pb.LeagueList{
  175. Total: int32(len(leagueList)),
  176. List: leagueList,
  177. }
  178. return rsp, code.OK
  179. }
  180. // 模糊搜索联盟
  181. func (p *actor) leagueSearch(req *pb.Str) (*pb.LeagueList, int32) {
  182. var (
  183. keyword = strings.ToLower(req.Value)
  184. id = int64(0)
  185. )
  186. if cutils.IsNumeric(keyword) {
  187. id, _ = cstring.ToInt64(keyword)
  188. }
  189. leagueList := []*pb.LeagueSearch{}
  190. for _, leagueID := range p.leagueIDs {
  191. leagueTable, found := db.GetMapLeagueTable(leagueID)
  192. if !found {
  193. clog.Warnf("[leagueSearch]league not found. leagueID = %d", leagueID)
  194. continue
  195. }
  196. if keyword == "" || leagueTable.LeagueID == id ||
  197. strings.Contains(strings.ToLower(leagueTable.LeagueInfo.LeagueName), keyword) ||
  198. strings.Contains(strings.ToLower(leagueTable.LeagueInfo.LeagueAbbName), keyword) {
  199. leagueList = append(leagueList, leagueTable.ToLeagueSearchProto(0))
  200. }
  201. }
  202. rsp := &pb.LeagueList{
  203. Total: int32(len(leagueList)),
  204. List: leagueList,
  205. }
  206. return rsp, code.OK
  207. }
  208. // 获取联盟外交列表
  209. func (p *actor) diplomacyInfos(req *pb.None) (*pb.LeagueDiplomacyInfos, int32) {
  210. infos := &pb.LeagueDiplomacyInfos{}
  211. for _, leagueID := range p.leagueIDs {
  212. leagueTable, found := db.GetMapLeagueTable(leagueID)
  213. if !found {
  214. clog.Warnf("[leagueList]league not found. leagueID = %d", leagueID)
  215. continue
  216. }
  217. infos.List = append(infos.List, leagueTable.ToLeagueDiplomacyProto())
  218. }
  219. return infos, code.OK
  220. }
  221. // 联盟名称变更
  222. func (p *actor) leagueNameChange(req *pb.LeagueNameChange) int32 {
  223. var (
  224. playerID = req.PlayerID
  225. leagueID = req.LeagueID
  226. newLeagueName = req.NewName
  227. )
  228. // 获取联盟数据
  229. leagueTable, found := db.GetMapLeagueTable(leagueID)
  230. if !found {
  231. return code.LeagueNotExist
  232. }
  233. leagueMemberTable, found := db.GetMapLeagueMemberTable(leagueID)
  234. if !found {
  235. return code.LeagueMembersEmpty
  236. }
  237. oldLeagueName := leagueTable.LeagueInfo.LeagueName
  238. if !leagueMemberTable.LeagueMember.CheckPermission(playerID, enum.League_Permission_Diplomacy) {
  239. return code.LeaguePermissionDenied
  240. }
  241. // 判断当前名称是否一致
  242. if newLeagueName == oldLeagueName {
  243. return code.LeagueNameNotChange
  244. }
  245. // 判断是否重名
  246. errCode := p.CheckLeagueName(newLeagueName)
  247. if code.IsFail(errCode) {
  248. return errCode
  249. }
  250. // 更新名称
  251. leagueTable.LeagueInfo.LeagueName = newLeagueName
  252. leagueTable.Save2Queue()
  253. memberIDList := leagueMemberTable.LeagueMember.GetLeagueMemberIDs()
  254. updateLeagueInfo2Redis(leagueTable, leagueMemberTable, memberIDList...)
  255. // 抛事件
  256. p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague()))
  257. return code.OK
  258. }
  259. // 更新成员的联盟信息,联盟名称,简称,职位
  260. func updateLeagueInfo2Redis(leagueTable *db.MapLeagueTable, leagueMemberTable *db.MapLeagueMemberTable, memberIDList ...int64) {
  261. if len(memberIDList) <= 0 {
  262. return
  263. }
  264. var playerLeagueInfoList []*pb.PlayerLeagueInfo
  265. for _, memberID := range memberIDList {
  266. playerLeagueInfoList = append(playerLeagueInfoList, &pb.PlayerLeagueInfo{
  267. PlayerID: memberID,
  268. LeagueID: leagueTable.LeagueID,
  269. LeagueName: leagueTable.LeagueInfo.LeagueName,
  270. LeagueAbbName: leagueTable.LeagueInfo.LeagueAbbName,
  271. LeagueJob: leagueMemberTable.LeagueMember.GetLeagueMemberJob(memberID),
  272. })
  273. }
  274. redis.Game.UpdatePlayerDataLeagueInfo(playerLeagueInfoList...)
  275. }
  276. // 联盟简称变更
  277. func (p *actor) leagueAbbNameChange(req *pb.LeagueNameChange) int32 {
  278. var (
  279. playerID = req.PlayerID
  280. leagueID = req.LeagueID
  281. newLeagueAbbName = req.NewName
  282. )
  283. // 获取联盟数据
  284. leagueTable, found := db.GetMapLeagueTable(leagueID)
  285. if !found {
  286. return code.LeagueNotExist
  287. }
  288. leagueMemberTable, found := db.GetMapLeagueMemberTable(leagueID)
  289. if !found {
  290. return code.LeagueMembersEmpty
  291. }
  292. oldLeagueAbbName := leagueTable.LeagueInfo.LeagueAbbName
  293. if !leagueMemberTable.LeagueMember.CheckPermission(playerID, enum.League_Permission_Diplomacy) {
  294. return code.LeaguePermissionDenied
  295. }
  296. // 判断当前简称是否一致
  297. if newLeagueAbbName == oldLeagueAbbName {
  298. return code.LeagueNameNotChange
  299. }
  300. // 判断是否重名
  301. errCode := p.CheckLeagueAbbName(newLeagueAbbName)
  302. if code.IsFail(errCode) {
  303. return errCode
  304. }
  305. // 更新名称
  306. leagueTable.LeagueInfo.LeagueAbbName = newLeagueAbbName
  307. leagueTable.Save2Queue()
  308. memberIDList := leagueMemberTable.LeagueMember.GetLeagueMemberIDs()
  309. updateLeagueInfo2Redis(leagueTable, leagueMemberTable, memberIDList...)
  310. // 抛事件
  311. p.PostEvent(event.NewMapLeagueSync(leagueTable.LeagueID, leagueTable.ToMapLeague()))
  312. return code.OK
  313. }
  314. // 检测联盟名称是否可用
  315. func (p *actor) CheckLeagueName(leagueName string) int32 {
  316. //检测联盟名称长度是否符合
  317. ok := data.Const.CheckLeagueNameLen(leagueName)
  318. if !ok {
  319. return code.LeagueNameLimit
  320. }
  321. //判断是否包含特殊符号 只能是字符、数字和中文
  322. if errCode := hasSpecialCharsForLeagueName(leagueName); code.IsFail(errCode) {
  323. return errCode
  324. }
  325. // 判断联盟名称是否存在
  326. for _, leagueID := range p.leagueIDs {
  327. leagueTable, found := db.GetMapLeagueTable(leagueID)
  328. if !found {
  329. continue
  330. }
  331. if leagueTable.LeagueInfo.LeagueName == leagueName {
  332. return code.LeagueNameExist
  333. }
  334. }
  335. return code.OK
  336. }
  337. // 检测联盟简称是否可用
  338. func (p *actor) CheckLeagueAbbName(leagueAbbName string) int32 {
  339. ok := data.Const.CheckLeagueAbbNameLen(leagueAbbName)
  340. if !ok {
  341. return code.LeagueAbbNameLimit
  342. }
  343. //判断是否包含特殊符号 只能是字符和数字 TODO 现在暂时一样
  344. if errCode := hasSpecialCharsForLeagueAbbName(leagueAbbName); code.IsFail(errCode) {
  345. return errCode
  346. }
  347. // 判断联盟名称是否存在
  348. for _, leagueID := range p.leagueIDs {
  349. leagueTable, found := db.GetMapLeagueTable(leagueID)
  350. if !found {
  351. continue
  352. }
  353. if leagueTable.LeagueInfo.LeagueAbbName == leagueAbbName {
  354. return code.LeagueAbbNameExist
  355. }
  356. }
  357. return code.OK
  358. }
  359. func hasSpecialCharsForLeagueName(leagueName string) int32 {
  360. for _, r := range leagueName {
  361. //判断是否为字母、数字 或者 汉字
  362. if !(unicode.IsLetter(r) || unicode.IsNumber(r) || unicode.In(r, unicode.Han)) {
  363. return code.LeagueNameHasSpecial
  364. }
  365. }
  366. return code.OK
  367. }
  368. func hasSpecialCharsForLeagueAbbName(leagueAbbName string) int32 {
  369. for _, r := range leagueAbbName {
  370. //判断是否为字母、数字 或者 汉字
  371. if !(unicode.IsLetter(r) || unicode.IsNumber(r)) {
  372. return code.LeagueNameHasSpecial
  373. }
  374. }
  375. return code.OK
  376. }