player.go 33 KB

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