league_base.go 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. package mapLeague
  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. "f1-game/internal/extend/utils"
  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. dbLeague "f1-game/nodes/map/internal/db/data/league"
  22. leagueAttr "f1-game/nodes/map/league/attr"
  23. leagueBase "f1-game/nodes/map/league/base"
  24. leagueStorage "f1-game/nodes/map/league/storage"
  25. "math/rand/v2"
  26. ctime "github.com/cherry-game/cherry/extend/time"
  27. cproto "github.com/cherry-game/cherry/net/proto"
  28. )
  29. func (p *actorLeague) initLeagueBase() {
  30. p.Local().Register(nameLocal.MapLeague_Upgrade, p.leagueUpgrade)
  31. p.Local().Register(nameLocal.MapLeague_ApplyList, p.leagueApplyList)
  32. p.Local().Register(nameLocal.MapLeague_ApplyOption, p.leagueApplyOption)
  33. p.Local().Register(nameLocal.MapLeague_ApplyAgreeAll, p.leagueApplyAgreeAll)
  34. p.Local().Register(nameLocal.MapLeague_ClearApplyList, p.leagueClearApplyList)
  35. p.Local().Register(nameLocal.MapLeague_Setting, p.leagueSetting)
  36. p.Local().Register(nameLocal.MapLeague_FlagSet, p.leagueFlagSet)
  37. p.Local().Register(nameLocal.MapLeague_LogList, p.leagueLogList)
  38. p.Local().Register(nameLocal.MapLeague_ResidenceBack, p.leagueResidenceBack)
  39. p.Local().Register(nameLocal.MapLeague_MapMark, p.leagueMapMark)
  40. p.Local().Register(nameLocal.MapLeague_MapMarkEdit, p.leagueMapMarkEdit)
  41. p.Local().Register(nameLocal.MapLeague_MapMarkDelete, p.leagueMapMarkDelete)
  42. p.Remote().Register(nameRemote.MapLeague_Info, p.leagueInfo)
  43. p.Remote().Register(nameRemote.MapLeague_ResidenceRemove, p.leagueResidenceRemove)
  44. p.Remote().Register(nameRemote.MapLeague_ForceResidenceBack, p.forceResidenceBack)
  45. p.Remote().Register(nameRemote.MapLeague_Join, p.leagueJoin)
  46. }
  47. func (p *actorLeague) leagueInfo(req *pb.I64) (*pb.League, int32) {
  48. leagueID := req.Value
  49. leagueTable, found := db.GetMapLeagueTable(leagueID)
  50. if !found {
  51. return nil, code.LeagueNotExist
  52. }
  53. league := leagueTable.ToLeagueInfoProto()
  54. // 设置联盟名称 // TODO 后续改成缓存的map直接读取map的
  55. if len(league.Diplomacy.Applys) > 0 {
  56. for _, apply := range league.Diplomacy.Applys {
  57. leagueTable, found := db.GetMapLeagueTable(apply.LeagueID)
  58. if found {
  59. apply.LeagueName = leagueTable.LeagueInfo.LeagueName
  60. }
  61. }
  62. }
  63. leagueMemberTable, found := db.GetMapLeagueMemberTable(leagueID)
  64. if found {
  65. league.LeaguePrestige = leagueMemberTable.GetMemberPrestige()
  66. }
  67. return league, code.OK
  68. }
  69. // apply 加入联盟
  70. func (p *actorLeague) leagueJoin(req *pb.I64I32) int32 {
  71. var (
  72. playerID = req.Key
  73. mainCityLevel = req.Value
  74. )
  75. if playerID < 1 || p.leagueID < 1 {
  76. return code.IllegalArgument
  77. }
  78. //判断联盟是否存在 获取联盟信息
  79. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  80. if !found {
  81. return code.LeagueNotExist
  82. }
  83. // 判断是否提交过申请
  84. if leagueTable.LeagueInfo.CheckApplyExist(playerID) {
  85. return code.LeagueApplyRepeat
  86. }
  87. // 判断玩家等级是否满足
  88. if mainCityLevel < leagueTable.LeagueInfo.JoinNeedLevel {
  89. return code.LeagueNeedLevelNotEnough
  90. }
  91. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  92. if !found {
  93. return code.LeagueMembersEmpty
  94. }
  95. //判断当前联盟是否已满人 如果满人则拒绝入会申请
  96. if leagueMemberTable.GetLeagueMemberCount() >= leagueTable.LeagueInfo.Attrs.GetI32(enum.LeagueAttrMemberCountLimit) {
  97. return code.LeagueMembersLimit
  98. }
  99. // 申请需要审批
  100. if leagueTable.LeagueInfo.IsJoinApproval() {
  101. // 添加申请记录
  102. leagueTable.LeagueInfo.AddApply(playerID)
  103. // 通知可处理申请的在线管理(有人员权限的管理员)
  104. p.leagueJoinApplyNotice(leagueTable.LeagueInfo.LeaderID, leagueMemberTable, playerID)
  105. } else {
  106. errCode := actorRemote.MapPlayer.LeagueJoin(playerID, &pb.LeagueJoinNotice{
  107. LeagueID: p.leagueID,
  108. LeagueName: p.leagueTable.LeagueInfo.LeagueName,
  109. CastleConfigIDs: p.leagueTable.Castles.GetConfigIDs(),
  110. })
  111. if code.IsFail(errCode) {
  112. p.Warn("[leagueJoin] player fail. leagueID:%d, playerID:%d", p.leagueID, playerID)
  113. return errCode
  114. }
  115. // 成功 加入联盟
  116. p.doLeagueMemberJoin(leagueTable, leagueMemberTable, playerID)
  117. }
  118. leagueTable.Save2Queue()
  119. return code.OK
  120. }
  121. // 联盟升级
  122. func (p *actorLeague) leagueUpgrade(session *cproto.Session, _ *pb.None) {
  123. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  124. if !found {
  125. p.ResponseCode(session, code.LeagueNotExist)
  126. return
  127. }
  128. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  129. if !found {
  130. p.ResponseCode(session, code.LeagueMembersEmpty)
  131. return
  132. }
  133. // 检测是否有权限
  134. opPlayerID := sessions.GetPlayerID(session)
  135. ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Construction)
  136. if !ok {
  137. p.ResponseCode(session, code.LeaguePermissionDenied)
  138. return
  139. }
  140. var (
  141. curLevel = leagueTable.LeagueInfo.Level
  142. nextLevel = curLevel + 1
  143. )
  144. curLevelRow, found := data.LeagueLevel.GetByLevel(curLevel)
  145. if !found {
  146. p.ResponseCode(session, code.LeagueLevelConfigNotExist)
  147. return
  148. }
  149. // 已达最大等级
  150. if curLevelRow.Exp.Value <= 0 {
  151. p.ResponseCode(session, code.LeagueMaxLevel)
  152. return
  153. }
  154. // 获取下一等级配置
  155. _, found = data.LeagueLevel.GetByLevel(nextLevel)
  156. if !found {
  157. p.ResponseCode(session, code.LeagueLevelConfigNotExist)
  158. return
  159. }
  160. assets := types.Assets{
  161. {ID: curLevelRow.Exp.Key, Num: int64(curLevelRow.Exp.Value)},
  162. }
  163. errCode := p.subAssets(assets)
  164. if code.IsFail(errCode) {
  165. p.ResponseCode(session, errCode)
  166. return
  167. }
  168. leagueTable.LeagueInfo.Level = nextLevel
  169. // 更新属性
  170. leagueAttr.Service().UpdateAttrs(leagueTable)
  171. leagueTable.Save2Queue()
  172. objectID := int64(0)
  173. build, found := leagueTable.Builds.GetByType(constant.MapBuild_LeaguePoint)
  174. if found {
  175. objectID = build.ObjectID
  176. }
  177. p.PostEvent(event.NewLeagueUpgrade(p.leagueID, objectID, leagueTable.LeagueInfo.Level))
  178. // 检查更新仓库容量
  179. leagueStorage.Service().CheckAndInitCapacity(leagueTable)
  180. p.ResponseCode(session, code.OK)
  181. // 联盟升级推送
  182. leagueBase.Service().LeagueUpgradPush(leagueTable, leagueMemberTable)
  183. }
  184. // 获取入盟申请列表
  185. func (p *actorLeague) leagueApplyList(session *cproto.Session, _ *pb.None) {
  186. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  187. if !found {
  188. p.ResponseCode(session, code.LeagueNotExist)
  189. return
  190. }
  191. var (
  192. list = []*pb.LeagueApply{}
  193. playerIDs = []int64{}
  194. )
  195. for _, pair := range leagueTable.LeagueInfo.LeagueApplys {
  196. apply := &pb.LeagueApply{
  197. PlayerID: pair.Key,
  198. ApplyTime: pair.Value,
  199. }
  200. list = append(list, apply)
  201. playerIDs = append(playerIDs, pair.Key)
  202. }
  203. if len(playerIDs) > 0 {
  204. // 获取玩家基础信息
  205. playerDataMap := redis.Game.GetPlayerDataMap(playerIDs, nameRedis.PlayerBaseFields...)
  206. if len(playerDataMap) > 0 {
  207. for _, apply := range list {
  208. playerData, found := playerDataMap[apply.PlayerID]
  209. if found {
  210. apply.PlayerName = playerData.PlayerName
  211. apply.Level = playerData.LordLevel
  212. }
  213. }
  214. }
  215. }
  216. resp := &pb.LeagueApplyList{
  217. List: list,
  218. }
  219. p.Response(session, resp)
  220. }
  221. // 联盟申请处理 拒绝/通过
  222. func (p *actorLeague) leagueApplyOption(session *cproto.Session, req *pb.I64Bool) {
  223. var (
  224. opPlayerID = sessions.GetPlayerID(session)
  225. targetPlayerID = req.Key
  226. isArgee = req.Value
  227. )
  228. if targetPlayerID < 1 {
  229. p.ResponseCode(session, code.IllegalArgument)
  230. return
  231. }
  232. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  233. if !found {
  234. p.ResponseCode(session, code.LeagueNotExist)
  235. return
  236. }
  237. // 检测申请是否存在
  238. if !leagueTable.LeagueInfo.CheckApplyExist(targetPlayerID) {
  239. p.ResponseCode(session, code.LeagueApplyNotExist)
  240. return
  241. }
  242. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  243. if !found {
  244. p.ResponseCode(session, code.LeagueMembersEmpty)
  245. return
  246. }
  247. if !leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Member) {
  248. p.ResponseCode(session, code.LeaguePermissionDenied)
  249. return
  250. }
  251. errCode := code.OK
  252. //通过申请
  253. if isArgee {
  254. // 判断玩家是否已存在联盟中
  255. if leagueMemberTable.CheckMemberExist(targetPlayerID) {
  256. p.ResponseCode(session, code.LeagueAlreadyJoin)
  257. return
  258. }
  259. // 判断联盟人数是否已满
  260. if leagueMemberTable.GetLeagueMemberCount() >= leagueTable.LeagueInfo.Attrs.GetI32(enum.LeagueAttrMemberCountLimit) {
  261. p.ResponseCode(session, code.LeagueMembersLimit)
  262. return
  263. }
  264. errCode := actorRemote.MapPlayer.LeagueJoin(targetPlayerID, &pb.LeagueJoinNotice{
  265. LeagueID: p.leagueID,
  266. LeagueName: p.leagueTable.LeagueInfo.LeagueName,
  267. CastleConfigIDs: p.leagueTable.Castles.GetConfigIDs(),
  268. })
  269. if code.IsOK(errCode) {
  270. // 成功 加入联盟
  271. p.doLeagueMemberJoin(leagueTable, leagueMemberTable, targetPlayerID)
  272. }
  273. }
  274. // 不管通过还是拒绝 都需要移除申请记录
  275. leagueTable.LeagueInfo.RemoveApply(targetPlayerID)
  276. leagueTable.Save2Queue()
  277. p.ResponseCode(session, errCode)
  278. }
  279. // 一键同意入盟申请
  280. func (p *actorLeague) leagueApplyAgreeAll(session *cproto.Session, _ *pb.None) {
  281. opPlayerID := sessions.GetPlayerID(session)
  282. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  283. if !found {
  284. p.ResponseCode(session, code.LeagueMembersEmpty)
  285. return
  286. }
  287. if !leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Member) {
  288. p.ResponseCode(session, code.LeaguePermissionDenied)
  289. return
  290. }
  291. if p.leagueTable.LeagueInfo.LeagueApplys.IsEmpty() {
  292. p.ResponseCode(session, code.LeagueApplyNotExist)
  293. return
  294. }
  295. var (
  296. curMemberCount = leagueMemberTable.GetLeagueMemberCount()
  297. memberCountLimit = p.leagueTable.LeagueInfo.Attrs.GetI32(enum.LeagueAttrMemberCountLimit)
  298. )
  299. // 判断联盟人数是否已满
  300. if curMemberCount >= memberCountLimit {
  301. p.ResponseCode(session, code.LeagueMembersLimit)
  302. return
  303. }
  304. var (
  305. removeApplys = []int64{}
  306. joinPlayerIDs = []int64{}
  307. )
  308. for _, pair := range p.leagueTable.LeagueInfo.LeagueApplys {
  309. targetPlayerID := pair.Key
  310. // 判断玩家是否已存在联盟中
  311. if exist := leagueMemberTable.CheckMemberExist(targetPlayerID); exist {
  312. removeApplys = append(removeApplys, targetPlayerID)
  313. continue
  314. }
  315. errCode := actorRemote.MapPlayer.LeagueJoin(targetPlayerID, &pb.LeagueJoinNotice{
  316. LeagueID: p.leagueID,
  317. LeagueName: p.leagueTable.LeagueInfo.LeagueName,
  318. CastleConfigIDs: p.leagueTable.Castles.GetConfigIDs(),
  319. })
  320. if code.IsOK(errCode) {
  321. joinPlayerIDs = append(joinPlayerIDs, targetPlayerID)
  322. curMemberCount++
  323. }
  324. removeApplys = append(removeApplys, targetPlayerID)
  325. // 检测联盟成员数是否超出上限
  326. if curMemberCount >= memberCountLimit {
  327. break
  328. }
  329. }
  330. // 添加加入联盟的玩家
  331. if len(joinPlayerIDs) > 0 {
  332. p.doLeagueMemberJoin(p.leagueTable, leagueMemberTable, joinPlayerIDs...)
  333. }
  334. if len(removeApplys) > 0 {
  335. // 删除入盟申请
  336. p.leagueTable.LeagueInfo.RemoveApply(removeApplys...)
  337. p.leagueTable.Save2Queue()
  338. }
  339. resp := &pb.I64List{
  340. List: removeApplys,
  341. }
  342. p.Response(session, resp)
  343. }
  344. // 清除联盟申请列表
  345. func (p *actorLeague) leagueClearApplyList(session *cproto.Session, _ *pb.None) {
  346. opPlayerID := sessions.GetPlayerID(session)
  347. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  348. if !found {
  349. p.ResponseCode(session, code.LeagueNotExist)
  350. return
  351. }
  352. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  353. if !found {
  354. p.ResponseCode(session, code.LeagueMembersEmpty)
  355. return
  356. }
  357. // 判断玩家是否有权处理
  358. if !leagueMemberTable.LeagueMember.CheckPermission(opPlayerID, enum.League_Permission_Member) {
  359. p.ResponseCode(session, code.LeaguePermissionDenied)
  360. return
  361. }
  362. // 清除申请列表
  363. if leagueTable.LeagueInfo.ClearApplyList() {
  364. leagueTable.Save2Queue()
  365. }
  366. p.ResponseCode(session, code.OK)
  367. }
  368. // 入盟等级&审批&公告设置
  369. func (p *actorLeague) leagueSetting(session *cproto.Session, req *pb.LeagueBaseSetting) {
  370. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  371. if !found {
  372. p.ResponseCode(session, code.LeagueNotExist)
  373. return
  374. }
  375. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  376. if !found {
  377. p.ResponseCode(session, code.LeagueMembersEmpty)
  378. return
  379. }
  380. // 判断玩家是否有权限 需要外交权限
  381. opPlayerID := sessions.GetPlayerID(session)
  382. ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Diplomacy)
  383. if !ok {
  384. p.ResponseCode(session, code.LeaguePermissionDenied)
  385. return
  386. }
  387. var (
  388. update = false
  389. needApprove = req.NeedApprove
  390. levelLimit = req.LevelLimit
  391. leagueNotice = req.LeagueNotice
  392. )
  393. if leagueTable.LeagueInfo.JoinApproval != needApprove {
  394. leagueTable.LeagueInfo.JoinApproval = needApprove
  395. update = true
  396. }
  397. if leagueTable.LeagueInfo.JoinNeedLevel != levelLimit {
  398. // 判断等级是否存在
  399. maxLevel := data.FacilityLevel.GetMaxLevel(enum.Facility_MainID)
  400. if 0 <= levelLimit && levelLimit <= maxLevel {
  401. leagueTable.LeagueInfo.JoinNeedLevel = levelLimit
  402. update = true
  403. }
  404. }
  405. if leagueTable.LeagueInfo.LeagueNotice != leagueNotice {
  406. if utils.CheckStrLen(leagueNotice, data.Const.LeagueNoticeLimit) {
  407. leagueTable.LeagueInfo.LeagueNotice = leagueNotice
  408. update = true
  409. }
  410. }
  411. if update {
  412. leagueTable.Save2Queue()
  413. }
  414. resp := &pb.LeagueBaseSetting{
  415. NeedApprove: leagueTable.LeagueInfo.JoinApproval,
  416. LevelLimit: leagueTable.LeagueInfo.JoinNeedLevel,
  417. LeagueNotice: leagueTable.LeagueInfo.LeagueNotice,
  418. }
  419. p.Response(session, resp)
  420. }
  421. // 联盟旗帜设置
  422. func (p *actorLeague) leagueFlagSet(session *cproto.Session, req *pb.I32I32) {
  423. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  424. if !found {
  425. p.ResponseCode(session, code.LeagueNotExist)
  426. return
  427. }
  428. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  429. if !found {
  430. p.ResponseCode(session, code.LeagueMembersEmpty)
  431. return
  432. }
  433. // 判断玩家是否有权限 需要外交权限
  434. opPlayerID := sessions.GetPlayerID(session)
  435. ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Diplomacy)
  436. if !ok {
  437. p.ResponseCode(session, code.LeaguePermissionDenied)
  438. return
  439. }
  440. var (
  441. flagBg = req.Key
  442. flagIcon = req.Value
  443. )
  444. // 检测旗帜背景是否存在
  445. flagBgRow, found := data.LeagueFlag.GetByFlagID(flagBg)
  446. if !found {
  447. p.ResponseCode(session, code.LeagueFlagBgNotExist)
  448. return
  449. }
  450. if flagBgRow.FlagType != enum.League_FlagBg {
  451. p.ResponseCode(session, code.LeagueFlagBgError)
  452. return
  453. }
  454. // 检测旗帜图标是否存在
  455. flagIconRow, found := data.LeagueFlag.GetByFlagID(flagIcon)
  456. if !found {
  457. p.ResponseCode(session, code.LeagueFlagIconNotExist)
  458. return
  459. }
  460. if flagIconRow.FlagType != enum.League_FlagIcon {
  461. p.ResponseCode(session, code.LeagueFlagIconError)
  462. return
  463. }
  464. // TODO 设置旗帜是否需要扣除道具/设置冷却时间
  465. // 设置旗帜
  466. leagueTable.LeagueInfo.FlagBg = flagBg
  467. leagueTable.LeagueInfo.FlagIcon = flagIcon
  468. leagueTable.Save2Queue()
  469. resp := &pb.I32I32{
  470. Key: leagueTable.LeagueInfo.FlagBg,
  471. Value: leagueTable.LeagueInfo.FlagIcon,
  472. }
  473. p.Response(session, resp)
  474. }
  475. // 申请入盟通知
  476. func (p *actorLeague) leagueJoinApplyNotice(leaderID int64, leagueMemberTable *db.MapLeagueMemberTable, applyPlayerID int64) {
  477. playerList := leagueMemberTable.LeagueMember.GetPlayerListByPermission(leaderID, enum.League_Permission_Member)
  478. for _, playerID := range playerList {
  479. session, found := sessions.GetSession(playerID)
  480. if !found {
  481. continue
  482. }
  483. resp := &pb.I64{
  484. Value: applyPlayerID,
  485. }
  486. sessions.PushWithSession(session, nameRoute.PushLeague_AddApply, resp)
  487. }
  488. }
  489. // 联盟日志列表
  490. func (p *actorLeague) leagueLogList(session *cproto.Session, req *pb.I32) {
  491. _, found := db.GetMapLeagueTable(p.leagueID)
  492. if !found {
  493. p.ResponseCode(session, code.LeagueNotExist)
  494. return
  495. }
  496. leagueLogTable, found := db.GetMapLeagueLogTable(p.leagueID)
  497. if !found {
  498. p.ResponseCode(session, code.LeagueLogDataNotExist)
  499. return
  500. }
  501. var (
  502. logType = req.Value
  503. resp = &pb.LeagueLogList{}
  504. )
  505. leagueLogList := leagueLogTable.LeagueLogType.GetLeagueLogs(logType)
  506. if len(leagueLogList) > 0 {
  507. for _, leagueLog := range leagueLogList {
  508. resp.List = append(resp.List, leagueLog.ToProto())
  509. }
  510. }
  511. p.Response(session, resp)
  512. }
  513. // 联盟驻地迁入
  514. func (p *actorLeague) leagueResidenceBack(session *cproto.Session, req *pb.I32) {
  515. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  516. if !found {
  517. p.ResponseCode(session, code.LeagueNotExist)
  518. return
  519. }
  520. build, found := leagueTable.Builds.GetByType(constant.MapBuild_LeaguePoint)
  521. if !found {
  522. p.ResponseCode(session, code.LeagueResidenceNotExist)
  523. return
  524. }
  525. // 正在建造中
  526. if build.BuildEndTime > ctime.Now().ToMillisecond() {
  527. p.ResponseCode(session, code.LeagueResidenceBuilding)
  528. return
  529. }
  530. // 检测下标是否正确
  531. index := req.Value
  532. if index < 0 || !data.IsInnerSceneFoundation(index) {
  533. p.ResponseCode(session, code.IllegalArgument)
  534. return
  535. }
  536. _, found = leagueTable.Residences.Get(index)
  537. if found {
  538. p.ResponseCode(session, code.LeagueResidenceHadMember)
  539. return
  540. }
  541. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  542. if !found {
  543. p.ResponseCode(session, code.LeagueMembersEmpty)
  544. return
  545. }
  546. playerID := sessions.GetPlayerID(session)
  547. if found = leagueMemberTable.CheckMemberExist(playerID); !found {
  548. p.ResponseCode(session, code.LeagueMemberNotExist)
  549. return
  550. }
  551. var (
  552. gameNodeID = sessions.GetGameNodeID(session)
  553. costs = data.Const.GetLeagueResidenceBackCost()
  554. )
  555. // 执行迁入奖励扣除
  556. _, errCode := actorRemote.GamePlayer.AssetSub(gameNodeID, playerID, costs, ao.LeagueResidenceBackCost)
  557. if code.IsFail(errCode) {
  558. p.ResponseCode(session, errCode)
  559. return
  560. }
  561. // 执行入驻流程
  562. _, errCode = mapCall.Logic.RelocateBack(playerID, p.leagueID)
  563. if code.IsFail(errCode) {
  564. p.ResponseCode(session, errCode)
  565. return
  566. }
  567. residence := &dbLeague.Residence{
  568. PlayerID: playerID,
  569. }
  570. leagueTable.Residences[index] = residence
  571. // 通知所有成员
  572. p.LeagueResidenceNotice(leagueMemberTable.GetLeagueMemberIDs(), index, playerID)
  573. p.ResponseCode(session, code.OK)
  574. }
  575. // 联盟驻地迁出
  576. func (p *actorLeague) leagueResidenceRemove(req *pb.I64) int32 {
  577. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  578. if !found {
  579. return code.LeagueNotExist
  580. }
  581. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  582. if !found {
  583. return code.LeagueMembersEmpty
  584. }
  585. // 如果当前玩家是联盟成员 移除驻地信息
  586. if leagueMemberTable.LeagueMember.CheckMemberExist(req.Value) {
  587. targetPlayerID := req.Value
  588. if leagueTable.RemoveResidence(targetPlayerID) {
  589. p.LeagueResidenceRemoveNotice(leagueMemberTable.GetLeagueMemberIDs(), targetPlayerID)
  590. }
  591. }
  592. return code.OK
  593. }
  594. // 被动迁入驻地
  595. func (p *actorLeague) forceResidenceBack(req *pb.I64) {
  596. playerID := req.Value
  597. p.Debug("[forceRelocateBack] PlayerID = %d", playerID)
  598. _, found := p.leagueTable.Builds.GetByType(constant.MapBuild_LeaguePoint)
  599. if !found {
  600. p.Debug("[forceRelocateBack] league point not exist: PlayerID = %d", playerID)
  601. return
  602. }
  603. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  604. if !found {
  605. return
  606. }
  607. if found = leagueMemberTable.CheckMemberExist(playerID); !found {
  608. p.Debug("[forceRelocateBack] Player %d not in league", playerID)
  609. return
  610. }
  611. foundIndex := int32(-1)
  612. // 给成员随机一个位置
  613. for _, index := range rand.Perm(len(data.InnerScene())) {
  614. if !data.IsInnerSceneFoundation(int32(index)) {
  615. continue
  616. }
  617. if _, found := p.leagueTable.Residences.Get(int32(index)); !found {
  618. foundIndex = int32(index)
  619. break
  620. }
  621. }
  622. if foundIndex == -1 {
  623. p.Debug("[forceRelocateBack] no empty index for Player: %d", playerID)
  624. return
  625. }
  626. residence := &dbLeague.Residence{
  627. PlayerID: playerID,
  628. }
  629. p.leagueTable.Residences.Put(foundIndex, residence)
  630. // 通知所有成员
  631. p.LeagueResidenceNotice(leagueMemberTable.GetLeagueMemberIDs(), foundIndex, playerID)
  632. }
  633. // 驻地迁入通知
  634. func (p *actorLeague) LeagueResidenceNotice(members []int64, index int32, playerID int64) {
  635. if len(members) <= 0 {
  636. return
  637. }
  638. proto := &pb.LeagueResidence{
  639. Index: index,
  640. PlayerID: playerID,
  641. PlayerName: leagueBase.Service().GetPlayerName(playerID),
  642. }
  643. // 通知在线联盟成员
  644. for _, memberPlayerID := range members {
  645. session, found := sessions.GetSession(memberPlayerID)
  646. if found {
  647. sessions.PushWithSession(session, nameRoute.PushMapLeague_ResidenceChange, proto)
  648. }
  649. }
  650. }
  651. // 驻地迁出通知
  652. func (p *actorLeague) LeagueResidenceRemoveNotice(members []int64, playerID int64) {
  653. if len(members) <= 0 {
  654. return
  655. }
  656. proto := &pb.I64{
  657. Value: playerID,
  658. }
  659. // 通知在线联盟成员
  660. for _, memberPlayerID := range members {
  661. session, found := sessions.GetSession(memberPlayerID)
  662. if found {
  663. sessions.PushWithSession(session, nameRoute.PushMapLeague_ResidenceRemove, proto)
  664. }
  665. }
  666. }
  667. // 联盟地图标记
  668. func (p *actorLeague) leagueMapMark(session *cproto.Session, req *pb.MapMarkRequest) {
  669. var (
  670. opPlayerID = sessions.GetPlayerID(session)
  671. title = req.Title
  672. desc = req.Desc
  673. point = req.Point
  674. command = req.Command
  675. markID, ok = data.PointToTileID(point.X, point.Y)
  676. )
  677. if !ok {
  678. p.ResponseCode(session, code.MapGetPointFail)
  679. return
  680. }
  681. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  682. if !found {
  683. p.ResponseCode(session, code.LeagueNotExist)
  684. return
  685. }
  686. _, found = leagueTable.MapMarks.Get(markID)
  687. if found {
  688. p.ResponseCode(session, code.MapMark_AlreadyExist)
  689. return
  690. }
  691. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  692. if !found {
  693. p.ResponseCode(session, code.LeagueMembersEmpty)
  694. return
  695. }
  696. // 检查权限
  697. if !leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Command) {
  698. p.ResponseCode(session, code.LeaguePermissionDenied)
  699. return
  700. }
  701. // 判断是否达到上限
  702. if leagueTable.MapMarks.Size() >= data.Const.LeagueMapMarkNumLimit {
  703. p.ResponseCode(session, code.MapMark_NumLimit)
  704. return
  705. }
  706. // 判断标题和描述长度是否合法
  707. if !data.Const.CheckLeagueMapMarkTitle(title) {
  708. p.ResponseCode(session, code.MapMark_TitleLenLimit)
  709. return
  710. }
  711. if !data.Const.CheckLeagueMapMarkDesc(desc) {
  712. p.ResponseCode(session, code.MapMark_DescLenLimit)
  713. return
  714. }
  715. // 检测指令是否合法
  716. if constant.IsMapMarkCommandFail(command) {
  717. p.ResponseCode(session, code.MapMark_CommandNotExist)
  718. return
  719. }
  720. mapMark := &dbLeague.MapMark{
  721. Title: title,
  722. Desc: desc,
  723. Point: types.NewPoint(point.X, point.Y),
  724. Command: command,
  725. MarkTime: ctime.Now().ToSecond(),
  726. }
  727. leagueTable.MapMarks.Put(markID, mapMark)
  728. leagueTable.Save2Queue()
  729. // 广播给所有联盟成员
  730. p.mapMarkChangePush(leagueMemberTable.GetLeagueMemberIDs(), markID)
  731. // 发送指挥邮件
  732. p.SendLeagueMail(leagueMemberTable, opPlayerID, 0, enum.MailType_Command, title, desc, false)
  733. p.ResponseCode(session, code.OK)
  734. }
  735. // 删除联盟地图标记
  736. func (p *actorLeague) leagueMapMarkDelete(session *cproto.Session, req *pb.I32) {
  737. var (
  738. opPlayerID = sessions.GetPlayerID(session)
  739. markID = req.Value
  740. )
  741. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  742. if !found {
  743. p.ResponseCode(session, code.LeagueNotExist)
  744. return
  745. }
  746. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  747. if !found {
  748. p.ResponseCode(session, code.LeagueMembersEmpty)
  749. return
  750. }
  751. ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Command)
  752. if !ok {
  753. p.ResponseCode(session, code.LeaguePermissionDenied)
  754. return
  755. }
  756. if ok = leagueTable.DeleteMapMark(markID); !ok {
  757. p.ResponseCode(session, code.MapMark_NotExist)
  758. return
  759. }
  760. leagueTable.Save2Queue()
  761. // 广播给所有在线成员
  762. p.mapMarkDelPush(leagueMemberTable.GetLeagueMemberIDs(), markID)
  763. p.ResponseCode(session, code.OK)
  764. }
  765. // 联盟标记更新
  766. func (p *actorLeague) leagueMapMarkEdit(session *cproto.Session, req *pb.MapMarkEditRequest) {
  767. var (
  768. opPlayerID = sessions.GetPlayerID(session)
  769. markID = req.MarkID
  770. )
  771. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  772. if !found {
  773. p.ResponseCode(session, code.LeagueNotExist)
  774. return
  775. }
  776. leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
  777. if !found {
  778. p.ResponseCode(session, code.LeagueMembersEmpty)
  779. return
  780. }
  781. ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Command)
  782. if !ok {
  783. p.ResponseCode(session, code.LeaguePermissionDenied)
  784. return
  785. }
  786. mapMark, found := leagueTable.MapMarks.Get(markID)
  787. if !found {
  788. p.ResponseCode(session, code.MapMark_NotExist)
  789. return
  790. }
  791. // 内容不变
  792. if mapMark.Title == req.Title && mapMark.Desc == req.Desc && mapMark.Command == req.Command {
  793. p.ResponseCode(session, code.MapMark_NotChange)
  794. return
  795. }
  796. mapMark.Title = req.Title
  797. mapMark.Desc = req.Desc
  798. mapMark.Command = req.Command
  799. mapMark.MarkTime = ctime.Now().ToSecond()
  800. leagueTable.Save2Queue()
  801. // 广播给所有在线成员
  802. p.mapMarkChangePush(leagueMemberTable.GetLeagueMemberIDs(), markID)
  803. // 发送指挥邮件
  804. p.SendLeagueMail(leagueMemberTable, opPlayerID, 0, enum.MailType_Command, mapMark.Title, mapMark.Desc, false)
  805. p.ResponseCode(session, code.OK)
  806. }
  807. // 联盟地图标记列表推送
  808. func (p *actorLeague) mapMarkChangePush(members []int64, markID int32) {
  809. if len(members) <= 0 {
  810. return
  811. }
  812. leagueTable, found := db.GetMapLeagueTable(p.leagueID)
  813. if !found {
  814. return
  815. }
  816. mapMark, found := leagueTable.MapMarks.Get(markID)
  817. if !found {
  818. return
  819. }
  820. proto := mapMark.ToProto(markID)
  821. // 通知所有在线成员
  822. for _, memberPlayerID := range members {
  823. session, found := sessions.GetSession(memberPlayerID)
  824. if found {
  825. sessions.PushWithSession(session, nameRoute.PushMapLeague_MapMarkChange, proto)
  826. }
  827. }
  828. }
  829. // 删除联盟地图标记通知
  830. func (p *actorLeague) mapMarkDelPush(members []int64, markID int32) {
  831. if len(members) <= 0 {
  832. return
  833. }
  834. proto := &pb.I32{
  835. Value: markID,
  836. }
  837. for _, memberPlayerID := range members {
  838. session, found := sessions.GetSession(memberPlayerID)
  839. if found {
  840. sessions.PushWithSession(session, nameRoute.PushMapLeague_MapMarkDel, proto)
  841. }
  842. }
  843. }