service.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package vip
  2. import (
  3. capp "f1-game/internal/cherry_app"
  4. "f1-game/internal/code"
  5. "f1-game/internal/data"
  6. "f1-game/internal/event"
  7. facade "f1-game/internal/facade"
  8. nameActor "f1-game/internal/name/actor"
  9. nameRemote "f1-game/internal/name/remote"
  10. nameRoute "f1-game/internal/name/route"
  11. "f1-game/internal/pb"
  12. "f1-game/internal/sessions"
  13. "f1-game/nodes/game/internal/db"
  14. ctime "github.com/cherry-game/cherry/extend/time"
  15. cfacade "github.com/cherry-game/cherry/facade"
  16. clog "github.com/cherry-game/cherry/logger"
  17. cproto "github.com/cherry-game/cherry/net/proto"
  18. )
  19. var srv = &service{}
  20. func Service() *service {
  21. return srv
  22. }
  23. type service struct {
  24. facade.PlayerServiceBase[*db.PlayerTable]
  25. }
  26. func (*service) OnReset(playerTable *db.PlayerTable, curTime *ctime.CherryTime, byLogin bool) {
  27. playerTable.Vip.DailyReset()
  28. playerTable.Save2Queue()
  29. }
  30. func (p *service) OnLogin(playerTable *db.PlayerTable, session *cproto.Session) {
  31. // 新用户初始化vip属性
  32. if session.Contains(sessions.IsNewPlayer) {
  33. row := data.Vip.GetMinLevelRow()
  34. playerTable.Vip.Level = row.Level
  35. playerTable.Vip.Exp = 0
  36. playerTable.Vip.Attrs = row.Attrs
  37. }
  38. }
  39. func (p *service) Push(playerTable *db.PlayerTable, session *cproto.Session) {
  40. proto := playerTable.Vip.ToProto()
  41. proto.ContinuousLoginDays = playerTable.Stats.ContinueLoginDays
  42. sessions.PushWithSession(session, nameRoute.PushGamePlayer_VipInfo, proto)
  43. }
  44. func (p *service) VipPush(playerTable *db.PlayerTable) {
  45. if session, found := sessions.GetSession(playerTable.PlayerID); found {
  46. p.Push(playerTable, session)
  47. }
  48. }
  49. func (p *service) AddExp(playerID int64, exp int64) int32 {
  50. var (
  51. playerTable, _ = db.GetPlayerTable(playerID)
  52. vip = &playerTable.Vip
  53. levelUp bool
  54. maxLevel = data.Vip.GetMaxLevel()
  55. )
  56. vip.Exp += exp
  57. // 是否升级
  58. for vip.Level < maxLevel {
  59. row, ok := data.Vip.GetByLevel(vip.Level)
  60. if !ok {
  61. return code.ConfigNotFound_VipLevel
  62. }
  63. if row.Exp > vip.Exp {
  64. break
  65. }
  66. vip.Exp -= row.Exp
  67. // 升级
  68. vip.Level++
  69. // 更新属性
  70. vip.Attrs = row.Attrs
  71. levelUp = true
  72. }
  73. // 保存
  74. playerTable.Save2Queue()
  75. // 推送
  76. if session, found := sessions.GetSession(playerID); found {
  77. p.Push(playerTable, session)
  78. }
  79. // 抛升级事件
  80. if levelUp {
  81. capp.PostEvent(event.NewVipLevelUp(playerID, vip.Level))
  82. // 升级也需要重新激活新的属性
  83. if !vip.IsExpired {
  84. p.SyncMapActiveVip(playerTable)
  85. }
  86. // 发送系统消息事件
  87. // capp.PostEvent(event.NewChatSystemMsg(playerID, enum.ChatMsgType_VipUp, nil, nil, vip.Level))
  88. }
  89. return code.OK
  90. }
  91. // 增加VIP有效期天数
  92. func (p *service) AddDay(playerID int64, day int32) int32 {
  93. var (
  94. playerTable, _ = db.GetPlayerTable(playerID)
  95. vip = &playerTable.Vip
  96. now = ctime.Now()
  97. isActive = false // 是否是激活
  98. )
  99. // 先判断是否已经过期
  100. if vip.ExpireTime < now.ToMillisecond() {
  101. vip.ExpireTime = now.ToMillisecond()
  102. isActive = true
  103. // 设置不过期
  104. vip.IsExpired = false
  105. capp.PostEvent(event.NewVipStatus(playerID))
  106. }
  107. vip.ExpireTime += int64(day) * ctime.MillisecondsPerDay
  108. playerTable.Save2Queue()
  109. // 推送
  110. if session, found := sessions.GetSession(playerID); found {
  111. p.Push(playerTable, session)
  112. }
  113. if isActive {
  114. p.SyncMapActiveVip(playerTable)
  115. }
  116. return code.OK
  117. }
  118. // 同步到地图玩家激活的vip信息
  119. func (p *service) SyncMapActiveVip(playerTable *db.PlayerTable) {
  120. // 如果地图还没开放就不同步,等地图开启再激活
  121. if playerTable.Map.MapNodeID == "" {
  122. return
  123. }
  124. targetPath := cfacade.NewChildPath(playerTable.Map.MapNodeID, nameActor.Map_Player, playerTable.PlayerID)
  125. vipProto := &pb.SyncMapPlayerVip{
  126. PlayerID: playerTable.PlayerID,
  127. Level: playerTable.Vip.Level,
  128. Attrs: playerTable.Vip.Attrs.ToProto(),
  129. ExpireTime: playerTable.Vip.ExpireTime,
  130. }
  131. capp.Call(targetPath, nameRemote.MapPlayer_SyncVip, vipProto)
  132. }
  133. // 检查VIP是否过期
  134. func (p *service) CheckVipExpired(playerID int64) {
  135. playerTable, _ := db.GetPlayerTable(playerID)
  136. if playerTable.Vip.IsExpired {
  137. return
  138. }
  139. if playerTable.Vip.ExpireTime < ctime.Now().ToMillisecond() {
  140. playerTable.Vip.IsExpired = true
  141. playerTable.Save2Queue()
  142. // 发送vip过期时间
  143. capp.PostEvent(event.NewVipStatus(playerID))
  144. clog.Debugf("[CheckVipExpired] playerID = %d, vip expired", playerID)
  145. }
  146. }
  147. // 获取VIP加成值
  148. func (p *service) GetVipAttrAdd(playerID int64, attrID int32) int64 {
  149. playerTable, _ := db.GetPlayerTable(playerID)
  150. if playerTable.Vip.IsExpired {
  151. return 0
  152. }
  153. return playerTable.Vip.Attrs.GetI64(attrID)
  154. }