tablesink_impl.go 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. package gamelogic
  2. import (
  3. "encoding/json"
  4. "math/rand"
  5. "sort"
  6. "time"
  7. robotmanager "bet24.com/servers/insecureframe/robot"
  8. waterpool "bet24.com/servers/micros/waterpool/proto"
  9. "bet24.com/servers/user"
  10. )
  11. func (ts *tablesink) checkAndStartGame() {
  12. if ts.gameScene.Phase != Phase_Free &&
  13. ts.gameScene.Phase != Phase_End {
  14. return
  15. }
  16. // 查看是否所有人都ready
  17. readyCount := 0
  18. for i := 0; i < CHAIR_COUNT; i++ {
  19. usr := ts.table.GetUserByChair(i)
  20. if usr == nil {
  21. continue
  22. }
  23. userStatus := usr.GetUserStatus()
  24. // 旁观不判断
  25. if userStatus <= user.UserStatus_Free ||
  26. userStatus == user.UserStatus_Watch {
  27. continue
  28. }
  29. if usr.GetUserStatus() != user.UserStatus_Ready && userStatus != user.UserStatus_Offline {
  30. ts.table.LogWithTableId("-----checkAndStartGame: chair[%d]: %d, status: %d", i, usr.GetUserId(), usr.GetUserStatus())
  31. return
  32. }
  33. readyCount++
  34. }
  35. ts.table.LogWithTableId("-----checkAndStartGame : %d ", readyCount)
  36. if readyCount >= CHAIR_COUNT {
  37. ts.startGame()
  38. }
  39. }
  40. func (ts *tablesink) checkIsNeedRobot() {
  41. if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
  42. return
  43. }
  44. if ts.roomInfo.RobotCount == 0 {
  45. return
  46. }
  47. if ts.table.IsPrivate() {
  48. return
  49. }
  50. count := 0
  51. for i := 0; i < CHAIR_COUNT; i++ {
  52. usr := ts.table.GetUserByChair(i)
  53. if usr == nil {
  54. continue
  55. }
  56. if usr.GetUserStatus() <= user.UserStatus_Free {
  57. continue
  58. }
  59. count++
  60. }
  61. chairCount := CHAIR_COUNT
  62. if count >= chairCount {
  63. return
  64. }
  65. robotCount := chairCount - count
  66. ts.table.LogWithTableId("-------checkIsNeedRobot. need: %d ------", robotCount)
  67. if robotCount > 0 {
  68. time.AfterFunc(1000*time.Millisecond, func() {
  69. if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
  70. return
  71. }
  72. tableID := ts.table.GetTableID()
  73. robotmanager.GetOneRobotEnterTable(tableID, ts.roomInfo.MinGold, ts.roomInfo.MaxGold)
  74. })
  75. }
  76. }
  77. func (ts *tablesink) removeOneRobot() {
  78. if ts.gameScene.Phase != Phase_End && ts.gameScene.Phase != Phase_Free {
  79. return
  80. }
  81. for i := 0; i < CHAIR_COUNT; i++ {
  82. usr := ts.table.GetUserByChair(i)
  83. if usr == nil {
  84. continue
  85. }
  86. if !usr.IsRobot() {
  87. continue
  88. }
  89. ts.table.KickUserByChair(i, false)
  90. }
  91. }
  92. func (ts *tablesink) checkUserReadyStatus(chair int) {
  93. if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
  94. ts.table.LogWithTableId("tablesink.checkUserReadyStatus status not right %d", ts.gameScene.Phase)
  95. return
  96. }
  97. usr := ts.table.GetUserByChair(chair)
  98. if usr == nil {
  99. ts.table.LogWithTableId("tablesink.checkUserReadyStatus user not exist %d", chair)
  100. return
  101. }
  102. if ts.gameScene.Phase == Phase_End {
  103. ts.table.SetUserReadyStatus(usr.GetUserIndex(), true)
  104. return
  105. }
  106. if !usr.IsRobot() {
  107. ts.table.LogWithTableId("tablesink.checkUserReadyStatus kicking [%d]: %d ", chair, usr.GetUserId())
  108. ts.table.UserWatch(usr.GetUserIndex())
  109. return
  110. }
  111. //桌上还有没有真人,有就准备,没有就踢走
  112. count := 0
  113. for i := 0; i < CHAIR_COUNT; i++ {
  114. u := ts.table.GetUserByChair(i)
  115. if u == nil {
  116. continue
  117. }
  118. if u.IsRobot() {
  119. continue
  120. }
  121. if u.GetUserStatus() <= user.UserStatus_Free {
  122. continue
  123. }
  124. count++
  125. }
  126. if count >= 1 {
  127. ts.table.SetUserReadyStatus(usr.GetUserIndex(), true)
  128. } else {
  129. ts.table.LogWithTableId("tablesink.checkUserReadyStatus: %d ", usr.GetUserId())
  130. if usr.IsRobot() {
  131. ts.table.KickUser(usr.GetUserIndex(), false)
  132. } else {
  133. ts.table.UserWatch(usr.GetUserIndex())
  134. }
  135. }
  136. }
  137. func (ts *tablesink) getSecond(phase int) int {
  138. ret := 0
  139. switch phase {
  140. case Phase_Free:
  141. ret = ts.roomInfo.SecFree
  142. case Phase_JackPot:
  143. ret = ts.roomInfo.SecJackPot
  144. case Phase_SendCard:
  145. ret = ts.roomInfo.SecSendCard
  146. case Phase_RobBanker:
  147. ret = ts.roomInfo.SecRobBanker
  148. case Phase_ConfirmBanker:
  149. ret = ts.roomInfo.SecConfirmBanker
  150. case Phase_Action:
  151. ret = ts.roomInfo.SecAction
  152. case Phase_CompareCard:
  153. ret = ts.roomInfo.SecCompareCard
  154. case Phase_RoundEnd:
  155. ret = ts.roomInfo.SecRoundEnd
  156. case Phase_End:
  157. ret = ts.roomInfo.SecEnd
  158. }
  159. if ret < 100 {
  160. ret *= 1000
  161. }
  162. return ret
  163. }
  164. func (ts *tablesink) recvCancleAutoMsg(userIndex int32, data string) {
  165. usr := ts.table.GetPlayer(userIndex)
  166. if usr == nil {
  167. ts.table.LogWithTableId("tablesink.recvCancleAutoMsg,user[%d] not exist", userIndex)
  168. return
  169. }
  170. chairId := usr.GetUserChairId()
  171. if chairId == -1 {
  172. return
  173. }
  174. if !ts.gameScene.Players[chairId].AutoOut {
  175. return
  176. }
  177. ts.gameScene.Players[chairId].AutoOut = false
  178. // 重启倒计时
  179. if ts.gameScene.WhoseTurn != chairId {
  180. return
  181. }
  182. if ts.gameScene.Phase == Phase_RobBanker || ts.gameScene.Phase == Phase_Action {
  183. ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
  184. }
  185. }
  186. func (ts *tablesink) recvAutoMsg(userIndex int32, data string) {
  187. usr := ts.table.GetPlayer(userIndex)
  188. if usr == nil {
  189. ts.table.LogWithTableId("tablesink.recvAutoMsg,user[%d] not exist", userIndex)
  190. return
  191. }
  192. chairId := usr.GetUserChairId()
  193. if chairId == -1 {
  194. return
  195. }
  196. ts.gameScene.Players[chairId].AutoOut = true
  197. // 重启倒计时
  198. if ts.gameScene.WhoseTurn != chairId {
  199. return
  200. }
  201. if ts.gameScene.Phase == Phase_RobBanker || ts.gameScene.Phase == Phase_Action {
  202. ts.table.SetTimer(TIMER_GAME, SEC_AUTO)
  203. }
  204. }
  205. func (ts *tablesink) killAutoTimer() {
  206. for i := 0; i < CHAIR_COUNT; i++ {
  207. ts.table.KillTimer(TIMER_AUTO_ACTION_0 + i)
  208. }
  209. }
  210. func (ts *tablesink) canStartGame(needCost bool) bool {
  211. count := 0
  212. for i := 0; i < CHAIR_COUNT; i++ {
  213. usr := ts.table.GetUserByChair(i)
  214. if usr == nil {
  215. break
  216. }
  217. userStatus := usr.GetUserStatus()
  218. if userStatus != user.UserStatus_Ready && userStatus != user.UserStatus_Offline {
  219. ts.table.LogWithTableId("ts.startGame chair[%d] userStatue = %d", i, userStatus)
  220. break
  221. }
  222. if !needCost {
  223. count++
  224. continue
  225. }
  226. userGold := ts.table.GetUserChipOrGoldByUser(usr)
  227. if userGold < ts.roomInfo.MinGold || (ts.roomInfo.MaxGold > 0 && userGold > ts.roomInfo.MaxGold) {
  228. ts.table.LogWithTableId("tablesink.startGame %d 金币不足,站起", usr.GetUserId())
  229. if usr.IsRobot() {
  230. go ts.table.KickUser(usr.GetUserIndex(), false)
  231. } else {
  232. go ts.table.UserWatch(usr.GetUserIndex())
  233. }
  234. break
  235. }
  236. // 先投注
  237. ok := ts.writeScore(usr.GetUserId(), -ts.roomInfo.BaseScore, 0, 0, ScoreType_Bet, ts.roomInfo.RoomName, usr.IsRobot())
  238. if !ok {
  239. break
  240. }
  241. ts.gameScene.Players[i].initData(usr.GetUserId(), ts.roomInfo.InitScore)
  242. ts.gameScene.Players[i].IsValid = true
  243. ts.gameScene.Players[i].userID = usr.GetUserId()
  244. ts.gameScene.Players[i].isRobot = usr.IsRobot()
  245. count++
  246. }
  247. if count < CHAIR_COUNT {
  248. ts.table.LogWithTableId("游戏开始,用户不足")
  249. if !needCost {
  250. return false
  251. }
  252. ts.gameScene.Phase = Phase_End
  253. ts.gameScene.PhaseIndex = 0
  254. // 分数还原
  255. for i := 0; i < CHAIR_COUNT; i++ {
  256. if !ts.gameScene.Players[i].IsValid {
  257. continue
  258. }
  259. ts.writeScore(ts.gameScene.Players[i].userID, ts.roomInfo.BaseScore, 0, 0,
  260. ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
  261. }
  262. if ts.table.IsPrivate() {
  263. ts.table.PrivateRoomSetWinners([]int{})
  264. }
  265. ts.endGame()
  266. ts.gameScene.initData(ts.table.GetTableID())
  267. return false
  268. }
  269. return true
  270. }
  271. func (ts *tablesink) startGame() {
  272. ts.gameScene.initData(ts.table.GetTableID())
  273. if ts.canStartGame(true) {
  274. ts.table.SetTimer(TIMER_START_GAME, SEC_DELAY)
  275. }
  276. }
  277. func (ts *tablesink) checkStartGame() {
  278. if !ts.canStartGame(false) {
  279. return
  280. }
  281. ts.startJackPot()
  282. ts.table.StartGame()
  283. ts.table.LogWithTableId("tablesink.gameStart[%d]", ts.table.GetTableID())
  284. }
  285. func (ts *tablesink) startJackPot() {
  286. value := waterpool.GetInventoryValue(GAMEID, waterpool.RoomType_Normal, ts.roomInfo.RoomName)
  287. ts.gameScene.Phase = Phase_JackPot
  288. ts.gameScene.JackPotAmount = ts.roomInfo.GetJackpotAmount(value)
  289. ts.gameScene.dump()
  290. ts.resetGameTimer()
  291. }
  292. func (ts *tablesink) gameStart() {
  293. // 发牌
  294. ts.logic.shuffle()
  295. for i := 0; i < CHAIR_COUNT; i++ {
  296. usr := ts.table.GetUserByChair(i)
  297. if usr == nil {
  298. continue
  299. }
  300. userStatus := usr.GetUserStatus()
  301. if userStatus <= user.UserStatus_Free ||
  302. userStatus == user.UserStatus_Watch {
  303. continue
  304. }
  305. if !ts.gameScene.Players[i].IsValid || ts.gameScene.Players[i].Score <= 0 {
  306. continue
  307. }
  308. ts.gameScene.Players[i].Status = Player_Status_Play
  309. ts.gameScene.Players[i].HandCards = ts.logic.getHandCards()
  310. sort.Slice(ts.gameScene.Players[i].HandCards, func(m, n int) bool {
  311. if getCardValue(ts.gameScene.Players[i].HandCards[m]) > getCardValue(ts.gameScene.Players[i].HandCards[n]) {
  312. return true
  313. } else if getCardValue(ts.gameScene.Players[i].HandCards[m]) == getCardValue(ts.gameScene.Players[i].HandCards[n]) {
  314. return getCardType(ts.gameScene.Players[i].HandCards[m]) > getCardType(ts.gameScene.Players[i].HandCards[n])
  315. }
  316. return false
  317. })
  318. ts.gameScene.Players[i].CardType = getHandCardType(ts.gameScene.Players[i].HandCards)
  319. }
  320. ts.gameScene.Phase = Phase_SendCard
  321. ts.gameScene.PhaseIndex = 0
  322. ts.gameScene.LastTurn = -1
  323. ts.gameScene.Index++
  324. ts.LastOpraTime = time.Now()
  325. ts.table.NotifySceneChanged(-1)
  326. ts.resetGameTimer()
  327. }
  328. func (ts *tablesink) dealGamePlay() {
  329. ts.table.LogWithTableId("------dealGamePlay -----")
  330. ts.gameScene.Phase = Phase_RobBanker
  331. ts.gameScene.PhaseIndex = 0
  332. ts.gameScene.WhoseTurn = ts.gameScene.FirstActionPlayer
  333. ts.gameScene.CurrentMinRobScore = ts.roomInfo.MinRobBankerScore
  334. ts.gameScene.Index++
  335. ts.LastOpraTime = time.Now()
  336. ts.table.NotifySceneChanged(-1)
  337. ts.resetGameTimer()
  338. }
  339. func (ts *tablesink) dealConfirmBanker() {
  340. ts.table.LogWithTableId("------dealConfirmBanker -----")
  341. ts.gameScene.PhaseIndex = 0
  342. ts.gameScene.confirmBanker()
  343. ts.gameScene.Index++
  344. ts.LastOpraTime = time.Now()
  345. ts.table.NotifySceneChanged(-1)
  346. ts.table.SetTimer(TIMER_START_ACTION, SEC_START_ACTION)
  347. }
  348. func (ts *tablesink) dealStartAction() {
  349. ts.gameScene.Phase = Phase_Action
  350. ts.gameScene.PhaseIndex = 0
  351. ts.gameScene.ActionPhase = ActionPhase_Banker_GiveMoney
  352. ts.gameScene.CurrentActionPlayer = -1
  353. ts.gameScene.LastTurn = -1
  354. ts.gameScene.Index++
  355. ts.LastOpraTime = time.Now()
  356. ts.table.NotifySceneChanged(-1)
  357. ts.resetGameTimer()
  358. }
  359. func (ts *tablesink) dealCompareCard() {
  360. ts.gameScene.PhaseIndex = 0
  361. ts.gameScene.Index++
  362. ts.gameScene.compareCard()
  363. ts.gameScene.roundEnd()
  364. ts.gameScene.isNeedCalc = false
  365. ts.LastOpraTime = time.Now()
  366. ts.table.NotifySceneChanged(-1)
  367. ts.table.SetTimer(TIMER_ROUND_END, SEC_COMPARE_TO_ROUND_END)
  368. }
  369. func (ts *tablesink) dealRoundEnd() {
  370. ts.gameScene.Phase = Phase_RoundEnd
  371. if ts.gameScene.isNeedCalc {
  372. ts.gameScene.roundEnd()
  373. }
  374. ts.gameScene.PhaseIndex = 0
  375. ts.gameScene.Index++
  376. ts.LastOpraTime = time.Now()
  377. ts.table.NotifySceneChanged(-1)
  378. ts.resetGameTimer()
  379. for i := 0; i < CHAIR_COUNT; i++ {
  380. if !ts.gameScene.Players[i].IsValid {
  381. continue
  382. }
  383. if ts.gameScene.Players[i].ChangeScore > 0 && ts.roomInfo.LevelParam >= 100 {
  384. value := ts.roomInfo.LevelParam * ts.gameScene.Players[i].ChangeScore / 10000
  385. value = ts.table.AddExperience(ts.gameScene.Players[i].userID, value)
  386. ts.gameScene.Players[i].Experience += value
  387. }
  388. if ts.gameScene.Players[i].Score == 0 {
  389. usr := ts.table.GetPlayerByUserId(ts.gameScene.Players[i].userID)
  390. usr.SetUserStatus(Player_Status_Free)
  391. ts.table.SetTimer(TIMER_KICK_USER_0+i, SEC_KICK_USER)
  392. }
  393. }
  394. }
  395. func (ts *tablesink) dealGameTimeOut() {
  396. if ts.gameScene.Phase == Phase_End {
  397. return
  398. }
  399. switch ts.gameScene.Phase {
  400. case Phase_JackPot:
  401. first := rand.Intn(CHAIR_COUNT)
  402. ts.gameScene.gameInit(first)
  403. ts.gameStart()
  404. return
  405. case Phase_SendCard:
  406. ts.dealGamePlay()
  407. return
  408. case Phase_RobBanker:
  409. if !isValidChair(ts.gameScene.WhoseTurn) {
  410. ts.table.LogWithTableId("tablesink.dealGameTimeOut invalid whoseturn")
  411. return
  412. }
  413. if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
  414. ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
  415. }
  416. ts.dealRobBanker(ts.gameScene.WhoseTurn, 0)
  417. return
  418. case Phase_ConfirmBanker:
  419. ts.dealConfirmBanker()
  420. return
  421. case Phase_Action:
  422. if !isValidChair(ts.gameScene.WhoseTurn) {
  423. ts.table.LogWithTableId("tablesink.dealGameTimeOut invalid whoseturn")
  424. return
  425. }
  426. if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
  427. ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
  428. }
  429. action := 0
  430. switch ts.gameScene.ActionPhase {
  431. case ActionPhase_Banker_GiveMoney:
  432. action = Action_Banker_CompareCardDirect
  433. case ActionPhase_Player_Reply:
  434. action = Action_Player_CompareCard
  435. case ActionPhase_Banker_Reply:
  436. action = Action_Banker_DisAgree
  437. }
  438. ts.dealAction(ts.gameScene.WhoseTurn, action, 0)
  439. return
  440. case Phase_CompareCard:
  441. ts.dealCompareCard()
  442. return
  443. case Phase_RoundEnd:
  444. if ts.gameScene.nextGame(ts.roomInfo.WinScore) {
  445. if len(ts.gameScene.RoundWinner) > 0 {
  446. ts.gameScene.gameInit(ts.gameScene.RoundWinner[0])
  447. } else {
  448. if ts.gameScene.FirstActionPlayer == -1 {
  449. first := rand.Intn(CHAIR_COUNT)
  450. ts.gameScene.gameInit(first)
  451. } else {
  452. ts.gameScene.gameInit(getPreviousChair(ts.gameScene.FirstActionPlayer))
  453. }
  454. }
  455. ts.gameStart()
  456. } else {
  457. ts.enterEndPhase()
  458. }
  459. return
  460. }
  461. ts.table.LogWithTableId("tablesink.dealGameTimeOut unreachable")
  462. }
  463. func (ts *tablesink) resetGameTimer() {
  464. ts.killAutoTimer()
  465. switch ts.gameScene.Phase {
  466. case Phase_JackPot:
  467. fallthrough
  468. case Phase_SendCard:
  469. fallthrough
  470. case Phase_ConfirmBanker:
  471. fallthrough
  472. case Phase_CompareCard:
  473. fallthrough
  474. case Phase_RoundEnd:
  475. ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
  476. default:
  477. if !isValidChair(ts.gameScene.WhoseTurn) {
  478. return
  479. }
  480. chairId := ts.gameScene.WhoseTurn
  481. usr := ts.table.GetUserByChair(chairId)
  482. if usr == nil {
  483. ts.table.LogWithTableId("resetGameTimer Phase:%d ChairId:%d nnot exist", ts.gameScene.Phase, chairId)
  484. ts.gameScene.Phase = Phase_End
  485. ts.gameScene.PhaseIndex = 0
  486. // 分数还原
  487. for i := 0; i < CHAIR_COUNT; i++ {
  488. if !ts.gameScene.Players[i].IsValid {
  489. continue
  490. }
  491. ts.writeScore(ts.gameScene.Players[i].userID, ts.roomInfo.BaseScore, 0, 0,
  492. ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
  493. }
  494. if ts.table.IsPrivate() {
  495. ts.table.PrivateRoomSetWinners([]int{})
  496. }
  497. ts.endGame()
  498. ts.gameScene.initData(ts.table.GetTableID())
  499. return
  500. }
  501. if (ts.gameScene.Players[chairId].AutoOut || usr.GetUserStatus() == user.UserStatus_Offline) && !usr.IsRobot() {
  502. ts.table.SetTimer(TIMER_GAME, SEC_AUTO)
  503. } else {
  504. ts.table.SetTimer(TIMER_GAME, ts.getSecond(ts.gameScene.Phase))
  505. }
  506. }
  507. ts.checkRobotAction()
  508. }
  509. func (ts *tablesink) recvAction(userIndex int32, data string) bool {
  510. usr := ts.table.GetPlayer(userIndex)
  511. if usr == nil {
  512. ts.table.LogWithTableId("tablesink.recvAction,user[%d] not exist", userIndex)
  513. return false
  514. }
  515. chairId := usr.GetUserChairId()
  516. if !isValidChair(chairId) {
  517. ts.table.LogWithTableId("tablesink.recvAction invalid chair %d", chairId)
  518. return false
  519. }
  520. ts.gameScene.Players[chairId].AutoOut = false
  521. if !ts.gameScene.Players[chairId].IsValid {
  522. ts.table.LogWithTableId("tablesink.recvAction invalid player [%d]", chairId)
  523. return false
  524. }
  525. var cmd CmdAction
  526. e := json.Unmarshal([]byte(data), &cmd)
  527. if e != nil {
  528. ts.table.LogWithTableId("tablesink.recvAction Unmarshal failed %s", data)
  529. return false
  530. }
  531. ts.table.KillTimer(TIMER_GAME)
  532. ret := false
  533. errMsg := ""
  534. switch cmd.Action {
  535. case Action_RobBanker:
  536. ret, errMsg = ts.dealRobBanker(chairId, cmd.Param)
  537. case Action_Banker_GiveMoney:
  538. fallthrough
  539. case Action_Banker_CompareCardDirect:
  540. fallthrough
  541. case Action_Player_CompareCard:
  542. fallthrough
  543. case Action_Player_Agree:
  544. fallthrough
  545. case Action_Player_AddMoney:
  546. fallthrough
  547. case Action_Banker_Agree:
  548. fallthrough
  549. case Action_Banker_DisAgree:
  550. ret, errMsg = ts.dealAction(chairId, cmd.Action, cmd.Param)
  551. }
  552. if !ret {
  553. var cmdFailed CmdActionFailed
  554. cmdFailed.CmdAction = cmd
  555. cmdFailed.ErrMsg = errMsg
  556. d, _ := json.Marshal(cmdFailed)
  557. ts.table.SendGameData(userIndex, CMD_ACTION_FAILED, string(d))
  558. }
  559. return ret
  560. }
  561. func (ts *tablesink) dealRobBanker(chairId, amount int) (bool, string) {
  562. if chairId != ts.gameScene.WhoseTurn {
  563. return false, "Not WhoseTurn"
  564. }
  565. usr := ts.table.GetUserByChair(chairId)
  566. if usr == nil {
  567. return false, "User Not Exist"
  568. }
  569. p := ts.gameScene.Players[chairId]
  570. if !p.IsValid || p.Status != Player_Status_Play {
  571. return false, "Invaild Player"
  572. }
  573. if amount > 0 && amount < ts.gameScene.CurrentMinRobScore &&
  574. p.Score > ts.gameScene.CurrentMinRobScore {
  575. return false, "Invaild Amount"
  576. }
  577. if amount > ts.roomInfo.InitScore {
  578. return false, "Invaild Amount"
  579. }
  580. if amount >= ts.gameScene.CurrentMinRobScore {
  581. ts.gameScene.CurrentMinRobScore = amount
  582. ts.gameScene.CurrentMinRobScore += ts.roomInfo.MinRobBankerScore
  583. if ts.gameScene.CurrentMinRobScore > ts.roomInfo.InitScore {
  584. ts.gameScene.CurrentMinRobScore = ts.roomInfo.InitScore
  585. }
  586. }
  587. ts.gameScene.Players[chairId].RobScore = amount
  588. ts.gameScene.Players[chairId].Score -= amount
  589. if amount == 0 {
  590. ts.gameScene.Players[chairId].Status = Player_Status_GiveUp
  591. }
  592. if ts.gameScene.Players[chairId].Score == 0 || amount == ts.roomInfo.InitScore {
  593. ts.gameScene.Players[chairId].Status = Player_Status_AllIn
  594. }
  595. ts.gameScene.PhaseIndex++
  596. ts.gameScene.Index++
  597. ts.gameScene.addUserAction(chairId, Action_RobBanker, amount)
  598. if getPreviousChair(ts.gameScene.WhoseTurn) != ts.gameScene.FirstActionPlayer {
  599. ts.gameScene.nextChair()
  600. } else {
  601. ts.gameScene.LastTurn = ts.gameScene.WhoseTurn
  602. ts.gameScene.WhoseTurn = -1
  603. }
  604. ts.gameScene.Players[chairId].setLastData(Action_RobBanker, amount)
  605. ts.LastOpraTime = time.Now()
  606. ts.table.NotifySceneChanged(-1)
  607. if ts.gameScene.isBelowOneRobBanker() {
  608. ts.table.SetTimer(TIMER_ROUND_END, SEC_ROBBANKER_TO_ROUND_END)
  609. return true, ""
  610. }
  611. if ts.gameScene.isAllDoRobBanker() {
  612. ts.gameScene.Phase = Phase_ConfirmBanker
  613. }
  614. ts.resetGameTimer()
  615. return true, ""
  616. }
  617. func (ts *tablesink) dealAction(chairId int, action, param int) (bool, string) {
  618. if chairId != ts.gameScene.WhoseTurn {
  619. return false, "Not WhoseTurn"
  620. }
  621. usr := ts.table.GetUserByChair(chairId)
  622. if usr == nil {
  623. return false, "User Not Exist"
  624. }
  625. p := ts.gameScene.Players[chairId]
  626. if !p.IsValid || (p.Status != Player_Status_Play && p.Status != Player_Status_AllIn) {
  627. return false, "Invaild Player"
  628. }
  629. isActionOver := false
  630. switch ts.gameScene.ActionPhase {
  631. case ActionPhase_Banker_GiveMoney:
  632. if param != 0 {
  633. if param < ts.roomInfo.MinBankerGiveScore || param > ts.gameScene.Players[chairId].RobScore {
  634. return false, "Over RobScore"
  635. }
  636. }
  637. if ts.gameScene.Players[ts.gameScene.Banker].RobScore == 0 {
  638. return false, "Score=0"
  639. }
  640. ts.gameScene.CurrentTradeAmount = param
  641. ts.gameScene.nextActionChair()
  642. if param == 0 {
  643. ts.gameScene.Players[ts.gameScene.CurrentActionPlayer].Status = Player_Status_CompareCard
  644. ts.gameScene.ActionPhase = ActionPhase_Banker_GiveMoney
  645. if ts.gameScene.isActionOver() {
  646. isActionOver = true
  647. } else {
  648. ts.gameScene.WhoseTurn = ts.gameScene.Banker
  649. }
  650. } else {
  651. ts.gameScene.ActionPhase = ActionPhase_Player_Reply
  652. }
  653. case ActionPhase_Player_Reply:
  654. if ts.gameScene.Players[ts.gameScene.Banker].RobScore == 0 {
  655. return false, "Score=0"
  656. }
  657. if param == 1 {
  658. ts.gameScene.Players[chairId].Score += ts.gameScene.Players[chairId].RobScore + ts.gameScene.CurrentTradeAmount
  659. ts.gameScene.Players[ts.gameScene.Banker].RobScore -= ts.gameScene.CurrentTradeAmount
  660. ts.gameScene.CurrentTradeAmount = 0
  661. ts.gameScene.Players[chairId].RobScore = 0
  662. ts.gameScene.ActionPhase = ActionPhase_Banker_GiveMoney
  663. ts.gameScene.Players[chairId].Status = Player_Status_GiveUp
  664. if ts.gameScene.isActionOver() {
  665. isActionOver = true
  666. }
  667. } else if param == 0 {
  668. ts.gameScene.CurrentTradeAmount = 0
  669. ts.gameScene.ActionPhase = ActionPhase_Banker_GiveMoney
  670. ts.gameScene.Players[chairId].Status = Player_Status_CompareCard
  671. if ts.gameScene.isActionOver() {
  672. isActionOver = true
  673. }
  674. } else {
  675. if param < ts.gameScene.CurrentTradeAmount ||
  676. param > (ts.gameScene.Players[ts.gameScene.Banker].RobScore+ts.gameScene.CurrentTradeAmount) {
  677. return false, "Over RobScore"
  678. }
  679. ts.gameScene.CurrentTradeAmount = param
  680. ts.gameScene.ActionPhase = ActionPhase_Banker_Reply
  681. }
  682. ts.gameScene.LastTurn = chairId
  683. ts.gameScene.WhoseTurn = ts.gameScene.Banker
  684. case ActionPhase_Banker_Reply:
  685. if param == 1 {
  686. if ts.gameScene.Players[ts.gameScene.Banker].RobScore == 0 {
  687. return false, "Score=0"
  688. }
  689. chair := ts.gameScene.CurrentActionPlayer
  690. ts.gameScene.Players[chair].Score += ts.gameScene.Players[chair].RobScore + ts.gameScene.CurrentTradeAmount
  691. ts.gameScene.Players[ts.gameScene.Banker].RobScore -= ts.gameScene.CurrentTradeAmount
  692. ts.gameScene.CurrentTradeAmount = 0
  693. ts.gameScene.Players[chair].RobScore = 0
  694. ts.gameScene.Players[chair].Status = Player_Status_GiveUp
  695. } else {
  696. ts.gameScene.CurrentTradeAmount = 0
  697. ts.gameScene.Players[ts.gameScene.CurrentActionPlayer].Status = Player_Status_CompareCard
  698. }
  699. if ts.gameScene.isActionOver() {
  700. isActionOver = true
  701. } else {
  702. ts.gameScene.ActionPhase = ActionPhase_Banker_GiveMoney
  703. }
  704. ts.gameScene.LastTurn = chairId
  705. ts.gameScene.WhoseTurn = ts.gameScene.Banker
  706. }
  707. if isActionOver {
  708. ts.gameScene.WhoseTurn = -1
  709. }
  710. ts.gameScene.PhaseIndex++
  711. ts.gameScene.Index++
  712. ts.gameScene.addUserAction(chairId, action, param)
  713. ts.gameScene.Players[chairId].setLastData(action, param)
  714. ts.LastOpraTime = time.Now()
  715. ts.table.NotifySceneChanged(-1)
  716. if isActionOver {
  717. if ts.gameScene.isNoNeedCompare() {
  718. ts.table.SetTimer(TIMER_ROUND_END, SEC_ACTION_TO_ROUND_END)
  719. return true, ""
  720. } else {
  721. ts.gameScene.Phase = Phase_CompareCard
  722. }
  723. }
  724. ts.resetGameTimer()
  725. return true, ""
  726. }
  727. func (ts *tablesink) enterEndPhase() {
  728. // 结算
  729. winner := ts.gameScene.getWinner()
  730. ts.table.LogWithTableId("tablesink.enterEndPhase getWinners:%d", winner)
  731. // 写分
  732. for i := 0; i < CHAIR_COUNT; i++ {
  733. p := &ts.gameScene.Players[i]
  734. usr := ts.table.GetUserByChair(i)
  735. if !p.IsValid || usr == nil {
  736. continue
  737. }
  738. p.EndScore = p.Score
  739. score := 0
  740. if i == winner {
  741. score = ts.gameScene.JackPotAmount
  742. ts.writeScore(p.userID, ts.gameScene.JackPotAmount, 0, 0, ScoreType_End, ts.roomInfo.RoomName, p.isRobot)
  743. }
  744. if !p.isRobot {
  745. waterpool.ReduceInventoryValue(GAMEID, ts.roomInfo.RoomName, score-ts.roomInfo.BaseScore, waterpool.RoomType_Normal)
  746. }
  747. // 写记录
  748. if ts.table.IsPrivate() {
  749. } else {
  750. go ts.table.WriteBetRecordWithSetcount(p.userID, ts.roomInfo.InitScore, score, 1.0, "normal", "",
  751. ts.roomInfo.RoomName, ts.gameScene.GameIndex)
  752. }
  753. }
  754. ts.gameScene.Phase = Phase_End
  755. ts.LastOpraTime = time.Now()
  756. ts.table.NotifySceneChanged(-1)
  757. if ts.table.IsPrivate() {
  758. list := []int{}
  759. list = append(list, winner)
  760. ts.table.PrivateRoomSetWinners(list)
  761. }
  762. ts.endGame()
  763. ts.gameScene.initData(ts.table.GetTableID())
  764. }
  765. func (ts *tablesink) endGame() {
  766. ts.table.LogWithTableId("--------endGame-----------")
  767. ts.gameScene.dump()
  768. ts.table.KillAllTimer()
  769. ts.table.EndGame()
  770. robotCount := 0
  771. for i := 0; i < CHAIR_COUNT; i++ {
  772. usr := ts.table.GetUserByChair(i)
  773. if usr == nil {
  774. continue
  775. }
  776. if !usr.IsRobot() {
  777. ts.table.SetTimer(TIMER_READY_0+i, SEC_READY)
  778. ts.gameScene.Players[i].isEndToStart = true
  779. } else {
  780. robotCount++
  781. }
  782. }
  783. if robotCount > 0 {
  784. ts.table.SetTimer(TIMER_REMOVE_ROBOT, 1000+rand.Intn(1000))
  785. }
  786. }
  787. // 聊天
  788. func (ts *tablesink) recvChatMsg(userIndex int32, data string) {
  789. usr := ts.table.GetPlayer(userIndex)
  790. if usr == nil {
  791. ts.table.LogWithTableId("tablesink.recvChatMsg,usr[%d] not exist", userIndex)
  792. return
  793. }
  794. ts.table.SendGameData(-1, CMD_TABLECHAT, data)
  795. }
  796. func (ts *tablesink) writeScore(userId int, amount, tax int, status, scoreType int, sourceName string, isRobot bool) bool {
  797. ok, _ := ts.table.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName)
  798. if ok && !isRobot {
  799. waterpool.ReduceInventoryValue(GAMEID, ts.roomInfo.RoomName, amount, waterpool.RoomType_Normal)
  800. }
  801. return ok
  802. }
  803. func (ts *tablesink) checkRobotAction() {
  804. if ts.gameScene.Phase != Phase_Action && ts.gameScene.Phase != Phase_RobBanker {
  805. return
  806. }
  807. if !ts.gameScene.Players[ts.gameScene.WhoseTurn].isRobot {
  808. return
  809. }
  810. sec := ts.roomInfo.MinActionSec + rand.Intn(ts.roomInfo.MaxActionSec-ts.roomInfo.MinActionSec)
  811. ts.table.SetTimer(TIMER_ROBOT_0+ts.gameScene.WhoseTurn, sec)
  812. }
  813. func (ts *tablesink) getEventType(chairId int) int {
  814. if chairId == ts.gameScene.FirstActionPlayer {
  815. return 1
  816. }
  817. score := 0
  818. isFisrtAction := false
  819. for i := 0; i < CHAIR_COUNT; i++ {
  820. chair := (ts.gameScene.FirstActionPlayer + CHAIR_COUNT - i) % CHAIR_COUNT
  821. if chair == chairId && score == 0 {
  822. isFisrtAction = true
  823. break
  824. }
  825. if ts.gameScene.Players[chair].Status == Player_Status_AllIn {
  826. return 2
  827. }
  828. if ts.gameScene.Players[chair].RobScore > 0 {
  829. if score < ts.gameScene.Players[chair].RobScore {
  830. score = ts.gameScene.Players[chair].RobScore
  831. }
  832. }
  833. }
  834. if isFisrtAction {
  835. return 1
  836. }
  837. if score < ts.roomInfo.InitScore {
  838. return 0
  839. }
  840. return -1
  841. }
  842. func (ts *tablesink) onTimerRobotAction(chairId int) {
  843. if chairId != ts.gameScene.WhoseTurn {
  844. return
  845. }
  846. if ts.gameScene.Phase == Phase_RobBanker {
  847. score := 0
  848. limit := ts.gameScene.Players[chairId].Score
  849. eventType := ts.getEventType(chairId)
  850. if ts.gameScene.Players[chairId].CardType <= CardType_DoublePair {
  851. if ts.gameScene.Players[chairId].robotType == 1 {
  852. if eventType == 1 {
  853. if limit > 2100 {
  854. time := (limit - 2000) / ts.roomInfo.MinRobBankerDifferScore
  855. score = 2000 + rand.Intn(time)*ts.roomInfo.MinRobBankerDifferScore
  856. } else {
  857. score = limit
  858. }
  859. } else if eventType == 0 {
  860. if limit <= ts.gameScene.CurrentMinRobScore {
  861. score = limit
  862. } else {
  863. score = ts.gameScene.CurrentMinRobScore
  864. }
  865. }
  866. } else {
  867. if eventType == 1 {
  868. if limit > ts.roomInfo.MinRobBankerScore {
  869. score = ts.roomInfo.MinRobBankerScore
  870. } else {
  871. score = limit
  872. }
  873. }
  874. }
  875. } else {
  876. if ts.gameScene.Players[chairId].robotType == 1 {
  877. if eventType == 1 {
  878. if limit > 2100 {
  879. time := (limit - 2000) / ts.roomInfo.MinRobBankerDifferScore
  880. score = 2000 + rand.Intn(time)*ts.roomInfo.MinRobBankerDifferScore
  881. } else {
  882. score = limit
  883. }
  884. } else if eventType == 0 || eventType == 2 {
  885. if limit <= ts.gameScene.CurrentMinRobScore {
  886. score = limit
  887. } else {
  888. score = ts.gameScene.CurrentMinRobScore
  889. }
  890. }
  891. } else {
  892. if eventType == 1 {
  893. score = limit
  894. } else if eventType == 0 {
  895. if limit <= ts.gameScene.CurrentMinRobScore {
  896. score = limit
  897. } else {
  898. score = ts.gameScene.CurrentMinRobScore
  899. }
  900. }
  901. }
  902. }
  903. if score > ts.roomInfo.InitScore {
  904. score = ts.roomInfo.InitScore
  905. }
  906. ts.dealRobBanker(chairId, score)
  907. } else {
  908. data := 0
  909. action := 0
  910. switch ts.gameScene.ActionPhase {
  911. case ActionPhase_Banker_GiveMoney:
  912. data = ts.roomInfo.MinBankerGiveScore
  913. action = Action_Banker_GiveMoney
  914. case ActionPhase_Player_Reply:
  915. if ts.gameScene.Players[chairId].CardType <= CardType_DoublePair {
  916. action = Action_Player_Agree
  917. data = 1
  918. } else {
  919. if ts.gameScene.Players[chairId].robotType == 1 {
  920. action = Action_Player_CompareCard
  921. data = 0
  922. } else {
  923. if ts.gameScene.CurrentTradeAmount >= ts.gameScene.Players[ts.gameScene.Banker].RobScore/2 {
  924. action = Action_Player_CompareCard
  925. data = 0
  926. } else {
  927. c := ts.gameScene.Players[ts.gameScene.Banker].RobScore / 2 / ts.roomInfo.BetLevel
  928. if c <= 1 {
  929. data = (c + 1) * ts.roomInfo.BetLevel
  930. action = Action_Player_AddMoney
  931. } else {
  932. r := rand.Intn(c)
  933. data = (ts.gameScene.Players[ts.gameScene.Banker].RobScore/2/ts.roomInfo.BetLevel + r) * ts.roomInfo.BetLevel
  934. action = Action_Player_AddMoney
  935. }
  936. }
  937. }
  938. }
  939. case ActionPhase_Banker_Reply:
  940. if ts.gameScene.Players[chairId].robotType == 1 {
  941. action = Action_Banker_DisAgree
  942. data = 0
  943. } else {
  944. if ts.gameScene.CurrentTradeAmount <= ts.gameScene.Players[ts.gameScene.Banker].RobScore/2 {
  945. data = 1
  946. action = Action_Banker_Agree
  947. } else {
  948. action = Action_Banker_DisAgree
  949. data = 0
  950. }
  951. }
  952. }
  953. ts.dealAction(chairId, action, data)
  954. }
  955. }