player.go 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  1. package models
  2. import (
  3. "context"
  4. "fmt"
  5. mhayaString "github.com/mhaya/extend/string"
  6. mhayaTime "github.com/mhaya/extend/time"
  7. "github.com/mhaya/game/game_cluster/internal/constant"
  8. "github.com/mhaya/game/game_cluster/internal/data"
  9. "github.com/mhaya/game/game_cluster/internal/mdb"
  10. "github.com/mhaya/game/game_cluster/internal/param"
  11. "github.com/mhaya/game/game_cluster/internal/third"
  12. "github.com/mhaya/game/game_cluster/internal/token"
  13. mhayaLogger "github.com/mhaya/logger"
  14. "math/rand"
  15. "slices"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. type Player struct {
  21. UserName string `json:"userName" bson:"userName"` // 用户名
  22. OpenId string `json:"openId" bson:"openId"` // 对应tgid
  23. UserNameMaybe string `json:"userNameMaybe" bson:"userNameMaybe"` // 昵称
  24. NickName string `json:"nickName" bson:"nickName"` // 昵称
  25. Pid string `json:"pid" bson:"pid"` // 上级ID
  26. XID string `json:"xID" bson:"xID"` // 绑定推特ID
  27. TonWall string `json:"tonWall" bson:"tonWall"` // 绑定钱包地址
  28. Email string `json:"email" bson:"email"` // 邮箱
  29. Mobile string `json:"mobile" bson:"mobile"` // 手机号
  30. Avatar string `json:"avatar" bson:"avatar"` // 头像
  31. Password string `json:"-" bson:"password"` //账户密码
  32. Salt string `json:"-" bson:"salt"` //密码盐
  33. IsSetPwd bool `json:"isSetPwd" bson:"-"` //是否设置密码
  34. PwdErrTimes int `json:"pwdErrTimes" bson:"pwdErrTimes"` //密码错误次数
  35. PwdErrRefreshTime int64 `json:"pwdErrRefreshTime" bson:"pwdErrRefreshTime"` //密码到期时间
  36. IsCashOut int `json:"-" bson:"IsCashOut"` //服务器判断是否有提现的数据 0 否 1是
  37. IsRobot int `json:"isRobot" bson:"isRobot"` // 是否为机器人
  38. IsLeader int `json:"isLeader" bson:"isLeader"` // 是否是社区长
  39. IsVip int `json:"isVip" bson:"isVip"` // 是否为VIP
  40. IsFirstBindingXID int `json:"isFirstBindingXID" bson:"isFirstBindingXID"` // 是否是第一次绑定推特
  41. Level int `json:"level" bson:"level"` // 等级
  42. Exp int `json:"exp" bson:"exp"` // 经验
  43. Gender int `json:"gender" bson:"gender"` // 性别
  44. Birthday string `json:"birthday" bson:"birthday"` // 生日
  45. Successions int `json:"successions" bson:"successions"` // 连续登陆天数
  46. MaxSuccessions int `json:"maxSuccessions" bson:"maxSuccessions"` // 最大连续等级天数
  47. PrevTime int64 `json:"prevTime" bson:"prevTime"` // 上次登陆时间
  48. LoginTime int64 `json:"loginTime" bson:"loginTime"` // 登陆时间
  49. LoginIP string `json:"loginIP" bson:"loginIP"` // 登录IP
  50. LoginFailure int `json:"loginFailure" bson:"loginFailure"` // 登陆失败次数
  51. JoinIP string `json:"joinIP" bson:"joinIP"` // 注册IP
  52. Rank int `json:"rank" bson:"rank"` // 排名
  53. JoinTime int64 `json:"joinTime" bson:"joinTime"` // 注册时间
  54. CreateTime int64 `json:"createTime" bson:"createTime"` // 创建时间
  55. UpdateTime int64 `json:"updateTime" bson:"updateTime"` // 更新时间
  56. DailyRefreshTime int64 `json:"dailyRefreshTime" bson:"dailyRefreshTime"` // 每日刷新时间
  57. HourRefreshTime int64 `json:"hourRefreshTime" bson:"hourRefreshTime"` // 每小时更新
  58. WeeklyRefreshTime int64 `json:"weeklyRefreshTime" bson:"weeklyRefreshTime"` // 每周刷新时间
  59. RollDay int64 `json:"rollDay" bson:"rollDay"` // 抽奖日期
  60. Status int `json:"status" bson:"status"` // 状态
  61. Roll *Roll `json:"roll" bson:"roll"` // 抽奖
  62. Guide int `json:"guide" bson:"guide"` //
  63. Share *Share `json:"share" bson:"share"` // 分享
  64. FirstReward int `json:"firstReward" bson:"firstReward"` // 首次登陆奖励
  65. Index int `json:"-" bson:"index"` // 索引
  66. Item ItemBasePack `json:"item" bson:"item"` // 道具
  67. SinIn SignIn `json:"sinIn" bson:"sinIn"` // 签到
  68. DailyTask DailyTask `json:"dailyTask" bson:"dailyTask"` // 日常任务
  69. AchieveTask AchieveTask `json:"achieveTask" bson:"achieveTask"` // 成就任务
  70. RankReward RankReward `json:"rankReward" bson:"rankReward"` // 排行奖励
  71. Invite Invite `json:"invite" bson:"invite"` // 邀请
  72. PlayerReward map[int]*PlayerRewardBase `json:"-" bson:"-"`
  73. InviteReward *InviteReward `json:"inviteReward" bson:"inviteReward"` // 邀请奖励
  74. InviteNodeReward InviteNodeReward `json:"inviteNodeReward" bson:"inviteNodeReward"` // 邀请节点奖励
  75. ClaimInviteNum int `json:"claimInviteNum" bson:"claimInviteNum"` // 当前周期,已领取的节点邀请奖励基数
  76. FirstClaimReward FirstReward `json:"firstClaimReward" bson:"firstClaimReward"` // 首次奖励
  77. }
  78. func NewPlayer(token *token.Token) *Player {
  79. return &Player{
  80. UserName: token.PlayerID,
  81. OpenId: token.OpenID,
  82. NickName: token.Nickname,
  83. IsRobot: 0,
  84. Successions: 1,
  85. MaxSuccessions: 1,
  86. LoginTime: mhayaTime.Now().Unix(),
  87. CreateTime: mhayaTime.Now().Unix(),
  88. UpdateTime: mhayaTime.Now().Unix(),
  89. RollDay: mhayaTime.Now().Unix(),
  90. Exp: 0,
  91. Status: 1,
  92. Rank: 0,
  93. Item: NewItem(),
  94. Guide: 1,
  95. Level: 1,
  96. Index: 1,
  97. FirstReward: 1,
  98. Roll: &Roll{RollNums: 0, RollDays: 0},
  99. DailyTask: NewDailyTask(),
  100. Share: &Share{IsDrawShare: 0},
  101. SinIn: NewSignIn(),
  102. AchieveTask: NewAchieveTask(),
  103. RankReward: NewRankReward(),
  104. Invite: NewInvite(),
  105. InviteNodeReward: NewInviteNodeReward(),
  106. FirstClaimReward: NewFirstReward(),
  107. }
  108. }
  109. func NewBotPlayer(token *token.Token) *Player {
  110. return &Player{
  111. UserName: token.PlayerID,
  112. OpenId: token.OpenID,
  113. NickName: token.Nickname,
  114. IsRobot: 1,
  115. Successions: 1,
  116. MaxSuccessions: 1,
  117. LoginTime: mhayaTime.Now().Unix(),
  118. CreateTime: mhayaTime.Now().Unix(),
  119. UpdateTime: mhayaTime.Now().Unix(),
  120. RollDay: mhayaTime.Now().Unix(),
  121. Exp: 0,
  122. Status: 1,
  123. Rank: 0,
  124. Item: NewItem(),
  125. Guide: 1,
  126. Level: 1,
  127. Index: 1,
  128. FirstReward: 1,
  129. Roll: &Roll{RollNums: 0, RollDays: 0},
  130. DailyTask: NewDailyTask(),
  131. Share: &Share{IsDrawShare: 0},
  132. SinIn: NewSignIn(),
  133. AchieveTask: NewAchieveTask(),
  134. RankReward: NewRankReward(),
  135. Invite: NewInvite(),
  136. }
  137. }
  138. func (p *Player) Init() {
  139. if p.InviteReward == nil {
  140. p.InviteReward = &InviteReward{IsClaim: 0}
  141. }
  142. }
  143. // InitDaily 每日刷新
  144. func (p *Player) InitDaily() {
  145. if !mhayaTime.CreateFromTimestamp(p.DailyRefreshTime).IsToday() {
  146. ////刷新每日任务
  147. //p.DailyTask.RefreshDailyTask()
  148. ////刷新抽奖每日分享
  149. //p.Share.RefreshShare()
  150. //刷新是否有排行榜奖励
  151. p.RankReward.InitRank(p.UserName, 1)
  152. //更新时间到当天
  153. p.DailyRefreshTime = mhayaTime.Now().Unix()
  154. }
  155. }
  156. func (p *Player) InitWeekly() {
  157. if !mhayaTime.CreateFromTimestamp(p.WeeklyRefreshTime).IsThisWeek() {
  158. p.SinIn.RefreshSignIn()
  159. //刷新是否有排行榜奖励
  160. p.RankReward.InitRank(p.UserName, 2)
  161. p.WeeklyRefreshTime = mhayaTime.Now().Unix()
  162. }
  163. }
  164. func (p *Player) InitSignIn() {
  165. ret := data.WeeklySignInConfig.GetAll()
  166. signInNode := []int{1009, 1010, 1011, 1012}
  167. // 最近一次签到
  168. //p.SinIn.RefreshSignIn()
  169. last, exists := p.SinIn.Sign[p.SinIn.Num-1]
  170. if !exists {
  171. // 签到数据初始化
  172. p.SinIn.RefreshSignIn()
  173. p.SinIn.RefreshSignNode(signInNode)
  174. return
  175. }
  176. // todo 测试代码
  177. //p.SinIn.RefreshSignIn()
  178. //p.SinIn.RefreshSignNode(signInNode)
  179. // 将时间戳转换为 time.Time 类型
  180. t := time.Unix(last.SignTime, 0)
  181. fmt.Sprintln(t)
  182. // todo 测试代码
  183. // 减去一天
  184. //t = t.Add(-24 * time.Hour)
  185. // 计算第二天的开始时间(即第二天的零点)
  186. // todo 正式代码
  187. //nextDayStart := t.Add(24 * time.Hour).Truncate(24 * time.Hour)
  188. //if p.SinIn.Num >= len(ret)-1 && time.Now().After(nextDayStart) {
  189. // // 签到周期满的第二天
  190. // p.SinIn.RefreshSignIn()
  191. //}
  192. // todo 测试代码
  193. if p.SinIn.Num >= len(ret) {
  194. p.SinIn.RefreshSignIn()
  195. }
  196. maxNodeId := signInNode[len(signInNode)-1]
  197. maxNode, _ := data.DiscreteRuleConfig.Get(maxNodeId)
  198. maxDay, _ := strconv.Atoi(maxNode.Condition)
  199. //if p.SinIn.NodeProgress.Curr >= maxDay && time.Now().After(nextDayStart) {
  200. // // 签到周期满的第二天
  201. // p.SinIn.RefreshSignNode(signInNode)
  202. //}
  203. // todo 测试代码
  204. if p.SinIn.NodeProgress.Curr >= maxDay {
  205. // 签到周期满的第二天
  206. p.SinIn.RefreshSignNode(signInNode)
  207. }
  208. }
  209. func (p *Player) InitAchieveTask() {
  210. p.AchieveTask.RefreshAchieveTask()
  211. }
  212. func (p *Player) LevelUp() bool {
  213. ret, ok := data.LevelConfig.Get(p.Level + 1)
  214. if !ok {
  215. return false
  216. }
  217. curLevel := p.Level
  218. if p.Item[ItemGold].CurNum >= ret.DiceNum && p.Item[ItemInvite].CurNum >= ret.Invite {
  219. p.Level += 1
  220. if p.Level > curLevel {
  221. p.Item[ItemGold].AddMaxNum(ret.DiceLimit)
  222. p.Item[ItemGold].CurNum -= ret.DiceNum
  223. p.Item[ItemInvite].CurNum -= ret.Invite
  224. go p.SetPassiveInviteReward()
  225. //添加日志
  226. mhayaLogger.Infof("player level up, playerName=%v,level=%v", p.UserName, p.Level)
  227. p.SetPlayerRewardLog(SourceLevelUp, p.Level, []data.ItemReward{{ItemID: ItemAllRoll, ItemBaseType: 2, Amount: ret.DiceLimit}}, []data.ItemReward{}, p.Level)
  228. return true
  229. }
  230. }
  231. return false
  232. }
  233. //func (p *Player) RefreshRoll() bool {
  234. // ret, ok := data.DiscreteRuleConfig.Get(RefreshRoll)
  235. // if !ok {
  236. // return false
  237. // }
  238. // arr := strings.Split(ret.Condition, ",")
  239. // if len(arr) == 0 {
  240. // return false
  241. // }
  242. // h, _ := mhayaString.ToInt64(arr[0])
  243. // //m, _ := mhayaString.ToInt64(arr[1])
  244. // s := mhayaTime.CreateFromTimestamp(p.RollDay).DiffInSeconds(mhayaTime.Now())
  245. // if s >= h {
  246. // p.RollDay = mhayaTime.Now().Unix()
  247. // num := p.Item[ItemRoll].AddAll()
  248. // num := p.Item[ItemGold].AddSameTwo(8)
  249. // if num > 0 {
  250. // p.SetPlayerRewardLog(SourceRefreshRoll, 1, []data.ItemReward{{ItemID: ItemRoll, ItemBaseType: 1, Amount: num}}, []data.ItemReward{}, 0)
  251. // p.SetPlayerRewardLog(SourceRefreshRoll, 2, []data.ItemReward{{ItemID: ItemGold, ItemBaseType: 1, Amount: num}}, []data.ItemReward{}, 0)
  252. // }
  253. // mhayaLogger.Infof("RefreshRoll by condition 1 rollDay:%d,num:%v", s, num)
  254. // return true
  255. // }
  256. // return false
  257. //}
  258. func (p *Player) CheckTaskByType1(openid int64, id int) bool {
  259. ret := data.AchieveTaskConfig.GetAll()
  260. mhayaLogger.Debugf("ret => %v", ret)
  261. for _, v := range ret {
  262. if v.Type == 2 {
  263. continue
  264. }
  265. mhayaLogger.Debugf("execute => GetIfChannel1()")
  266. if v.ID == id {
  267. if v.ID == 2 {
  268. if third.GetIfChannel(openid) == 1 {
  269. mhayaLogger.Debugf("execute => GetIfChannel2()")
  270. return true
  271. } else {
  272. mhayaLogger.Debugf("execute => GetIfChannel3()")
  273. return false
  274. }
  275. } else {
  276. return true
  277. }
  278. }
  279. }
  280. mhayaLogger.Debugf("execute => GetIfChannel4()")
  281. return false
  282. }
  283. func (p *Player) FinishAchieveTaskByType1(id int) bool {
  284. mhayaLogger.Debugf("FinishAchieveTaskByType1 id = %v", id)
  285. //if a, ok := p.AchieveTask[id]; ok {
  286. // mhayaLogger.Debugf("FinishAchieveTaskByType1 num = %v Validate = %v", a.Num, a.Validate)
  287. //if a.Num == 0 && a.Validate == 1 { //待验证
  288. openid, ok1 := mhayaString.ToInt64(p.OpenId)
  289. if !ok1 {
  290. mhayaLogger.Warnf("FinishAchieveTaskByType1 验证失败 username :%v, id : %v", p.UserName, id)
  291. return false
  292. }
  293. if p.CheckTaskByType1(openid, id) {
  294. p.AchieveTask[id].Validate = 2 //验证成功
  295. p.AchieveTask[id].Num = 1
  296. p.AchieveTask[id].Status = 1
  297. p.AchieveTask[id].RewardNum = 1
  298. //处理邀请订阅顺序问题
  299. if id == 2 {
  300. go p.SetPassiveInviteReward()
  301. }
  302. return true
  303. } else {
  304. p.AchieveTask[id].Validate = 0 //验证成功
  305. p.AchieveTask[id].Status = 0
  306. mhayaLogger.Warnf("FinishAchieveTaskByType1 验证失败 username :%v, id : %v", p.UserName, id)
  307. return false
  308. }
  309. //} else {
  310. // if a.Validate == 0 {
  311. // p.AchieveTask[id].Validate = 1
  312. // }
  313. //}
  314. //return true
  315. //}
  316. return false
  317. }
  318. // FinishAchieveTaskByType2 完成成就类型2
  319. func (p *Player) FinishAchieveTaskByType2() bool {
  320. //var range data.RangeInt32{}
  321. for _, v := range p.AchieveTask {
  322. if v.Type == 2 {
  323. ret, ok := data.AchieveTaskConfig.Get(v.ID)
  324. if !ok {
  325. continue
  326. }
  327. if p.Item[ItemInvite].Num <= ret.Condition.Max && p.AchieveTask[v.ID].Num != ret.Condition.Max {
  328. p.AchieveTask[v.ID].Num += 1
  329. if p.AchieveTask[v.ID].Num >= ret.Condition.Min && p.AchieveTask[v.ID].Num <= ret.Condition.Max {
  330. p.AchieveTask[v.ID].Status = 1
  331. p.AchieveTask[v.ID].RewardNum += 1
  332. }
  333. }
  334. }
  335. }
  336. return false
  337. }
  338. func (p *Player) FinishDailyTask(tp, num int) bool {
  339. var f bool
  340. for i := 0; i < num; i++ {
  341. for _, v := range p.DailyTask {
  342. if v.Type == tp && v.Status == 0 {
  343. p.DailyTask[v.ID].Num += 1
  344. if p.DailyTask[v.ID].Num == v.Condition {
  345. p.DailyTask[v.ID].Status = 1
  346. f = true
  347. continue
  348. }
  349. }
  350. }
  351. }
  352. return f
  353. }
  354. func (p *Player) RollOnce(num int) *param.RollOnce {
  355. var roll param.RollOnce
  356. levelConfig, ok := data.LevelConfig.Get(p.Level)
  357. if !ok {
  358. return nil
  359. }
  360. if levelConfig == nil {
  361. return nil
  362. }
  363. r1 := rand.Int31n(6) + 1
  364. r2 := rand.Int31n(6) + 1
  365. r3 := rand.Int31n(6) + 1
  366. //rule 4
  367. if (r1 == 1 && r2 == 1 && r3 == 1) || (r1 == 6 && r2 == 6 && r3 == 6) {
  368. roll.Score = levelConfig.Ratio * levelConfig.Rule4
  369. roll.RollType = constant.RollSpecialTripleBet
  370. } else if r1 == r2 && r2 == r3 {
  371. roll.Score = levelConfig.Ratio * levelConfig.Rule3
  372. roll.RollType = constant.RollTripleBet
  373. } else if r1 == r2 || r1 == r3 || r2 == r3 {
  374. roll.Score = levelConfig.Ratio * levelConfig.Rule2
  375. roll.RollType = constant.RollDoubleBet
  376. } else {
  377. roll.Score = levelConfig.Ratio * levelConfig.Rule1
  378. if r1+r2+r3 > 9 {
  379. roll.RollType = constant.RollBigBet
  380. } else {
  381. roll.RollType = constant.RollSmallBet
  382. }
  383. }
  384. roll.Rand = make(map[int]int32)
  385. roll.Rand[1] = r1
  386. roll.Rand[2] = r2
  387. roll.Rand[3] = r3
  388. p.Item[ItemScore].Add(roll.Score * num)
  389. p.Item[ItemGold].Sub(1 * num)
  390. p.SetPlayerRewardLog(SourceRoll, 0, []data.ItemReward{{ItemID: ItemScore, ItemBaseType: 1, Amount: roll.Score * num}}, []data.ItemReward{{ItemID: ItemGold, ItemBaseType: 1, Amount: 1 * num}}, roll)
  391. p.Roll.RollNums += 1 * num
  392. roll.IsDailyTask = p.FinishDailyTask(1, num)
  393. roll.IsLevelUp = p.LevelUp()
  394. return &roll
  395. }
  396. // Draw 最多尝试重复执行50次
  397. func (p *Player) Draw() *param.Draw {
  398. for i := 0; i < 50; i++ {
  399. draw, ok := p.DrawOnce()
  400. if ok {
  401. return draw
  402. }
  403. }
  404. return nil
  405. }
  406. func (p *Player) NewPlayer10Draw() {
  407. if p.Roll.DrawTotal == 0 {
  408. ret, ok := data.DiscreteRuleConfig.Get(NewPlayer10Draw)
  409. if !ok {
  410. return
  411. }
  412. arr := strings.Split(ret.Condition, ",")
  413. if len(arr) != 2 {
  414. return
  415. }
  416. minC := mhayaString.ToIntD(arr[0], 4)
  417. MaxC := mhayaString.ToIntD(arr[1], 6)
  418. p.Roll.NewDraw = make(map[int]int)
  419. wei := []int{1, 2, 4, 5, 12}
  420. wei2 := []int{1, 2, 4, 12}
  421. var m []int
  422. for i := 0; i < minC; i++ {
  423. r := rand.Intn(2)
  424. if r == 0 {
  425. m = append(m, 5)
  426. } else {
  427. m = append(m, 5)
  428. }
  429. }
  430. var num = len(m)
  431. var num2 = 0
  432. for i := 0; i < 10-minC; i++ {
  433. if num2 == 0 {
  434. if num >= MaxC {
  435. k2 := rand.Intn(len(wei2))
  436. cur := wei2[k2]
  437. if cur == 11 || cur == 5 {
  438. num++
  439. }
  440. if cur == 4 || cur == 12 {
  441. num2++
  442. }
  443. m = append(m, cur)
  444. } else {
  445. k := rand.Intn(len(wei))
  446. cur := wei[k]
  447. if cur == 11 || cur == 5 {
  448. num++
  449. }
  450. if cur == 4 || cur == 12 {
  451. num2++
  452. }
  453. m = append(m, cur)
  454. }
  455. } else {
  456. if num >= MaxC-1 {
  457. k2 := rand.Intn(len(wei2))
  458. cur := wei2[k2]
  459. if cur == 11 || cur == 5 {
  460. num++
  461. }
  462. if cur == 4 || cur == 12 {
  463. num2++
  464. }
  465. m = append(m, cur)
  466. } else {
  467. k := rand.Intn(len(wei))
  468. cur := wei[k]
  469. if cur == 11 || cur == 5 {
  470. num++
  471. }
  472. if cur == 4 || cur == 12 {
  473. num2++
  474. }
  475. m = append(m, cur)
  476. }
  477. }
  478. }
  479. m = Shuffle(m)
  480. for key, v := range m {
  481. p.Roll.NewDraw[key+1] = v
  482. }
  483. }
  484. }
  485. func Shuffle(slice []int) []int {
  486. rand.Seed(time.Now().UnixNano())
  487. for i := len(slice) - 1; i > 0; i-- {
  488. j := rand.Intn(i + 1)
  489. slice[i], slice[j] = slice[j], slice[i]
  490. }
  491. return slice
  492. }
  493. func (p *Player) DrawOnce() (*param.Draw, bool) {
  494. var ret map[int]*data.DrawConfigRow
  495. var draw param.Draw
  496. var wg = 0
  497. p.NewPlayer10Draw()
  498. if p.Roll.DrawTotal < 10 {
  499. ret = data.DrawConfig.GetByType(1)
  500. for _, v := range ret {
  501. wg += v.Weight
  502. }
  503. } else {
  504. ret = data.DrawConfig.GetByType(2)
  505. for _, v := range ret {
  506. wg += v.Weight
  507. }
  508. }
  509. if wg == 0 {
  510. return nil, false
  511. }
  512. var cur int
  513. var curID int
  514. //出去新手10连后规则
  515. if p.Roll.DrawTotal >= 10 {
  516. weight := int(rand.Int31n(int32(wg))) + 1
  517. for _, v := range ret {
  518. if v.Weight == 0 {
  519. continue
  520. }
  521. if weight > cur && weight <= cur+v.Weight {
  522. curID = v.ID
  523. break
  524. }
  525. cur += v.Weight
  526. }
  527. } else {
  528. curID = p.Roll.NewDraw[p.Roll.DrawTotal+1]
  529. //0.1u兼容处理
  530. if curID == 11 {
  531. curID = 5
  532. }
  533. }
  534. if d, ok := ret[curID]; ok {
  535. if d.HourTotalCondition > 0 {
  536. i, err := GetDrawHour(curID)
  537. if err != nil {
  538. return nil, false
  539. }
  540. if int(i) > d.HourTotalCondition {
  541. return nil, false
  542. }
  543. }
  544. if d.DailyTotalCondition > 0 {
  545. i, err := GetDrawDailyKey(curID)
  546. if err != nil {
  547. return nil, false
  548. }
  549. if int(i) > d.DailyTotalCondition {
  550. return nil, false
  551. }
  552. }
  553. if d.WeeklyTotalCondition > 0 {
  554. i, err := GetDrawWeeklyKey(curID)
  555. if err != nil {
  556. return nil, false
  557. }
  558. if int(i) > d.WeeklyTotalCondition {
  559. return nil, false
  560. }
  561. }
  562. p.Item.AddItem(d.Reward)
  563. p.Item[ItemDrawsNumber].Sub(1)
  564. draw.Reward = d.Reward
  565. draw.ID = d.Order
  566. draw.CurID = curID
  567. if len(p.Roll.Draw) == 0 {
  568. p.Roll.Draw = make(map[int]int)
  569. }
  570. if len(p.Roll.DrawRatio) == 0 {
  571. p.Roll.DrawRatio = make(map[int]float64)
  572. }
  573. p.Roll.Draw[curID] += 1
  574. p.Roll.DrawTotal += 1
  575. p.Roll.DrawRatio[curID] = float64(p.Roll.Draw[curID]) / float64(p.Roll.DrawTotal)
  576. p.SetPlayerRewardLog(SourceDraw, 0, draw.Reward, []data.ItemReward{{1, ItemDrawsNumber, 1}}, draw)
  577. } else {
  578. return nil, false
  579. }
  580. return &draw, true
  581. }
  582. func GetDrawHour(id int) (int64, error) {
  583. s := mhayaTime.CreateFromTime(mhayaTime.Now().Hour(), 0, 0).ToDateTimeFormat()
  584. key := fmt.Sprintf("%v:%v:%v", constant.DrawHourKey, id, s)
  585. return mdb.RDB.IncrBy(context.Background(), key, 1).Result()
  586. }
  587. func GetDrawDailyKey(id int) (int64, error) {
  588. key := fmt.Sprintf("%v:%v:%v", constant.DrawDailyKey, id, mhayaTime.Now().Format(mhayaTime.DateFormat))
  589. return mdb.RDB.IncrBy(context.Background(), key, 1).Result()
  590. }
  591. func GetDrawWeeklyKey(id int) (int64, error) {
  592. key := fmt.Sprintf("%v:%v:%v", constant.DrawWeeklyKey, id, mhayaTime.Now().Week())
  593. return mdb.RDB.IncrBy(context.Background(), key, 1).Result()
  594. }
  595. //func (p *Player) SignIn() *param.ChangeData {
  596. // var sign param.ChangeData
  597. // p.SinIn.SignDailyTime = mhayaTime.Now().Unix()
  598. // p.SinIn.Sign[p.SinIn.Num].IsSign = 1
  599. // p.SinIn.Sign[p.SinIn.Num].SignTime = mhayaTime.Now().Unix()
  600. // var addItem AddItem
  601. // at := addItem.Add(p.SinIn.Sign[p.SinIn.Num].Reward)
  602. // sign.AddItem = at
  603. // p.Item.AddItem(p.SinIn.Sign[p.SinIn.Num].Reward)
  604. // p.SinIn.Num += 1
  605. // p.SetPlayerRewardLog(SourceSignIn, p.SinIn.Num, p.SinIn.Sign[p.SinIn.Num].Reward, []data.ItemReward{}, nil)
  606. //
  607. // // 节点奖励进度
  608. // p.SinIn.NodeProgress.Curr += 1
  609. //
  610. // // 领取节点奖励
  611. //
  612. // sign.IsLevelUp = p.LevelUp()
  613. // return &sign
  614. //}
  615. func (p *Player) SetPlayerRewardLog(tp, tid int, addReward, subReward []data.ItemReward, desc interface{}) {
  616. p.Index += 1
  617. if len(p.PlayerReward) == 0 {
  618. p.PlayerReward = make(map[int]*PlayerRewardBase)
  619. }
  620. p.PlayerReward[p.Index] = &PlayerRewardBase{
  621. UserName: p.UserName,
  622. AddReward: addReward,
  623. SubReward: subReward,
  624. Desc: desc,
  625. Source: tp,
  626. SourceId: tid,
  627. CreateTime: mhayaTime.Now().Unix(),
  628. }
  629. }
  630. func (p *Player) SetPassiveInviteReward() {
  631. ret2, ok := data.DiscreteRuleConfig.Get(InvitePlayer)
  632. c, tok := mhayaString.ToInt(ret2.Condition)
  633. if !ok || !tok || c != p.Level {
  634. return
  635. }
  636. ret3, ok := data.DiscreteRuleConfig.Get(InviteVipPlayer)
  637. c, tok = mhayaString.ToInt(ret3.Condition)
  638. if !ok || !tok || c != p.Level {
  639. return
  640. }
  641. var isCheck bool
  642. if ts, ok := p.AchieveTask[2]; ok {
  643. if ts.Num == 1 {
  644. isCheck = true
  645. }
  646. }
  647. if !isCheck {
  648. // 升级邀请奖励
  649. openid, _ := mhayaString.ToInt64(p.OpenId)
  650. if third.GetIfChannel(openid) == 0 {
  651. mhayaLogger.Infof("player SetPassiveInviteReward,Not following the channel playerName=%v,level=%v,pid=%v", p.UserName, p.Level, p.Pid)
  652. return
  653. }
  654. }
  655. //被邀请人
  656. key := fmt.Sprintf("%v:1:%v", constant.InviteKey, p.UserName)
  657. //获取邀请人
  658. pUid := mdb.RDB.Get(context.Background(), key).Val()
  659. /* pbase := mdb.RDB.HGet(context.Background(), constant.PlayerBaseKey, pUid).Val()
  660. mdb.RDB.Del(context.Background(), key)
  661. var base param.PlayerBase
  662. err := jsoniter.Unmarshal([]byte(pbase), &base)
  663. if err != nil {
  664. return
  665. }*/
  666. var addItem []data.ItemReward
  667. if p.IsVip == 0 {
  668. //主动邀请记录, 设置邀请人数量+1
  669. key = fmt.Sprintf("%v:%v:%v", constant.InviteKey, InvitePlayer, pUid)
  670. err := mdb.RDB.IncrBy(context.Background(), key, 1).Err()
  671. if err != nil {
  672. mhayaLogger.Infof("player SetPassiveInviteReward,not vip invite playerName=%v,level=%v,param=%v,err=%v", p.UserName, p.Level, key, err)
  673. }
  674. addItem = append(addItem, ret2.Reward...)
  675. } else {
  676. //主动邀请记录, 设置邀请人数量+1
  677. key = fmt.Sprintf("%v:%v:%v", constant.InviteKey, InviteVipPlayer, pUid)
  678. err := mdb.RDB.IncrBy(context.Background(), key, 1).Err()
  679. if err != nil {
  680. mhayaLogger.Infof("player SetPassiveInviteReward, vip invite playerName=%v,level=%v,param=%v,err=%v", p.UserName, p.Level, key, err)
  681. }
  682. addItem = append(addItem, ret3.Reward...)
  683. }
  684. /* //社区长额外奖励
  685. if base.IsLeader == 1 {
  686. ret, ok := data.DiscreteRuleConfig.Get(InvitePlayerByLeader)
  687. if !ok {
  688. return
  689. }
  690. addItem = append(addItem, ret.Reward...)
  691. }*/
  692. if p.InviteReward.IsClaim == 2 {
  693. p.InviteReward.Reward = []data.ItemReward{}
  694. p.InviteReward.IsClaim = 0
  695. p.InviteReward.RewardTime = 0
  696. }
  697. p.InviteReward.Reward = append(p.InviteReward.Reward, addItem...)
  698. p.InviteReward.Merge()
  699. }
  700. func (p *Player) SetInviteReward() {
  701. ret, ok := data.DiscreteRuleConfig.Get(InvitePlayerByLeader)
  702. if !ok {
  703. return
  704. }
  705. ret2, ok := data.DiscreteRuleConfig.Get(InvitePlayer)
  706. if !ok {
  707. return
  708. }
  709. ret3, ok := data.DiscreteRuleConfig.Get(InviteVipPlayer)
  710. if !ok {
  711. return
  712. }
  713. var addItem []data.ItemReward
  714. key1 := fmt.Sprintf("%v:%v:%v", constant.InviteKey, InvitePlayer, p.UserName)
  715. key2 := fmt.Sprintf("%v:%v:%v", constant.InviteKey, InviteVipPlayer, p.UserName)
  716. //自己作为邀请人判断奖励
  717. freeNum, _ := mdb.RDB.Get(context.Background(), key1).Int()
  718. VipNum, _ := mdb.RDB.Get(context.Background(), key2).Int()
  719. for i := 0; i < freeNum; i++ {
  720. addItem = append(addItem, ret2.Reward...)
  721. p.SetPlayerRewardLog(SourceInvite, InvitePlayer, []data.ItemReward{}, []data.ItemReward{}, 2)
  722. if p.IsLeader == 1 {
  723. addItem = append(addItem, ret.Reward...)
  724. p.SetPlayerRewardLog(SourceInvite, InvitePlayerByLeader, []data.ItemReward{}, []data.ItemReward{}, 2)
  725. }
  726. p.Item[ItemInvite].Num += 1
  727. p.Item[ItemInvite].CurNum += 1
  728. p.Invite.Set(InvitePlayer, ret.Reward)
  729. p.FinishAchieveTaskByType2()
  730. mdb.RDB.DecrBy(context.Background(), key1, 1)
  731. }
  732. for i := 0; i < VipNum; i++ {
  733. addItem = append(addItem, ret3.Reward...)
  734. p.SetPlayerRewardLog(SourceInvite, InviteVipPlayer, []data.ItemReward{}, []data.ItemReward{}, 2)
  735. if p.IsLeader == 1 {
  736. addItem = append(addItem, ret.Reward...)
  737. p.SetPlayerRewardLog(SourceInvite, InvitePlayerByLeader, []data.ItemReward{}, []data.ItemReward{}, 2)
  738. }
  739. p.Item[ItemInvite].Num += 1
  740. p.Item[ItemInvite].CurNum += 1
  741. p.Invite.Set(InviteVipPlayer, ret.Reward)
  742. p.FinishAchieveTaskByType2()
  743. mdb.RDB.DecrBy(context.Background(), key2, 1)
  744. }
  745. if (freeNum + VipNum) > 0 {
  746. SetRank(constant.RankSourceInvite, p.IsRobot, p.UserName, freeNum+VipNum)
  747. }
  748. if p.InviteReward.IsClaim == 2 {
  749. p.InviteReward.Reward = []data.ItemReward{}
  750. p.InviteReward.IsClaim = 0
  751. p.InviteReward.RewardTime = 0
  752. }
  753. p.InviteReward.Reward = append(p.InviteReward.Reward, addItem...)
  754. p.InviteReward.Merge()
  755. }
  756. func (p *Player) SetInvite(pid string) bool {
  757. key := fmt.Sprintf("%v:1:%v", constant.InviteKey, p.UserName)
  758. ret, ok := data.DiscreteRuleConfig.Get(InviteMaxExpireTime)
  759. if !ok {
  760. mhayaLogger.Warn("SetInvite return 1")
  761. return false
  762. }
  763. t, _ := mhayaString.ToInt64(ret.Condition)
  764. err := mdb.RDB.Set(context.Background(), key, pid, time.Duration(t)*24*time.Hour).Err()
  765. if err != nil {
  766. mhayaLogger.Warn("SetInvite return 1")
  767. return false
  768. }
  769. key2 := fmt.Sprintf("%v:%v:%v", constant.InviteKey, InvitePlayer, p.Pid)
  770. lRange, _ := mdb.RDB.LRange(context.Background(), key2, 0, -1).Result()
  771. if slices.Contains(lRange, p.UserName) {
  772. mhayaLogger.Warn("SetInvite return 1")
  773. return false
  774. }
  775. mdb.RDB.LPush(context.Background(), key2, p.UserName)
  776. key3 := fmt.Sprintf("%v:%v:%v", constant.InviteTagKey, InvitePlayer, p.Pid)
  777. pTag := mdb.RDB.Get(context.Background(), key3).Val()
  778. mKey := fmt.Sprintf("%v:%v:%v", constant.InviteTagKey, InvitePlayer, p.UserName)
  779. mhayaLogger.Debugf("SetInvite finish 1")
  780. if pTag != "" {
  781. mdb.RDB.Set(context.Background(), mKey, pTag, 0)
  782. tagKey := fmt.Sprintf("%v:%v:%v", constant.InviteTagKey, 2, pTag)
  783. mdb.RDB.Incr(context.Background(), tagKey)
  784. } else {
  785. kol, _ := data.KolConfig.Get(p.Pid)
  786. if kol != nil {
  787. mdb.RDB.Set(context.Background(), mKey, kol.Mark, 0)
  788. tagKey := fmt.Sprintf("%v:%v:%v", constant.InviteTagKey, 2, kol.Mark)
  789. mdb.RDB.Incr(context.Background(), tagKey)
  790. }
  791. }
  792. mhayaLogger.Debugf("SetInvite finish 2")
  793. return true
  794. }
  795. func (p *Player) ClaimInviteReward(id int) param.ChangeData {
  796. var resp param.ChangeData
  797. if len(p.InviteReward.Reward) > 0 {
  798. var addItem AddItem
  799. resp.AddItem = addItem.Add(p.InviteReward.Reward)
  800. p.Item.AddItem(p.InviteReward.Reward)
  801. p.InviteReward.IsClaim = 2
  802. p.InviteReward.RewardTime = mhayaTime.Now().Unix()
  803. p.InviteReward.Reward = []data.ItemReward{}
  804. p.SetPlayerRewardLog(SourceInvite, id, p.InviteReward.Reward, []data.ItemReward{}, nil)
  805. }
  806. p.LevelUp()
  807. return resp
  808. }
  809. func (p *Player) ClaimAchieveTaskReward(id int) param.ChangeData {
  810. var resp param.ChangeData
  811. if ach, ok := p.AchieveTask[id]; ok {
  812. if ach.Status == 1 && ach.RewardNum > 0 {
  813. var addItem AddItem
  814. resp.AddItem = addItem.Add(ach.Reward)
  815. p.Item.AddItem(ach.Reward)
  816. ach.RewardNum -= 1
  817. p.SetPlayerRewardLog(SourceAchieveTask, id, ach.Reward, []data.ItemReward{}, nil)
  818. }
  819. if ach.RewardNum == 0 {
  820. ret, _ := data.AchieveTaskConfig.Get(ach.ID)
  821. if ret.Condition.Max == ach.Num {
  822. p.AchieveTask[id].Status = 2
  823. } else {
  824. p.AchieveTask[id].Status = 0
  825. }
  826. }
  827. }
  828. p.LevelUp()
  829. return resp
  830. }
  831. func (p *Player) ClaimDailyTaskReward(id int) param.ChangeData {
  832. var resp param.ChangeData
  833. if task, ok := p.DailyTask[id]; ok {
  834. if task.Status == 1 {
  835. var addItem AddItem
  836. resp.AddItem = addItem.Add(task.Reward)
  837. p.Item.AddItem(task.Reward)
  838. task.Status = 2
  839. p.SetPlayerRewardLog(SourceDailyTask, id, task.Reward, []data.ItemReward{}, nil)
  840. }
  841. }
  842. p.LevelUp()
  843. return resp
  844. }
  845. // 初始化邀请节点奖励
  846. func (p *Player) InitInviteNodeReword() {
  847. //key := fmt.Sprintf("%v:%v", constant.InviteNodeHistoryKey, p.UserName)
  848. //mdb.RDB.Del(context.Background(), key)
  849. icfg := data.InviteConfig.GetAll()
  850. var maxCondition int
  851. var isUpdate bool
  852. for _, value := range icfg {
  853. maxCondition += value.Condition
  854. if item, ok := p.InviteNodeReward[value.ID]; ok {
  855. if !slices.Equal(item.Reward, value.Reward) || item.Condition != value.Condition {
  856. isUpdate = true
  857. }
  858. } else {
  859. isUpdate = true
  860. }
  861. }
  862. if (len(p.InviteNodeReward) == 0) || isUpdate {
  863. // 初次邀请和更新奖励配置
  864. p.RefreshInviteNodeReward(icfg)
  865. } else if p.ClaimInviteNum >= maxCondition {
  866. // 奖励周期满,重置奖励
  867. p.RefreshInviteNodeReward(icfg)
  868. // 保留刷新前的奖励历史记录
  869. var beforeNum int64
  870. for _, item := range p.InviteNodeReward {
  871. beforeNum += int64(item.Condition)
  872. }
  873. mhayaLogger.Debugf("刷新邀请奖励周期")
  874. key := fmt.Sprintf("%v:%v", constant.InviteNodeHistoryKey, p.UserName)
  875. mdb.RDB.IncrBy(context.Background(), key, beforeNum)
  876. }
  877. }
  878. // 刷新邀请节点奖励
  879. func (p *Player) RefreshInviteNodeReward(icfg map[int]*data.InviteConfigRow) {
  880. p.InviteNodeReward = make(map[int]*InviteNodeRewardItem)
  881. for _, row := range icfg {
  882. condition := row.Condition
  883. inviteReward := &InviteNodeRewardItem{
  884. ID: row.ID,
  885. IsClaim: 0,
  886. IsUnlock: 1,
  887. Reward: row.Reward,
  888. Condition: condition,
  889. }
  890. p.InviteNodeReward[row.ID] = inviteReward
  891. p.ClaimInviteNum = 0
  892. }
  893. }
  894. // 初始化首次奖励
  895. func (p *Player) InitFirstReward() {
  896. drcAll := data.DiscreteRuleConfig.GetAll()
  897. ids := []int{1002, 1003, 1004, 1005, 1006}
  898. for _, id := range ids {
  899. diConfig, _ := drcAll[id]
  900. // todo 测试代码
  901. _, exists := p.FirstClaimReward[id]
  902. if !exists {
  903. item := &FirstRewardItem{
  904. Reward: diConfig.Reward,
  905. }
  906. p.FirstClaimReward[id] = item
  907. }
  908. }
  909. default_friend := []int{2001, 2002, 2003}
  910. openid, _ := strconv.ParseInt(p.OpenId, 10, 64)
  911. playerLevel, _ := data.PlayerConfig.Get(openid)
  912. // 3级以上的老用户专属奖励
  913. if playerLevel != nil && playerLevel.Level > 2 {
  914. level_reword := []int{10001, 10002, 10003, 10004, 10005, 10006, 10007, 10007, 10008, 10009, 10010}
  915. for _, id := range level_reword {
  916. ID := 1000
  917. if drcAll[id].Condition == (strconv.Itoa(playerLevel.Level)) {
  918. _, exists := p.FirstClaimReward[ID]
  919. if !exists {
  920. item := &FirstRewardItem{
  921. IsClaim: 0,
  922. Reward: drcAll[id].Reward,
  923. }
  924. newItem := &FirstRewardItem{
  925. IsClaim: 0,
  926. Reward: drcAll[10001].Reward,
  927. }
  928. oldAmount := item.Reward[0].Amount - drcAll[10001].Reward[0].Amount
  929. oldReward := data.ItemReward{
  930. ItemBaseType: 1,
  931. ItemID: 1,
  932. Amount: oldAmount,
  933. }
  934. oldItem := &FirstRewardItem{
  935. IsClaim: 0,
  936. Reward: []data.ItemReward{oldReward},
  937. }
  938. // 设置新用户的初始奖励
  939. p.FirstClaimReward[ID] = item
  940. p.FirstClaimReward[1001] = newItem
  941. // 设置老用户多出的奖励
  942. p.FirstClaimReward[10001] = oldItem
  943. }
  944. break
  945. }
  946. }
  947. } else {
  948. ID := 1000
  949. _, exists := p.FirstClaimReward[ID]
  950. if !exists {
  951. item := &FirstRewardItem{
  952. IsClaim: 0,
  953. Reward: drcAll[10001].Reward,
  954. }
  955. p.FirstClaimReward[ID] = item
  956. }
  957. }
  958. for _, id := range default_friend {
  959. row, _ := drcAll[id]
  960. if row == nil {
  961. continue
  962. }
  963. // todo 测试代码
  964. _, exists := p.FirstClaimReward[id]
  965. if !exists {
  966. item := &FirstRewardItem{
  967. IsClaim: 0,
  968. Reward: row.Reward,
  969. }
  970. p.FirstClaimReward[id] = item
  971. }
  972. }
  973. }