qznn.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. package game
  2. //这里处理房间状态的变化
  3. type QZNNStatus int
  4. type QznnRoundUserStatus int
  5. const (
  6. QZNNStatusInit QZNNStatus = 1 //等待有2位准备好
  7. QZNNStatusWait QZNNStatus = 2 //等待加入,此时不能退出
  8. QZNNStatusChooseMaster QZNNStatus = 3 //选择坐庄完成
  9. QZNNStatusChooseMul QZNNStatus = 4 //选择倍数完成
  10. QZNNStatusCal QZNNStatus = 5 //结算完,进入初始化状态
  11. QznnRoundUserStatusWait QznnRoundUserStatus = 1 //等待选庄
  12. QznnRoundUserStatusWaitMul QznnRoundUserStatus = 2 //等待选倍数
  13. QznnRoundUserStatusWaitOpen QznnRoundUserStatus = 3 //等待开牌
  14. QznnRoundUserStatusWaitCal QznnRoundUserStatus = 4 //等待结算
  15. )
  16. // var globalIndex uint64 = 800000
  17. // var qznnRoundMap = map[uint32]*QznnRound{}
  18. // var qznnRoundMapLocker = sync.Mutex{}
  19. // type ReadyReq struct {
  20. // RoomID uint32
  21. // UserID uint32
  22. // }
  23. // type ChooseMasterReq struct {
  24. // RoomID uint32
  25. // UserID uint32
  26. // Mul int //0不抢,1,2,3
  27. // }
  28. // type ChooseMulReq struct {
  29. // RoomID uint32
  30. // UserID uint32
  31. // Mul int //1-15
  32. // }
  33. // type OpenReq struct {
  34. // RoomID uint32
  35. // UserID uint32
  36. // }
  37. // type QznnRoundUser struct {
  38. // UserID uint32
  39. // MasterMul int //抢庄倍数
  40. // ChooseMul int //倍数
  41. // IsMaster bool //是否为庄家
  42. // Status QznnRoundUserStatus //状态
  43. // }
  44. // type QznnRound struct {
  45. // RoomID uint32
  46. // Issue string
  47. // Status QZNNStatus
  48. // UserMap map[uint32]*QznnRoundUser
  49. // StartTime time.Time
  50. // ChooseMasterCh chan bool
  51. // ChooseMulCh chan bool
  52. // OpenCh chan bool
  53. // }
  54. // //按时间处理状态变化
  55. // func (p *QznnRound) Start() {
  56. // p.StartTime = time.Now()
  57. // //发送开始消息
  58. // {
  59. // data, err := proto.Marshal(&gameproto.Start{
  60. // RoomID: p.RoomID,
  61. // MulList: []uint32{0, 1, 2, 3},
  62. // })
  63. // if err != nil {
  64. // logrus.Error(err)
  65. // return
  66. // }
  67. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  68. // RoomID: p.RoomID,
  69. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeStart),
  70. // Data: string(data),
  71. // })
  72. // }
  73. // logrus.Info("QznnReady start ==>", p.StartTime)
  74. // //等待完毕
  75. // onStatusChange(p)
  76. // //选择坐庄
  77. // select {
  78. // case <-p.ChooseMasterCh:
  79. // //
  80. // case <-time.After(5 * time.Second):
  81. // func() {
  82. // //等超时,则默认处理
  83. // qznnRoundMapLocker.Lock()
  84. // defer qznnRoundMapLocker.Unlock()
  85. // for _, item := range p.UserMap {
  86. // if item.MasterMul == 0 {
  87. // item.MasterMul = 1
  88. // data, err := proto.Marshal(&gameproto.ChooseMaster{
  89. // UserID: item.UserID,
  90. // Mul: uint32(item.MasterMul),
  91. // })
  92. // if err != nil {
  93. // logrus.Error(err)
  94. // return
  95. // }
  96. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  97. // RoomID: p.RoomID,
  98. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMaster),
  99. // Data: string(data),
  100. // })
  101. // }
  102. // }
  103. // }()
  104. // }
  105. // p.Status = QZNNStatusChooseMaster
  106. // //选完
  107. // func() {
  108. // qznnRoundMapLocker.Lock()
  109. // defer qznnRoundMapLocker.Unlock()
  110. // userID := uint32(0)
  111. // for _, item := range p.UserMap {
  112. // userID = item.UserID
  113. // break
  114. // }
  115. // data, err := proto.Marshal(&gameproto.ChooseMasterFinish{
  116. // MasterUserID: userID,
  117. // MulList: []uint32{1, 2, 3, 4, 5, 6, 7, 8},
  118. // RoomID: p.RoomID,
  119. // })
  120. // if err != nil {
  121. // logrus.Error(err)
  122. // return
  123. // }
  124. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  125. // RoomID: p.RoomID,
  126. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMasterFinish),
  127. // Data: string(data),
  128. // })
  129. // }()
  130. // onStatusChange(p)
  131. // //选择倍数
  132. // select {
  133. // case <-p.ChooseMulCh:
  134. // //
  135. // case <-time.After(5 * time.Second):
  136. // func() {
  137. // //等超时,则默认处理
  138. // qznnRoundMapLocker.Lock()
  139. // defer qznnRoundMapLocker.Unlock()
  140. // for _, item := range p.UserMap {
  141. // if item.MasterMul == 0 {
  142. // item.MasterMul = 1
  143. // data, err := proto.Marshal(&gameproto.ChooseMaster{
  144. // UserID: item.UserID,
  145. // Mul: uint32(item.ChooseMul),
  146. // RoomID: p.RoomID,
  147. // })
  148. // if err != nil {
  149. // logrus.Error(err)
  150. // return
  151. // }
  152. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  153. // RoomID: p.RoomID,
  154. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMaster),
  155. // Data: string(data),
  156. // })
  157. // }
  158. // }
  159. // }()
  160. // }
  161. // p.Status = QZNNStatusChooseMul
  162. // //选完
  163. // func() {
  164. // qznnRoundMapLocker.Lock()
  165. // defer qznnRoundMapLocker.Unlock()
  166. // data, err := proto.Marshal(&gameproto.ChooseMulinish{
  167. // RoomID: p.RoomID,
  168. // })
  169. // if err != nil {
  170. // logrus.Error(err)
  171. // return
  172. // }
  173. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  174. // RoomID: p.RoomID,
  175. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMulinish),
  176. // Data: string(data),
  177. // })
  178. // }()
  179. // //开牌
  180. // select {
  181. // case <-p.OpenCh:
  182. // //
  183. // case <-time.After(15 * time.Second):
  184. // func() {
  185. // //等超时,则默认处理
  186. // qznnRoundMapLocker.Lock()
  187. // defer qznnRoundMapLocker.Unlock()
  188. // for _, item := range p.UserMap {
  189. // if item.Status == QznnRoundUserStatusWaitOpen {
  190. // item.Status = QznnRoundUserStatusWaitCal
  191. // data, err := proto.Marshal(&gameproto.Open{
  192. // CardList: []uint32{1, 2, 3, 4, 5},
  193. // Winloss: 100,
  194. // UserID: item.UserID,
  195. // RoomID: p.RoomID,
  196. // })
  197. // if err != nil {
  198. // logrus.Error(err)
  199. // return
  200. // }
  201. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  202. // RoomID: p.RoomID,
  203. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeOpen),
  204. // Data: string(data),
  205. // })
  206. // }
  207. // }
  208. // }()
  209. // }
  210. // <-time.After(3 * time.Second)
  211. // p.Status = QZNNStatusInit
  212. // data, err := proto.Marshal(&gameproto.GameInit{})
  213. // if err != nil {
  214. // logrus.Error(err)
  215. // return
  216. // }
  217. // nxd.SendMsgToRoomUser(p.RoomID, online.Msg{
  218. // RoomID: p.RoomID,
  219. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeGameInit),
  220. // Data: string(data),
  221. // })
  222. // onStatusChange(p)
  223. // }
  224. // func QznnRoomStatus(roomID uint32) (QZNNStatus, bool) {
  225. // qznnRoundMapLocker.Lock()
  226. // defer qznnRoundMapLocker.Unlock()
  227. // roomRound, exists := qznnRoundMap[roomID]
  228. // if !exists {
  229. // return QZNNStatusInit, false
  230. // }
  231. // return roomRound.Status, true
  232. // }
  233. // func QznnReady(ctx *gin.Context) {
  234. // var err error
  235. // readyReq := ReadyReq{}
  236. // if err := ctx.ShouldBindJSON(&readyReq); err != nil {
  237. // logrus.Error(err)
  238. // webutils.FailedResponseErr(ctx, err)
  239. // return
  240. // }
  241. // userModel := model.User{}
  242. // err = userModel.GetUserByID(readyReq.UserID)
  243. // if err != nil {
  244. // logrus.Error(err)
  245. // webutils.FailedResponse(ctx, "内部错误")
  246. // return
  247. // }
  248. // qznnRoundMapLocker.Lock()
  249. // defer qznnRoundMapLocker.Unlock()
  250. // roomRound, exists := qznnRoundMap[readyReq.RoomID]
  251. // if !exists {
  252. // roomRound = &QznnRound{
  253. // RoomID: readyReq.RoomID,
  254. // Issue: GetIssue(readyReq.RoomID),
  255. // Status: QZNNStatusInit,
  256. // UserMap: map[uint32]*QznnRoundUser{},
  257. // StartTime: time.Time{},
  258. // ChooseMasterCh: make(chan bool),
  259. // ChooseMulCh: make(chan bool),
  260. // OpenCh: make(chan bool),
  261. // }
  262. // qznnRoundMap[readyReq.RoomID] = roomRound
  263. // }
  264. // if roomRound.Status != QZNNStatusWait && roomRound.Status != QZNNStatusInit {
  265. // webutils.FailedResponse(ctx, "游戏已经开始,无法加入")
  266. // return
  267. // }
  268. // _, exists = roomRound.UserMap[uint32(userModel.ID)]
  269. // if !exists {
  270. // roomRound.UserMap[uint32(userModel.ID)] = &QznnRoundUser{
  271. // UserID: uint32(userModel.ID),
  272. // MasterMul: 1,
  273. // ChooseMul: 1,
  274. // IsMaster: false,
  275. // Status: QznnRoundUserStatusWait,
  276. // }
  277. // } else {
  278. // webutils.SuccessResponse(ctx, gin.H{
  279. // "status": "exists",
  280. // })
  281. // }
  282. // if len(roomRound.UserMap) >= 2 && roomRound.Status == QZNNStatusInit {
  283. // //开始
  284. // roomRound.Status = QZNNStatusWait
  285. // go roomRound.Start()
  286. // }
  287. // webutils.SuccessResponse(ctx, nil)
  288. // }
  289. // func QznnUnReady(ctx *gin.Context) {
  290. // readyReq := ReadyReq{}
  291. // if err := ctx.ShouldBindJSON(&readyReq); err != nil {
  292. // logrus.Error(err)
  293. // webutils.FailedResponseErr(ctx, err)
  294. // return
  295. // }
  296. // qznnRoundMapLocker.Lock()
  297. // defer qznnRoundMapLocker.Unlock()
  298. // roomRound, exists := qznnRoundMap[readyReq.RoomID]
  299. // if !exists {
  300. // roomRound = &QznnRound{
  301. // RoomID: readyReq.RoomID,
  302. // Issue: GetIssue(readyReq.RoomID),
  303. // Status: QZNNStatusInit,
  304. // UserMap: map[uint32]*QznnRoundUser{},
  305. // StartTime: time.Time{},
  306. // ChooseMasterCh: make(chan bool),
  307. // ChooseMulCh: make(chan bool),
  308. // OpenCh: make(chan bool),
  309. // }
  310. // qznnRoundMap[readyReq.RoomID] = roomRound
  311. // }
  312. // if roomRound.Status != QZNNStatusInit {
  313. // webutils.FailedResponse(ctx, "游戏已经开始,无法取消")
  314. // return
  315. // }
  316. // delete(roomRound.UserMap, readyReq.UserID)
  317. // webutils.SuccessResponse(ctx, nil)
  318. // }
  319. // func QznnChooseMaster(ctx *gin.Context) {
  320. // req := ChooseMasterReq{}
  321. // if err := ctx.ShouldBindJSON(&req); err != nil {
  322. // logrus.Error(err)
  323. // webutils.FailedResponseErr(ctx, err)
  324. // return
  325. // }
  326. // qznnRoundMapLocker.Lock()
  327. // defer qznnRoundMapLocker.Unlock()
  328. // roomRound, exists := qznnRoundMap[req.RoomID]
  329. // if !exists {
  330. // logrus.Error("用户不存在")
  331. // webutils.FailedResponse(ctx, "用户错误")
  332. // return
  333. // }
  334. // if roomRound.Status != QZNNStatusWait {
  335. // logrus.Error("状态错误")
  336. // webutils.FailedResponse(ctx, "状态错误")
  337. // return
  338. // }
  339. // roomRound.UserMap[req.UserID].Status = QznnRoundUserStatusWaitMul
  340. // roomRound.UserMap[req.UserID].MasterMul = req.Mul
  341. // allIsWaitMul := true
  342. // for _, item := range roomRound.UserMap {
  343. // if item.Status != QznnRoundUserStatusWaitMul {
  344. // allIsWaitMul = false
  345. // break
  346. // }
  347. // }
  348. // //发消息
  349. // data, err := proto.Marshal(&gameproto.ChooseMaster{
  350. // UserID: req.UserID,
  351. // Mul: uint32(roomRound.UserMap[req.UserID].MasterMul),
  352. // })
  353. // if err != nil {
  354. // logrus.Error(err)
  355. // return
  356. // }
  357. // nxd.SendMsgToRoomUser(roomRound.RoomID, online.Msg{
  358. // RoomID: roomRound.RoomID,
  359. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMaster),
  360. // Data: string(data),
  361. // })
  362. // if allIsWaitMul {
  363. // func() {
  364. // roomRound.ChooseMasterCh <- true
  365. // }()
  366. // }
  367. // webutils.SuccessResponse(ctx, nil)
  368. // }
  369. // func QznnChooseMul(ctx *gin.Context) {
  370. // req := ChooseMulReq{}
  371. // if err := ctx.ShouldBindJSON(&req); err != nil {
  372. // logrus.Error(err)
  373. // webutils.FailedResponseErr(ctx, err)
  374. // return
  375. // }
  376. // qznnRoundMapLocker.Lock()
  377. // defer qznnRoundMapLocker.Unlock()
  378. // roomRound, exists := qznnRoundMap[req.RoomID]
  379. // if !exists {
  380. // logrus.Error("用户不存在")
  381. // webutils.FailedResponse(ctx, "用户错误")
  382. // return
  383. // }
  384. // if roomRound.Status != QZNNStatusChooseMaster {
  385. // logrus.Error("状态错误")
  386. // webutils.FailedResponse(ctx, "状态错误")
  387. // return
  388. // }
  389. // roomRound.UserMap[req.UserID].Status = QznnRoundUserStatusWaitOpen
  390. // roomRound.UserMap[req.UserID].ChooseMul = req.Mul
  391. // allIsWaitCal := true
  392. // for _, item := range roomRound.UserMap {
  393. // if item.Status != QznnRoundUserStatusWaitOpen {
  394. // allIsWaitCal = false
  395. // break
  396. // }
  397. // }
  398. // data, err := proto.Marshal(&gameproto.ChooseMul{
  399. // UserID: req.UserID,
  400. // Mul: uint32(roomRound.UserMap[req.UserID].ChooseMul),
  401. // })
  402. // if err != nil {
  403. // logrus.Error(err)
  404. // return
  405. // }
  406. // nxd.SendMsgToRoomUser(roomRound.RoomID, online.Msg{
  407. // RoomID: roomRound.RoomID,
  408. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeChooseMul),
  409. // Data: string(data),
  410. // })
  411. // if allIsWaitCal {
  412. // func() {
  413. // roomRound.ChooseMulCh <- true
  414. // }()
  415. // }
  416. // webutils.SuccessResponse(ctx, nil)
  417. // }
  418. // func QznnOpen(ctx *gin.Context) {
  419. // req := OpenReq{}
  420. // if err := ctx.ShouldBindJSON(&req); err != nil {
  421. // logrus.Error(err)
  422. // webutils.FailedResponseErr(ctx, err)
  423. // return
  424. // }
  425. // qznnRoundMapLocker.Lock()
  426. // defer qznnRoundMapLocker.Unlock()
  427. // roomRound, exists := qznnRoundMap[req.RoomID]
  428. // if !exists {
  429. // logrus.Error("用户不存在")
  430. // webutils.FailedResponse(ctx, "用户错误")
  431. // return
  432. // }
  433. // if roomRound.Status != QZNNStatusChooseMul {
  434. // logrus.Error("状态错误")
  435. // webutils.FailedResponse(ctx, "状态错误")
  436. // return
  437. // }
  438. // roomRound.UserMap[req.UserID].Status = QznnRoundUserStatusWaitCal
  439. // allIsWaitCal := true
  440. // for _, item := range roomRound.UserMap {
  441. // if item.Status != QznnRoundUserStatusWaitMul {
  442. // allIsWaitCal = false
  443. // break
  444. // }
  445. // }
  446. // data, err := proto.Marshal(&gameproto.Open{
  447. // CardList: []uint32{1, 2, 3, 4, 5},
  448. // Winloss: 100,
  449. // UserID: req.UserID,
  450. // RoomID: req.RoomID,
  451. // })
  452. // if err != nil {
  453. // logrus.Error(err)
  454. // return
  455. // }
  456. // nxd.SendMsgToRoomUser(req.RoomID, online.Msg{
  457. // RoomID: req.RoomID,
  458. // NotifyType: uint32(gameproto.NotifyTypeEnum_NotifyTypeOpen),
  459. // Data: string(data),
  460. // })
  461. // if allIsWaitCal {
  462. // func() {
  463. // roomRound.OpenCh <- true
  464. // }()
  465. // }
  466. // webutils.SuccessResponse(ctx, nil)
  467. // }
  468. // func onStatusChange(p *QznnRound) {
  469. // qznnRoundMapLocker.Lock()
  470. // defer qznnRoundMapLocker.Unlock()
  471. // if p.Status == QZNNStatusWait {
  472. // //等3秒,用于新进来的人准备
  473. // <-time.After(3 * time.Second)
  474. // return
  475. // }
  476. // if p.Status == QZNNStatusChooseMaster {
  477. // fmt.Println("master finish")
  478. // return
  479. // }
  480. // if p.Status == QZNNStatusChooseMul {
  481. // fmt.Println("mul finish")
  482. // return
  483. // }
  484. // if p.Status == QZNNStatusCal {
  485. // fmt.Println("open finish")
  486. // return
  487. // }
  488. // if p.Status == QZNNStatusInit {
  489. // //清理,然后发通知
  490. // for k := range p.UserMap {
  491. // delete(p.UserMap, k)
  492. // }
  493. // fmt.Println("重新进入初始化,等下一轮开始")
  494. // return
  495. // }
  496. // //这里是异常了
  497. // logrus.Fatal("异常:", p)
  498. // }
  499. // func GetIssue(roomID uint32) string {
  500. // index := atomic.AddUint64(&globalIndex, 1)
  501. // return fmt.Sprintf("%d-%d-%d", roomID, time.Now().Unix(), index)
  502. // }