player_lord.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. package player
  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. nameEvent "f1-game/internal/name/event"
  9. nameLocal "f1-game/internal/name/local"
  10. nameRedis "f1-game/internal/name/redis"
  11. "f1-game/internal/pb"
  12. "f1-game/nodes/game/internal/db"
  13. dbPlayer "f1-game/nodes/game/internal/db/data/player"
  14. "f1-game/nodes/game/player/asset"
  15. ao "f1-game/nodes/game/player/asset/origin"
  16. "f1-game/nodes/game/player/lord"
  17. gameMap "f1-game/nodes/game/player/map"
  18. "strings"
  19. ctime "github.com/cherry-game/cherry/extend/time"
  20. cfacade "github.com/cherry-game/cherry/facade"
  21. cproto "github.com/cherry-game/cherry/net/proto"
  22. )
  23. func (p *actorPlayer) initLord() {
  24. p.Local().Register(nameLocal.Player_LordInfo, p.lordInfo)
  25. p.Local().Register(nameLocal.Player_LordChangeName, p.lordChangeName)
  26. p.Local().Register(nameLocal.Player_LordChangeIcon, p.lordChangeIcon)
  27. p.Local().Register(nameLocal.Player_LordChangeFrame, p.lordChangeFrame)
  28. p.Local().Register(nameLocal.Player_LordChangeBg, p.lordChangeBg)
  29. p.Local().Register(nameLocal.Player_LordChangeDesc, p.lordChangeDesc)
  30. p.Local().Register(nameLocal.Player_LordShowActive, p.lordShowActive)
  31. p.Local().Register(nameLocal.Player_LordShowView, p.lordShowView)
  32. p.Local().Register(nameLocal.Player_LordLangSelect, p.lordLangSelect)
  33. p.Local().Register(nameLocal.Player_LordShowDataSet, p.lordShowDataSet)
  34. p.EventRegister(nameEvent.Hero_Get, p.activeHeroShow)
  35. p.EventRegister(nameEvent.Hero_Star, p.heroStarRefreshPrestige)
  36. p.EventRegister(nameEvent.Player_Reset, p.onPlayerDataSync)
  37. }
  38. // 获取领主信息
  39. func (p *actorPlayer) lordInfo(session *cproto.Session, req *pb.I64) {
  40. if req.Value < 1 {
  41. p.ResponseCode(session, code.IllegalArgument)
  42. return
  43. }
  44. playerData := redis.Game.GetPlayerData(req.Value, nameRedis.PlayerDetailFields...)
  45. if playerData == nil {
  46. p.ResponseCode(session, code.PlayerDetailNotFound)
  47. return
  48. }
  49. // 玩家声望信息
  50. prestige := &pb.PrestigeDetail{
  51. CurPrestige: playerData.Prestige,
  52. }
  53. // 转换
  54. rsp := &pb.LordDetail{
  55. PlayerID: playerData.PlayerID,
  56. PlayerName: playerData.PlayerName,
  57. IconID: playerData.IconID,
  58. FrameID: playerData.FrameID,
  59. BgID: playerData.BgID,
  60. Desc: playerData.Desc,
  61. MapNodeID: playerData.MapNodeID,
  62. TotalLoginDays: playerData.TotalLoginDays,
  63. Prestige: prestige,
  64. Point: &pb.Point{X: playerData.X, Y: playerData.Y},
  65. }
  66. // 玩家数据展示
  67. showDatas := redis.Game.GetPlayerSetting(p.playerID)
  68. if showDatas != nil {
  69. rsp.ShowDatas = showDatas
  70. }
  71. // 获取联盟信息
  72. rsp.League = &pb.LeaguePlayerJob{
  73. LeagueID: playerData.LeagueID,
  74. LeagueName: playerData.LeagueName,
  75. LeagueAbbName: playerData.LeagueAbbName,
  76. JobID: playerData.LeagueJob,
  77. }
  78. p.Response(session, rsp)
  79. }
  80. // 修改领主名称
  81. func (p *actorPlayer) lordChangeName(session *cproto.Session, req *pb.Str) {
  82. var (
  83. playerTable = p.PlayerTable()
  84. newPlayerName = strings.TrimSpace(req.Value)
  85. curTime = ctime.Now().ToSecond()
  86. )
  87. // 名字相同
  88. if playerTable.Lord.Name == newPlayerName {
  89. p.ResponseCode(session, code.PlayerNameSame)
  90. return
  91. }
  92. // 长度不符
  93. if ok := data.Const.CheckPlayerNameLen(newPlayerName); !ok {
  94. p.ResponseCode(session, code.PlayerNameLimit)
  95. return
  96. }
  97. // 判断名称是否存在
  98. _, exist := db.PlayerNameIsExist(newPlayerName)
  99. if exist {
  100. p.ResponseCode(session, code.PlayerNameExist)
  101. return
  102. }
  103. // 改名冷却中
  104. if curTime < playerTable.Lord.LastChangeNameTime+data.Const.PlayerChangeNameCD {
  105. p.ResponseCode(session, code.PlayerChangeNameCD)
  106. return
  107. }
  108. // 首次免费
  109. if playerTable.Lord.ChangeNameCount > 0 {
  110. // 判断消耗
  111. _, errCode := asset.Service().Subs(p.playerID, data.Const.PlayerChangeNameCost, ao.PlayerChangeNameCost)
  112. if code.IsFail(errCode) {
  113. p.ResponseCode(session, errCode)
  114. return
  115. }
  116. }
  117. playerTable.UpdatePlayerName(newPlayerName, curTime)
  118. playerTable.Save2Queue()
  119. redis.Game.UpdatePlayerDataField(playerTable.PlayerID, nameRedis.Player_PlayerName, newPlayerName)
  120. p.Response(session, &pb.I64Str{Key: curTime, Value: newPlayerName})
  121. // 同步到地图
  122. gameMap.Service().SyncMapPlayer(p.playerID)
  123. }
  124. // 修改领主头像
  125. func (p *actorPlayer) lordChangeIcon(session *cproto.Session, req *pb.I32) {
  126. var (
  127. playerTable = p.PlayerTable()
  128. showID = req.Value
  129. )
  130. lordShowRow, found := data.LordShow.GetByShowID(showID)
  131. if !found {
  132. p.ResponseCode(session, code.ShowConfigNotExist)
  133. return
  134. }
  135. if lordShowRow.Type != enum.ShowType_Icon {
  136. p.ResponseCode(session, code.ShowTypeError)
  137. return
  138. }
  139. // 判断是否解锁
  140. show, found := playerTable.Shows.GetShow(showID)
  141. if !found {
  142. p.ResponseCode(session, code.ShowNotUnlock)
  143. return
  144. }
  145. if show.ExpireTime != 0 && show.ExpireTime <= ctime.Now().ToSecond() {
  146. p.ResponseCode(session, code.ShowExpire)
  147. return
  148. }
  149. if !show.IsViewed {
  150. show.IsViewed = true
  151. }
  152. playerTable.Lord.IconID = showID
  153. playerTable.Save2Queue()
  154. redis.Game.UpdatePlayerDataField(playerTable.PlayerID, nameRedis.Player_IconID, showID)
  155. resp := &pb.I32{Value: showID}
  156. p.Response(session, resp)
  157. // 同步到地图
  158. gameMap.Service().SyncMapPlayer(p.playerID)
  159. }
  160. // 修改领主头像框
  161. func (p *actorPlayer) lordChangeFrame(session *cproto.Session, req *pb.I32) {
  162. var (
  163. playerTable = p.PlayerTable()
  164. showID = req.Value
  165. )
  166. lordShowRow, found := data.LordShow.GetByShowID(showID)
  167. if !found {
  168. p.ResponseCode(session, code.ShowConfigNotExist)
  169. return
  170. }
  171. if lordShowRow.Type != enum.ShowType_Frame {
  172. p.ResponseCode(session, code.ShowTypeError)
  173. return
  174. }
  175. // 判断是否解锁
  176. show, found := playerTable.Shows.GetShow(showID)
  177. if !found {
  178. p.ResponseCode(session, code.ShowNotUnlock)
  179. return
  180. }
  181. if show.ExpireTime != 0 && show.ExpireTime <= ctime.Now().ToSecond() {
  182. p.ResponseCode(session, code.ShowExpire)
  183. return
  184. }
  185. playerTable.Lord.FrameID = showID
  186. playerTable.Save2Queue()
  187. redis.Game.UpdatePlayerDataField(playerTable.PlayerID, nameRedis.Player_FrameID, showID)
  188. resp := &pb.I32{Value: showID}
  189. p.Response(session, resp)
  190. // 同步到地图
  191. gameMap.Service().SyncMapPlayer(p.playerID)
  192. }
  193. // 修改领主主页背景
  194. func (p *actorPlayer) lordChangeBg(session *cproto.Session, req *pb.I32) {
  195. var (
  196. playerTable = p.PlayerTable()
  197. showID = req.Value
  198. )
  199. lordShowRow, found := data.LordShow.GetByShowID(showID)
  200. if !found {
  201. p.ResponseCode(session, code.ShowConfigNotExist)
  202. return
  203. }
  204. if lordShowRow.Type != enum.ShowType_Bg {
  205. p.ResponseCode(session, code.ShowTypeError)
  206. return
  207. }
  208. // 判断是否解锁
  209. show, found := playerTable.Shows.GetShow(showID)
  210. if !found {
  211. p.ResponseCode(session, code.ShowNotUnlock)
  212. return
  213. }
  214. if show.ExpireTime != 0 && show.ExpireTime <= ctime.Now().ToSecond() {
  215. p.ResponseCode(session, code.ShowExpire)
  216. return
  217. }
  218. playerTable.Lord.BgID = showID
  219. playerTable.Save2Queue()
  220. redis.Game.UpdatePlayerDataField(playerTable.PlayerID, nameRedis.Player_BgID, showID)
  221. resp := &pb.I32{Value: showID}
  222. p.Response(session, resp)
  223. }
  224. // 修改领主主页简介
  225. func (p *actorPlayer) lordChangeDesc(session *cproto.Session, req *pb.Str) {
  226. var (
  227. playerTable = p.PlayerTable()
  228. desc = strings.TrimSpace(req.Value)
  229. )
  230. // 判断是否超过限制
  231. if data.Const.CheckPlayerDescLen(desc) {
  232. p.ResponseCode(session, code.PlayerDescLenLimit)
  233. return
  234. }
  235. if playerTable.Lord.Desc != desc {
  236. playerTable.Lord.Desc = desc
  237. playerTable.Save2Queue()
  238. // 更新到redis
  239. redis.Game.UpdatePlayerDataField(playerTable.PlayerID, nameRedis.Player_Desc, desc)
  240. }
  241. resp := &pb.Str{Value: desc}
  242. p.Response(session, resp)
  243. }
  244. // 外显激活
  245. func (p *actorPlayer) lordShowActive(session *cproto.Session, req *pb.I32) {
  246. var (
  247. playerTable = p.PlayerTable()
  248. showID = req.Value
  249. )
  250. lordShowRow, found := data.LordShow.GetByShowID(showID)
  251. if !found {
  252. p.ResponseCode(session, code.ShowConfigNotExist)
  253. return
  254. }
  255. show, found := playerTable.Shows.GetShow(showID)
  256. if found && show.ExpireTime <= 0 {
  257. p.ResponseCode(session, code.ShowAlreadyActive)
  258. return
  259. }
  260. // 英雄都是自动激活
  261. if lordShowRow.ActiveCondition.Key == enum.Hero_Active {
  262. p.ResponseCode(session, code.ShowActiveTypeError)
  263. return
  264. }
  265. _, errCode := asset.Service().Sub(p.playerID, lordShowRow.ActiveCondition.Value, 1, ao.ShowActiveCost)
  266. if code.IsFail(errCode) {
  267. p.ResponseCode(session, errCode)
  268. return
  269. }
  270. // 激活外显
  271. playerTable.Shows.ActiveShow(showID, lordShowRow.ExpireTime)
  272. playerTable.Save2Queue()
  273. p.Response(session, show.ToProto(showID))
  274. }
  275. // 查看外显 消除红点
  276. func (p *actorPlayer) lordShowView(session *cproto.Session, req *pb.I32) {
  277. var (
  278. playerTable = p.PlayerTable()
  279. showID = req.Value
  280. )
  281. show, found := playerTable.Shows.GetShow(showID)
  282. if !found {
  283. p.ResponseCode(session, code.ShowNotUnlock)
  284. return
  285. }
  286. if !show.IsViewed {
  287. show.IsViewed = true
  288. playerTable.Save2Queue()
  289. }
  290. p.ResponseCode(session, code.OK)
  291. }
  292. // 语言设置
  293. func (p *actorPlayer) lordLangSelect(session *cproto.Session, req *pb.Str) {
  294. var (
  295. playerTable = p.PlayerTable()
  296. lang = req.Value
  297. )
  298. if playerTable.Settings.Language != lang {
  299. _, found := enum.ParseLanguage(lang)
  300. if !found {
  301. p.ResponseCode(session, code.LanguageNotExist)
  302. return
  303. }
  304. playerTable.Settings.Language = lang
  305. playerTable.Save2Queue()
  306. }
  307. resp := &pb.Str{Value: playerTable.Settings.Language}
  308. p.Response(session, resp)
  309. }
  310. func (p *actorPlayer) lordShowDataSet(session *cproto.Session, req *pb.LordShowDataList) {
  311. var (
  312. playerTable = p.PlayerTable()
  313. showList = req.Datas
  314. )
  315. if len(showList) != len(enum.AllShowDataTypes) {
  316. p.ResponseCode(session, code.ShowDataLenNoSame)
  317. return
  318. }
  319. var (
  320. showDatas = []*dbPlayer.ShowData{}
  321. showCount = 0
  322. )
  323. for _, show := range showList {
  324. showType := show.ShowType
  325. showDataType, found := enum.CheckShowDataTypeExist(showType)
  326. if !found {
  327. p.ResponseCode(session, code.ShowDataTypeNotExist)
  328. return
  329. }
  330. if show.IsShow {
  331. showCount++
  332. if showCount > data.Const.PlayerShowDataCount {
  333. p.ResponseCode(session, code.ShowDataCountLimit)
  334. return
  335. }
  336. }
  337. showData := &dbPlayer.ShowData{
  338. ShowType: showDataType,
  339. IsShow: show.IsShow,
  340. }
  341. showDatas = append(showDatas, showData)
  342. }
  343. playerTable.Settings.ShowDatas = showDatas
  344. playerTable.Save2Queue()
  345. // 缓存到redis上
  346. redis.Game.UpdatePlayerSetting(playerTable.PlayerID, req)
  347. p.Response(session, req)
  348. }
  349. // 获得英雄判断激活外显
  350. func (p *actorPlayer) activeHeroShow(e cfacade.IEventData) {
  351. evt, ok := e.(*event.HeroGet)
  352. if !ok || evt.Heroes().Len() < 1 {
  353. return
  354. }
  355. var (
  356. playerTable = p.PlayerTable()
  357. heroes = evt.Heroes()
  358. updateList = []int32{}
  359. )
  360. for _, hero := range heroes {
  361. row, found := data.LordShow.GetHeroShow(hero.ID)
  362. if !found {
  363. continue
  364. }
  365. show, found := playerTable.Shows.GetShow(row.ShowID)
  366. // 已激活且当前为永久
  367. if found && show.ExpireTime <= 0 {
  368. continue
  369. }
  370. // 激活外显
  371. playerTable.Shows.ActiveShow(row.ShowID, row.ExpireTime)
  372. updateList = append(updateList, row.ShowID)
  373. }
  374. if len(updateList) > 0 {
  375. playerTable.Save2Queue()
  376. // 推送英雄变更
  377. lord.Service().ChangePush(p.playerID, updateList...)
  378. }
  379. }
  380. // 英雄升星刷新声望
  381. func (p *actorPlayer) heroStarRefreshPrestige(e cfacade.IEventData) {
  382. // 刷新英雄声望
  383. lord.Service().UpdatePrestige(p.playerID)
  384. }
  385. // 跨天同步玩家信息
  386. func (p *actorPlayer) onPlayerDataSync(c cfacade.IEventData) {
  387. _, ok := c.(*event.PlayerReset)
  388. if !ok {
  389. return
  390. }
  391. var (
  392. playerTable = p.PlayerTable()
  393. fields = map[string]any{}
  394. )
  395. fields[nameRedis.Player_TotalLoginDays] = playerTable.Stats.TotalLoginDays
  396. redis.Game.SavePlayerDataFields(p.playerID, fields)
  397. }