player_lord.go 12 KB

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