player_league.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. package mapPlayer
  2. import (
  3. actorRemote "f1-game/internal/actor_remote"
  4. "f1-game/internal/code"
  5. "f1-game/internal/component/redis"
  6. "f1-game/internal/constant"
  7. "f1-game/internal/data"
  8. "f1-game/internal/enum"
  9. "f1-game/internal/event"
  10. nameActor "f1-game/internal/name/actor"
  11. nameLocal "f1-game/internal/name/local"
  12. nameRedis "f1-game/internal/name/redis"
  13. nameRemote "f1-game/internal/name/remote"
  14. nameRoute "f1-game/internal/name/route"
  15. "f1-game/internal/pb"
  16. "f1-game/internal/sessions"
  17. "f1-game/internal/types"
  18. ao "f1-game/nodes/game/player/asset/origin"
  19. mapCall "f1-game/nodes/map/internal/call"
  20. "f1-game/nodes/map/internal/db"
  21. "f1-game/nodes/map/player/league"
  22. "f1-game/nodes/map/player/season"
  23. ctime "github.com/cherry-game/cherry/extend/time"
  24. cfacade "github.com/cherry-game/cherry/facade"
  25. cproto "github.com/cherry-game/cherry/net/proto"
  26. )
  27. func (p *actorPlayer) initPlayerLeague() {
  28. p.Local().Register(nameLocal.MapPlayer_LeagueCreate, p.leagueCreate)
  29. p.Local().Register(nameLocal.MapPlayer_LeagueJoin, p.leagueJoin)
  30. p.Local().Register(nameLocal.MapPlayer_LeagueList, p.leagueList)
  31. p.Local().Register(nameLocal.MapPlayer_LeagueSearch, p.leagueSearch)
  32. p.Local().Register(nameLocal.MapPlayer_LeagueInfo, p.leagueInfo)
  33. p.Local().Register(nameLocal.MapPlayer_LeagueNameChange, p.leagueNameChange)
  34. p.Local().Register(nameLocal.MapPlayer_LeagueAbbNameChange, p.leagueAbbNameChange)
  35. p.Local().Register(nameLocal.MapPlayer_LeagueDiplomacyList, p.leagueDiplomacyList)
  36. p.Remote().Register(nameRemote.MapLeague_JoinNotice, p.leagueJoinNotice)
  37. p.Remote().Register(nameRemote.MapLeague_QuitNotice, p.leagueQuitNotice)
  38. // TODO 未处理
  39. //p.Event().Register(nameEvent.Player_Login, p.onLogin)
  40. }
  41. // 创建联盟
  42. func (p *actorPlayer) leagueCreate(session *cproto.Session, req *pb.LeagueCreateRequest) {
  43. playerTable := db.GetMapPlayerTable(p.playerID)
  44. var (
  45. leagueName = req.LeagueName
  46. leagueAbbName = req.LeagueAbbName
  47. flagBg = req.FlagBg
  48. flagIcon = req.FlagIcon
  49. )
  50. //判断玩家是否加入联盟
  51. if playerTable.LeagueID > 0 {
  52. p.ResponseCode(session, code.LeagueAlreadyJoin)
  53. return
  54. }
  55. // TODO 判断玩家主城等级是否满足 等待后续城建迁移完成处理
  56. // 检测旗帜背景是否合法
  57. flagBgRow, found := data.LeagueFlag.GetByFlagID(flagBg)
  58. if !found {
  59. p.ResponseCode(session, code.LeagueFlagBgNotExist)
  60. return
  61. }
  62. if flagBgRow.FlagType != enum.League_FlagBg {
  63. p.ResponseCode(session, code.LeagueFlagBgError)
  64. return
  65. }
  66. // 检测旗帜图标是否合法
  67. flagIconRow, found := data.LeagueFlag.GetByFlagID(flagIcon)
  68. if !found {
  69. p.ResponseCode(session, code.LeagueFlagIconNotExist)
  70. return
  71. }
  72. if flagIconRow.FlagType != enum.League_FlagIcon {
  73. p.ResponseCode(session, code.LeagueFlagIconError)
  74. return
  75. }
  76. // TODO 暂时从redis获取GameNodeID 后面部队和进入地图流程更新再调整
  77. playerData := redis.Game.GetPlayerData(p.playerID, nameRedis.PlayerGameNodeFields...)
  78. if playerData == nil {
  79. p.ResponseCode(session, code.DataNotFound)
  80. return
  81. }
  82. // 请求game检测创建联盟需要消耗的金币满足
  83. errCode := actorRemote.GamePlayer.AssetCheck(playerData.GameNodeID, p.playerID, data.Const.LeagueCreateCost)
  84. if code.IsFail(errCode) {
  85. p.ResponseCode(session, errCode)
  86. return
  87. }
  88. // 尝试创建联盟
  89. leagueID, errCode := mapCall.League.LeagueCreate(p.playerID, leagueName, leagueAbbName, flagBg, flagIcon)
  90. if code.IsFail(errCode) {
  91. p.ResponseCode(session, errCode)
  92. return
  93. }
  94. // 请求game扣除创建联盟消耗
  95. actorRemote.GamePlayer.AssetSub(playerData.GameNodeID, p.playerID, data.Const.LeagueCreateCost, ao.CreateLeagueCost)
  96. // 执行联盟创建通知
  97. p.doLeagueJoinNotice(leagueID, leagueName, false)
  98. // 发送联盟创建事件
  99. p.PostEvent(event.NewLeagueCreate(p.playerID, leagueID))
  100. p.ResponseCode(session, code.OK)
  101. }
  102. // 申请加入联盟 只处理玩家申请加入联盟的流程
  103. func (p *actorPlayer) leagueJoin(session *cproto.Session, req *pb.I64) {
  104. var (
  105. leagueID = req.Value
  106. playerTable = db.GetMapPlayerTable(p.playerID)
  107. )
  108. if leagueID <= 0 {
  109. p.ResponseCode(session, code.IllegalArgument)
  110. return
  111. }
  112. if playerTable.LeagueID > 0 {
  113. p.ResponseCode(session, code.LeagueAlreadyJoin)
  114. return
  115. }
  116. // 判断退出联盟冷却时间
  117. if data.Const.CheckLeagueQuitCD(playerTable.LeagueQuitTime) {
  118. p.ResponseCode(session, code.LeagueQuitCD)
  119. return
  120. }
  121. // 申请加入联盟
  122. errCode := mapCall.League.LeagueJoin(p.playerID, leagueID,
  123. playerTable.Facilities.GetFacilityLevel(enum.Facility_MainID))
  124. if code.IsFail(errCode) {
  125. p.ResponseCode(session, errCode)
  126. return
  127. }
  128. p.ResponseCode(session, code.OK)
  129. }
  130. // 获取联盟列表
  131. func (p *actorPlayer) leagueList(session *cproto.Session, req *pb.None) {
  132. leagueList, errCode := mapCall.League.LeagueList(p.playerID)
  133. if code.IsFail(errCode) {
  134. p.ResponseCode(session, errCode)
  135. return
  136. }
  137. p.Response(session, leagueList)
  138. }
  139. // 获取联盟外交列表
  140. func (p *actorPlayer) leagueDiplomacyList(session *cproto.Session, _ *pb.None) {
  141. var (
  142. diplpmacyReq = &pb.None{}
  143. resp = &pb.LeagueDiplomacyInfos{}
  144. target = cfacade.NewPath("", nameActor.Map_League)
  145. )
  146. errCode := p.CallWait(target, nameRemote.MapLeague_DiplomacyInfos, diplpmacyReq, resp)
  147. if code.IsFail(errCode) {
  148. p.ResponseCode(session, errCode)
  149. return
  150. }
  151. p.Response(session, resp)
  152. }
  153. // 联盟搜索
  154. func (p *actorPlayer) leagueSearch(session *cproto.Session, req *pb.Str) {
  155. keyword := req.Value
  156. if len(keyword) < 1 {
  157. p.ResponseCode(session, code.IllegalArgument)
  158. return
  159. }
  160. rsp, errCode := mapCall.League.LeagueSearch(keyword)
  161. if code.IsFail(errCode) {
  162. p.ResponseCode(session, errCode)
  163. return
  164. }
  165. if len(rsp.List) < 1 {
  166. p.ResponseCode(session, code.LeagueSearchNotExist)
  167. return
  168. }
  169. p.Response(session, rsp)
  170. }
  171. // 联盟信息
  172. func (p *actorPlayer) leagueInfo(session *cproto.Session, req *pb.I64) {
  173. leagueID := req.Value
  174. if leagueID < 1 {
  175. p.ResponseCode(session, code.IllegalArgument)
  176. return
  177. }
  178. var (
  179. infoReq = &pb.I64{Value: leagueID}
  180. resp = &pb.League{}
  181. target = cfacade.NewChildPath("", nameActor.Map_League, leagueID)
  182. )
  183. errCode := p.CallWait(target, nameRemote.MapLeague_Info, infoReq, resp)
  184. if code.IsFail(errCode) {
  185. p.ResponseCode(session, errCode)
  186. return
  187. }
  188. p.Response(session, resp)
  189. }
  190. // 联盟名称更改
  191. func (p *actorPlayer) leagueNameChange(session *cproto.Session, req *pb.Str) {
  192. playerTable := db.GetMapPlayerTable(p.playerID)
  193. leagueID := playerTable.LeagueID
  194. if leagueID < 1 {
  195. p.ResponseCode(session, code.LeagueNotJoin)
  196. return
  197. }
  198. assets := types.Assets{}
  199. assets.Add(data.Const.LeagueChangeNameCost.ID, data.Const.LeagueChangeNameCost.Num)
  200. errCode := actorRemote.GamePlayer.AssetCheck(playerTable.GameNodeID, p.playerID, assets)
  201. if code.IsFail(errCode) {
  202. p.ResponseCode(session, errCode)
  203. return
  204. }
  205. var (
  206. changeReq = &pb.LeagueNameChange{
  207. PlayerID: p.playerID,
  208. LeagueID: leagueID,
  209. NewName: req.Value,
  210. }
  211. target = cfacade.NewPath("", nameActor.Map_League)
  212. )
  213. errCode = p.CallWait(target, nameRemote.MapLeague_NameChange, changeReq, nil)
  214. if code.IsFail(errCode) {
  215. p.ResponseCode(session, errCode)
  216. return
  217. }
  218. actorRemote.GamePlayer.AssetSub(playerTable.GameNodeID, p.playerID, assets, ao.LeagueChangeNameCost)
  219. resp := &pb.Str{
  220. Value: req.Value,
  221. }
  222. p.Response(session, resp)
  223. }
  224. // 联盟简称更改
  225. func (p *actorPlayer) leagueAbbNameChange(session *cproto.Session, req *pb.Str) {
  226. playerTable := db.GetMapPlayerTable(p.playerID)
  227. leagueID := playerTable.LeagueID
  228. if leagueID < 1 {
  229. p.ResponseCode(session, code.LeagueNotJoin)
  230. return
  231. }
  232. assets := types.Assets{}
  233. assets.Add(data.Const.LeagueChangeAbbNameCost.ID, data.Const.LeagueChangeAbbNameCost.Num)
  234. errCode := actorRemote.GamePlayer.AssetCheck(playerTable.GameNodeID, p.playerID, assets)
  235. if code.IsFail(errCode) {
  236. p.ResponseCode(session, errCode)
  237. return
  238. }
  239. var (
  240. changeReq = &pb.LeagueNameChange{
  241. PlayerID: p.playerID,
  242. LeagueID: leagueID,
  243. NewName: req.Value,
  244. }
  245. target = cfacade.NewPath("", nameActor.Map_League)
  246. )
  247. errCode = p.CallWait(target, nameRemote.MapLeague_AbbNameChange, changeReq, nil)
  248. if code.IsFail(errCode) {
  249. p.ResponseCode(session, errCode)
  250. return
  251. }
  252. // 扣除消耗
  253. actorRemote.GamePlayer.AssetSub(playerTable.GameNodeID, p.playerID, assets, ao.LeagueChangeAbbNameCost)
  254. resp := &pb.Str{
  255. Value: req.Value,
  256. }
  257. p.Response(session, resp)
  258. }
  259. // 加入联盟通知
  260. func (p *actorPlayer) leagueJoinNotice(req *pb.I64Str) int32 {
  261. return p.doLeagueJoinNotice(req.Key, req.Value, true)
  262. }
  263. func (p *actorPlayer) doLeagueJoinNotice(leagueID int64, leagueName string, join bool) int32 {
  264. p.Debug("[doLeagueJoinNotice] join league. playerID:%d, leagueID: %d", p.playerID, leagueID)
  265. playerTable := db.GetMapPlayerTable(p.playerID)
  266. if playerTable.LeagueID > 0 && playerTable.LeagueID != leagueID {
  267. p.Debug("[doLeagueJoinNotice] join league fail. playerID:%d, leagueID: %d", p.playerID, leagueID)
  268. return code.LeagueAlreadyJoinOther
  269. }
  270. // 更新玩家所属联盟ID
  271. playerTable.LeagueID = leagueID
  272. playerTable.Save2Queue()
  273. // 创建玩家关联联盟聊天室
  274. target := cfacade.NewChildPath(playerTable.GameNodeID, nameActor.GamePlayer, p.playerID)
  275. p.Call(target, nameRemote.Player_ChatRoomUpdate, &pb.PlayerChatRoomUpdate{
  276. ChatType: int32(enum.ChatType_League),
  277. ChatID: leagueID,
  278. })
  279. session, found := sessions.GetSession(p.playerID)
  280. if found {
  281. // 更新联盟ID到gate的session
  282. league.Service().SetSession(session, playerTable.LeagueID)
  283. // 推送联盟信息
  284. mapCall.League.LeagueOnLogin(p.playerID, playerTable.LeagueID)
  285. }
  286. // 抛事件
  287. p.PostEvent(event.NewLeagueJoin(p.playerID, leagueID, leagueName))
  288. if join {
  289. // 发送加入成功邮件 // TODO 暂时往game写
  290. actorRemote.GameMail.Send(playerTable.GameNodeID, &pb.SendMail{
  291. ToPlayerID: p.playerID,
  292. TemplateID: constant.MailID_LeagueJoinSuccess,
  293. TemplateParams: []string{leagueName},
  294. })
  295. }
  296. p.Debug("[doLeagueJoinNotice] join league finish. playerID:%d, leagueID: %d", p.playerID, leagueID)
  297. return code.OK
  298. }
  299. // 退出联盟通知
  300. func (p *actorPlayer) leagueQuitNotice(req *pb.I64) int32 {
  301. var (
  302. leagueID = req.Value
  303. playerTable = db.GetMapPlayerTable(p.playerID)
  304. )
  305. // 防止不同的联盟ID
  306. if playerTable.LeagueID != leagueID {
  307. return code.LeagueMemberNotExist
  308. }
  309. // 去掉玩家关联联盟ID
  310. playerTable.LeagueID = 0
  311. playerTable.LeagueQuitTime = ctime.Now().ToSecond()
  312. playerTable.Save2Queue()
  313. session, found := sessions.GetSession(p.playerID)
  314. if found {
  315. // 更新联盟ID到gate的session
  316. league.Service().SetSession(session, 0)
  317. }
  318. // 退出玩家关联联盟聊天室
  319. target := cfacade.NewChildPath(playerTable.GameNodeID, nameActor.GamePlayer, p.playerID)
  320. p.Call(target, nameRemote.Player_ChatRoomUpdate, &pb.PlayerChatRoomUpdate{
  321. ChatType: int32(enum.ChatType_League),
  322. ChatID: leagueID,
  323. IsExit: true,
  324. })
  325. rsp := &pb.I64{
  326. Value: leagueID,
  327. }
  328. // 推送退出联盟通知
  329. sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_LeagueQuit, rsp)
  330. // 抛事件
  331. p.PostEvent(event.NewLeagueQuit(p.playerID, 0))
  332. // TODO 重新随机一个主城位置
  333. //mapCall.Logic.AddMainCity(p.playerID, leagueID, true)
  334. // 记录联盟类型的已结算的赛季霸业任务状态
  335. season.Service().LeagueQuitSeasonQuestRecord(p.playerID, leagueID)
  336. return code.OK
  337. }