github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/game/internal/landlord_room.go (about) 1 package internal 2 3 import ( 4 "common" 5 "conf" 6 "fmt" 7 "game/poker" 8 "msg" 9 "sort" 10 "strconv" 11 "time" 12 13 "github.com/name5566/leaf/log" 14 "github.com/name5566/leaf/timer" 15 "gopkg.in/mgo.v2/bson" 16 ) 17 18 // 玩家状态 19 const ( 20 _ = iota 21 landlordReady // 1 准备 22 landlordWaiting // 2 等待 23 landlordActionBid // 3 前端显示叫地主动作 24 landlordActionGrab // 4 前端显示抢地主动作 25 landlordActionDouble // 5 前端显示加倍动作 26 landlordActionShowCards // 6 前端显示明牌动作 27 landlordActionDiscard // 7 前端显示出牌动作 28 ) 29 30 // 倒计时 31 /* 32 const ( 33 cd_landlordBid = 5 // 5 秒 34 cd_landlordGrab = 3 // 3 秒 35 cd_landlordDouble = 3 // 3 秒 36 cd_landlordShowCards = 3 // 3 秒 37 cd_landlordDiscard = 20 // 20 秒 38 cd_landlordDiscardNothing = 3 // 3 秒 39 ) 40 */ 41 type LandlordRoom struct { 42 room 43 rule *poker.LandlordRule 44 userIDPlayerDatas map[int]*LandlordPlayerData // Key: userID 45 cards []int // 洗好的牌 46 lastThree []int // 最后三张 47 discards []int // 玩家出的牌 48 rests []int // 剩余的牌 49 50 dealerUserID int // 庄家 userID(庄家第一个叫地主) 51 bidUserID int // 叫地主的玩家 userID(只有一个) 52 grabUserIDs []int // 抢地主的玩家 userID 53 landlordUserID int // 地主 userID 54 peasantUserIDs []int // 农民 userID 55 discarderUserID int // 最近一次出牌的人 userID 56 57 finisherUserID int // 上一局出完牌的人 userID(做下一局庄家) 58 spring bool // 春天 59 60 bidTimer *timer.Timer 61 grabTimer *timer.Timer 62 doubleTimer *timer.Timer 63 showCardsTimer *timer.Timer 64 discardTimer *timer.Timer 65 66 winnerUserIDs []int 67 shuffleTimes int // 洗牌次数(最多二次) 68 } 69 70 // 玩家数据 71 type LandlordPlayerData struct { 72 user *User 73 state int 74 position int // 用户在桌子上的位置,从 0 开始 75 76 owner bool // 房主 77 dealer bool 78 showCards bool // 明牌 79 multiple int // 倍数 80 81 hands []int // 手牌 82 discards [][]int // 打出的牌 83 analyzer *poker.LandlordAnalyzer 84 85 actionDiscardType int // 出牌动作类型 86 actionTimestamp int64 // 记录动作时间戳 87 88 roundResult *poker.LandlordPlayerRoundResult 89 90 hosted bool // 是否被托管 91 vipChips int64 92 taskID51 int // 单局打出2个顺子3次 93 taskID2001 int // 单局打出两个炸弹 94 roundResults []poker.LandlordPlayerRoundResult 95 originHands []int 96 } 97 98 func newLandlordRoom(rule *poker.LandlordRule) *LandlordRoom { 99 roomm := new(LandlordRoom) 100 roomm.state = roomIdle 101 roomm.loginIPs = make(map[string]bool) 102 roomm.positionUserIDs = make(map[int]int) 103 roomm.userIDPlayerDatas = make(map[int]*LandlordPlayerData) 104 roomm.rule = rule 105 106 switch roomm.rule.RoomType { 107 case roomPractice: 108 roomm.desc = "练习场" 109 case roomBaseScoreMatching: 110 roomm.desc = fmt.Sprintf("金币场 底分%v 入场金币%v", roomm.rule.BaseScore, roomm.rule.MinChips) 111 case roomBaseScorePrivate: 112 roomm.desc = fmt.Sprintf("金币私人房 底分%v 入场金币%v", roomm.rule.BaseScore, roomm.rule.MinChips) 113 case roomVIPPrivate: 114 roomm.desc = fmt.Sprintf("VIP私人房 入场金币%v", roomm.rule.MinChips) 115 case roomRedPacketMatching, roomRedPacketPrivate: 116 roomm.desc = fmt.Sprintf("%v元红包场", roomm.rule.RedPacketType) 117 } 118 return roomm 119 } 120 121 func (roomm *LandlordRoom) getShowCardsUserIDs() []int { 122 userIDs := make([]int, 0) 123 for userID, playerData := range roomm.userIDPlayerDatas { 124 if playerData.showCards { 125 userIDs = append(userIDs, userID) 126 } 127 } 128 return userIDs 129 } 130 131 func (roomm *LandlordRoom) RealPlayer() int { 132 count := 0 133 for _, userID := range roomm.positionUserIDs { 134 playerData := roomm.userIDPlayerDatas[userID] 135 if !playerData.user.isRobot() { 136 count++ 137 } 138 } 139 return count 140 } 141 func (roomm *LandlordRoom) allReady() bool { 142 if !roomm.full() { 143 return false 144 } 145 count := 0 146 for _, userID := range roomm.positionUserIDs { 147 playerData := roomm.userIDPlayerDatas[userID] 148 if playerData.state == landlordReady { 149 count++ 150 } 151 } 152 if count == roomm.rule.MaxPlayers { 153 return true 154 } 155 return false 156 } 157 158 func (roomm *LandlordRoom) allWaiting() bool { 159 count := 0 160 for _, userID := range roomm.positionUserIDs { 161 playerData := roomm.userIDPlayerDatas[userID] 162 if playerData.state == landlordWaiting { 163 count++ 164 } 165 } 166 if count == roomm.rule.MaxPlayers { 167 return true 168 } 169 return false 170 } 171 172 func (roomm *LandlordRoom) empty() bool { 173 return len(roomm.positionUserIDs) == 0 174 } 175 176 func (roomm *LandlordRoom) full() bool { 177 return len(roomm.positionUserIDs) == roomm.rule.MaxPlayers 178 } 179 180 func (roomm *LandlordRoom) playTogether(user *User) bool { 181 for _, playerUserID := range roomm.positionUserIDs { 182 playerData := roomm.userIDPlayerDatas[playerUserID] 183 if playerData != nil && playerData.user.baseData.togetherUserIDs[user.baseData.userData.UserID] || user.baseData.togetherUserIDs[playerUserID] { 184 return true 185 } 186 } 187 return false 188 } 189 190 func (roomm *LandlordRoom) Enter(user *User) bool { 191 userID := user.baseData.userData.UserID 192 if playerData, ok := roomm.userIDPlayerDatas[userID]; ok { // 断线重连 193 playerData.user = user 194 user.WriteMsg(&msg.S2C_EnterRoom{ 195 Error: msg.S2C_EnterRoom_OK, 196 RoomType: roomm.rule.RoomType, 197 RoomNumber: roomm.number, 198 Position: playerData.position, 199 BaseScore: roomm.rule.BaseScore, 200 RedPacketType: roomm.rule.RedPacketType, 201 RoomDesc: roomm.desc, 202 MaxPlayers: roomm.rule.MaxPlayers, 203 MinChips: roomm.rule.MinChips, 204 Tickects: roomm.rule.Tickets, 205 GamePlaying: roomm.state == roomGame, 206 }) 207 log.Debug("userID: %v 重连进入房间, 房间类型: %v", userID, roomm.rule.RoomType) 208 return true 209 } 210 // 玩家已满 211 if roomm.full() { 212 user.WriteMsg(&msg.S2C_EnterRoom{ 213 Error: msg.S2C_EnterRoom_Full, 214 RoomNumber: roomm.number, 215 }) 216 return false 217 } 218 219 if !user.checkRoomMinChips(roomm.rule.MinChips, false) { 220 return false 221 } 222 223 switch roomm.rule.RoomType { 224 case roomBaseScoreMatching: 225 if roomm.rule.BaseScore == 500 && !user.checkRoomMaxChips(60000, false) { 226 return false 227 } 228 } 229 230 switch roomm.rule.RoomType { 231 case roomBaseScoreMatching, roomRedPacketMatching: 232 roomm.loginIPs[user.baseData.userData.LoginIP] = true 233 } 234 for pos := 0; pos < roomm.rule.MaxPlayers; pos++ { 235 if _, ok := roomm.positionUserIDs[pos]; ok { 236 continue 237 } 238 roomm.SitDown(user, pos) 239 user.WriteMsg(&msg.S2C_EnterRoom{ 240 Error: msg.S2C_EnterRoom_OK, 241 RoomType: roomm.rule.RoomType, 242 RoomNumber: roomm.number, 243 Position: pos, 244 BaseScore: roomm.rule.BaseScore, 245 RedPacketType: roomm.rule.RedPacketType, 246 RoomDesc: roomm.desc, 247 MaxPlayers: roomm.rule.MaxPlayers, 248 MinChips: roomm.rule.MinChips, 249 Tickects: roomm.rule.Tickets, 250 GamePlaying: roomm.state == roomGame, 251 }) 252 log.Debug("userID: %v 进入房间: %v, 房主: %v, 类型: %v", userID, roomm.number, roomm.ownerUserID, roomm.rule.RoomType) 253 switch roomm.rule.RoomType { 254 case roomRedPacketMatching, roomRedPacketPrivate: 255 calculateRedPacketMatchOnlineNumber(roomm.rule.RedPacketType) 256 } 257 return true 258 } 259 user.WriteMsg(&msg.S2C_EnterRoom{ 260 Error: msg.S2C_EnterRoom_Unknown, 261 RoomNumber: roomm.number, 262 }) 263 return false 264 } 265 266 func (roomm *LandlordRoom) Exit(user *User) { 267 roomm.finisherUserID = -1 268 269 userID := user.baseData.userData.UserID 270 playerData := roomm.userIDPlayerDatas[userID] 271 if playerData == nil { 272 return 273 } 274 playerData.state = 0 275 276 broadcast(&msg.S2C_StandUp{ 277 Position: playerData.position, 278 }, roomm.positionUserIDs, -1) 279 log.Debug("userID: %v 退出房间: %v, 类型: %v", userID, roomm.number, roomm.rule.RoomType) 280 broadcast(&msg.S2C_ExitRoom{ 281 Error: msg.S2C_ExitRoom_OK, 282 Position: playerData.position, 283 }, roomm.positionUserIDs, -1) 284 285 roomm.StandUp(user, playerData.position) // 站起 286 delete(userIDRooms, userID) // 退出 287 delete(roomm.loginIPs, user.baseData.userData.LoginIP) // 删除玩家登录IP 288 289 if roomm.empty() { // 玩家为空,解散房间 290 delete(roomNumberRooms, roomm.number) 291 } else { 292 if roomm.ownerUserID == userID { // 转移房主 293 for _, userID := range roomm.positionUserIDs { 294 roomm.ownerUserID = userID 295 break 296 } 297 } 298 } 299 } 300 301 func (roomm *LandlordRoom) Leave(userID int) { 302 roomm.finisherUserID = -1 303 304 playerData := roomm.userIDPlayerDatas[userID] 305 if playerData == nil { 306 return 307 } 308 playerData.state = 0 309 310 log.Debug("userID: %v 离开房间: %v, 类型: %v", userID, roomm.number, roomm.rule.RoomType) 311 312 delete(roomm.positionUserIDs, playerData.position) 313 delete(roomm.userIDPlayerDatas, userID) 314 315 delete(userIDRooms, userID) // 退出 316 317 if roomm.empty() { // 玩家为空,解散房间 318 delete(roomNumberRooms, roomm.number) 319 } else { 320 if roomm.ownerUserID == userID { // 转移房主 321 for _, userID := range roomm.positionUserIDs { 322 roomm.ownerUserID = userID 323 break 324 } 325 } 326 } 327 } 328 329 func (roomm *LandlordRoom) SitDown(user *User, pos int) { 330 userID := user.baseData.userData.UserID 331 roomm.positionUserIDs[pos] = userID 332 333 playerData := roomm.userIDPlayerDatas[userID] 334 if playerData == nil { 335 playerData = new(LandlordPlayerData) 336 playerData.user = user 337 playerData.vipChips = 0 338 playerData.position = pos 339 playerData.owner = userID == roomm.ownerUserID 340 playerData.analyzer = new(poker.LandlordAnalyzer) 341 playerData.roundResult = new(poker.LandlordPlayerRoundResult) 342 343 roomm.userIDPlayerDatas[userID] = playerData 344 } 345 chips := playerData.user.baseData.userData.Chips 346 if roomm.rule.RoomType == roomVIPPrivate { 347 chips = playerData.vipChips 348 } 349 msgTemp := &msg.S2C_SitDown{ 350 Position: playerData.position, 351 Owner: playerData.owner, 352 AccountID: playerData.user.baseData.userData.AccountID, 353 LoginIP: playerData.user.baseData.userData.LoginIP, 354 Nickname: playerData.user.baseData.userData.Nickname, 355 Headimgurl: playerData.user.baseData.userData.Headimgurl, 356 Sex: playerData.user.baseData.userData.Sex, 357 Ready: playerData.state == landlordReady, 358 Chips: chips, 359 } 360 //switch roomm.rule.RoomType { 361 //case roomBaseScoreMatching, roomRedPacketMatching: 362 // msg.Nickname = "******" 363 // msg.Headimgurl = defaultAvatar 364 // msg.Chips = -1 365 //} 366 broadcast(msgTemp, roomm.positionUserIDs, pos) 367 } 368 369 func (roomm *LandlordRoom) StandUp(user *User, pos int) { 370 delete(roomm.positionUserIDs, pos) 371 delete(roomm.userIDPlayerDatas, user.baseData.userData.UserID) 372 } 373 374 func (roomm *LandlordRoom) GetAllPlayers(user *User) { 375 for pos := 0; pos < roomm.rule.MaxPlayers; pos++ { 376 userID := roomm.positionUserIDs[pos] 377 playerData := roomm.userIDPlayerDatas[userID] 378 if playerData == nil { 379 user.WriteMsg(&msg.S2C_StandUp{ 380 Position: pos, 381 }) 382 } else { 383 chips := playerData.user.baseData.userData.Chips 384 if roomm.rule.RoomType == roomVIPPrivate { 385 chips = playerData.vipChips 386 } 387 msgTemp := &msg.S2C_SitDown{ 388 Position: playerData.position, 389 Owner: playerData.owner, 390 AccountID: playerData.user.baseData.userData.AccountID, 391 LoginIP: playerData.user.baseData.userData.LoginIP, 392 Nickname: playerData.user.baseData.userData.Nickname, 393 Headimgurl: playerData.user.baseData.userData.Headimgurl, 394 Sex: playerData.user.baseData.userData.Sex, 395 Ready: playerData.state == landlordReady, 396 Chips: chips, 397 } 398 //switch roomm.rule.RoomType { 399 //case roomBaseScoreMatching, roomRedPacketMatching: 400 // if user.baseData.userData.UserID != userID { 401 // msg.Nickname = "******" 402 // msg.Headimgurl = defaultAvatar 403 // msg.Chips = -1 404 // } 405 //} 406 user.WriteMsg(msgTemp) 407 } 408 } 409 } 410 411 func (roomm *LandlordRoom) StartGame() { 412 roomm.state = roomGame 413 roomm.prepare() 414 415 broadcast(&msg.S2C_GameStart{}, roomm.positionUserIDs, -1) 416 // 所有玩家都发十七张牌 417 for _, userID := range roomm.positionUserIDs { 418 playerData := roomm.userIDPlayerDatas[userID] 419 playerData.state = landlordWaiting 420 421 if roomm.rule.RoomType == roomBaseScoreMatching || roomm.rule.RoomType == roomRedPacketMatching { 422 if len(playerData.user.baseData.togetherUserIDs) > 5 { 423 count := 0 424 for k := range playerData.user.baseData.togetherUserIDs { 425 if count == 2 { 426 break 427 } 428 delete(playerData.user.baseData.togetherUserIDs, k) 429 count++ 430 } 431 } 432 for _, togetherUserID := range roomm.positionUserIDs { 433 if userID != togetherUserID { 434 playerData.user.baseData.togetherUserIDs[togetherUserID] = true 435 } 436 } 437 } 438 // 扣除门票 439 if roomm.shuffleTimes == 1 && roomm.rule.Tickets > 0 { 440 playerData.user.baseData.userData.Chips -= roomm.rule.Tickets 441 playerData.user.WriteMsg(&msg.S2C_UpdatePlayerChips{ 442 Position: playerData.position, 443 Chips: playerData.user.baseData.userData.Chips, 444 }) 445 446 roomm.updateTaskTicket(userID) 447 } 448 // 手牌有十七张 449 playerData.hands = append(playerData.hands, roomm.rests[:17]...) 450 playerData.originHands = playerData.hands 451 // 排序 452 sort.Sort(sort.Reverse(sort.IntSlice(playerData.hands))) 453 log.Debug("userID %v 手牌: %v", userID, poker.ToCardsString(playerData.hands)) 454 playerData.analyzer.Analyze(playerData.hands) 455 // 剩余的牌 456 roomm.rests = roomm.rests[17:] 457 458 if user, ok := userIDUsers[userID]; ok { 459 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 460 Multiple: playerData.multiple, 461 }) 462 user.WriteMsg(&msg.S2C_UpdatePokerHands{ 463 Position: playerData.position, 464 Hands: playerData.hands, 465 NumberOfHands: len(playerData.hands), 466 ShowCards: playerData.showCards, 467 }) 468 } 469 if playerData.showCards { 470 roomm.doTask(userID, 9) // 累计明牌开始10次 471 roomm.doTask(userID, 26) // 累计明牌开始2次,奖励2000金币 472 roomm.doTask(userID, 27) // 累计明牌开始3次,奖励3000金币 473 //初级任务 累计明牌开始10次 1012 474 //fmt.Println("************玩家明牌:***************") 475 //playerData.user.updateRedPacketTask(1012) 476 broadcast(&msg.S2C_LandlordShowCards{ 477 Position: playerData.position, 478 }, roomm.positionUserIDs, -1) 479 480 broadcast(&msg.S2C_UpdatePokerHands{ 481 Position: playerData.position, 482 Hands: playerData.hands, 483 NumberOfHands: len(playerData.hands), 484 ShowCards: true, 485 }, roomm.positionUserIDs, playerData.position) 486 } else { 487 broadcast(&msg.S2C_UpdatePokerHands{ 488 Position: playerData.position, 489 Hands: []int{}, 490 NumberOfHands: len(playerData.hands), 491 }, roomm.positionUserIDs, playerData.position) 492 } 493 } 494 // 庄家叫地主 495 roomm.bid(roomm.dealerUserID) 496 } 497 498 func (roomm *LandlordRoom) EndGame() { 499 if len(roomm.winnerUserIDs) > 0 { 500 for _, player := range roomm.userIDPlayerDatas { 501 if player != nil { 502 log.Release("******************************%v", player.user.baseData.userData.CardCode != "") 503 if player.user.baseData.userData.CardCode != "" || player.user.baseData.userData.UserID != roomm.winnerUserIDs[0] { 504 continue 505 } 506 player.user.baseData.userData.PlayTimes++ 507 if player.user.baseData.userData.PlayTimes < conf.GetCfgCard().PlayTimes { 508 updateUserData(player.user.baseData.userData.UserID, bson.M{"$set": bson.M{ 509 "playtimes": player.user.baseData.userData.PlayTimes, 510 }, 511 }) 512 player.user.WriteMsg(&msg.S2C_CardMa{ 513 Code: player.user.baseData.userData.CardCode, 514 Total: conf.GetCfgCard().PlayTimes, 515 PlayTimes: player.user.baseData.userData.PlayTimes, 516 Completed: player.user.baseData.userData.CardCode != "", 517 }) 518 } else { 519 now := time.Now() 520 next := now.Add(24 * time.Hour) 521 player.user.baseData.userData.CardCode = "D" + common.GetTodayCode(4) 522 player.user.baseData.userData.Taken = false 523 player.user.baseData.userData.CollectDeadLine = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()).Unix() 524 updateUserData(player.user.baseData.userData.UserID, bson.M{"$set": bson.M{ 525 "cardcode": player.user.baseData.userData.CardCode, 526 "taken": player.user.baseData.userData.Taken, 527 "collectdeadline": player.user.baseData.userData.CollectDeadLine, 528 "playtimes": player.user.baseData.userData.PlayTimes, 529 }, 530 }) 531 player.user.WriteMsg(&msg.S2C_CardMa{ 532 Code: player.user.baseData.userData.CardCode, 533 Total: conf.GetCfgCard().PlayTimes, 534 PlayTimes: player.user.baseData.userData.PlayTimes, 535 Completed: player.user.baseData.userData.CardCode != "", 536 }) 537 } 538 } 539 } 540 } 541 roomm.shuffleTimes = 0 542 543 roomm.showHand() 544 roomm.decideWinner() 545 for _, userID := range roomm.positionUserIDs { 546 var roundResults []poker.LandlordPlayerRoundResult 547 548 playerData := roomm.userIDPlayerDatas[userID] 549 roundResults = append(roundResults, poker.LandlordPlayerRoundResult{ 550 Nickname: playerData.user.baseData.userData.Nickname, 551 Headimgurl: playerData.user.baseData.userData.Headimgurl, 552 Landlord: roomm.landlordUserID == userID, 553 BaseScore: roomm.rule.BaseScore, 554 Multiple: playerData.multiple, 555 Chips: playerData.roundResult.Chips, 556 RedPacket: playerData.roundResult.RedPacket, 557 }) 558 for i := 1; i < roomm.rule.MaxPlayers; i++ { 559 otherUserID := roomm.positionUserIDs[(playerData.position+i)%roomm.rule.MaxPlayers] 560 otherPlayerData := roomm.userIDPlayerDatas[otherUserID] 561 roundResults = append(roundResults, poker.LandlordPlayerRoundResult{ 562 Nickname: otherPlayerData.user.baseData.userData.Nickname, 563 Headimgurl: otherPlayerData.user.baseData.userData.Headimgurl, 564 Landlord: roomm.landlordUserID == otherUserID, 565 BaseScore: roomm.rule.BaseScore, 566 Multiple: otherPlayerData.multiple, 567 Chips: otherPlayerData.roundResult.Chips, 568 RedPacket: otherPlayerData.roundResult.RedPacket, 569 }) 570 } 571 playerData.roundResults = roundResults 572 573 switch roomm.rule.RoomType { 574 case roomBaseScoreMatching: 575 roomm.resetTask(userID, 32) // 单局打出2个炸弹 576 //初级任务 单局打出2个炸弹 2001 577 playerData.user.clearRedPacketTask(2001) 578 if playerData.taskID51 > 1 { 579 //高级任务 单局打两个顺子5次 3000 580 playerData.user.updateRedPacketTask(3000) 581 582 roomm.doTask(userID, 51) // 单局打出2个顺子3次 583 roomm.doTask(userID, 61) // 单局打出2个顺子4次 584 roomm.doTask(userID, 62) // 单局打出2个顺子5次 585 } 586 587 if playerData.taskID2001 > 1 { 588 //中级任务 单局打出两个炸弹一次 589 playerData.user.updateRedPacketTask(2001) 590 } 591 592 roomm.calculateChips(userID, playerData.roundResult.Chips) // 结算筹码 593 case roomRedPacketMatching, roomRedPacketPrivate: 594 //新人任务 参加一次红包赛 1003 595 playerData.user.updateRedPacketTask(1003) 596 roomm.doTask(userID, 28) // 参加一次红包比赛 597 roomm.doTask(userID, 29) // 参加一次红包比赛,奖励5000金币 598 doActivityTask(userID, 1018) // 活动期间完成18次红包比赛,奖励999金币 599 600 roomm.calculateChips(userID, playerData.roundResult.Chips) // 结算筹码 601 case roomBaseScorePrivate, roomVIPPrivate: 602 roomm.calculateChips(userID, playerData.roundResult.Chips) // 结算筹码 603 } 604 } 605 roomm.endTimestamp = time.Now().Unix() 606 //保存战绩 607 room := roomm 608 for _, userID := range room.positionUserIDs { 609 playerData := room.userIDPlayerDatas[userID] 610 if playerData.user.isRobot() { 611 continue 612 } 613 amount := playerData.user.baseData.userData.Chips 614 r := &GameRecord{ 615 AccountId: playerData.user.baseData.userData.AccountID, 616 Desc: fmt.Sprintf("门票:%v 底分:%v 倍数:%v", room.rule.Tickets, room.rule.BaseScore, playerData.multiple), 617 RoomNumber: room.number, 618 Profit: playerData.roundResult.Chips, 619 Amount: amount, 620 StartTimestamp: room.eachRoundStartTimestamp, 621 EndTimestamp: room.endTimestamp, 622 Nickname: playerData.user.baseData.userData.Nickname, 623 IsSpring: room.spring, 624 LastThree: poker.ToCardsString(room.lastThree), 625 Channel: playerData.user.baseData.userData.Channel, 626 } 627 for _, userID := range room.positionUserIDs { 628 playerData := room.userIDPlayerDatas[userID] 629 re := ResultData{ 630 AccountId: playerData.user.baseData.userData.AccountID, 631 Nickname: playerData.user.baseData.userData.Nickname, 632 Hands: poker.ToCardsString(playerData.originHands), 633 Chips: playerData.roundResult.Chips, 634 Headimgurl: playerData.user.baseData.userData.Headimgurl, 635 Dealer: playerData.user.baseData.userData.UserID == room.landlordUserID, 636 } 637 if room.rule.RoomType == roomRedPacketMatching { 638 re.Chips = int64(-room.rule.BaseScore) 639 } 640 r.Results = append(r.Results, re) 641 } 642 if room.rule.RoomType == roomRedPacketMatching { 643 r.Profit = -int64(room.rule.BaseScore) 644 } 645 saveGameRecord(r) 646 } 647 648 for _, userID := range roomm.positionUserIDs { 649 if user, ok := userIDUsers[userID]; ok { 650 user.WriteMsg(&msg.S2C_UpdateUserChips{ 651 Chips: user.baseData.userData.Chips, 652 }) 653 } 654 roomm.updateAllPlayerChips(userID) 655 if roomm.rule.BaseScore == 10000 { 656 //高级任务 参与土豪场10次 3009 657 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(3009) 658 } 659 //新人任务 累计对局10局 1000 660 if roomm.rule.RoomType == roomBaseScoreMatching { 661 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(1000) 662 } 663 roomm.doTask(userID, 5) // 累计对局10局 664 roomm.doTask(userID, 17) // 累计对局5局,奖励2000金币 665 roomm.doTask(userID, 18) // 累计对局10局,奖励3000金币 666 roomm.doTask(userID, 19) // 累计对局15局,奖励5000金币 667 if roomm.rule.BaseScore == 3000 { 668 roomm.doTask(userID, 37) // 普通场对局10次 669 //中级任务 普通场累计对局10次 2003 670 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(2003) 671 } 672 } 673 for _, p := range roomm.userIDPlayerDatas { 674 p.user.LastTaskId = 0 675 } 676 if roomm.rule.RoomType == roomVIPPrivate { 677 for _, userID := range roomm.positionUserIDs { 678 playerData := roomm.userIDPlayerDatas[userID] 679 playerData.vipChips = 0 680 } 681 } 682 skeleton.AfterFunc(1500*time.Millisecond, func() { 683 for _, userID := range roomm.positionUserIDs { 684 playerData := roomm.userIDPlayerDatas[userID] 685 //playerData.user.offerSubsidy() 686 roomm.sendRoundResult(userID, playerData.roundResults) 687 playerData.user.AskSubsidyChip() 688 } 689 690 roomm.state = roomIdle 691 for _, userID := range roomm.positionUserIDs { 692 switch roomm.rule.RoomType { 693 case roomBaseScoreMatching, roomRedPacketMatching, roomRedPacketPrivate: 694 roomm.Leave(userID) 695 } 696 } 697 }) 698 } 699 700 // 断线重连 701 func (roomm *LandlordRoom) reconnect(user *User) { 702 thePlayerData := roomm.userIDPlayerDatas[user.baseData.userData.UserID] 703 if thePlayerData == nil { 704 return 705 } 706 user.WriteMsg(&msg.S2C_GameStart{}) 707 if roomm.landlordUserID > 0 { 708 landlordPlayerData := roomm.userIDPlayerDatas[roomm.landlordUserID] 709 user.WriteMsg(&msg.S2C_DecideLandlord{ 710 Position: landlordPlayerData.position, 711 }) 712 user.WriteMsg(&msg.S2C_UpdateLandlordLastThree{ 713 Cards: roomm.lastThree, 714 }) 715 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 716 Multiple: thePlayerData.multiple, 717 }) 718 } 719 if roomm.discarderUserID > 0 { 720 discarderPlayerData := roomm.userIDPlayerDatas[roomm.discarderUserID] 721 if len(discarderPlayerData.discards) > 1 { 722 prevDiscards := discarderPlayerData.discards[len(discarderPlayerData.discards)-1] 723 user.WriteMsg(&msg.S2C_LandlordDiscard{ 724 Position: discarderPlayerData.position, 725 Cards: prevDiscards, 726 }) 727 } 728 } 729 roomm.getPlayerData(user, thePlayerData, false) 730 731 for i := 1; i < roomm.rule.MaxPlayers; i++ { 732 otherUserID := roomm.positionUserIDs[(thePlayerData.position+i)%roomm.rule.MaxPlayers] 733 otherPlayerData := roomm.userIDPlayerDatas[otherUserID] 734 735 roomm.getPlayerData(user, otherPlayerData, true) 736 } 737 } 738 739 func (roomm *LandlordRoom) getPlayerData(user *User, playerData *LandlordPlayerData, other bool) { 740 hands := playerData.hands 741 if other && !playerData.showCards { 742 hands = []int{} 743 } 744 user.WriteMsg(&msg.S2C_UpdatePokerHands{ 745 Position: playerData.position, 746 Hands: hands, 747 NumberOfHands: len(playerData.hands), 748 ShowCards: playerData.showCards, 749 }) 750 if playerData.hosted { 751 user.WriteMsg(&msg.S2C_SystemHost{ 752 Position: playerData.position, 753 Host: true, 754 }) 755 } 756 switch playerData.state { 757 case landlordActionBid: 758 after := int(time.Now().Unix() - playerData.actionTimestamp) 759 countdown := conf.GetCfgTimeout().LandlordBid - after 760 if countdown > 1 { 761 user.WriteMsg(&msg.S2C_ActionLandlordBid{ 762 Position: playerData.position, 763 Countdown: countdown - 1, 764 }) 765 } 766 case landlordActionGrab: 767 after := int(time.Now().Unix() - playerData.actionTimestamp) 768 countdown := conf.GetCfgTimeout().LandlordGrab - after 769 if countdown > 1 { 770 user.WriteMsg(&msg.S2C_ActionLandlordGrab{ 771 Position: playerData.position, 772 Countdown: countdown - 1, 773 }) 774 } 775 case landlordActionDouble: 776 if other { 777 return 778 } 779 after := int(time.Now().Unix() - playerData.actionTimestamp) 780 countdown := conf.GetCfgTimeout().LandlordDouble - after 781 if countdown > 1 { 782 user.WriteMsg(&msg.S2C_ActionLandlordDouble{ 783 Countdown: countdown - 1, 784 }) 785 } 786 case landlordActionShowCards: 787 if other { 788 return 789 } 790 after := int(time.Now().Unix() - playerData.actionTimestamp) 791 countdown := conf.GetCfgTimeout().LandlordShowCards - after 792 if countdown > 1 { 793 user.WriteMsg(&msg.S2C_ActionLandlordShowCards{ 794 Countdown: countdown - 1, 795 }) 796 } 797 case landlordActionDiscard: 798 after := int(time.Now().Unix() - playerData.actionTimestamp) 799 var prevDiscards []int 800 if roomm.discarderUserID > 0 && roomm.discarderUserID != user.baseData.userData.UserID { 801 discarderPlayerData := roomm.userIDPlayerDatas[roomm.discarderUserID] 802 prevDiscards = discarderPlayerData.discards[len(discarderPlayerData.discards)-1] 803 } 804 countdown := conf.GetCfgTimeout().LandlordDiscard - after 805 if countdown > 1 { 806 user.WriteMsg(&msg.S2C_ActionLandlordDiscard{ 807 ActionDiscardType: playerData.actionDiscardType, 808 Position: playerData.position, 809 Countdown: countdown - 1, 810 PrevDiscards: prevDiscards, 811 }) 812 } 813 } 814 } 815 816 func (roomm *LandlordRoom) prepare() { 817 // 洗牌 818 switch roomm.rule.MaxPlayers { 819 case 2: 820 roomm.cards = common.Shuffle(poker.LandlordAllCards2P) 821 case 3: 822 roomm.cards = common.Shuffle(poker.LandlordAllCards) 823 } 824 roomm.shuffleTimes++ 825 // 确定庄家 826 roomm.dealerUserID = roomm.positionUserIDs[0] 827 if len(roomm.getShowCardsUserIDs()) == 0 { // 无人明牌 828 roomm.dealerUserID = roomm.positionUserIDs[0] 829 if roomm.finisherUserID > 0 { 830 roomm.dealerUserID = roomm.finisherUserID 831 } 832 } else { 833 roomm.dealerUserID = roomm.getShowCardsUserIDs()[0] 834 } 835 roomm.startTimestamp = time.Now().Unix() 836 roomm.eachRoundStartTimestamp = roomm.startTimestamp 837 dealerPlayerData := roomm.userIDPlayerDatas[roomm.dealerUserID] 838 dealerPlayerData.dealer = true 839 // 确定闲家(注:闲家的英文单词也为player) 840 dealerPos := dealerPlayerData.position 841 for i := 1; i < roomm.rule.MaxPlayers; i++ { 842 playerPos := (dealerPos + i) % roomm.rule.MaxPlayers 843 playerUserID := roomm.positionUserIDs[playerPos] 844 playerPlayerData := roomm.userIDPlayerDatas[playerUserID] 845 playerPlayerData.dealer = false 846 } 847 roomm.lastThree = []int{} 848 roomm.discards = []int{} 849 // 剩余的牌 850 roomm.rests = roomm.cards 851 852 roomm.bidUserID = -1 853 roomm.grabUserIDs = []int{} 854 roomm.landlordUserID = -1 855 roomm.peasantUserIDs = []int{} 856 roomm.discarderUserID = -1 857 roomm.finisherUserID = -1 858 roomm.spring = false 859 roomm.winnerUserIDs = []int{} 860 861 multiple := 1 862 if len(roomm.getShowCardsUserIDs()) > 0 { 863 multiple = 2 864 } 865 for _, userID := range roomm.positionUserIDs { 866 playerData := roomm.userIDPlayerDatas[userID] 867 playerData.multiple = multiple 868 playerData.hands = []int{} 869 playerData.discards = [][]int{} 870 playerData.actionTimestamp = 0 871 playerData.hosted = false 872 873 roundResult := playerData.roundResult 874 roundResult.Chips = 0 875 } 876 } 877 878 func (roomm *LandlordRoom) showHand() { 879 for _, userID := range roomm.positionUserIDs { 880 playerData := roomm.userIDPlayerDatas[userID] 881 if len(playerData.hands) > 0 { 882 broadcast(&msg.S2C_UpdatePokerHands{ 883 Position: playerData.position, 884 Hands: playerData.hands, 885 NumberOfHands: len(playerData.hands), 886 }, roomm.positionUserIDs, -1) 887 } 888 } 889 } 890 891 // 确定赢家 892 func (roomm *LandlordRoom) decideWinner() { 893 roomm.spring = true 894 landlordWin := true 895 landlordPlayerData := roomm.userIDPlayerDatas[roomm.landlordUserID] 896 var loserUserIDs []int // 用于连胜任务统计 897 if roomm.landlordUserID == roomm.winnerUserIDs[0] { 898 loserUserIDs = append(loserUserIDs, roomm.peasantUserIDs...) 899 for _, peasantUserID := range roomm.peasantUserIDs { 900 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 901 if len(peasantPlayerData.discards) > 0 { 902 roomm.spring = false 903 break 904 } 905 } 906 log.Debug("游戏结束 地主胜利 春天: %v", roomm.spring) 907 roomm.doTask(roomm.landlordUserID, 48) // 以地主身份获胜10局 908 //初级任务 以地主身份获胜5局 1014 909 landlordPlayerData.user.updateRedPacketTask(1014) 910 //中级任务 以地主身份获胜10次 2011 911 landlordPlayerData.user.updateRedPacketTask(2011) 912 if roomm.rule.BaseScore == 3000 { 913 roomm.doTask(roomm.landlordUserID, 59) // 普通场地主身份获胜6局 914 } 915 } else { 916 landlordWin = false 917 roomm.winnerUserIDs = roomm.peasantUserIDs 918 loserUserIDs = append(loserUserIDs, roomm.landlordUserID) 919 if len(landlordPlayerData.discards) > 1 { 920 roomm.spring = false 921 } 922 log.Debug("游戏结束 农民胜利 春天: %v", roomm.spring) 923 for _, userID := range roomm.peasantUserIDs { 924 roomm.doTask(userID, 49) // 以农民身份获胜12局 925 if roomm.rule.BaseScore == 3000 { 926 roomm.doTask(userID, 60) // 普通场农民身份获胜8局 927 } 928 } 929 } 930 if roomm.spring { 931 roomm.calculateMultiple(-1, 2) 932 broadcast(&msg.S2C_LandlordSpring{}, roomm.positionUserIDs, -1) 933 //高级任务 打出两个春天 3006 934 roomm.userIDPlayerDatas[roomm.winnerUserIDs[0]].user.updateRedPacketTask(3006) 935 } 936 if landlordWin { 937 switch roomm.rule.RoomType { 938 case roomBaseScoreMatching, roomBaseScorePrivate: 939 landlordPlayerData.roundResult.Chips = 0 940 for _, peasantUserID := range roomm.peasantUserIDs { 941 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 942 peasantLoss := int64(peasantPlayerData.multiple) * int64(roomm.rule.BaseScore) 943 if peasantLoss > peasantPlayerData.user.baseData.userData.Chips { 944 peasantPlayerData.roundResult.Chips = -peasantPlayerData.user.baseData.userData.Chips 945 } else { 946 peasantPlayerData.roundResult.Chips = -peasantLoss 947 } 948 landlordPlayerData.roundResult.Chips += -peasantPlayerData.roundResult.Chips 949 } 950 landlordGain := int64(roomm.rule.BaseScore) * int64(landlordPlayerData.multiple) 951 if landlordGain > landlordPlayerData.user.baseData.userData.Chips { 952 landlordGain = landlordPlayerData.user.baseData.userData.Chips 953 } 954 if landlordGain < landlordPlayerData.roundResult.Chips { 955 landlordPlayerData.roundResult.Chips = 0 956 for _, peasantUserID := range roomm.peasantUserIDs { 957 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 958 peasantLoss := landlordGain * int64(peasantPlayerData.multiple) / int64(landlordPlayerData.multiple) 959 if peasantLoss > peasantPlayerData.user.baseData.userData.Chips { 960 peasantPlayerData.roundResult.Chips = -peasantPlayerData.user.baseData.userData.Chips 961 } else { 962 peasantPlayerData.roundResult.Chips = -peasantLoss 963 } 964 landlordPlayerData.roundResult.Chips += -peasantPlayerData.roundResult.Chips 965 } 966 } 967 case roomVIPPrivate: 968 landlordPlayerData.roundResult.Chips = 0 969 for _, peasantUserID := range roomm.peasantUserIDs { 970 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 971 peasantPlayerData.roundResult.Chips = -peasantPlayerData.vipChips 972 landlordPlayerData.roundResult.Chips += peasantPlayerData.vipChips 973 peasantPlayerData.vipChips = 0 // 农民输光VIP筹码 974 } 975 case roomRedPacketMatching, roomRedPacketPrivate: 976 landlordPlayerData.roundResult.RedPacket = float64(roomm.rule.RedPacketType) 977 } 978 } else { 979 var peasantsGain int64 980 switch roomm.rule.RoomType { 981 case roomBaseScoreMatching, roomBaseScorePrivate: 982 for _, peasantUserID := range roomm.peasantUserIDs { 983 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 984 peasantGain := int64(roomm.rule.BaseScore) * int64(peasantPlayerData.multiple) 985 if peasantGain > peasantPlayerData.user.baseData.userData.Chips { 986 peasantPlayerData.roundResult.Chips = peasantPlayerData.user.baseData.userData.Chips 987 } else { 988 peasantPlayerData.roundResult.Chips = peasantGain 989 } 990 peasantsGain += peasantPlayerData.roundResult.Chips 991 } 992 if peasantsGain > landlordPlayerData.user.baseData.userData.Chips { 993 peasantsGain = landlordPlayerData.user.baseData.userData.Chips 994 landlordPlayerData.roundResult.Chips = 0 995 for _, peasantUserID := range roomm.peasantUserIDs { 996 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 997 peasantGain := peasantsGain * int64(peasantPlayerData.multiple) / int64(landlordPlayerData.multiple) 998 if peasantGain > peasantPlayerData.user.baseData.userData.Chips { 999 peasantPlayerData.roundResult.Chips = peasantPlayerData.user.baseData.userData.Chips 1000 } else { 1001 peasantPlayerData.roundResult.Chips = peasantGain 1002 } 1003 landlordPlayerData.roundResult.Chips += -peasantPlayerData.roundResult.Chips 1004 } 1005 } else { 1006 landlordPlayerData.roundResult.Chips = -peasantsGain 1007 } 1008 case roomVIPPrivate: 1009 peasantsGain = landlordPlayerData.vipChips 1010 landlordPlayerData.roundResult.Chips = -peasantsGain 1011 landlordPlayerData.vipChips = 0 // 地主输光VIP筹码 1012 var peasantsTotalVIPChips int64 = 0 1013 for _, peasantUserID := range roomm.peasantUserIDs { 1014 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 1015 peasantsTotalVIPChips += peasantPlayerData.vipChips 1016 } 1017 for _, peasantUserID := range roomm.peasantUserIDs { 1018 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 1019 peasantPlayerData.roundResult.Chips = peasantsGain * peasantPlayerData.vipChips / peasantsTotalVIPChips 1020 } 1021 case roomRedPacketMatching, roomRedPacketPrivate: 1022 for _, peasantUserID := range roomm.peasantUserIDs { 1023 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 1024 peasantPlayerData.roundResult.RedPacket = float64(roomm.rule.RedPacketType) / float64(len(roomm.peasantUserIDs)) 1025 } 1026 } 1027 } 1028 switch roomm.rule.RoomType { 1029 case roomRedPacketMatching, roomRedPacketPrivate: 1030 for _, userID := range roomm.positionUserIDs { 1031 playerData := roomm.userIDPlayerDatas[userID] 1032 if !playerData.user.isRobot() && playerData.roundResult.RedPacket > 0 { 1033 WriteRedPacketGrantRecord(playerData.user.baseData.userData, 3, fmt.Sprintf("%v元红包场”胜利", roomm.rule.RedPacketType), playerData.roundResult.RedPacket) 1034 } 1035 saveRedPacketMatchResultData(&RedPacketMatchResultData{ 1036 UserID: userID, 1037 RedPacketType: roomm.rule.RedPacketType, 1038 RedPacket: playerData.roundResult.RedPacket, 1039 Taken: false, 1040 CreatedAt: time.Now().Unix(), 1041 }) 1042 // 扣除参赛筹码 1043 playerData.roundResult.Chips = -roomm.rule.MinChips 1044 } 1045 } 1046 for _, userID := range loserUserIDs { 1047 roomm.resetTask(userID, 6) // 任意场连胜2局 1048 roomm.resetTask(userID, 20) // 任意场连胜2局,奖励3000金币 1049 roomm.resetTask(userID, 21) // 任意场连胜3局,奖励5000金币 1050 roomm.resetTask(userID, 50) // 连胜5局 1051 roomm.userIDPlayerDatas[userID].user.clearRedPacketTask(2008) 1052 roomm.userIDPlayerDatas[userID].user.clearRedPacketTask(3004) 1053 roomm.userIDPlayerDatas[userID].user.clearRedPacketTask(1001) 1054 //计入流水(竞技场计入流水) 1055 if roomm.rule.RoomType == basescoreMatching && !roomm.userIDPlayerDatas[userID].user.isRobot() { 1056 1057 //自己的流水记录 1058 a := &AgentProfit{ 1059 Accountid: roomm.userIDPlayerDatas[userID].user.baseData.userData.AccountID, 1060 FirstLevelChips: 0, 1061 OtherLevelChips: 0, 1062 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1063 Str: common.TimeFormat(), 1064 Chips: int64(-roomm.userIDPlayerDatas[userID].roundResult.Chips), 1065 } 1066 a.insert() 1067 if roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId != 0 { 1068 a = &AgentProfit{ 1069 Accountid: int(roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId), 1070 FirstLevelChips: int64(-roomm.userIDPlayerDatas[userID].roundResult.Chips), 1071 OtherLevelChips: 0, 1072 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1073 Str: common.TimeFormat(), 1074 Chips: 0, 1075 } 1076 a.insert() 1077 1078 accountid := roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId 1079 Label: 1080 for { 1081 1082 data := new(UserData) 1083 data.readByAccountID(accountid) 1084 if data.ParentId != 0 { 1085 accountid = data.ParentId 1086 a = &AgentProfit{ 1087 Accountid: int(accountid), 1088 FirstLevelChips: 0, 1089 OtherLevelChips: int64(-roomm.userIDPlayerDatas[userID].roundResult.Chips), 1090 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1091 Str: common.TimeFormat(), 1092 Chips: 0, 1093 } 1094 a.insert() 1095 continue 1096 } 1097 break Label 1098 1099 } 1100 } 1101 } 1102 } 1103 for _, userID := range roomm.winnerUserIDs { 1104 //初级任务 明牌获胜3次 1015 1105 //高级任务 明牌获胜5次 3007 1106 1107 if roomm.userIDPlayerDatas[userID].showCards { 1108 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(1015) 1109 1110 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(3007) 1111 1112 } 1113 //新人任务 累计胜利10局 1004 1114 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(1004) 1115 roomm.doTask(userID, 0) // 累计胜利10局 1116 roomm.doTask(userID, 14) // 累计胜利3局,奖励2000金币 1117 roomm.doTask(userID, 15) // 累计胜利5局,奖励3000金币 1118 roomm.doTask(userID, 16) // 累计胜利6局,奖励3000金币 1119 1120 roomm.doTask(userID, 6) // 任意场连胜2局 1121 roomm.doTask(userID, 20) // 任意场连胜2局,奖励3000金币 1122 roomm.doTask(userID, 21) // 任意场连胜3局,奖励5000金币 1123 roomm.doTask(userID, 50) // 连胜5局 1124 //新人任务 连胜2局 1001 1125 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(1001) 1126 //初级任务 胜利5局 1005 1127 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(1005) 1128 //中级任务 连胜5局 2008 1129 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(2008) 1130 //高级任务 连胜8局 3004 1131 roomm.userIDPlayerDatas[userID].user.updateRedPacketTask(3004) 1132 if user, ok := userIDUsers[userID]; ok { 1133 user.baseData.userData.Wins += 1 // 统计胜场 1134 } else { 1135 updateUserData(userID, bson.M{"$inc": bson.M{"wins": 1}}) 1136 } 1137 1138 switch roomm.rule.RoomType { 1139 case roomBaseScoreMatching, roomBaseScorePrivate, roomVIPPrivate: 1140 playerData := roomm.userIDPlayerDatas[userID] 1141 upsertMonthChipsRank(userID, playerData.roundResult.Chips) 1142 } 1143 switch roomm.rule.RoomType { 1144 case roomBaseScoreMatching, roomBaseScorePrivate, roomVIPPrivate, roomRedPacketMatching, roomRedPacketPrivate: 1145 upsertMonthWinsRank(userID, 1) 1146 } 1147 //计入流水(竞技场计入流水) 1148 if roomm.rule.RoomType == basescoreMatching && !roomm.userIDPlayerDatas[userID].user.isRobot() { 1149 1150 //自己的流水记录 1151 a := &AgentProfit{ 1152 Accountid: roomm.userIDPlayerDatas[userID].user.baseData.userData.AccountID, 1153 FirstLevelChips: 0, 1154 OtherLevelChips: 0, 1155 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1156 Str: common.TimeFormat(), 1157 Chips: int64(roomm.userIDPlayerDatas[userID].roundResult.Chips), 1158 } 1159 a.insert() 1160 if roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId != 0 { 1161 a = &AgentProfit{ 1162 Accountid: int(roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId), 1163 FirstLevelChips: int64(roomm.userIDPlayerDatas[userID].roundResult.Chips), 1164 OtherLevelChips: 0, 1165 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1166 Str: common.TimeFormat(), 1167 Chips: 0, 1168 } 1169 a.insert() 1170 accountid := roomm.userIDPlayerDatas[userID].user.baseData.userData.ParentId 1171 Label1: 1172 for { 1173 1174 data := new(UserData) 1175 data.readByAccountID(accountid) 1176 if data.ParentId != 0 { 1177 accountid = data.ParentId 1178 a = &AgentProfit{ 1179 Accountid: int(accountid), 1180 FirstLevelChips: 0, 1181 OtherLevelChips: int64(roomm.userIDPlayerDatas[userID].roundResult.Chips), 1182 CreateDat: common.OneDay0ClockTimestamp(time.Now()), 1183 Str: common.TimeFormat(), 1184 Chips: 0, 1185 } 1186 a.insert() 1187 continue 1188 } 1189 break Label1 1190 1191 } 1192 } 1193 } 1194 } 1195 } 1196 1197 // 发送单局结果 1198 func (roomm *LandlordRoom) sendRoundResult(userID int, roundResults []poker.LandlordPlayerRoundResult) { 1199 if user, ok := userIDUsers[userID]; ok { 1200 result := poker.ResultLose 1201 if common.InArray(roomm.winnerUserIDs, userID) { 1202 result = poker.ResultWin 1203 } 1204 tempMsg := &msg.S2C_LandlordRoundResult{ 1205 Result: result, 1206 RoomDesc: roomm.desc, 1207 Spring: roomm.spring, 1208 RoundResults: roundResults, 1209 ContinueGame: true, 1210 } 1211 switch roomm.rule.RoomType { 1212 case roomRedPacketMatching, roomRedPacketPrivate: 1213 tempMsg.ContinueGame = false 1214 } 1215 user.WriteMsg(tempMsg) 1216 } 1217 } 1218 1219 // 计算倍数 1220 func (roomm *LandlordRoom) calculateMultiple(theUserID int, multiple int) { 1221 if theUserID == -1 || roomm.landlordUserID == theUserID { 1222 for _, userID := range roomm.positionUserIDs { 1223 playerData := roomm.userIDPlayerDatas[userID] 1224 playerData.multiple *= multiple 1225 if user, ok := userIDUsers[userID]; ok { 1226 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 1227 Multiple: playerData.multiple, 1228 }) 1229 } 1230 } 1231 } else { 1232 thePlayerData := roomm.userIDPlayerDatas[theUserID] 1233 thePlayerData.multiple *= multiple 1234 if user, ok := userIDUsers[theUserID]; ok { 1235 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 1236 Multiple: thePlayerData.multiple, 1237 }) 1238 } 1239 landlordMultiple := roomm.calculateLandlordMultiple() 1240 if user, ok := userIDUsers[roomm.landlordUserID]; ok { 1241 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 1242 Multiple: landlordMultiple, 1243 }) 1244 } 1245 } 1246 } 1247 1248 // 计算地主的倍数 1249 func (roomm *LandlordRoom) calculateLandlordMultiple() int { 1250 landlordPlayerData := roomm.userIDPlayerDatas[roomm.landlordUserID] 1251 landlordPlayerData.multiple = 0 1252 for i := 1; i < roomm.rule.MaxPlayers; i++ { 1253 peasantUserID := roomm.positionUserIDs[(landlordPlayerData.position+i)%roomm.rule.MaxPlayers] 1254 peasantPlayerData := roomm.userIDPlayerDatas[peasantUserID] 1255 landlordPlayerData.multiple += peasantPlayerData.multiple 1256 } 1257 return landlordPlayerData.multiple 1258 } 1259 1260 // 结算筹码 1261 func (roomm *LandlordRoom) calculateChips(userID int, chips int64) { 1262 if user, ok := userIDUsers[userID]; ok { 1263 user.baseData.userData.Chips += chips 1264 1265 if user.isRobot() { 1266 switch roomm.rule.RoomType { 1267 case roomBaseScoreMatching: 1268 upsertRobotData(time.Now().Format("20060102"), bson.M{"$inc": bson.M{"basescorematchingbalance": chips}}) 1269 case roomRedPacketMatching: 1270 upsertRobotData(time.Now().Format("20060102"), bson.M{"$inc": bson.M{"redpacketmatchingbalance": chips}}) 1271 } 1272 } 1273 } else { 1274 updateUserData(userID, bson.M{"$inc": bson.M{"chips": chips}}) 1275 } 1276 } 1277 1278 // 更新所有玩家的筹码 1279 func (roomm *LandlordRoom) updateAllPlayerChips(playerUserID int) { 1280 if user, ok := userIDUsers[playerUserID]; ok { 1281 for _, userID := range roomm.positionUserIDs { 1282 playerData := roomm.userIDPlayerDatas[userID] 1283 chips := playerData.user.baseData.userData.Chips 1284 if roomm.rule.RoomType == roomVIPPrivate { 1285 chips = playerData.vipChips 1286 } 1287 user.WriteMsg(&msg.S2C_UpdatePlayerChips{ 1288 Position: playerData.position, 1289 Chips: chips, 1290 }) 1291 } 1292 } 1293 } 1294 1295 // 换桌(练习场、底分匹配场、红包匹配场才可以换桌) 1296 func (roomm *LandlordRoom) changeTable(user *User) { 1297 userID := user.baseData.userData.UserID 1298 playerData := roomm.userIDPlayerDatas[userID] 1299 if playerData == nil { 1300 return 1301 } 1302 for i := 1; i < roomm.rule.MaxPlayers; i++ { 1303 otherUserID := roomm.positionUserIDs[(playerData.position+i)%roomm.rule.MaxPlayers] 1304 if otherUserID > 0 { 1305 otherPlayerData := roomm.userIDPlayerDatas[otherUserID] 1306 if otherPlayerData != nil { 1307 user.WriteMsg(&msg.S2C_StandUp{Position: otherPlayerData.position}) 1308 } 1309 } 1310 } 1311 broadcast(&msg.S2C_StandUp{ 1312 Position: playerData.position, 1313 }, roomm.positionUserIDs, -1) 1314 1315 broadcast(&msg.S2C_ExitRoom{ 1316 Error: msg.S2C_ExitRoom_OK, 1317 Position: playerData.position, 1318 }, roomm.positionUserIDs, playerData.position) 1319 1320 roomm.StandUp(user, playerData.position) // 站起 1321 delete(userIDRooms, userID) // 退出 1322 delete(roomm.loginIPs, user.baseData.userData.LoginIP) // 删除玩家登录IP 1323 if roomm.empty() { // 玩家为空,解散房间 1324 log.Debug("userID: %v 退出房间,房间解散", userID) 1325 delete(roomNumberRooms, roomm.number) 1326 } else { 1327 if roomm.ownerUserID == userID { // 转移房主 1328 for _, userID := range roomm.positionUserIDs { 1329 roomm.ownerUserID = userID 1330 break 1331 } 1332 log.Debug("userID: %v 退出房间, 转移房主 :%v", userID, roomm.ownerUserID) 1333 user.baseData.ownerUserID = roomm.ownerUserID 1334 } else { 1335 log.Debug("userID: %v 退出房间", userID) 1336 } 1337 } 1338 switch roomm.rule.RoomType { 1339 case roomPractice: 1340 for _, r := range roomNumberRooms { 1341 room := r.(*LandlordRoom) 1342 if room.rule.RoomType == roomPractice && !room.full() && room.ownerUserID != user.baseData.ownerUserID { 1343 user.enterRoom(r) 1344 return 1345 } 1346 } 1347 case roomBaseScoreMatching: 1348 if conf.Server.Model { 1349 for _, r := range roomNumberRooms { 1350 room := r.(*LandlordRoom) 1351 if !room.loginIPs[user.baseData.userData.LoginIP] && room.rule.RoomType == roomBaseScoreMatching && room.rule.BaseScore == roomm.rule.BaseScore && !room.full() && room.ownerUserID != user.baseData.ownerUserID { 1352 if !room.playTogether(user) { 1353 user.enterRoom(r) 1354 return 1355 } 1356 } 1357 } 1358 for _, r := range roomNumberRooms { 1359 room := r.(*LandlordRoom) 1360 if room.rule.RoomType == roomBaseScoreMatching && room.rule.BaseScore == roomm.rule.BaseScore && !room.full() && room.ownerUserID != user.baseData.ownerUserID { 1361 1362 user.enterRoom(r) 1363 return 1364 1365 } 1366 } 1367 } 1368 case roomRedPacketMatching: 1369 // 一元红包场换房 1370 if roomm.rule.RedPacketType == 1 { 1371 if time.Now().Hour() < conf.GetOneRedpacketInfo().Start || time.Now().Hour() > conf.GetOneRedpacketInfo().End { 1372 user.WriteMsg(&msg.S2C_EnterRoom{Error: msg.S2C_EnterRoom_NotRightNow}) 1373 return 1374 } 1375 } 1376 if roomm.rule.RedPacketType == 10 { 1377 if time.Now().Hour() < conf.GetTenRedpacketInfo().Start || time.Now().Hour() > conf.GetTenRedpacketInfo().End { 1378 user.WriteMsg(&msg.S2C_EnterRoom{Error: msg.S2C_EnterRoom_NotRightNow}) 1379 return 1380 } 1381 } 1382 if !conf.Server.Model { 1383 for _, r := range roomNumberRooms { 1384 room := r.(*LandlordRoom) 1385 if !room.loginIPs[user.baseData.userData.LoginIP] && room.rule.RoomType == roomRedPacketMatching && room.rule.RedPacketType == roomm.rule.RedPacketType && !room.full() && room.ownerUserID != user.baseData.ownerUserID { 1386 if !room.playTogether(user) { 1387 user.enterRoom(r) 1388 return 1389 } 1390 } 1391 } 1392 } 1393 for _, r := range roomNumberRooms { 1394 room := r.(*LandlordRoom) 1395 if room.rule.RoomType == roomRedPacketMatching && room.rule.RedPacketType == roomm.rule.RedPacketType && !room.full() && room.ownerUserID != user.baseData.ownerUserID { 1396 1397 user.enterRoom(r) 1398 return 1399 1400 } 1401 } 1402 } 1403 user.createLandlordRoom(roomm.rule) 1404 } 1405 1406 func (room *LandlordRoom) updateTaskTicket(userID int) { 1407 playerData := room.userIDPlayerDatas[userID] 1408 for _, task := range playerData.user.baseData.taskIDTaskDatas { 1409 if TaskList[task.TaskID].Type == taskRedPacket && task.Progress < TaskList[task.TaskID].Total { 1410 upsertTaskTicket(bson.M{"userid": userID, "finish": false, "taskid": task.TaskID}, 1411 bson.M{"$inc": bson.M{"ticket_" + strconv.Itoa(int(room.rule.Tickets)): 1}}) 1412 } 1413 } 1414 }