role_invitation.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. package model
  2. import (
  3. "rocommon/util"
  4. "roserver/baseserver/model"
  5. "roserver/baseserver/set"
  6. "roserver/serverproto"
  7. )
  8. func (this *Role) InvitationNumberGet() {
  9. if this.roleInvitation != nil {
  10. ret := this.roleInvitation.InvitationNumberGet()
  11. if ret != serverproto.ErrorCode_ERROR_OK {
  12. ackMsg := &serverproto.SCInvitationNumberAck{
  13. Error: int32(ret),
  14. }
  15. this.ReplayGate(ackMsg, true)
  16. }
  17. }
  18. }
  19. func (this *Role) InvitationNumberUserInfoGet(number uint64) {
  20. if this.roleInvitation != nil {
  21. ret := this.roleInvitation.InvitationNumberUserInfoGet(number)
  22. if ret != serverproto.ErrorCode_ERROR_OK {
  23. ackMsg := &serverproto.SCInvitationNumberUserInfoAck{
  24. Error: int32(ret),
  25. }
  26. this.ReplayGate(ackMsg, true)
  27. }
  28. }
  29. }
  30. func (this *Role) InvitationBeToMember(number, uid uint64) {
  31. if this.roleInvitation != nil {
  32. ret := this.roleInvitation.InvitationBeToMember(number, uid)
  33. if ret != serverproto.ErrorCode_ERROR_OK {
  34. ackMsg := &serverproto.SCInvitationBeToMemberAck{
  35. Error: int32(ret),
  36. }
  37. this.ReplayGate(ackMsg, true)
  38. }
  39. }
  40. }
  41. func (this *Role) InvitationReward(taskIdLIst []uint32) {
  42. if this.roleInvitation != nil {
  43. this.roleInvitation.InvitationReward(taskIdLIst)
  44. }
  45. }
  46. func (this *Role) InvitationClick(memberUidList []uint64) {
  47. if this.roleInvitation != nil {
  48. ret := this.roleInvitation.InvitationClick(memberUidList)
  49. ackMsg := &serverproto.SCInvitationDelMemberAck{
  50. Error: int32(ret),
  51. }
  52. this.ReplayGate(ackMsg, true)
  53. }
  54. }
  55. func (this *Role) InvitationClickReplay(replayMasterUid uint64) {
  56. if this.roleInvitation != nil {
  57. ret := this.roleInvitation.InvitationClickReplay(replayMasterUid)
  58. if ret != serverproto.ErrorCode_ERROR_OK {
  59. ackMsg := &serverproto.SCInvitationClickReplayAck{
  60. Error: int32(ret),
  61. }
  62. this.ReplayGate(ackMsg, true)
  63. }
  64. }
  65. }
  66. func (this *Role) InvitationDelMember(memberUidList []uint64) {
  67. if this.roleInvitation != nil {
  68. ret := this.roleInvitation.InvitationDelMember(memberUidList)
  69. if ret != serverproto.ErrorCode_ERROR_OK {
  70. ackMsg := &serverproto.SCInvitationDelMemberAck{
  71. Error: int32(ret),
  72. }
  73. this.ReplayGate(ackMsg, true)
  74. }
  75. }
  76. }
  77. const (
  78. Invitation_Member_Max_Num = 30
  79. )
  80. type RoleInvitation struct {
  81. SaveObject
  82. clickNum int32 //拍一拍剩余次数
  83. selfInvitationNum uint64 //自己的邀请码
  84. masterUid uint64 //导师uid
  85. masterEndTime uint64
  86. bBaseSave bool
  87. taskList map[uint32]*serverproto.InvitationTaskData
  88. //玩家提供的初心值记录(有的玩家会被踢出但是已经贡献了)
  89. memberUidList map[uint64]*serverproto.InvitationMemberValData
  90. memberNum int32
  91. logList []*serverproto.InvitationLogData
  92. clickMemberList []uint64
  93. clickReplayMasterList []uint64
  94. changeMemberUidList set.Interface //uint64
  95. changeTaskList set.Interface //uint32
  96. changeLogList []*serverproto.InvitationLogData
  97. tmpMasterUidBf *serverproto.CommonPlayerBriefInfo
  98. tmpMasterNumber uint64
  99. }
  100. func newRoleInvitation(r *Role) *RoleInvitation {
  101. obj := &RoleInvitation{
  102. SaveObject: SaveObject{
  103. role: r,
  104. },
  105. taskList: map[uint32]*serverproto.InvitationTaskData{},
  106. changeMemberUidList: set.New(set.NonThreadSafe),
  107. changeTaskList: set.New(set.NonThreadSafe),
  108. memberUidList: map[uint64]*serverproto.InvitationMemberValData{},
  109. }
  110. return obj
  111. }
  112. func (this *RoleInvitation) Load(ms interface{}) bool {
  113. return true
  114. }
  115. func (this *RoleInvitation) LoadOther(msg interface{}) bool {
  116. info := msg.(*serverproto.RoleInvitation)
  117. if info == nil {
  118. this.clickNum = model.GlobalInvitationClickNum
  119. this.SetDirty(true)
  120. return true
  121. }
  122. for idx := 0; idx < len(info.TaskList); idx++ {
  123. this.taskList[info.TaskList[idx].TaskId] = info.TaskList[idx]
  124. }
  125. for idx := 0; idx < len(info.MemberUidList); idx++ {
  126. this.memberUidList[info.MemberUidList[idx].Uid] = info.MemberUidList[idx]
  127. if !info.MemberUidList[idx].State {
  128. this.memberNum++
  129. }
  130. }
  131. this.logList = info.LogList
  132. this.clickMemberList = info.ClickMemberList
  133. this.clickReplayMasterList = info.ClickReplayMasterList
  134. this.clickNum = info.ClickNum
  135. this.selfInvitationNum = info.SelfInvitationNumber
  136. this.masterUid = info.MasterUid
  137. this.masterEndTime = info.MasterEndTime
  138. return true
  139. }
  140. func (this *RoleInvitation) StartupNtf() {
  141. ntfMsg := &serverproto.SCInvitationStartupNtf{
  142. InvitationInfo: &serverproto.RoleInvitation{
  143. ClickNum: this.clickNum,
  144. SelfInvitationNumber: this.selfInvitationNum,
  145. MasterUid: this.masterUid,
  146. LogList: this.logList,
  147. ClickMemberList: this.clickMemberList,
  148. ClickReplayMasterList: this.clickReplayMasterList,
  149. },
  150. }
  151. for _, uidData := range this.memberUidList {
  152. if uidData.State {
  153. continue
  154. }
  155. ntfMsg.InvitationInfo.MemberUidList = append(ntfMsg.InvitationInfo.MemberUidList, uidData)
  156. }
  157. for _, data := range this.taskList {
  158. ntfMsg.InvitationInfo.TaskList = append(ntfMsg.InvitationInfo.TaskList, data)
  159. }
  160. this.role.ReplayGate(ntfMsg, true)
  161. }
  162. func (this *RoleInvitation) Save() {
  163. this.SetDirty(false)
  164. util.DebugF("uid=%v RoleInvitation save...", this.role.GetUUid())
  165. saveMsg := &serverproto.SSInvitationSaveNtf{
  166. BaseSave: this.bBaseSave,
  167. ClickNum: this.clickNum,
  168. SelfInvitationNumber: this.selfInvitationNum,
  169. MasterUid: this.masterUid,
  170. ClickMemberList: this.clickMemberList,
  171. ClickReplayMasterList: this.clickReplayMasterList,
  172. }
  173. this.bBaseSave = false
  174. saveMsg.MemberNum = this.memberNum
  175. for _, val := range this.changeMemberUidList.List() {
  176. memberData, ok := this.memberUidList[val.(uint64)]
  177. if ok {
  178. saveMsg.AddMemberUidList = append(saveMsg.AddMemberUidList, memberData)
  179. } else {
  180. saveMsg.DelMemberUidList = append(saveMsg.DelMemberUidList, val.(uint64))
  181. }
  182. }
  183. for _, val := range this.changeTaskList.List() {
  184. if taskData, ok := this.taskList[val.(uint32)]; ok {
  185. saveMsg.TaskList = append(saveMsg.TaskList, taskData)
  186. }
  187. }
  188. saveMsg.AddLogList = append(saveMsg.AddLogList, this.changeLogList...)
  189. this.role.SendDb(saveMsg)
  190. this.changeTaskList.Clear()
  191. this.changeMemberUidList.Clear()
  192. this.changeLogList = this.changeLogList[:0]
  193. }
  194. func (this *RoleInvitation) DailyReset(notify bool) {
  195. this.clickNum = model.GlobalInvitationClickNum
  196. this.clickMemberList = this.clickMemberList[:0]
  197. this.clickReplayMasterList = this.clickReplayMasterList[:0]
  198. this.bBaseSave = true
  199. this.SetDirty(true)
  200. if notify {
  201. dataNtfMsg := this.dataChangeNtf()
  202. this.role.ReplayGate(dataNtfMsg, true)
  203. }
  204. }
  205. func (this *RoleInvitation) dataChangeNtf() *serverproto.SCInvitationChangNtf {
  206. ntfMsg := &serverproto.SCInvitationChangNtf{
  207. InvitationInfo: &serverproto.RoleInvitation{
  208. SelfInvitationNumber: this.selfInvitationNum,
  209. ClickNum: this.clickNum,
  210. MasterUid: this.masterUid,
  211. ClickMemberList: this.clickMemberList,
  212. MasterEndTime: this.masterEndTime,
  213. ClickReplayMasterList: this.clickReplayMasterList,
  214. },
  215. }
  216. return ntfMsg
  217. }
  218. func (this *RoleInvitation) setClickNum(clickNum int32) {
  219. this.clickNum = clickNum
  220. this.bBaseSave = true
  221. this.SetDirty(true)
  222. }
  223. func (this *RoleInvitation) setSelfInvitationNumber(number uint64) {
  224. this.selfInvitationNum = number
  225. this.bBaseSave = true
  226. this.SetDirty(true)
  227. }
  228. func (this *RoleInvitation) setMasterUid(masterUid uint64) {
  229. this.masterUid = masterUid
  230. this.bBaseSave = true
  231. this.SetDirty(true)
  232. }
  233. func (this *RoleInvitation) addClickMember(memberUid uint64) {
  234. this.clickMemberList = append(this.clickMemberList, memberUid)
  235. this.bBaseSave = true
  236. this.SetDirty(true)
  237. }
  238. func (this *RoleInvitation) addClickReplayMember(replayMasterUid uint64) {
  239. this.clickReplayMasterList = append(this.clickReplayMasterList, replayMasterUid)
  240. this.bBaseSave = true
  241. this.SetDirty(true)
  242. }
  243. func (this *RoleInvitation) isMember(memberUid uint64) bool {
  244. data, ok := this.memberUidList[memberUid]
  245. if ok {
  246. return !data.State
  247. }
  248. return false
  249. }
  250. func (this *RoleInvitation) getMember(memberUid uint64) *serverproto.InvitationMemberValData {
  251. data, ok := this.memberUidList[memberUid]
  252. if ok {
  253. return data
  254. }
  255. return nil
  256. }
  257. func (this *RoleInvitation) InvitationNumberGet() serverproto.ErrorCode {
  258. ssMsg := &serverproto.SSInvitationGenNumberReq{
  259. MasterUid: this.masterUid,
  260. }
  261. if this.selfInvitationNum <= 0 {
  262. ssMsg.GenNumber = true
  263. }
  264. this.role.SendDb(ssMsg)
  265. return serverproto.ErrorCode_ERROR_OK
  266. }
  267. func (this *RoleInvitation) OnInvitationNumberGet(number uint64, masterUid uint64) {
  268. if number > 0 && this.selfInvitationNum <= 0 {
  269. this.setSelfInvitationNumber(number)
  270. }
  271. //导师uid不合法(被解除了关系)
  272. if this.masterUid > 0 && masterUid == 0 {
  273. this.setMasterUid(0)
  274. }
  275. ntfMsg := this.dataChangeNtf()
  276. this.role.ReplayGate(ntfMsg, true)
  277. ackMsg := &serverproto.SCInvitationNumberAck{
  278. Error: int32(serverproto.ErrorCode_ERROR_OK),
  279. }
  280. this.role.ReplayGate(ackMsg, true)
  281. }
  282. func (this *RoleInvitation) InvitationNumberUserInfoGet(number uint64) serverproto.ErrorCode {
  283. if number <= 100000 {
  284. return serverproto.ErrorCode_ERROR_INVITATION_NUMBER_INVALID
  285. }
  286. //cd time
  287. if this.masterEndTime > util.GetTimeMilliseconds() {
  288. return serverproto.ErrorCode_ERROR_INVITATION_MASTER_END_TIME
  289. }
  290. //已经成为其他玩家的学员
  291. if this.masterUid > 0 {
  292. return serverproto.ErrorCode_ERROR_INVITATION_HAS_MASTER
  293. }
  294. //根据邀请码查询玩家信息
  295. ssMsg := &serverproto.SSInvitationNumberUserInfoReq{
  296. Number: number,
  297. }
  298. this.role.SendDb(ssMsg)
  299. return serverproto.ErrorCode_ERROR_OK
  300. }
  301. func (this *RoleInvitation) OnInvitationNumberUserInfoGet(msg *serverproto.SSInvitationNumberUserInfoAck) {
  302. ackMsg := &serverproto.SCInvitationNumberUserInfoAck{
  303. Error: int32(serverproto.ErrorCode_ERROR_OK),
  304. Brief: msg.Brief,
  305. }
  306. if msg.Error != int32(serverproto.ErrorCode_ERROR_OK) {
  307. ackMsg.Error = msg.Error
  308. } else {
  309. if msg.MemberNum >= Invitation_Member_Max_Num {
  310. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_INVITATION_NUM_LIMIT)
  311. }
  312. this.tmpMasterNumber = msg.Number
  313. this.tmpMasterUidBf = msg.Brief
  314. }
  315. this.role.ReplayGate(ackMsg, true)
  316. }
  317. func (this *RoleInvitation) InvitationBeToMember(number, uid uint64) serverproto.ErrorCode {
  318. //已经成为其他玩家的学员
  319. if this.masterUid > 0 {
  320. return serverproto.ErrorCode_ERROR_INVITATION_HAS_MASTER
  321. }
  322. //cd time
  323. if this.masterEndTime > util.GetTimeMilliseconds() {
  324. return serverproto.ErrorCode_ERROR_INVITATION_MASTER_END_TIME
  325. }
  326. if number == this.tmpMasterNumber && this.tmpMasterUidBf != nil && uid == this.tmpMasterUidBf.Uid {
  327. ssMsg := &serverproto.SSInvitationBeToMemberReq{
  328. MasterNumber: number,
  329. MasterUid: uid,
  330. SelfUid: &serverproto.InvitationMemberValData{
  331. Uid: this.role.GetUUid(),
  332. Level: this.role.GetRoleLevel(),
  333. TotalRecharge: this.role.GetTotalRecharge(),
  334. },
  335. }
  336. this.role.SendSocial(ssMsg)
  337. return serverproto.ErrorCode_ERROR_OK
  338. }
  339. return serverproto.ErrorCode_ERROR_INVITATION_NUMBER_INVALID
  340. }
  341. //from social 来自其他game服务器的成为导师成员请求
  342. //为找到对应master在线数据
  343. //todo...
  344. // 需要做合法性校验,如果中间添加学员成功但是学员设置导师UID出错,需要定期检查成员的合法性
  345. func (this *RoleInvitation) InvitationBeToMemberSSReq(masterNumber, masterUid uint64, memberUid *serverproto.InvitationMemberValData) serverproto.ErrorCode {
  346. if this.selfInvitationNum <= 0 || this.selfInvitationNum != masterNumber || this.role.GetUUid() != masterUid {
  347. return serverproto.ErrorCode_ERROR_INVITATION_NUMBER_INVALID
  348. }
  349. if len(this.memberUidList) >= Invitation_Member_Max_Num {
  350. return serverproto.ErrorCode_ERROR_INVITATION_NUM_LIMIT
  351. }
  352. memData := this.getMember(memberUid.Uid)
  353. if memData == nil || memData.State {
  354. return serverproto.ErrorCode_ERROR_INVITATION_IS_MEMBER
  355. }
  356. if memData != nil {
  357. memData.Level = memberUid.Level
  358. memData.TotalRecharge = memberUid.TotalRecharge
  359. this.memberUidList[memberUid.Uid] = memData
  360. } else {
  361. this.memberUidList[memberUid.Uid] = memberUid
  362. }
  363. this.memberNum++
  364. this.changeMemberUidList.Add(memberUid.Uid)
  365. this.SetDirty(true)
  366. ntfMsg := this.dataChangeNtf()
  367. ntfMsg.InvitationInfo.MemberUidList = append(ntfMsg.InvitationInfo.MemberUidList, memberUid)
  368. this.role.ReplayGate(ntfMsg, true)
  369. return serverproto.ErrorCode_ERROR_OK
  370. }
  371. //玩家填写邀请码成员学员的ack
  372. func (this *RoleInvitation) OnInvitationBeToMember(masterNumber, masterUid uint64, memberUid *serverproto.InvitationMemberValData, retCode int32) {
  373. switch retCode {
  374. case int32(serverproto.ErrorCode_ERROR_EXPEDITION_NOT_FIND_SERVICE_ID):
  375. //master玩家最近未上线,db操作
  376. ssDBMsg := &serverproto.SSInvitationBeToMemberDBReq{
  377. MasterNumber: masterNumber,
  378. MasterUid: masterUid,
  379. SelfUid: memberUid,
  380. }
  381. this.role.SendDb(ssDBMsg)
  382. case int32(serverproto.ErrorCode_ERROR_OK):
  383. //填写邀请码成为学员操作成功
  384. this.masterEndTime = util.GetTimeMilliseconds() + 24*60*60*1000
  385. this.setMasterUid(masterUid)
  386. //完成任务
  387. this.TaskCheck(serverproto.TaskType_Invitation_Number_Num, 1)
  388. ntfMsg := this.dataChangeNtf()
  389. this.role.ReplayGate(ntfMsg, true)
  390. ackMsg := &serverproto.SCInvitationBeToMemberAck{
  391. Error: retCode,
  392. }
  393. this.role.ReplayGate(ackMsg, true)
  394. default:
  395. ackMsg := &serverproto.SCInvitationBeToMemberAck{
  396. Error: retCode,
  397. }
  398. this.role.ReplayGate(ackMsg, true)
  399. }
  400. }
  401. //优化效率算法
  402. //1,有序列表
  403. //2,二分查找 和当前给定等级最低匹配元素索引
  404. //3,统计个数
  405. func (this *RoleInvitation) TaskCheck(taskType serverproto.TaskType, count int32) {
  406. //不是学员,并且也不是导师 不需要任务检测
  407. if this.masterUid <= 0 || len(this.memberUidList) <= 0 {
  408. return
  409. }
  410. typeTaskList, ok := model.ConvertInvitationTaskTypeList[int32(taskType)]
  411. if !ok {
  412. return
  413. }
  414. dataNtfMsg := this.dataChangeNtf()
  415. switch taskType {
  416. case serverproto.TaskType_Invitation_Number_Num:
  417. for idx := 0; idx < len(typeTaskList); idx++ {
  418. cfgData := typeTaskList[idx]
  419. taskData, ok := this.taskList[cfgData.TaskId]
  420. if !ok {
  421. taskData = &serverproto.InvitationTaskData{
  422. TaskId: cfgData.TaskId,
  423. CompleteMaxCount: cfgData.CompleteNum,
  424. }
  425. this.taskList[taskData.TaskId] = taskData
  426. }
  427. if taskData.RewardCount >= taskData.CompleteMaxCount {
  428. continue
  429. }
  430. taskData.Progress += count
  431. this.changeTaskList.Add(taskData.TaskId)
  432. bRet := this.taskConditionCheck(taskData, cfgData.ConditionList[int32(taskType)], taskType)
  433. if bRet {
  434. dataNtfMsg.InvitationInfo.TaskList = append(dataNtfMsg.InvitationInfo.TaskList, taskData)
  435. }
  436. this.SetDirty(true)
  437. }
  438. case serverproto.TaskType_Invitation_Base_Level_Num:
  439. fallthrough
  440. case serverproto.TaskType_Invitation_Recharge_Num:
  441. for idx := 0; idx < len(typeTaskList); idx++ {
  442. cfgData := typeTaskList[idx]
  443. taskData, ok := this.taskList[cfgData.TaskId]
  444. if !ok {
  445. taskData = &serverproto.InvitationTaskData{
  446. TaskId: cfgData.TaskId,
  447. CompleteMaxCount: cfgData.CompleteNum,
  448. }
  449. this.taskList[taskData.TaskId] = taskData
  450. }
  451. if taskData.RewardCount >= taskData.CompleteMaxCount {
  452. continue
  453. }
  454. bRet := this.taskConditionCheck(taskData, cfgData.ConditionList[int32(taskType)], taskType)
  455. if bRet {
  456. dataNtfMsg.InvitationInfo.TaskList = append(dataNtfMsg.InvitationInfo.TaskList, taskData)
  457. }
  458. }
  459. }
  460. }
  461. func (this *RoleInvitation) taskConditionCheck(taskData *serverproto.InvitationTaskData, conditionList []int32, taskType serverproto.TaskType) bool {
  462. switch taskType {
  463. case serverproto.TaskType_Invitation_Number_Num:
  464. targetNum := conditionList[1]
  465. newRewardCount := int32(taskData.Progress / targetNum)
  466. if taskData.RewardCount != newRewardCount {
  467. taskData.RewardCount = newRewardCount
  468. return true
  469. }
  470. case serverproto.TaskType_Invitation_Base_Level_Num:
  471. baseLevel := conditionList[1]
  472. targetNum := conditionList[2]
  473. curNum := this.taskConditionLevelNum(baseLevel)
  474. if taskData.Progress < curNum {
  475. taskData.Progress = curNum
  476. this.SetDirty(true)
  477. this.changeTaskList.Add(taskData.TaskId)
  478. newRewardCount := int32(taskData.Progress / targetNum)
  479. if taskData.RewardCount != newRewardCount {
  480. taskData.RewardCount = newRewardCount
  481. return true
  482. }
  483. }
  484. case serverproto.TaskType_Invitation_Recharge_Num:
  485. rechargeNum := conditionList[1]
  486. targetNum := conditionList[2]
  487. curNum := this.taskConditionRechargeNum(float32(rechargeNum))
  488. if taskData.Progress < curNum {
  489. taskData.Progress = curNum
  490. this.SetDirty(true)
  491. this.changeTaskList.Add(taskData.TaskId)
  492. newRewardCount := int32(taskData.Progress / targetNum)
  493. if taskData.RewardCount != newRewardCount {
  494. taskData.RewardCount = newRewardCount
  495. return true
  496. }
  497. }
  498. }
  499. return false
  500. }
  501. func (this *RoleInvitation) taskConditionLevelNum(baseLevel int32) int32 {
  502. var retNum int32 = 0
  503. for _, val := range this.memberUidList {
  504. if val.Level >= baseLevel {
  505. retNum++
  506. }
  507. }
  508. return retNum
  509. }
  510. func (this *RoleInvitation) taskConditionRechargeNum(rechargeNum float32) int32 {
  511. var retNum int32 = 0
  512. for _, val := range this.memberUidList {
  513. if val.TotalRecharge >= rechargeNum {
  514. retNum++
  515. }
  516. }
  517. return retNum
  518. }
  519. //等级,充值等数据变更时通知导师
  520. func (this *RoleInvitation) InvitationNoticeMaster(noticeParam *serverproto.KeyValueType) {
  521. if this.masterUid > 0 && this.selfInvitationNum > 0 {
  522. ntfMsg := &serverproto.SSInvitationMemberNoticeMasterReq{
  523. SelfUid: this.role.GetUUid(),
  524. MasterUid: this.masterUid,
  525. }
  526. this.role.SendSocial(ntfMsg)
  527. }
  528. }
  529. //成员等级,充值等数据变更时导师收到的通知
  530. func (this *RoleInvitation) OnInvitationNoticeMaster(noticeMsg *serverproto.SSInvitationMemberNoticeMasterReq) {
  531. memberData := this.getMember(noticeMsg.SelfUid)
  532. if memberData == nil || memberData.State {
  533. util.InfoF("uid=%v OnInvitationNoticeMaster not member member=%v param=%v", this.role.GetUUid(), noticeMsg.SelfUid, *noticeMsg.Param)
  534. return
  535. }
  536. if noticeMsg.Param.Key == int32(serverproto.TaskType_Invitation_Base_Level_Num) {
  537. memberData.Level = noticeMsg.Param.Value
  538. } else if noticeMsg.Param.Key == int32(serverproto.TaskType_Invitation_Recharge_Num) {
  539. memberData.TotalRecharge = float32(noticeMsg.Param.Value)
  540. }
  541. this.TaskCheck((serverproto.TaskType)(noticeMsg.Param.Key), 0)
  542. }
  543. func (this *RoleInvitation) InvitationClick(memberUidList []uint64) serverproto.ErrorCode {
  544. if this.clickNum <= 0 {
  545. return serverproto.ErrorCode_ERROR_INVITATION_NO_CLICK
  546. }
  547. var addItemList = map[int32]int32{}
  548. tmpClickNum := this.clickNum
  549. if len(memberUidList) > 0 {
  550. for idx := 0; idx < len(memberUidList); idx++ {
  551. if !this.isMember(memberUidList[idx]) {
  552. continue
  553. }
  554. bFind := false
  555. for k := 0; k < len(this.clickMemberList); k++ {
  556. if memberUidList[idx] == this.clickMemberList[k] {
  557. bFind = true
  558. break
  559. }
  560. }
  561. if !bFind {
  562. tmpClickNum--
  563. this.clickMemberList = append(this.clickMemberList, memberUidList[idx])
  564. addItemList[int32(serverproto.ResType_Res_Invitation)] += model.GlobalInvitationClickMasterRes
  565. this.sendClickChatMsg(memberUidList[idx])
  566. if tmpClickNum <= 0 {
  567. break
  568. }
  569. }
  570. }
  571. } else {
  572. //一键拍一拍
  573. for key := range this.memberUidList {
  574. bFind := false
  575. for k := 0; k < len(this.clickMemberList); k++ {
  576. if key == this.clickMemberList[k] {
  577. bFind = true
  578. break
  579. }
  580. }
  581. if !bFind {
  582. tmpClickNum--
  583. this.clickMemberList = append(this.clickMemberList, key)
  584. addItemList[int32(serverproto.ResType_Res_Invitation)] += model.GlobalInvitationClickMasterRes
  585. this.sendClickChatMsg(key)
  586. if tmpClickNum <= 0 {
  587. break
  588. }
  589. }
  590. }
  591. }
  592. if len(addItemList) > 0 {
  593. this.role.roleBag.AddItemList(addItemList, AddItemST{AddFrom: AddFrom_Invitation, Notify: true})
  594. }
  595. if this.clickNum != tmpClickNum {
  596. this.setClickNum(tmpClickNum)
  597. dataNtfMsg := this.dataChangeNtf()
  598. this.role.ReplayGate(dataNtfMsg, true)
  599. return serverproto.ErrorCode_ERROR_OK
  600. }
  601. return serverproto.ErrorCode_ERROR_INVITATION_NO_MEMBER_CLICK
  602. }
  603. func (this *RoleInvitation) sendClickChatMsg(targetUid uint64) {
  604. clickChatMsg := &serverproto.CSChatMessageReq{
  605. TargetId: targetUid,
  606. Type: int32(serverproto.ChatMessageType_CMT_PERSONAL),
  607. Message: &serverproto.ChatMessageInfo{
  608. SendTime: util.GetTimeMilliseconds(),
  609. SubType: int32(serverproto.ChatMessageSubType_CMT_SUB_TYPE_Invitation),
  610. },
  611. }
  612. this.role.GetRoleChat().SendMsg(targetUid, int32(serverproto.ChatMessageType_CMT_PERSONAL), clickChatMsg, true)
  613. }
  614. func (this *RoleInvitation) InvitationClickReplay(replayMasterUid uint64) serverproto.ErrorCode {
  615. for idx := 0; idx < len(this.clickReplayMasterList); idx++ {
  616. if this.clickReplayMasterList[idx] == replayMasterUid {
  617. return serverproto.ErrorCode_ERROR_INVITATION_CLICK_REPLAY
  618. }
  619. }
  620. this.addClickReplayMember(replayMasterUid)
  621. var addItemList = map[int32]int32{}
  622. addItemList[int32(serverproto.ResType_Res_Invitation)] += model.GlobalInvitationClickMemberRes
  623. this.role.roleBag.AddItemList(addItemList, AddItemST{AddFrom: AddFrom_Invitation, Notify: true})
  624. ackMsg := &serverproto.SCInvitationClickReplayAck{
  625. Error: int32(serverproto.ErrorCode_ERROR_OK),
  626. }
  627. ackMsg.RewardItemList = append(ackMsg.RewardItemList,
  628. &serverproto.KeyValueType{Key: int32(serverproto.ResType_Res_Invitation), Value: model.GlobalInvitationClickMemberRes})
  629. return serverproto.ErrorCode_ERROR_OK
  630. }
  631. func (this *RoleInvitation) InvitationDelMember(delMemberUidList []uint64) serverproto.ErrorCode {
  632. if len(delMemberUidList) > Invitation_Member_Max_Num {
  633. return serverproto.ErrorCode_ERROR_FAIL
  634. }
  635. dataNtfMsg := this.dataChangeNtf()
  636. ssDelMsg := &serverproto.SSInvitationDelMemberNtf{
  637. MasterUid: this.role.GetUUid(),
  638. }
  639. for idx := 0; idx < len(delMemberUidList); idx++ {
  640. delUid := delMemberUidList[idx]
  641. if delUid == 0 || delUid == this.role.GetUUid() {
  642. continue
  643. }
  644. if !this.isMember(delUid) {
  645. continue
  646. }
  647. delete(this.memberUidList, delUid)
  648. this.memberNum--
  649. if this.memberNum < 0 {
  650. this.memberNum = 0
  651. }
  652. this.changeMemberUidList.Add(delUid)
  653. this.SetDirty(true)
  654. dataNtfMsg.DelMemberUidList = append(dataNtfMsg.DelMemberUidList, delUid)
  655. ssDelMsg.DelMemberList = append(ssDelMsg.DelMemberList, delUid)
  656. }
  657. if len(dataNtfMsg.DelMemberUidList) > 0 {
  658. this.role.ReplayGate(dataNtfMsg, true)
  659. }
  660. if len(ssDelMsg.DelMemberList) > 0 {
  661. this.role.SendSocial(ssDelMsg)
  662. AddMailOnlineAndOffline(ssDelMsg.DelMemberList, model.GlobalMailIdInvitationDelMember, int32(serverproto.MailType_MailType_Invitation),
  663. nil, []int32{int32(util.GetTimeSeconds())}, "", "")
  664. }
  665. return serverproto.ErrorCode_ERROR_OK
  666. }
  667. //通知学员解除关系
  668. func (this *RoleInvitation) OnInvitationDelFromMaster(masterUid uint64) {
  669. if this.masterUid != 0 && this.masterUid == masterUid {
  670. this.setMasterUid(0)
  671. dataNtfMsg := this.dataChangeNtf()
  672. this.role.ReplayGate(dataNtfMsg, true)
  673. }
  674. }
  675. func (this *RoleInvitation) InvitationReward(taskIdList []uint32) {
  676. ackMsg := &serverproto.SCInvitationTaskRewardAck{
  677. Error: int32(serverproto.ErrorCode_ERROR_OK),
  678. }
  679. dataNtfMsg := this.dataChangeNtf()
  680. var addItemList = map[int32]int32{}
  681. for idx := 0; idx < len(taskIdList); idx++ {
  682. taskId := taskIdList[idx]
  683. taskData, ok := this.taskList[taskId]
  684. if !ok {
  685. continue
  686. }
  687. delRewardCount := taskData.RewardCount - taskData.RewardedCount
  688. if delRewardCount <= 0 {
  689. continue
  690. }
  691. cfgData, ok := model.ConvertInvitationTaskList[taskId]
  692. if !ok {
  693. continue
  694. }
  695. for key, val := range cfgData.RewardList {
  696. addItemList[key] += val * delRewardCount
  697. }
  698. taskData.RewardedCount = taskData.RewardCount
  699. this.changeTaskList.Add(taskId)
  700. this.SetDirty(true)
  701. dataNtfMsg.InvitationInfo.TaskList = append(dataNtfMsg.InvitationInfo.TaskList, taskData)
  702. ackMsg.TaskIdList = append(ackMsg.TaskIdList, taskId)
  703. }
  704. if len(addItemList) > 0 {
  705. this.role.AddItemList(addItemList, AddFrom_Invitation, true)
  706. this.role.ReplayGate(dataNtfMsg, true)
  707. for key, val := range addItemList {
  708. ackMsg.RewardItemList = append(ackMsg.RewardItemList, &serverproto.KeyValueType{Key: key, Value: val})
  709. }
  710. }
  711. this.role.ReplayGate(ackMsg, true)
  712. }