tablesink.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. package gamelogic
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/rand"
  6. "time"
  7. "bet24.com/servers/games/spinplay/config"
  8. "bet24.com/servers/insecureframe/frame"
  9. "bet24.com/servers/insecureframe/gate"
  10. "bet24.com/utils"
  11. )
  12. type tablesink struct {
  13. table frame.Table
  14. gameScene *GameScene
  15. roomInfo config.RoomInfo
  16. logic *cardlogic
  17. LastOpraTime time.Time //记录操作时间点
  18. privateData string
  19. }
  20. func newTableSink(table frame.Table, data string) *tablesink {
  21. ts := new(tablesink)
  22. ts.privateData = data
  23. ts.table = table
  24. ts.logic = newCardLogic()
  25. ts.gameScene = newGameScene(table.GetTableID())
  26. err := json.Unmarshal([]byte(data), &ts.roomInfo)
  27. if err != nil {
  28. found := false
  29. for _, v := range config.Rooms.Rooms {
  30. if data == v.RoomName {
  31. ts.roomInfo = v
  32. found = true
  33. break
  34. }
  35. }
  36. if !found {
  37. ts.roomInfo = config.Rooms.Rooms[0]
  38. }
  39. }
  40. return ts
  41. }
  42. func (ts *tablesink) Destroy() {
  43. ts.table.LogWithTableId("------tablesink: Destroy-------")
  44. }
  45. func (ts *tablesink) OnGetMinGold() int {
  46. return ts.roomInfo.MinGold
  47. }
  48. func (ts *tablesink) OnGetMaxGold() int {
  49. return ts.roomInfo.MaxGold
  50. }
  51. func (ts *tablesink) OnGameMessage(userIndex int32, msg, data string) bool {
  52. switch msg {
  53. case CMD_TABLECHAT:
  54. ts.recvChatMsg(userIndex, data)
  55. case CMD_CANCLE_AUTO:
  56. ts.recvCancleAutoMsg(userIndex, data)
  57. case CMD_AUTO:
  58. ts.recvAutoMsg(userIndex, data)
  59. case CMD_ACTION:
  60. return ts.recvAction(userIndex, data)
  61. default:
  62. ts.table.LogWithTableId("tablesink.OnGameMessage %s\n%s", msg, data)
  63. return false
  64. }
  65. return true
  66. }
  67. func (ts *tablesink) OnUserEnterTable(userIndex int32, chairId int) {
  68. usr := gate.GetUserInfo(userIndex)
  69. if usr == nil {
  70. ts.table.LogWithTableId("tablesink.OnUserEnterTable user not exist")
  71. return
  72. }
  73. ts.table.LogWithTableId("tablesink.OnUserEnterTable chair[%d]: %d:%s ", chairId, usr.GetUserId(), usr.GetUserNickName())
  74. if ts.table.GetUserChipOrGoldByUser(usr) < ts.roomInfo.MinGold {
  75. ts.table.LogWithTableId("----玩家:%d 金币不足: %d ", usr.GetUserId(), ts.table.GetUserChipOrGoldByUser(usr))
  76. ts.table.KickUser(userIndex, true)
  77. return
  78. }
  79. //下发房间配置
  80. d, _ := json.Marshal(ts.roomInfo.RoomInfoBase)
  81. ts.table.SendGameData(userIndex, CMD_ROOMINFO, string(d))
  82. //有玩家进桌, 更新在线
  83. if !Stopping {
  84. go func() {
  85. frame.UpdateRoomOnline(ts.roomInfo.RoomName, ts.roomInfo.RoomID-1)
  86. }()
  87. }
  88. ts.gameScene.Players[chairId].userID = usr.GetUserId()
  89. ts.gameScene.Players[chairId].isEndToStart = false
  90. // 机器人,100ms后准备
  91. if usr.IsRobot() {
  92. ts.table.SetTimer(TIMER_READY_0+chairId, 100)
  93. }
  94. if !usr.IsRobot() {
  95. ts.table.NotifySceneChanged(chairId)
  96. } else {
  97. ts.gameScene.Players[chairId].robotType = rand.Intn(2)
  98. }
  99. }
  100. func (ts *tablesink) OnUserExitTable(userIndex int32, chairId int) {
  101. //用户离开要判断是否为游戏玩家,不是游戏玩家不做业务逻辑处理
  102. usr := ts.table.GetPlayer(userIndex)
  103. if usr == nil {
  104. ts.table.LogWithTableId("tablesink.OnUserExitTable,usr[%d] not exist", userIndex)
  105. return
  106. }
  107. ts.table.LogWithTableId("tablesink.OnUserExitTable chair[%d]: %d:%s", chairId, usr.GetUserId(), usr.GetUserNickName())
  108. ts.gameScene.Players[chairId].isEndToStart = false
  109. ts.gameScene.Players[chairId].initData(0, 0)
  110. //有玩家离开, 更新在线
  111. if !Stopping {
  112. go func() {
  113. frame.UpdateRoomOnline(ts.roomInfo.RoomName, ts.roomInfo.RoomID-1)
  114. }()
  115. }
  116. if ts.gameScene.Phase == Phase_Free || ts.gameScene.Phase == Phase_End {
  117. ts.table.KillTimer(TIMER_READY_0 + chairId)
  118. if ts.gameScene.Phase != Phase_End {
  119. ts.table.SetTimer(TIMER_ADD_ROBOT, 1000)
  120. }
  121. go ts.checkAndStartGame()
  122. }
  123. }
  124. // 用户离线
  125. func (ts *tablesink) OnUserOffline(chairId int) {
  126. usr := ts.table.GetUserByChair(chairId)
  127. if usr == nil {
  128. ts.table.LogWithTableId("tablesink.OnUserOffline user not exist")
  129. return
  130. }
  131. ts.table.LogWithTableId("tablesink.OnUserOffline %d:%s", usr.GetUserId(), usr.GetUserNickName())
  132. }
  133. // 用户重进
  134. func (ts *tablesink) OnUserReplay(chairId int) {
  135. usr := ts.table.GetUserByChair(chairId)
  136. if usr == nil {
  137. ts.table.LogWithTableId("tablesink.OnUserOffline user not exist")
  138. return
  139. }
  140. ts.table.LogWithTableId("tablesink.OnUserReplay %d:%s", usr.GetUserId(), usr.GetUserNickName())
  141. //下发房间配置
  142. d, _ := json.Marshal(ts.roomInfo.RoomInfoBase)
  143. ts.table.SendGameData(usr.GetUserIndex(), CMD_ROOMINFO, string(d))
  144. ts.gameScene.Players[chairId].AutoOut = false
  145. }
  146. // 准备
  147. func (ts *tablesink) OnUserReady(userIndex int32, chairId int) {
  148. defer utils.TimeCost(fmt.Sprintf("tablesink.OnUserReady %d", userIndex))()
  149. usr := gate.GetUserInfo(userIndex)
  150. if usr == nil {
  151. ts.table.LogWithTableId("tablesink.OnUserReady user not exist")
  152. return
  153. }
  154. userGold := ts.table.GetUserChipOrGoldByUser(usr)
  155. if userGold < ts.roomInfo.MinGold || (ts.roomInfo.MaxGold > 0 && userGold > ts.roomInfo.MaxGold) {
  156. ts.table.LogWithTableId("tablesink.OnUserReady 玩家:%d 金币不足, T出去 ", usr.GetUserId())
  157. ts.table.KickUser(usr.GetUserIndex(), !usr.IsRobot())
  158. return
  159. }
  160. ts.table.LogWithTableId("tablesink.OnUserReady chair[%d]: %d:%s", chairId, usr.GetUserId(), usr.GetUserNickName())
  161. ts.table.KillTimer(TIMER_READY_0 + chairId)
  162. if ts.gameScene.Phase != Phase_End || ts.gameScene.Players[chairId].isEndToStart {
  163. ts.table.SetTimer(TIMER_ADD_ROBOT, 1000)
  164. }
  165. if !usr.IsRobot() && ts.gameScene.Players[chairId].isEndToStart {
  166. ts.table.NotifySceneChanged(chairId)
  167. }
  168. ts.checkAndStartGame()
  169. }
  170. // 取消准备
  171. func (ts *tablesink) OnUserCancelReady(userIndex int32, chairId int) {
  172. usr := gate.GetUserInfo(userIndex)
  173. if usr == nil {
  174. ts.table.LogWithTableId("tablesink.OnUserCancelReady user not exist")
  175. return
  176. }
  177. ts.table.LogWithTableId("tablesink.OnUserCancelReady %d:%s", usr.GetUserId(), usr.GetUserNickName())
  178. }
  179. func (ts *tablesink) OnGetChairScene(chairId int, isPlayer bool) string {
  180. now := time.Now()
  181. ts.gameScene.LeftSec = ts.getSecond(ts.gameScene.Phase)/1000 - int(now.Sub(ts.LastOpraTime).Seconds())
  182. return ts.gameScene.getScene(chairId, isPlayer, false)
  183. }
  184. func (ts *tablesink) OnGetChairCount() int {
  185. return CHAIR_COUNT
  186. }
  187. func (ts *tablesink) OnTimer(timerId int) {
  188. switch timerId {
  189. case TIMER_READY_0:
  190. fallthrough
  191. case TIMER_READY_1:
  192. fallthrough
  193. case TIMER_READY_2:
  194. fallthrough
  195. case TIMER_READY_3:
  196. ts.checkUserReadyStatus(timerId - TIMER_READY_0)
  197. case TIMER_ADD_ROBOT:
  198. ts.checkIsNeedRobot()
  199. case TIMER_START_GAME:
  200. ts.checkStartGame()
  201. case TIMER_GAME:
  202. ts.dealGameTimeOut()
  203. case TIMER_START_ACTION:
  204. ts.dealStartAction()
  205. case TIMER_ROUND_END:
  206. ts.dealRoundEnd()
  207. case TIMER_ROBOT_0:
  208. fallthrough
  209. case TIMER_ROBOT_1:
  210. fallthrough
  211. case TIMER_ROBOT_2:
  212. fallthrough
  213. case TIMER_ROBOT_3:
  214. ts.onTimerRobotAction(timerId - TIMER_ROBOT_0)
  215. case TIMER_REMOVE_ROBOT:
  216. ts.removeOneRobot()
  217. case TIMER_KICK_USER_0:
  218. fallthrough
  219. case TIMER_KICK_USER_1:
  220. fallthrough
  221. case TIMER_KICK_USER_2:
  222. fallthrough
  223. case TIMER_KICK_USER_3:
  224. ts.table.KickUserByChair(timerId-TIMER_KICK_USER_0, true)
  225. }
  226. }
  227. func (ts *tablesink) DumpScene() {
  228. ts.gameScene.dump()
  229. }
  230. func (ts *tablesink) GetGoldLimit() (min, max int) {
  231. return ts.roomInfo.MinGold, ts.roomInfo.MaxGold
  232. }
  233. func (ts *tablesink) IsDual() bool {
  234. return false
  235. }
  236. func (ts *tablesink) IsAllRobot() bool {
  237. return false
  238. }