signinwheelmgr.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. package signinwheel
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/rand"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "bet24.com/log"
  10. "bet24.com/servers/common"
  11. "bet24.com/servers/coreservice/broadcast"
  12. "bet24.com/servers/coreservice/video"
  13. inventory "bet24.com/servers/micros/item_inventory/proto"
  14. item "bet24.com/servers/micros/item_inventory/proto"
  15. cash "bet24.com/servers/micros/money/proto"
  16. user "bet24.com/servers/micros/userservices/proto"
  17. )
  18. func (sc *SigninWheelConfig) getResult() (int, int, []item.ItemPack) {
  19. base, mul := 0, 0
  20. var items []item.ItemPack
  21. rd := rand.Intn(sc.totalBaseChance)
  22. for i := len(sc.Base) - 1; i >= 0; i-- {
  23. if rd >= sc.Base[i].Chance {
  24. base = sc.Base[i].Param
  25. break
  26. }
  27. }
  28. rd = rand.Intn(sc.totalMultipleChance)
  29. for i := len(sc.Multiple) - 1; i >= 0; i-- {
  30. if rd >= sc.Multiple[i].Chance {
  31. mul = sc.Multiple[i].Param
  32. if sc.Multiple[i].Count > 0 {
  33. items = append(items, item.ItemPack{ItemId: sc.Multiple[i].ItemId, Count: sc.Multiple[i].Count})
  34. }
  35. break
  36. }
  37. }
  38. items = append(items, item.ItemPack{ItemId: item.Item_Gold, Count: base * mul})
  39. return base, mul, items
  40. }
  41. func newSigninWheelManager() *signinwheelmgr {
  42. sm := new(signinwheelmgr)
  43. sm.newMgr = newNewManager()
  44. sm.loadInfo()
  45. return sm
  46. }
  47. type signinwheelmgr struct {
  48. config SigninWheelConfig
  49. history []SigninWheelHistory
  50. config_client SigninWheelConfig
  51. newMgr *newmanager
  52. }
  53. func (sm *signinwheelmgr) loadInfo() {
  54. if sm.newMgr.isAvailable() {
  55. sm.config = sm.newMgr.getConfig()
  56. sm.config_client = sm.newMgr.getConfig()
  57. sm.history = getHistory()
  58. return
  59. }
  60. configStr := getSigninWheelConfig()
  61. err := json.Unmarshal([]byte(configStr), &sm.config)
  62. if err != nil {
  63. log.Debug("signinwheelmgr.loadInfo unmarshal failed %s", configStr)
  64. return
  65. }
  66. /*
  67. sort.Slice(sm.config.Base, func(i, j int) bool {
  68. return sm.config.Base[i].Param < sm.config.Base[j].Param
  69. })
  70. sort.Slice(sm.config.Multiple, func(i, j int) bool {
  71. return sm.config.Multiple[i].Param < sm.config.Multiple[j].Param
  72. })
  73. */
  74. d, _ := json.Marshal(sm.config)
  75. json.Unmarshal(d, &sm.config_client)
  76. //log.Debug("signinwheelmgr.loadInfo client = %s", string(d))
  77. // 把概率转换成区间
  78. base := 0
  79. for i := 0; i < len(sm.config.Base); i++ {
  80. if sm.config.Base[i].ItemId == 0 {
  81. sm.config.Base[i].ItemId = item.Item_Gold
  82. sm.config_client.Base[i].ItemId = item.Item_Gold
  83. }
  84. tmp := sm.config.Base[i].Chance
  85. sm.config.Base[i].Chance = base
  86. base += tmp
  87. sm.config_client.Base[i].Chance = 0
  88. }
  89. sm.config.totalBaseChance = base
  90. base = 0
  91. for i := 0; i < len(sm.config.Multiple); i++ {
  92. tmp := sm.config.Multiple[i].Chance
  93. sm.config.Multiple[i].Chance = base
  94. base += tmp
  95. sm.config_client.Multiple[i].Chance = 0
  96. }
  97. sm.config.totalMultipleChance = base
  98. sm.history = getHistory()
  99. time.AfterFunc(10*time.Minute, sm.loadInfo)
  100. }
  101. func (sm *signinwheelmgr) canSignin(userId int, ipAddress string, checkOnly bool) bool {
  102. if sm.newMgr.isAvailable() {
  103. if checkOnly {
  104. return true
  105. }
  106. if !cash.ReduceMoney(userId, sm.newMgr.getCost(), common.LOGTYPE_SIGNIN_WHEEL, "signinwheel", "wheel", ipAddress) {
  107. log.Release("signinwheelmgr.wheel userId[%d] cost[%d] not enough gold", userId, sm.newMgr.getCost())
  108. return false
  109. }
  110. return true
  111. }
  112. return !common.IsSameDay(getUserLastSignin(userId), common.GetTimeStamp())
  113. }
  114. func (sm *signinwheelmgr) getSigninWheelInfo(userId int) UserSiginWheelInfo {
  115. _, myPlayTimes, sysPlayTimes, _ := video.GetInfo(userId, video.Video_Sign)
  116. return UserSiginWheelInfo{
  117. CanSignin: sm.canSignin(userId, "", true),
  118. SigninWheelConfig: sm.config_client,
  119. MyPlayTimes: myPlayTimes,
  120. SysPlayTimes: sysPlayTimes,
  121. }
  122. }
  123. func (sm *signinwheelmgr) doSignin(userId int, ipAddress string, userGold int) (SigninWheelResult, int) {
  124. var ret SigninWheelResult
  125. if len(sm.config.Base) == 0 {
  126. log.Debug("signinwheelmgr.doSignin failed no config")
  127. return ret, 0
  128. }
  129. success, myPlayTimes := false, 0
  130. if !sm.canSignin(userId, ipAddress, false) {
  131. success, myPlayTimes, _ = video.Play(userId, video.Video_Sign)
  132. if !success {
  133. return ret, myPlayTimes
  134. }
  135. }
  136. userGold -= sm.newMgr.getCost()
  137. // 可以签到,取随机base和multiple
  138. if sm.newMgr.isAvailable() {
  139. ret.Base, ret.Multiple, ret.Items = sm.newMgr.getResult(userGold)
  140. } else {
  141. ret.Base, ret.Multiple, ret.Items = sm.config.getResult()
  142. }
  143. if ret.Base == 0 {
  144. log.Debug("signinwheelmgr.doSignin base == 0")
  145. return ret, myPlayTimes
  146. }
  147. time.AfterFunc(time.Second*8, func() {
  148. if success := inventory.AddItems(userId, ret.Items, "signinwheel", common.LOGTYPE_SEND_SIGN); !success {
  149. return
  150. }
  151. // 没有广播消息
  152. if len(sm.newMgr.configInfo.MsgLottery) <= 0 && len(sm.newMgr.configInfo.MsgLotteryAndGold) <= 0 {
  153. return
  154. }
  155. lottery, gold, broadcastMsg := 0, 0, ""
  156. // 碎片≥5的时候展示内容,金币≥5000时展示内容
  157. for _, v := range ret.Items {
  158. if v.ItemId == item.Item_Gold {
  159. gold += v.Count
  160. }
  161. }
  162. if gold >= 5000 {
  163. broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLotteryAndGold, "碎片数量", fmt.Sprintf("<color=#fff000>%d</color>", lottery))
  164. broadcastMsg = strings.ReplaceAll(broadcastMsg, "金币数量", fmt.Sprintf("<color=#04ff0a>%d</color><br/>", gold))
  165. } else if lottery >= 5 && gold > 0 {
  166. broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLotteryAndGold, "碎片数量", fmt.Sprintf("<color=#fff000>%d</color>", lottery))
  167. broadcastMsg = strings.ReplaceAll(broadcastMsg, "金币数量", fmt.Sprintf("<color=#04ff0a>%d</color><br/>", gold))
  168. } else if lottery >= 5 {
  169. broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLottery, "碎片数量", fmt.Sprintf("<color=#fff000>%d</color><br/>", lottery))
  170. }
  171. // 没有可广播的消息
  172. if len(broadcastMsg) <= 0 {
  173. return
  174. }
  175. // 获取用户信息
  176. if userInfo := user.GetUserInfo(userId); userInfo != nil {
  177. broadcastMsg = strings.ReplaceAll(broadcastMsg, "玩家昵称", fmt.Sprintf("<color=#ffafd8>%s</color>", userInfo.NickName))
  178. }
  179. go broadcast.SendBroadcast(userId, 0, 0, broadcastMsg, "")
  180. })
  181. // 写入签到记录
  182. go sm.doSigninAndUpdateHistory(userId, ret.Base, ret.Multiple, 0, ret.Items)
  183. return ret, myPlayTimes
  184. }
  185. func (sm *signinwheelmgr) doSigninAndUpdateHistory(userId, base, multiple, itemId int, items []item.ItemPack) {
  186. // 如果是空Items
  187. if len(items) == 0 {
  188. return
  189. }
  190. userSigninWheel(userId, base, multiple, 0, items)
  191. sm.history = getHistory()
  192. }
  193. func (sm *signinwheelmgr) getHistory() []SigninWheelHistory {
  194. var ret []SigninWheelHistory
  195. for _, v := range sm.history {
  196. u := user.GetUserInfo(v.UserId)
  197. if u == nil {
  198. log.Error("siginwheel.getHistory userId=%d ==> %+v", v.UserId, v)
  199. continue
  200. }
  201. ret = append(ret, SigninWheelHistory{
  202. UserId: v.UserId,
  203. NickName: u.NickName,
  204. FaceId: u.FaceId,
  205. FaceUrl: u.FaceUrl,
  206. SigninWheelResult: v.SigninWheelResult,
  207. })
  208. }
  209. return ret
  210. }
  211. func (sm *signinwheelmgr) dumpSys(param string) {
  212. log.Release("-------------------------------")
  213. log.Release("signinwheelmgr.dumpSys %s", param)
  214. defer func() {
  215. log.Release("+++++++++++++++++++++++++++++++")
  216. log.Release("")
  217. }()
  218. d, _ := json.Marshal(sm.config)
  219. log.Release(string(d))
  220. log.Release("totalChance = %d,%d", sm.config.totalBaseChance, sm.config.totalMultipleChance)
  221. d, _ = json.Marshal(sm.config_client)
  222. log.Release(string(d))
  223. }
  224. func (sm *signinwheelmgr) dumpUser(param string) {
  225. log.Release("-------------------------------")
  226. log.Release("signinwheelmgr.dumpUser %s", param)
  227. defer func() {
  228. log.Release("+++++++++++++++++++++++++++++++")
  229. log.Release("")
  230. }()
  231. var userId int
  232. var err error
  233. if userId, err = strconv.Atoi(param); err != nil {
  234. log.Release("atoi error %v", err)
  235. return
  236. }
  237. log.Release("user last signin time %d", getUserLastSignin(userId))
  238. }
  239. func (sm *signinwheelmgr) dumpHistory() {
  240. log.Release("-------------------------------")
  241. log.Release("signinwheelmgr.dumpHistory")
  242. defer func() {
  243. log.Release("+++++++++++++++++++++++++++++++")
  244. log.Release("")
  245. }()
  246. for _, v := range sm.history {
  247. log.Release(" %s,%d*%d=%d", v.NickName, v.Base, v.Multiple, v.Base*v.Multiple)
  248. }
  249. }
  250. func (sm *signinwheelmgr) test(param string) {
  251. log.Release("-------------------------------")
  252. log.Release("signinwheelmgr.test")
  253. defer func() {
  254. log.Release("+++++++++++++++++++++++++++++++")
  255. log.Release("")
  256. }()
  257. if !sm.newMgr.isAvailable() {
  258. log.Release("new manager not available")
  259. return
  260. }
  261. var testCount int
  262. var err error
  263. if testCount, err = strconv.Atoi(param); err != nil {
  264. log.Release("atoi error %v", err)
  265. return
  266. }
  267. initGold := 0
  268. for i := 0; i < testCount; i++ {
  269. initGold -= sm.newMgr.getCost()
  270. gold := initGold
  271. if gold < 0 {
  272. gold = 1
  273. }
  274. _, _, items := sm.newMgr.getResult(gold)
  275. for _, v := range items {
  276. if v.ItemId == 1 {
  277. initGold += v.Count
  278. }
  279. }
  280. }
  281. log.Release(" after [%d] rolls ,gold = %d", testCount, initGold)
  282. }
  283. func (sm *signinwheelmgr) testLevel(param string) {
  284. log.Release("-------------------------------")
  285. log.Release("signinwheelmgr.testLevel")
  286. defer func() {
  287. log.Release("+++++++++++++++++++++++++++++++")
  288. log.Release("")
  289. }()
  290. if !sm.newMgr.isAvailable() {
  291. log.Release("new manager not available")
  292. return
  293. }
  294. testCount := 100000
  295. level := 0
  296. var err error
  297. if level, err = strconv.Atoi(param); err != nil {
  298. for i := 0; i < sm.newMgr.getMaxLevel(); i++ {
  299. result := sm.getLevelResult(level, testCount)
  300. d, _ := json.Marshal(result)
  301. log.Release(" level[%d] after [%d] rolls ,result = %s", i, testCount, string(d))
  302. }
  303. return
  304. }
  305. result := sm.getLevelResult(level, testCount)
  306. d, _ := json.Marshal(result)
  307. log.Release(" after [%d] rolls ,result = %s", testCount, string(d))
  308. }
  309. func (sm *signinwheelmgr) getLevelResult(level int, testCount int) []*item.ItemPack {
  310. gold := sm.newMgr.getGoldByLevel(level)
  311. var results []*item.ItemPack
  312. for i := 0; i < testCount; i++ {
  313. _, _, items := sm.newMgr.getResult(gold)
  314. if len(items) == 0 {
  315. continue
  316. }
  317. for _, v := range items {
  318. if v.Count == 0 {
  319. continue
  320. }
  321. found := false
  322. for _, r := range results {
  323. if r.ItemId == v.ItemId {
  324. r.Count += v.Count
  325. found = true
  326. break
  327. }
  328. }
  329. if !found {
  330. results = append(results, &item.ItemPack{ItemId: v.ItemId, Count: v.Count})
  331. }
  332. }
  333. }
  334. return results
  335. }