league_mail.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  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/extend/utils"
  8. nameLocal "f1-game/internal/name/local"
  9. nameRedis "f1-game/internal/name/redis"
  10. nameRoute "f1-game/internal/name/route"
  11. "f1-game/internal/pb"
  12. "f1-game/internal/sessions"
  13. "f1-game/internal/types"
  14. "f1-game/nodes/map/internal/db"
  15. dbLeague "f1-game/nodes/map/internal/db/data/league"
  16. ctime "github.com/cherry-game/cherry/extend/time"
  17. cproto "github.com/cherry-game/cherry/net/proto"
  18. )
  19. func (p *actorLeague) initLeagueMail() {
  20. p.Local().Register(nameLocal.MapLeagueMail_Send, p.leagueMailSend)
  21. p.Local().Register(nameLocal.MapLeagueMail_Del, p.leagueMailDel)
  22. p.Local().Register(nameLocal.MapLeagueMail_MemberDel, p.leagueMailMemberDel)
  23. p.Local().Register(nameLocal.MapLeagueMail_Top, p.leagueMailTop)
  24. p.Local().Register(nameLocal.MapLeagueMail_Read, p.leagueMailRead)
  25. p.Local().Register(nameLocal.MapLeagueMail_FastRead, p.leagueMailFastRead)
  26. }
  27. // 发送/更新联盟邮件
  28. func (p *actorLeague) leagueMailSend(session *cproto.Session, req *pb.LeagueMailSend) {
  29. opPlayerID := sessions.GetPlayerID(session)
  30. _, found := db.GetMapLeagueTable(p.leagueID)
  31. if !found {
  32. p.ResponseCode(session, code.LeagueNotExist)
  33. return
  34. }
  35. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  36. if !found {
  37. p.ResponseCode(session, code.LeagueMembersEmpty)
  38. return
  39. }
  40. // 获取发送联盟邮件所需权限
  41. permID := enum.GetSendLeagueMailPermission(req.MailType)
  42. // 判断玩家是否有权处理
  43. if !leagueMemberTable.LeagueMember.CheckPermission(opPlayerID, permID) {
  44. p.ResponseCode(session, code.LeaguePermissionDenied)
  45. return
  46. }
  47. // 发送联盟邮件
  48. errCode := p.SendLeagueMail(leagueMemberTable, opPlayerID, req.MailID, req.MailType,
  49. req.Title, req.Content, req.IsTop)
  50. p.ResponseCode(session, errCode)
  51. }
  52. // 删除联盟邮件
  53. func (p *actorLeague) leagueMailDel(session *cproto.Session, req *pb.I64) {
  54. var (
  55. opPlayerID = sessions.GetPlayerID(session)
  56. mailID = req.Value
  57. mailType = enum.MailType_Decree
  58. )
  59. _, found := db.GetMapLeagueTable(p.leagueID)
  60. if !found {
  61. p.ResponseCode(session, code.LeagueNotExist)
  62. return
  63. }
  64. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  65. if !found {
  66. p.ResponseCode(session, code.LeagueMembersEmpty)
  67. return
  68. }
  69. // 判断玩家是否有权处理
  70. if !leagueMemberTable.LeagueMember.CheckPermission(opPlayerID, enum.League_Permission_Decree) {
  71. p.ResponseCode(session, code.LeaguePermissionDenied)
  72. return
  73. }
  74. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  75. if !found {
  76. p.ResponseCode(session, code.LeagueMailDataNotExist)
  77. return
  78. }
  79. removeMailIDs := []int64{mailID}
  80. leagueMailList := leagueMailTable.GetLeagueMails(mailType)
  81. if len(leagueMailList.List) <= 0 {
  82. p.ResponseCode(session, code.LeagueMailDataNotExist)
  83. return
  84. }
  85. if mailID <= 0 {
  86. // 删除所有邮件
  87. leagueMailList := leagueMailTable.DeleteLeagueMailList(mailType)
  88. for _, mail := range leagueMailList.List {
  89. removeMailIDs = append(removeMailIDs, mail.MailID)
  90. }
  91. } else {
  92. _, index := leagueMailList.GetLeagueMail(mailID)
  93. if index < 0 {
  94. p.ResponseCode(session, code.MailDataNotFound)
  95. return
  96. }
  97. _, ok := leagueMailList.DeleteLeagueMail(mailID)
  98. if !ok {
  99. p.ResponseCode(session, code.MailDelFail)
  100. return
  101. }
  102. removeMailIDs = append(removeMailIDs, mailID)
  103. }
  104. leagueMailTable.Save2Queue()
  105. // 通知联盟所有在线玩家
  106. p.leagueMailUpdateNotice(leagueMemberTable.GetLeagueMemberIDs(), mailType, leagueMailList.TopMailID, removeMailIDs)
  107. p.ResponseCode(session, code.OK)
  108. }
  109. func (p *actorLeague) leagueMailMemberDel(session *cproto.Session, req *pb.I64I32) {
  110. var (
  111. opPlayerID = sessions.GetPlayerID(session)
  112. mailID = req.Key
  113. mailType = req.Value
  114. )
  115. if mailType == enum.MailType_Decree {
  116. p.ResponseCode(session, code.MailDecreeNoCanDel)
  117. return
  118. }
  119. _, found := db.GetMapLeagueTable(p.leagueID)
  120. if !found {
  121. p.ResponseCode(session, code.LeagueNotExist)
  122. return
  123. }
  124. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  125. if !found {
  126. p.ResponseCode(session, code.LeagueMailDataNotExist)
  127. return
  128. }
  129. leagueMailList := leagueMailTable.GetLeagueMails(mailType)
  130. if len(leagueMailList.List) <= 0 {
  131. p.ResponseCode(session, code.LeagueMailDataNotExist)
  132. return
  133. }
  134. removeMailIDs := []int64{}
  135. // 删除特定同盟/指挥邮件
  136. if mailID > 0 {
  137. leagueMail, index := leagueMailList.GetLeagueMail(mailID)
  138. if index < 0 {
  139. p.ResponseCode(session, code.MailDataNotFound)
  140. return
  141. }
  142. if leagueMail.DelPlayerIDs.Contains(opPlayerID) {
  143. p.ResponseCode(session, code.MailAlreadyDel)
  144. return
  145. }
  146. leagueMail.DelPlayerIDs.Add(opPlayerID)
  147. removeMailIDs = append(removeMailIDs, mailID)
  148. } else {
  149. for _, leagueMail := range leagueMailList.List {
  150. if leagueMail.DelPlayerIDs.Contains(opPlayerID) || !leagueMail.ReadPlayerIDs.Contains(opPlayerID) {
  151. continue
  152. }
  153. leagueMail.DelPlayerIDs.Add(opPlayerID)
  154. removeMailIDs = append(removeMailIDs, leagueMail.MailID)
  155. }
  156. }
  157. // 暂无可删除邮件
  158. if len(removeMailIDs) <= 0 {
  159. p.ResponseCode(session, code.MailDelNotExist)
  160. return
  161. }
  162. // 通知玩家删除邮件
  163. member := []int64{opPlayerID}
  164. p.leagueMailUpdateNotice(member, mailType, leagueMailList.TopMailID, removeMailIDs)
  165. p.ResponseCode(session, code.OK)
  166. }
  167. // 置顶联盟邮件
  168. func (p *actorLeague) leagueMailTop(session *cproto.Session, req *pb.I64) {
  169. var (
  170. opPlayerID = sessions.GetPlayerID(session)
  171. mailID = req.Value
  172. mailType = enum.MailType_Decree
  173. )
  174. _, found := db.GetMapLeagueTable(p.leagueID)
  175. if !found {
  176. p.ResponseCode(session, code.LeagueNotExist)
  177. return
  178. }
  179. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  180. if !found {
  181. p.ResponseCode(session, code.LeagueMembersEmpty)
  182. return
  183. }
  184. // 判断玩家是否有权处理
  185. if !leagueMemberTable.LeagueMember.CheckPermission(opPlayerID, enum.League_Permission_Decree) {
  186. p.ResponseCode(session, code.LeaguePermissionDenied)
  187. return
  188. }
  189. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  190. if !found {
  191. p.ResponseCode(session, code.LeagueMailDataNotExist)
  192. return
  193. }
  194. leagueMailList := leagueMailTable.GetLeagueMails(mailType)
  195. _, index := leagueMailList.GetLeagueMail(mailID)
  196. if index < 0 {
  197. p.ResponseCode(session, code.MailDataNotFound)
  198. return
  199. }
  200. // 当前置顶邮件唯一ID相同则取消置顶 否则置顶
  201. if leagueMailList.TopMailID == mailID {
  202. leagueMailList.TopMailID = 0
  203. } else {
  204. leagueMailList.TopMailID = mailID
  205. }
  206. leagueMailTable.Save2Queue()
  207. resp := &pb.I64I32{
  208. Key: leagueMailList.TopMailID,
  209. Value: mailType,
  210. }
  211. // 通知联盟所有在线玩家
  212. sessions.PushPlayers(leagueMemberTable.GetLeagueMemberIDs(), nameRoute.PushLeagueMail_Top, resp)
  213. p.ResponseCode(session, code.OK)
  214. }
  215. // 联盟邮件变更通知
  216. func (p *actorLeague) leagueMailUpdateNotice(members []int64, mailType int32, topMailID int64, removeMailIDs []int64, addMails ...*dbLeague.LeagueMail) {
  217. if len(members) <= 0 {
  218. return
  219. }
  220. // 删除邮件
  221. if len(removeMailIDs) > 0 {
  222. removeResp := &pb.MailDelList{
  223. MailType: mailType,
  224. MailIDs: removeMailIDs,
  225. }
  226. sessions.PushPlayers(members, nameRoute.PushLeagueMail_Del, removeResp)
  227. }
  228. // 新增邮件
  229. if len(addMails) > 0 {
  230. addResp := &pb.MailList{
  231. MailType: mailType,
  232. TopMailID: topMailID,
  233. }
  234. for _, mail := range addMails {
  235. addResp.List = append(addResp.List, mail.ToProto(0))
  236. }
  237. sessions.PushPlayers(members, nameRoute.PushLeagueMail_New, addResp)
  238. }
  239. }
  240. // 阅读联盟邮件
  241. func (p *actorLeague) leagueMailRead(session *cproto.Session, req *pb.I64I32) {
  242. playerID := sessions.GetPlayerID(session)
  243. if playerID < 1 {
  244. p.ResponseCode(session, code.MailRequestDataError)
  245. return
  246. }
  247. var (
  248. mailID = req.Key
  249. mailType = req.Value
  250. )
  251. if enum.VaildateMailType(mailType) {
  252. p.ResponseCode(session, code.MailTypeError)
  253. return
  254. }
  255. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  256. if !found {
  257. p.ResponseCode(session, code.LeagueMembersEmpty)
  258. return
  259. }
  260. if found := leagueMemberTable.CheckMemberExist(playerID); !found {
  261. p.ResponseCode(session, code.LeagueMemberNotExist)
  262. return
  263. }
  264. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  265. if !found {
  266. p.ResponseCode(session, code.LeagueMailDataNotExist)
  267. return
  268. }
  269. leagueMailList := leagueMailTable.GetLeagueMails(mailType)
  270. leagueMail, index := leagueMailList.GetLeagueMail(mailID)
  271. if index < 0 {
  272. p.ResponseCode(session, code.MailDataNotFound)
  273. return
  274. }
  275. if !leagueMail.ReadPlayerIDs.Contains(playerID) {
  276. leagueMail.ReadPlayerIDs.Add(playerID)
  277. leagueMailTable.Save2Queue()
  278. }
  279. resp := &pb.I64I32{
  280. Key: mailID,
  281. Value: mailType,
  282. }
  283. p.Response(session, resp)
  284. }
  285. // 一键阅读联盟邮件
  286. func (p *actorLeague) leagueMailFastRead(session *cproto.Session, req *pb.I32) {
  287. playerID := sessions.GetPlayerID(session)
  288. if playerID < 1 {
  289. p.ResponseCode(session, code.MailRequestDataError)
  290. return
  291. }
  292. mailType := req.Value
  293. if enum.VaildateMailType(mailType) {
  294. p.ResponseCode(session, code.MailTypeError)
  295. return
  296. }
  297. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  298. if !found {
  299. p.ResponseCode(session, code.LeagueMembersEmpty)
  300. return
  301. }
  302. if found := leagueMemberTable.CheckMemberExist(playerID); !found {
  303. p.ResponseCode(session, code.LeagueMemberNotExist)
  304. return
  305. }
  306. mailIDs := &pb.I64List{}
  307. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  308. if found {
  309. leagueMails := leagueMailTable.GetLeagueMails(mailType)
  310. for _, leagueMail := range leagueMails.List {
  311. if !leagueMail.ReadPlayerIDs.Contains(playerID) {
  312. mailIDs.List = append(mailIDs.List, leagueMail.MailID)
  313. leagueMail.ReadPlayerIDs.Add(playerID)
  314. }
  315. }
  316. }
  317. if len(mailIDs.List) > 0 {
  318. leagueMailTable.Save2Queue()
  319. }
  320. p.Response(session, mailIDs)
  321. }
  322. // 发送联盟邮件
  323. func (p *actorLeague) SendLeagueMail(leagueMemberTable *db.MapLeagueMemberTable, opPlayerID, mailID int64,
  324. mailType int32, title, content string, top bool) int32 {
  325. leagueMailTable, found := db.GetMapLeagueMailTable(p.leagueID)
  326. if !found {
  327. return code.LeagueMailDataNotExist
  328. }
  329. if enum.VaildateLeagueMailType(mailType) {
  330. return code.MailTypeError
  331. }
  332. var (
  333. leagueMailLimit = data.Const.GetLeagueMailLimit(mailType)
  334. leagueMailList = leagueMailTable.GetLeagueMails(mailType)
  335. )
  336. // 当前存在类型邮件列表数据 且 当前为法令邮件 且 当前非更新邮件内容 判断是否达到上限
  337. if mailType == enum.MailType_Decree && mailID <= 0 {
  338. // 检测邮件数量是否超过限制 法令数量超出上限后不能添加 其他是删除旧的数据
  339. if leagueMailList.Size() >= leagueMailLimit {
  340. return code.MailNumLimit
  341. }
  342. }
  343. // 检测邮件标题&内容是否合法
  344. if !utils.CheckStrLen(title, data.Const.LeagueMailTitleLimit) {
  345. return code.MailTitleError
  346. }
  347. if !utils.CheckStrLen(content, data.Const.LeagueMailContentLimit) {
  348. return code.MailContentError
  349. }
  350. newMailID := int64(0)
  351. // 如果是法令邮件更新 删除旧法令邮件数据
  352. if mailType == enum.MailType_Decree && mailID > 0 {
  353. _, ok := leagueMailList.DeleteLeagueMail(mailID)
  354. if !ok {
  355. return code.MailDataNotFound
  356. }
  357. // 更新法令邮件 沿用旧的邮件ID
  358. newMailID = mailID
  359. }
  360. // 新增邮件
  361. if newMailID <= 0 {
  362. newMailID = leagueMailTable.NewLeagueMailID()
  363. }
  364. // 创建一封邮件 联盟邮件更新出了发送人&发送人原来的职位不变,其他都变,且需要新的红点
  365. leagueMail := &dbLeague.LeagueMail{
  366. MailID: newMailID,
  367. Title: title,
  368. Content: content,
  369. FromPlayerID: opPlayerID,
  370. Job: leagueMemberTable.LeagueMember.GetLeagueMemberJob(opPlayerID),
  371. SendTime: ctime.Now().ToSecond(),
  372. ReadPlayerIDs: types.List[int64]{},
  373. DelPlayerIDs: types.List[int64]{},
  374. }
  375. // 获取玩家名称
  376. playerData := redis.Game.GetPlayerData(opPlayerID, nameRedis.PlayerNameFields...)
  377. if playerData != nil {
  378. leagueMail.FromPlayerName = playerData.PlayerName
  379. }
  380. leagueMailList.AddLeagueMail(leagueMail)
  381. removeMailIDs := []int64{}
  382. // 检测邮件是否已满
  383. for leagueMailLimit > 0 && leagueMailList.Size() > leagueMailLimit {
  384. leagueMail, ok := leagueMailList.DeleteLeagueMailIndex(0)
  385. if !ok {
  386. break
  387. }
  388. removeMailIDs = append(removeMailIDs, leagueMail.MailID)
  389. }
  390. // 当前法令邮件才能设置置顶
  391. if mailType == enum.MailType_Decree && top {
  392. leagueMailList.TopMailID = leagueMail.MailID
  393. }
  394. // 更新保存邮件
  395. leagueMailTable.Save2Queue()
  396. // 通知联盟所有在线玩家
  397. p.leagueMailUpdateNotice(leagueMemberTable.GetLeagueMemberIDs(), mailType, leagueMailList.TopMailID, removeMailIDs, leagueMail)
  398. return code.OK
  399. }