threadsafe_table_game.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. package frame
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "time"
  6. "bet24.com/log"
  7. coreservice "bet24.com/servers/coreservice/client"
  8. "bet24.com/servers/insecureframe/gate"
  9. "bet24.com/servers/insecureframe/message"
  10. activityservice "bet24.com/servers/micros/activityservice/proto"
  11. audioroom "bet24.com/servers/micros/audioroom/proto"
  12. _ "bet24.com/servers/micros/ladderservice/proto"
  13. notification "bet24.com/servers/micros/notification/proto"
  14. privateroom "bet24.com/servers/micros/privateroom/proto"
  15. task "bet24.com/servers/micros/task/proto"
  16. userservices "bet24.com/servers/micros/userservices/proto"
  17. "bet24.com/servers/transaction"
  18. "bet24.com/servers/user"
  19. )
  20. func (t *ThreadsafeTable) GetTableID() int {
  21. return t.tableId
  22. }
  23. func (t *ThreadsafeTable) IsPrivate() bool {
  24. return t.isPrivate()
  25. }
  26. func (t *ThreadsafeTable) GetRoomNo() int {
  27. return t.roomNo
  28. }
  29. func (t *ThreadsafeTable) GetOwner() int {
  30. return t.owner
  31. }
  32. // 游戏准备好后,即可调用框架StartGame进行场景广播
  33. func (t *ThreadsafeTable) StartGame() {
  34. if t.tableStatus != TableStatus_Free {
  35. log.Release("ThreadsafeTable.StartGame not free status")
  36. return
  37. }
  38. t.startTime = time.Now().Unix()
  39. var userIds []int
  40. // 将所有用户状态改变
  41. for i := 0; i < t.chairCount; i++ {
  42. if t.users[i] == -1 {
  43. continue
  44. }
  45. usr := gate.GetUserInfo(t.users[i])
  46. if usr == nil || !usr.IsPlayer() {
  47. continue
  48. }
  49. gameFrame.setUserStatus(t.users[i], user.UserStatus_Play)
  50. userIds = append(userIds, usr.GetUserId())
  51. }
  52. t.tableStatus = TableStatus_Playing
  53. // 广播场景
  54. t.broadcastScene()
  55. if t.isPrivate() {
  56. go privateroom.SetRoomStatus(t.roomNo, privateroom.PrivateRoomStatus_Playing)
  57. }
  58. // 潜在好友
  59. go func(users []int) {
  60. reason := fmt.Sprintf("play %s", gameFrame.GetGameName())
  61. for i := 0; i < len(users)-1; i++ {
  62. for j := i + 1; j < len(users); j++ {
  63. coreservice.FriendAddPotential(users[i], users[j], reason)
  64. coreservice.FriendAddPotential(users[j], users[i], reason)
  65. }
  66. }
  67. }(userIds)
  68. }
  69. // 游戏结算后,调用
  70. func (t *ThreadsafeTable) EndGame() {
  71. if t.tableStatus != TableStatus_Playing {
  72. log.Debug("ThreadsafeTable.EndGame not playing status")
  73. return
  74. }
  75. // 将所有用户状态改变
  76. for i := 0; i < t.chairCount; i++ {
  77. if t.users[i] == -1 {
  78. continue
  79. }
  80. usr := gate.GetUserInfo(t.users[i])
  81. if usr == nil {
  82. // t.users[i] = -1
  83. continue
  84. }
  85. // 如果玩家得状态是准备,就不处理了
  86. if usr.GetUserStatus() == user.UserStatus_Ready {
  87. // 模拟发个准备
  88. go t.onUserReady(t.users[i], i, true)
  89. continue
  90. }
  91. gameFrame.setUserStatus(t.users[i], user.UserStatus_Sit)
  92. }
  93. t.tableStatus = TableStatus_Free
  94. gameFrame.removeOfflineByTableId(t.tableId)
  95. t.broadcastData(message.Table_GameEnd, "")
  96. if t.isPrivate() {
  97. go privateroom.SetRoomStatus(t.roomNo, privateroom.PrivateRoomStatus_Ended)
  98. }
  99. }
  100. func (t *ThreadsafeTable) MultiSetStart() {
  101. t.multiSetStatus = MultiSetStatus_Playing
  102. }
  103. func (t *ThreadsafeTable) MultiSetEnd() {
  104. t.multiSetStatus = MultiSetStatus_Free
  105. }
  106. func (t *ThreadsafeTable) GetUserByChair(chairId int) *user.UserInfo {
  107. if chairId < 0 || chairId >= len(t.users) {
  108. log.Debug("ThreadsafeTable.GetUserByChair %d not in %d", chairId, len(t.users))
  109. return nil
  110. }
  111. if t.users[chairId] == -1 {
  112. //log.Debug("ThreadsafeTable.GetUserByChair chair %d have no user", chairId)
  113. return nil
  114. }
  115. usr := t.getPlayer(t.users[chairId])
  116. if usr == nil {
  117. log.Debug("ThreadsafeTable.GetUserByChair chair %d user not exist", chairId)
  118. t.users[chairId] = -1
  119. return nil
  120. }
  121. return usr
  122. }
  123. // 踢人,fource表示就算玩家状态为Playing也踢走
  124. func (t *ThreadsafeTable) KickUser(userIndex int32, force bool) bool {
  125. for i := 0; i < t.chairCount; i++ {
  126. if t.users[i] == userIndex {
  127. return t.KickUserByChair(i, force)
  128. }
  129. }
  130. return false
  131. }
  132. func (t *ThreadsafeTable) KickUserByChair(chairId int, force bool) bool {
  133. usr := t.GetUserByChair(chairId)
  134. if usr == nil {
  135. return false
  136. }
  137. if !force && usr.GetUserStatus() == user.UserStatus_Play {
  138. log.Debug("ThreadsafeTable.KickUserByChair user is playing")
  139. return false
  140. }
  141. userIndex := usr.GetUserIndex()
  142. t.RemoveUser_safe(userIndex, !usr.IsRobot(), false)
  143. if force {
  144. gate.KickUser(userIndex)
  145. }
  146. return true
  147. }
  148. func (t *ThreadsafeTable) SendGameData(userIndex int32, msg, data string) {
  149. if userIndex == -1 {
  150. t.broadcastData(msg, data)
  151. return
  152. }
  153. // 检查userIndex是否有效
  154. for i := 0; i < t.chairCount; i++ {
  155. if t.users[i] == userIndex {
  156. gate.SendMessage(userIndex, msg, data)
  157. return
  158. }
  159. }
  160. for _, v := range t.watchUsers {
  161. if v.UserIndex == userIndex {
  162. gate.SendMessage(userIndex, msg, data)
  163. return
  164. }
  165. }
  166. log.Debug("ThreadsafeTable.SendGameData userIndex[%d][%s] not in table", userIndex, msg)
  167. }
  168. func (t *ThreadsafeTable) SendGameDataToChair(chairId int, msg, data string) {
  169. if chairId == -1 {
  170. t.broadcastData(msg, data)
  171. return
  172. }
  173. usr := t.GetUserByChair(chairId)
  174. if usr == nil {
  175. return
  176. }
  177. t.sendData(usr.GetUserIndex(), msg, data)
  178. }
  179. func (t *ThreadsafeTable) BroadcastToWatcher(msg, data string) {
  180. for _, v := range t.watchUsers {
  181. t.sendData(v.UserIndex, msg, data)
  182. }
  183. }
  184. func (t *ThreadsafeTable) GetPlayer(userIndex int32) *user.UserInfo {
  185. for i := 0; i < t.chairCount; i++ {
  186. if t.users[i] == userIndex {
  187. ret := gate.GetUserInfo(userIndex)
  188. if ret == nil {
  189. ret = gameFrame.getOfflineUser(userIndex)
  190. }
  191. return ret
  192. }
  193. }
  194. return nil
  195. }
  196. func (t *ThreadsafeTable) getPlayer(userIndex int32) *user.UserInfo {
  197. return t.GetPlayer(userIndex)
  198. }
  199. func (t *ThreadsafeTable) GetUserByUserId(userId int) *user.UserInfo {
  200. return gate.GetUserByUserId(userId)
  201. }
  202. func (t *ThreadsafeTable) GetPlayerByUserId(userId int) *user.UserInfo {
  203. for i := 0; i < t.chairCount; i++ {
  204. if t.users[i] == -1 {
  205. continue
  206. }
  207. usr := t.getPlayer(t.users[i])
  208. if usr == nil {
  209. continue
  210. }
  211. if usr.GetUserId() == userId {
  212. return usr
  213. }
  214. }
  215. return nil
  216. }
  217. func (t *ThreadsafeTable) GetUser(userIndex int32) (*user.UserInfo, bool) {
  218. usr := t.GetPlayer(userIndex)
  219. if usr != nil {
  220. return usr, true
  221. }
  222. // 旁观列表
  223. for _, v := range t.watchUsers {
  224. if v.UserIndex == userIndex {
  225. return gate.GetUserInfo(userIndex), false
  226. }
  227. }
  228. return nil, false
  229. }
  230. func (t *ThreadsafeTable) NotifySceneChanged(chairId int) {
  231. if chairId == -1 {
  232. t.broadcastScene()
  233. return
  234. }
  235. if !t.sendGameScene(chairId) {
  236. log.Debug("ThreadsafeTable NotifySceneChanged chairId[%d] is empty", chairId)
  237. }
  238. }
  239. func (t *ThreadsafeTable) onUserReady(userIndex int32, chairId int, isReady bool) {
  240. if isReady {
  241. t.tableSink.OnUserReady(userIndex, chairId)
  242. } else {
  243. t.tableSink.OnUserCancelReady(userIndex, chairId)
  244. }
  245. }
  246. func (t *ThreadsafeTable) WriteUserMoney(userId int, amount, tax int, status, scoreType int, sourceName string) (bool, int) {
  247. if scoreType < 100 {
  248. scoreType += gameFrame.gameSink.GetGameID() * 100
  249. }
  250. ret, amount := gate.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName, gameFrame.gameSink.IsChipRoom())
  251. return ret, amount
  252. }
  253. func (t *ThreadsafeTable) WriteUserMoneyWithModifyAmount(userId int, amount, tax int, status, scoreType int, sourceName string) int {
  254. if scoreType < 100 {
  255. scoreType += gameFrame.gameSink.GetGameID() * 100
  256. }
  257. return gate.WriteUserMoneyWithModifyAmount(userId, amount, tax, status, scoreType, sourceName, gameFrame.gameSink.IsChipRoom())
  258. }
  259. func (t *ThreadsafeTable) WriteBetRecordWithPlayTime(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, secsBefore int) {
  260. //log.Debug("ThreadsafeTable.WriteBetRecordWithPlayTime[%d]", userId)
  261. // 机器人不写分
  262. usr := t.GetUserByUserId(userId)
  263. if usr != nil && usr.IsRobot() {
  264. log.Debug("ThreadsafeTable.WriteBetRecordWithPlayTime[%d] robot return", userId)
  265. return
  266. }
  267. t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
  268. }
  269. func (t *ThreadsafeTable) delayReportUserBet() {
  270. t.reportUserBetsTimer = nil
  271. if len(t.tmpUserBets) == 0 {
  272. return
  273. }
  274. log.Debug("ThreadsafeTable.delayReportUserBet owner[%d] roomNo[%d] %v", t.owner, t.roomNo, t.tmpUserBets)
  275. audioroom.ReportUserBet(t.owner, t.roomNo, gameFrame.gameSink.GetGameID(), gameFrame.gameSink.GetRoomName(), t.tmpUserBets, gameFrame.IsChipRoom())
  276. t.tmpUserBets = []audioroom.UserBet{}
  277. }
  278. func (t *ThreadsafeTable) writeBetRecordWithPlayTime(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, secsBefore int) {
  279. gameId := gameFrame.gameSink.GetGameID()
  280. if gameFrame.gameSink.IsChipRoom() {
  281. transaction.WriteChipBetRecordAction(userId, gameId, "", betAmount, winAmount, 0, winRate, betDesc, resultDesc, secsBefore, "", roomName)
  282. } else {
  283. transaction.WriteBetRecordAction(userId, gameId, "", betAmount, winAmount, 0, winRate, betDesc, resultDesc, secsBefore, "", roomName)
  284. }
  285. go func() {
  286. if t.isMatch() {
  287. // 在比赛模块中完成任务
  288. //coreservice.DoTaskAction(userId, task.TaskAction_playmatch, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  289. } else {
  290. task.DoTaskAction(userId, task.TaskAction_playgame, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  291. task.DoTaskAction(userId, task.TaskAction_fire, betAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  292. if winAmount-betAmount > 0 {
  293. task.DoTaskAction(userId, task.TaskAction_earn, winAmount-betAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  294. task.DoTaskAction(userId, task.TaskAction_wingame, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  295. }
  296. if winAmount > 0 {
  297. task.DoTaskAction(userId, task.TaskAction_betWin, winAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
  298. }
  299. }
  300. if !gameFrame.gameSink.IsChipRoom() {
  301. notification.AddNotification(userId, notification.Notification_Gold, "")
  302. //coreservice.AddGameExp(userId, gameId, winAmount-betAmount)
  303. coreservice.AddUserWinScore(userId, winAmount-betAmount)
  304. score := winAmount - betAmount
  305. if score < 0 {
  306. score = -score
  307. }
  308. if score > 0 {
  309. activityservice.TriggerSavingPot(userId, gameFrame.gameSink.GetGameID(), score)
  310. }
  311. }
  312. // 如果是语聊房游戏,存储并上报投注日志
  313. if t.GetOwner() > 0 && gameFrame.gameSink.GetChairCount() < 2 {
  314. t.tmpUserBets = append(t.tmpUserBets, audioroom.UserBet{
  315. UserId: userId,
  316. TotalBet: betAmount,
  317. TotalWin: winAmount,
  318. })
  319. if t.reportUserBetsTimer == nil {
  320. t.reportUserBetsTimer = time.AfterFunc(2*time.Second, t.delayReportUserBet)
  321. }
  322. }
  323. if gameFrame.IsLadderRoom() {
  324. //ladderservice.AddUserLadderScore(userId, gameId, roomName, winAmount-betAmount)
  325. }
  326. }()
  327. }
  328. func (t *ThreadsafeTable) WriteBetRecord(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string) {
  329. // 机器人不写分
  330. usr := t.GetUserByUserId(userId)
  331. if usr != nil && usr.IsRobot() {
  332. return
  333. }
  334. secsBefore := int(time.Now().Unix() - t.startTime)
  335. t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
  336. }
  337. func (t *ThreadsafeTable) WriteBetRecordWithSetcount(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, setCount int) {
  338. usr := t.GetUserByUserId(userId)
  339. if usr != nil && usr.IsRobot() {
  340. return
  341. }
  342. secsBefore := int(time.Now().Unix() - t.startTime)
  343. t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
  344. go transaction.WriteBetRecordSetCount(userId, gameFrame.gameSink.GetGameID(), secsBefore, setCount)
  345. }
  346. func (t *ThreadsafeTable) FinishGame(userId int, baseScore, gameType, playerCount int) {
  347. if gameFrame.gameSink.IsChipRoom() {
  348. return
  349. }
  350. usr := t.GetPlayerByUserId(userId)
  351. if usr == nil || usr.IsRobot() {
  352. return
  353. }
  354. go coreservice.TriggerCouponTask(userId, gameFrame.gameSink.GetGameID(), baseScore, gameType, playerCount)
  355. }
  356. func (t *ThreadsafeTable) GetTableStatus() int {
  357. return t.tableStatus
  358. }
  359. func (t *ThreadsafeTable) IsPlaying() bool {
  360. return t.tableStatus == TableStatus_Playing
  361. }
  362. func (t *ThreadsafeTable) IsMultiSetPlaying() bool {
  363. return t.multiSetStatus == MultiSetStatus_Playing
  364. }
  365. func (t *ThreadsafeTable) RequestADAward(userIndex int32, losingAmount int) {
  366. if gameFrame.gameSink.IsChipRoom() {
  367. return
  368. }
  369. if losingAmount >= 0 {
  370. log.Debug("ThreadsafeTable.RequestADAward %d not losing %d", userIndex, losingAmount)
  371. return
  372. }
  373. usr := t.GetPlayer(userIndex)
  374. if usr == nil {
  375. log.Debug("ThreadsafeTable.RequestADAward user %d not exist", userIndex)
  376. return
  377. }
  378. if usr.IsRobot() {
  379. return
  380. }
  381. ret := coreservice.VideoSettleInfo(usr.GetUserId(), losingAmount, gameFrame.gameSink.GetGameID())
  382. if !ret.Success {
  383. log.Debug("coreservice.VideoSettleInfo failed %d %d", usr.GetUserId(), losingAmount)
  384. return
  385. }
  386. var rewardInfo message.AdRewardInfo
  387. rewardInfo.SerialNo = ret.TimeStamp
  388. rewardInfo.ReturnGold = ret.ReturnAmount
  389. rewardInfo.UserId = usr.GetUserId()
  390. rewardInfo.LosingGold = losingAmount
  391. rewardInfo.MaxTimes = ret.MaxTimes
  392. rewardInfo.SettleAmount = ret.SettleAmount
  393. log.Debug("coreservice.VideoSettleInfo Success %d %d", usr.GetUserId(), rewardInfo.ReturnGold)
  394. d, _ := json.Marshal(rewardInfo)
  395. // 发给客户端
  396. t.sendData(userIndex, message.Frame_ADRewardInfo, string(d))
  397. }
  398. func (t *ThreadsafeTable) LogWithTableId(format string, a ...interface{}) {
  399. f := fmt.Sprintf("[%d] %v", t.tableId, format)
  400. log.Debug(fmt.Sprintf(f, a...))
  401. }
  402. func (t *ThreadsafeTable) SetUserEndGame(chairId int) {
  403. t.LogWithTableId("SetUserEndGame %d", chairId)
  404. usr := t.GetUserByChair(chairId)
  405. if usr == nil {
  406. log.Debug("ThreadsafeTable.SetUserEndGame chair %d not exist", chairId)
  407. return
  408. }
  409. gameFrame.setUserStatus(usr.GetUserIndex(), user.UserStatus_Sit)
  410. //gameFrame.remove(t.tableId)
  411. // 如果掉线
  412. go gameFrame.removeOfflineUser(usr.GetUserId(), usr)
  413. }
  414. func (t *ThreadsafeTable) SetTimer(timerId int, delayMs int) {
  415. //log.Debug("[%d]ThreadsafeTable.SetTimer %d %d time[%d]", t.tableId, timerId, delayMs, time.Now().UnixNano()/1000000)
  416. t.KillTimer(timerId)
  417. timer := time.AfterFunc(time.Duration(delayMs)*time.Millisecond, func() {
  418. //log.Debug("[%d]ThreadsafeTable.OnTimer %d time[%d]", t.tableId, timerId, time.Now().UnixNano()/1000000)
  419. t.timerChan <- timerId
  420. t.timerLock.Lock()
  421. delete(t.timers, timerId)
  422. t.timerLock.Unlock()
  423. })
  424. t.timerLock.Lock()
  425. t.timers[timerId] = timer
  426. t.timerLock.Unlock()
  427. }
  428. func (t *ThreadsafeTable) KillTimer(timerId int) {
  429. t.timerLock.RLock()
  430. timer, ok := t.timers[timerId]
  431. t.timerLock.RUnlock()
  432. if !ok {
  433. return
  434. }
  435. t.timerLock.Lock()
  436. delete(t.timers, timerId)
  437. t.timerLock.Unlock()
  438. timer.Stop()
  439. }
  440. func (t *ThreadsafeTable) KillAllTimer() {
  441. t.killAllTimer()
  442. }
  443. func (t *ThreadsafeTable) killAllTimer() {
  444. t.timerLock.RLock()
  445. for _, v := range t.timers {
  446. v.Stop()
  447. }
  448. t.timerLock.RUnlock()
  449. }
  450. func (t *ThreadsafeTable) SendBroadcast(userId int, userName string, score int) {
  451. gameId := gameFrame.gameSink.GetGameID()
  452. gameName := gameFrame.gameSink.GetGameName()
  453. go coreservice.SendGameWinBroadcast(userId, userName, score, gameId, gameName)
  454. }
  455. func (t *ThreadsafeTable) Dismiss() {
  456. t.dismiss_safe()
  457. }
  458. func (t *ThreadsafeTable) GetUserChipOrGold(userIndex int32) int {
  459. return t.GetUserChipOrGoldByUser(t.GetPlayer(userIndex))
  460. }
  461. func (t *ThreadsafeTable) GetUserChipOrGoldByUserId(userId int) int {
  462. //return t.GetUserChipOrGoldByUser(t.GetPlayerByUserId(userId))
  463. u := gate.GetUserByUserId(userId)
  464. if u == nil {
  465. return 0
  466. }
  467. return t.GetUserChipOrGoldByUser(u)
  468. }
  469. func (t *ThreadsafeTable) GetUserChipOrGoldByUser(usr *user.UserInfo) int {
  470. if usr == nil {
  471. return 0
  472. }
  473. if gameFrame.gameSink.IsChipRoom() {
  474. return usr.GetChip()
  475. }
  476. return usr.GetUserGold()
  477. }
  478. func (t *ThreadsafeTable) GetPlayerCount() int {
  479. return t.getPlayerCount()
  480. }
  481. func (t *ThreadsafeTable) UpdateGameScore(userId, scoreDelta int) {
  482. if !t.isPrivate() {
  483. //log.Release("ThreadsafeTable.UpdateGameScore not private room")
  484. return
  485. }
  486. go privateroom.UpdateUserGameScore(t.roomNo, userId, scoreDelta)
  487. }
  488. func (t *ThreadsafeTable) DismissPrivateRoom() {
  489. if !t.isPrivate() {
  490. log.Release("ThreadsafeTable.DismissPrivateRoom not private room")
  491. return
  492. }
  493. go privateroom.DismissPrivateRoom(t.roomNo)
  494. }
  495. func (t *ThreadsafeTable) PrivateRoomSetWinners(winners []int) {
  496. if !t.isPrivate() {
  497. log.Release("ThreadsafeTable.PrivateRoomSetWinners not private room")
  498. return
  499. }
  500. privateroom.SetWinners(t.roomNo, winners)
  501. // 如果是百人场,就释放房间
  502. if gameFrame.gameSink.GetChairCount() < 2 {
  503. go gameFrame.removeTable(t.tableId)
  504. }
  505. }
  506. func (t *ThreadsafeTable) AddExperience(userId, exp int) int {
  507. if exp <= 0 {
  508. log.Release("ThreadsafeTable.AddExperience [%d:%d] invalid exp", userId, exp)
  509. return 0
  510. }
  511. return userservices.AddExperience(userId, exp)
  512. }
  513. func (t *ThreadsafeTable) GetUserList() []*user.UserInfo {
  514. var ret []*user.UserInfo
  515. for _, v := range t.watchUsers {
  516. usr, _ := t.GetUser(v.UserIndex)
  517. if usr != nil {
  518. ret = append(ret, usr)
  519. }
  520. }
  521. return ret
  522. }
  523. func (t *ThreadsafeTable) PrivateRoomGetRoomType() string {
  524. if !t.isPrivate() {
  525. log.Release("ThreadsafeTable.PrivateRoomGetRoomType not private room")
  526. return ""
  527. }
  528. return privateroom.GetRoomType(t.roomNo)
  529. }
  530. func (t *ThreadsafeTable) PrivateRoomGetFeeAndPrize(userId int) (int, int) {
  531. if !t.isPrivate() {
  532. log.Release("ThreadsafeTable.PrivateRoomGetFeeAndPrize not private room")
  533. return 0, 0
  534. }
  535. return privateroom.GetFeeAndPrize(t.roomNo, userId)
  536. }
  537. func (t *ThreadsafeTable) CloseTable() {
  538. go gameFrame.removeTable(t.tableId)
  539. }