slotcommon.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. package slotcommon
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. _ "bet24.com/log"
  7. coreservice "bet24.com/servers/coreservice/client"
  8. "bet24.com/servers/games/slotcommon/betlevel"
  9. "bet24.com/servers/games/slotcommon/usermanager"
  10. notification "bet24.com/servers/micros/notification/proto"
  11. task "bet24.com/servers/micros/task/proto"
  12. userservices "bet24.com/servers/micros/userservices/proto"
  13. waterpool "bet24.com/servers/micros/waterpool/proto"
  14. "bet24.com/servers/transaction"
  15. "bet24.com/servers/user"
  16. )
  17. const DELAY_REMOVE = 300 // 300秒后删除用户
  18. const DELAY_CHECK = 60 // 每分钟检查一次
  19. type userFreeSpin struct {
  20. freeSpinTime int // 免费次数
  21. lastBetAmount int
  22. fromAd bool
  23. }
  24. type SlotSink interface {
  25. SendGameCmd(userId int, msg, data string)
  26. GetUserInfo(userId int) *user.UserInfo
  27. WriteMoney(userId int, gameId int, amount int, tax int, status int, scoreType int, srcName string) bool
  28. IsChipRoom() bool
  29. }
  30. type Slot_Message struct {
  31. MsgID int
  32. Data string
  33. }
  34. type Slotcommon struct {
  35. gameId int
  36. gameName string
  37. taxRate int
  38. slotSink SlotSink
  39. gameMessage string
  40. userFreeSpins map[int]*userFreeSpin
  41. lock *sync.RWMutex
  42. lockRemove *sync.RWMutex
  43. removingFreespins map[int]int64
  44. levelMgr *betlevel.BetLevelManager
  45. userlist map[int]int
  46. lockUser *sync.RWMutex
  47. }
  48. func NewSlotCommon(slotSink SlotSink, gameId int, gameName string, taxRate int, gameMessage string) *Slotcommon {
  49. sc := new(Slotcommon)
  50. sc.gameId = gameId
  51. sc.gameName = gameName
  52. sc.gameMessage = gameMessage
  53. sc.taxRate = taxRate
  54. sc.slotSink = slotSink
  55. sc.lock = &sync.RWMutex{}
  56. sc.userFreeSpins = make(map[int]*userFreeSpin)
  57. sc.removingFreespins = make(map[int]int64)
  58. sc.userlist = make(map[int]int)
  59. sc.lockRemove = &sync.RWMutex{}
  60. sc.lockUser = &sync.RWMutex{}
  61. go sc.checkRemoveUser()
  62. return sc
  63. }
  64. func (sm *Slotcommon) checkRemoveUser() {
  65. time.AfterFunc(DELAY_CHECK*time.Second, sm.checkRemoveUser)
  66. var toRemove []int
  67. latestRemoveTime := time.Now().Unix() - DELAY_REMOVE
  68. sm.lockRemove.RLock()
  69. for k, v := range sm.removingFreespins {
  70. if v < latestRemoveTime {
  71. toRemove = append(toRemove, k)
  72. }
  73. }
  74. sm.lockRemove.RUnlock()
  75. if len(toRemove) == 0 {
  76. return
  77. }
  78. sm.lockRemove.Lock()
  79. for _, v := range toRemove {
  80. delete(sm.removingFreespins, v)
  81. }
  82. sm.lockRemove.Unlock()
  83. sm.lock.Lock()
  84. for _, v := range toRemove {
  85. delete(sm.userFreeSpins, v)
  86. }
  87. sm.lock.Unlock()
  88. }
  89. func (this *Slotcommon) AddFreeSpin(userId int, freeCount, bet int, fromAd bool) {
  90. this.lock.Lock()
  91. uf, ok := this.userFreeSpins[userId]
  92. count := freeCount
  93. if ok {
  94. count += uf.freeSpinTime
  95. }
  96. this.userFreeSpins[userId] = &userFreeSpin{freeSpinTime: count, lastBetAmount: bet, fromAd: fromAd}
  97. this.lock.Unlock()
  98. }
  99. func (this *Slotcommon) UseFreeSpin(userId int) (bool, int, bool) {
  100. this.lock.Lock()
  101. defer this.lock.Unlock()
  102. t, ok := this.userFreeSpins[userId]
  103. if !ok || t.freeSpinTime <= 0 {
  104. return false, 0, false
  105. }
  106. t.freeSpinTime--
  107. return true, t.lastBetAmount, t.fromAd
  108. }
  109. func (this *Slotcommon) GetFreeSpinTime(userId int) int {
  110. this.lock.RLock()
  111. defer this.lock.RUnlock()
  112. t, ok := this.userFreeSpins[userId]
  113. if !ok {
  114. return 0
  115. }
  116. return t.freeSpinTime
  117. }
  118. func (this *Slotcommon) OnUserEnter(userId int) {
  119. //log.Debug("slotcommon.OnUserEnter %d", userId)
  120. this.lockUser.Lock()
  121. this.userlist[userId] = 1
  122. this.lockUser.Unlock()
  123. go transaction.Trans_SetGameStatus(userId, this.gameId, 1, this.gameName, this.slotSink.IsChipRoom())
  124. go coreservice.FriendSetUserStatus(userId, 1, this.gameName)
  125. this.lockRemove.Lock()
  126. delete(this.removingFreespins, userId)
  127. this.lockRemove.Unlock()
  128. }
  129. func (this *Slotcommon) OnUserExit(userId int) {
  130. found := false
  131. this.lockUser.Lock()
  132. _, found = this.userlist[userId]
  133. if found {
  134. delete(this.userlist, userId)
  135. }
  136. this.lockUser.Unlock()
  137. if !found {
  138. return
  139. }
  140. //log.Debug("slotcommon.OnUserExit %d", userId)
  141. go transaction.Trans_SetGameStatus(userId, this.gameId, 0, this.gameName, this.slotSink.IsChipRoom())
  142. go coreservice.FriendSetUserStatus(userId, 0, this.gameName)
  143. go this.slotSink.WriteMoney(userId, this.gameId, 0, 0, 0, this.gameId*100+99, this.gameName)
  144. if this.GetFreeSpinTime(userId) > 0 {
  145. this.lockRemove.Lock()
  146. this.removingFreespins[userId] = time.Now().Unix()
  147. this.lockRemove.Unlock()
  148. return
  149. }
  150. this.lock.Lock()
  151. defer this.lock.Unlock()
  152. delete(this.userFreeSpins, userId)
  153. }
  154. func (sc *Slotcommon) GetControlType(userId int) int {
  155. usr := sc.slotSink.GetUserInfo(userId)
  156. if usr == nil {
  157. return 0
  158. }
  159. return waterpool.GetControlType(usr.GetUserGold(), true, 0)
  160. }
  161. func (sc *Slotcommon) WriteResult(userId int, betAmount, winAmount int, freeSpin, fromAd bool, resultDesc string, gameId int) {
  162. tax := 0
  163. amount := betAmount
  164. if freeSpin {
  165. amount = 0
  166. }
  167. if sc.taxRate > 0 && (winAmount-amount) > 0 {
  168. tax = (winAmount - amount) / 100 * sc.taxRate
  169. }
  170. go func() {
  171. usr := sc.slotSink.GetUserInfo(userId)
  172. if usr == nil {
  173. return
  174. }
  175. if betAmount > 0 && !freeSpin && !fromAd {
  176. waterpool.AddBet(usr.GetUserGold(), betAmount, true, gameId)
  177. }
  178. if winAmount > 0 {
  179. waterpool.ReducePool(usr.GetUserGold(), winAmount, true, gameId)
  180. }
  181. }()
  182. isFree := 0
  183. if freeSpin {
  184. isFree = 1
  185. if fromAd {
  186. isFree = 2
  187. }
  188. }
  189. isNewbie := usermanager.IsNewbie(userId, sc.gameId)
  190. sc.slotSink.WriteMoney(userId, sc.gameId, winAmount-tax, tax, 2, 2+sc.gameId*100+isFree, sc.gameName)
  191. returnLevel := usermanager.GetUserReturnLevel(userId, sc.gameId, amount)
  192. usermanager.AddResult(userId, sc.gameId, betAmount, winAmount, isFree > 0)
  193. go func() {
  194. if winAmount > 0 {
  195. task.DoTaskAction(userId, task.TaskAction_betWin, winAmount, task.TaskScope{GameName: sc.gameName})
  196. }
  197. if sc.slotSink.IsChipRoom() {
  198. transaction.WriteChipBetRecordAction(userId, sc.gameId, "", amount,
  199. winAmount, tax, 2.0,
  200. sc.getBetDesc(betAmount, freeSpin, fromAd), resultDesc, returnLevel, "", sc.gameName)
  201. slotScore := 1
  202. if winAmount > betAmount {
  203. slotScore = 2
  204. }
  205. coreservice.AddSlotScore(userId, slotScore)
  206. } else {
  207. transaction.WriteBetRecordAction(userId, sc.gameId, "", amount,
  208. winAmount, tax, 2.0,
  209. sc.getBetDesc(betAmount, freeSpin, fromAd), resultDesc, returnLevel, "", sc.gameName)
  210. notification.AddNotification(userId, notification.Notification_Chip, "")
  211. if isFree == 0 {
  212. winAmount -= betAmount
  213. }
  214. userservices.AddGameExp(userId, sc.gameId, winAmount)
  215. }
  216. coreservice.AddUserWinScore(userId, winAmount)
  217. task.DoTaskAction(userId, task.TaskAction_playgame, 1, task.TaskScope{GameName: sc.gameName})
  218. task.DoTaskAction(userId, task.TaskAction_fire, amount, task.TaskScope{GameName: sc.gameName})
  219. // 上面已经减去betAmount
  220. realWin := winAmount
  221. if realWin > 0 {
  222. task.DoTaskAction(userId, task.TaskAction_earn, realWin, task.TaskScope{GameName: sc.gameName})
  223. task.DoTaskAction(userId, task.TaskAction_wingame, 1, task.TaskScope{GameName: sc.gameName})
  224. }
  225. }()
  226. // 如果之前是新手,现在不是
  227. if isNewbie != usermanager.IsNewbie(userId, sc.gameId) {
  228. sc.SendBetLevel(userId)
  229. sc.sendUnlockBet(userId)
  230. }
  231. }
  232. func (sc *Slotcommon) getBetDesc(betAmount int, isFree, fromAd bool) string {
  233. if isFree {
  234. nFromAd := 0
  235. if fromAd {
  236. nFromAd = 1
  237. }
  238. return fmt.Sprintf("%d|%d", betAmount, nFromAd)
  239. } else {
  240. return fmt.Sprintf("%d", betAmount)
  241. }
  242. }