Browse Source

1 增加后台获取桌子配置

2 通知退出桌子 增加用户id 用于区别观战用户
3 新增halltwo模块的编译
dev
MoQingYu 5 months ago
parent
commit
d5f08c65da
  1. 4
      BuildSelect.py
  2. 4
      game-server/game/21Game/app/core/core.go
  3. 6
      game-server/game/21Game/app/core/game/game.go
  4. 31
      game-server/game/21Game/app/core/game/game_bet.go
  5. 5
      game-server/game/21Game/app/core/game/game_disconnect.go
  6. 8
      game-server/game/21Game/app/core/game/game_get_banker.go
  7. 1
      game-server/game/21Game/app/core/game/game_get_room_info.go
  8. 10
      game-server/game/21Game/app/core/game/game_init.go
  9. 113
      game-server/game/21Game/app/core/game/game_logic.go
  10. 9
      game-server/game/21Game/app/core/game/game_operate.go
  11. 100
      game-server/game/21Game/app/core/game/game_out_room.go
  12. 11
      game-server/game/21Game/app/core/game/game_over.go
  13. 17
      game-server/game/21Game/app/core/game/game_player.go
  14. 47
      game-server/game/21Game/app/core/game/game_robot.go
  15. 142
      game-server/game/21Game/app/core/game/game_robot_timer.go
  16. 18
      game-server/game/21Game/app/core/game/game_watch.go
  17. 2
      game-server/game/21Game/app/core/protocol/protocol_msg.go
  18. 72
      game-server/game/21Game/app/core/room/roommgr.go
  19. 12
      game-server/game/21Game/app/gamemanage/gamemanage.go
  20. 1
      game-server/game/AndarBahar/app/core/protocol/protocol_msg.go
  21. 18
      game-server/game/DZ/app/config/config.go
  22. 4
      game-server/game/DZ/app/core/core.go
  23. 43
      game-server/game/DZ/app/core/game/game.go
  24. 10
      game-server/game/DZ/app/core/game/game_disconnect.go
  25. 9
      game-server/game/DZ/app/core/game/game_get_room_info.go
  26. 9
      game-server/game/DZ/app/core/game/game_init.go
  27. 91
      game-server/game/DZ/app/core/game/game_logic.go
  28. 14
      game-server/game/DZ/app/core/game/game_operate.go
  29. 85
      game-server/game/DZ/app/core/game/game_out_room.go
  30. 7
      game-server/game/DZ/app/core/game/game_over.go
  31. 33
      game-server/game/DZ/app/core/game/game_player.go
  32. 37
      game-server/game/DZ/app/core/game/game_robot.go
  33. 142
      game-server/game/DZ/app/core/game/game_robot_timer.go
  34. 3
      game-server/game/DZ/app/core/game/game_start.go
  35. 18
      game-server/game/DZ/app/core/game/game_watch.go
  36. 6
      game-server/game/DZ/app/core/protocol/protocol_msg.go
  37. 2
      game-server/game/DZ/app/core/protocol/protocol_struct.go
  38. 58
      game-server/game/DZ/app/core/room/roommgr.go
  39. 12
      game-server/game/DZ/app/gamemanage/gamemanage.go
  40. 112
      game-server/game/DZ/config/blood.json
  41. 4
      game-server/game/SixAndarBahar/app/core/core.go
  42. 4
      game-server/game/SixAndarBahar/app/core/game/game.go
  43. 5
      game-server/game/SixAndarBahar/app/core/game/game_disconnect.go
  44. 10
      game-server/game/SixAndarBahar/app/core/game/game_init.go
  45. 79
      game-server/game/SixAndarBahar/app/core/game/game_logic.go
  46. 83
      game-server/game/SixAndarBahar/app/core/game/game_out_room.go
  47. 5
      game-server/game/SixAndarBahar/app/core/game/game_over.go
  48. 1
      game-server/game/SixAndarBahar/app/core/game/game_player.go
  49. 42
      game-server/game/SixAndarBahar/app/core/game/game_robot.go
  50. 142
      game-server/game/SixAndarBahar/app/core/game/game_robot_timer.go
  51. 17
      game-server/game/SixAndarBahar/app/core/game/game_watch.go
  52. 1
      game-server/game/SixAndarBahar/app/core/protocol/protocol_msg.go
  53. 56
      game-server/game/SixAndarBahar/app/core/room/roommgr.go
  54. 20
      game-server/game/SixAndarBahar/app/gamemanage/gamemanage.go
  55. 1
      game-server/game/dragonTiger/app/core/protocol/protocol_msg.go
  56. 4
      game-server/game/rummy/app/core/core.go
  57. 4
      game-server/game/rummy/app/core/game/game.go
  58. 10
      game-server/game/rummy/app/core/game/game_disconnect.go
  59. 10
      game-server/game/rummy/app/core/game/game_init.go
  60. 5
      game-server/game/rummy/app/core/game/game_logic.go
  61. 86
      game-server/game/rummy/app/core/game/game_out_room.go
  62. 24
      game-server/game/rummy/app/core/game/game_over.go
  63. 1
      game-server/game/rummy/app/core/game/game_player.go
  64. 3
      game-server/game/rummy/app/core/game/game_watch.go
  65. 1
      game-server/game/rummy/app/core/protocol/protocol_msg.go
  66. 56
      game-server/game/rummy/app/core/room/roommgr.go
  67. 10
      game-server/game/rummy/app/gamemanage/gamemanage.go
  68. 14
      game-server/game/service/rpc_client/rpc_game.go
  69. 1
      game-server/game/sevenUpSevenDown/app/core/protocol/protocol_msg.go
  70. 1
      move.sh
  71. 1
      startserver.sh

4
BuildSelect.py

@ -69,6 +69,8 @@ def show_selection():
selected_options.append("/game-server/game/21Game")
if i == 16 and var.get():
selected_options.append("/game-server/game/DZ")
if i == 17 and var.get():
selected_options.append("/game-server/halltwo")
new_content = "my_array=\"" + " ".join(selected_options)+"\"" # 这里替换为您希望的新内容或者其他的逻辑计算得出的结果
with open(file_path, 'r', encoding='utf-8') as file:
@ -171,7 +173,7 @@ load_button.pack(pady=5)
# 创建变量列表用于跟踪选项状态
check_vars = []
options = ["mesh", "login", "hall", "gate", "commServer", "payment", "trackdot", "backstage", "operation", "dragonTiger", "rummy", "thirdgame", "AndarBahar", "SixAndarBahar","sevenUpSevenDown","21Game","DZ"]
options = ["mesh", "login", "hall", "gate", "commServer", "payment", "trackdot", "backstage", "operation", "dragonTiger", "rummy", "thirdgame", "AndarBahar", "SixAndarBahar","sevenUpSevenDown","21Game","DZ","halltwo"]
# 创建多选框
for option in options:

4
game-server/game/21Game/app/core/core.go

@ -53,6 +53,10 @@ func (c *Core) Init() {
userevt.SubscribeGoldChange(func(uid int64) {
gamemanage.UpdateUserGold(uid)
})
userevt.SubscribeTableConfigChange(func(gameID int64) {
gamemanage.UpdateTableConfig(gameID)
})
}
// Reconnect 掉线重连

6
game-server/game/21Game/app/core/game/game.go

@ -10,6 +10,7 @@ import (
"xgame/game/21Game/app/core/blood"
"xgame/game/21Game/app/core/types"
"xgame/internal/option/room"
gamepb "xgame/internal/service/game/pb"
"github.com/roylee0704/gron"
"github.com/shopspring/decimal"
@ -21,7 +22,7 @@ const (
const (
INVALID_VALUE = 0xFFFF //无效值
GAME_NAME = "6人AB" //游戏名字
GAME_NAME = "21点" //游戏名字
GAME_ID = 20009 //游戏ID
MAX_USER_NUM = 6 //房间最大人数
MAX_ROBOT_BUN = 3 //房间最多机器人
@ -57,7 +58,8 @@ const (
type Room struct {
RoomProxy *node.Proxy
Ctx context.Context
Opt *room.Options //房间的参数
Opt *room.Options //房间的参数
TableConfig *gamepb.GameTableTotal
DestroyRoomFunc func(int64) //销毁房间回调
QuitRoomFunc func(int64) //退出房间回调
NotifyFunc func(int32, interface{}) //大厅通知回调

31
game-server/game/21Game/app/core/game/game_bet.go

@ -2,7 +2,9 @@ package game
import (
"base/log"
"github.com/shopspring/decimal"
"strconv"
"time"
"xgame/game/21Game/app/core/protocol"
"xgame/game/21Game/app/route"
)
@ -68,6 +70,14 @@ func (rr *Room) OnUserBet(uid int64, msg interface{}) { // 用户下注
return
}
rr.UserScore[ChairId] = rr.UserScore[ChairId].Sub(decimal.NewFromInt(message.BetAmount))
rr.PlayerMap[ChairId].Gold = rr.PlayerMap[ChairId].Gold.Sub(decimal.NewFromInt(message.BetAmount))
if !rr.PlayerMap[ChairId].IsRobot && (rr.PlayerMap[ChairId].Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(rr.PlayerMap[ChairId], 1, message.BetAmount, 0, 0, rr.ReasonString, "", "", 0)
log.Debug("WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum)
}
BetRes.BetAmount = message.BetAmount
NotifyBet.ChairID = ChairId
@ -82,4 +92,25 @@ func (rr *Room) OnUserBet(uid int64, msg interface{}) { // 用户下注
rr.Send(TempPlayer, route.NotifyBet, NotifyBet)
}
}
for _, TempPlayer := range rr.PlayerWatchMap {
rr.Send(TempPlayer, route.NotifyBet, NotifyBet)
}
bBetEnd := true
for _, tempPlayer := range rr.PlayerMap {
if !tempPlayer.CanBet || tempPlayer.ChairId == rr.CurrBanker || tempPlayer.CellScore != 0 {
continue
}
bBetEnd = false
break
}
// 判断是否提前结束
milliseconds := time.Now().UnixMilli()
if milliseconds < rr.CurrentOperationTimer && bBetEnd { // 提前开始
log.Debug("OnUserBet 桌子号 ", rr.RId, " 下注提前结束 ")
rr.CurrentOperationTimer = milliseconds
}
}

5
game-server/game/21Game/app/core/game/game_disconnect.go

@ -9,7 +9,6 @@ import "base/log"
// OnDisconnect 玩家离线 保存正在游戏的进度
func (rr *Room) OnDisconnect(userId int64) {
rr.roomRWLock.Lock()
defer rr.roomRWLock.Unlock()
log.Debug(" 桌子号", rr.RId, "玩家", userId, "离线")
@ -26,8 +25,12 @@ func (rr *Room) OnDisconnect(userId int64) {
if player != nil {
if player.Uid == userId {
player.OnlineState = USER_OFF_LINE
rr.roomRWLock.Unlock()
rr.OnGetOutRoom(player.Uid)
rr.roomRWLock.Lock()
break
}
}
}
rr.roomRWLock.Unlock()
}

8
game-server/game/21Game/app/core/game/game_get_banker.go

@ -33,6 +33,14 @@ func (rr *Room) OnUserGetBanker(uid int64, msg interface{}) { // 用户抢庄
return
}
if rr.Opt.HostLimit != 0 && !rr.PlayerMap[ChairId].IsRobot && rr.PlayerMap[ChairId].Gold.IntPart() < rr.Opt.HostLimit {
log.Debug(" 桌子号", rr.RId, " 玩家", ChairId, "钱不够不能抢庄 ", rr.PlayerMap[ChairId].Gold.IntPart(), " 要求 ", rr.Opt.HostLimit)
BankerRes.Code = protocol.ErrorGetBanker
BankerRes.CodeMsg = "钱不够不能抢庄"
rr.Send(rr.PlayerMap[ChairId], route.GetBankerRes, BankerRes)
return
}
NotifyBanker.ChairID = ChairId
NotifyBanker.State = message.State
for _, TempPlayer := range rr.PlayerMap {

1
game-server/game/21Game/app/core/game/game_get_room_info.go

@ -21,6 +21,7 @@ func (rr *Room) OnGetRoomInfo(uid int64, ctx *node.Context) interface{} {
TableInfo.CurrentOperateUser = rr.CurrOperationPlayer
TableInfo.StatusChangeTimestamp = rr.CurrentOperationTimer
TableInfo.SingleMaxBet = rr.BankerLimitMax
TableInfo.BankerLimit = rr.Opt.HostLimit
TableInfo.RoomConfig = &protocol.TableConfig{
RechargeLimit: rr.BloodCtrl.RechargeLimit,
CellScore: rr.Opt.BetAssetOptions,

10
game-server/game/21Game/app/core/game/game_init.go

@ -3,6 +3,7 @@ package game
import (
"base/encoding/json"
"base/log"
"strconv"
"time"
"xgame/game/21Game/app/core/protocol"
"xgame/game/service/rpc_client"
@ -57,6 +58,15 @@ func (rr *Room) OnInit() bool {
// 读取配置文件
rr.InitBloodControl()
var gameTableConfig *gamepb.FetchGameTableTotalsReply
gameTableConfig = rpc_client.GetTableCtrlConfig(rr.RoomProxy, int64(rr.GameID), strconv.Itoa(int(rr.RoomID)))
if len(gameTableConfig.List) == 0 {
log.Error(" 21点后台获取桌子配置 无配置 房间等级 ", rr.RoomID)
} else {
rr.TableConfig = gameTableConfig.List[0]
log.Debug(" 21点后台获取桌子配置 房间等级 ", rr.RoomID, " 配置 ", rr.TableConfig)
}
//配置库存[房间的库存]
rr.StockValue = rr.BoolePool.BoolPoolSockNum

113
game-server/game/21Game/app/core/game/game_logic.go

@ -120,10 +120,11 @@ func (rr *Room) run() {
case protocol.STATE_BET:
{
if milliseconds >= rr.CurrentOperationTimer {
rr.CurrentOperationTimer = milliseconds + 60*1000
// 所有人下注
for index, tempPlayer := range rr.PlayerMap {
if tempPlayer.ChairId == rr.CurrBanker || rr.PlayerMap[index].CellScore != 0 {
if !tempPlayer.CanBet || tempPlayer.ChairId == rr.CurrBanker || rr.PlayerMap[index].CellScore != 0 {
continue
}
@ -135,11 +136,6 @@ func (rr *Room) run() {
rr.OnUserBet(tempPlayer.Uid, &protocol.BetReq{
BetAmount: rr.Opt.BetAssetOptions[0],
})
if !tempPlayer.IsRobot && (tempPlayer.Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(tempPlayer, 1, rr.Opt.BetAssetOptions[0], 0, 0, rr.ReasonString, "", "", 0)
log.Debug("定庄后 下注 WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum)
}
}
rr.CurrentGameState = protocol.STATE_BEGIN
@ -202,7 +198,7 @@ func (rr *Room) run() {
case protocol.STATE_OPERATE:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------ 超时操作 ", rr.RId, " 超时的信息 ", rr.CurrOperationPlayer, " ", rr.PlayerMap[rr.CurrOperationPlayer].Uid)
log.Debug(" 桌子号", rr.RId, " ------------------------------ 超时操作 ", " 超时的信息 ", rr.CurrOperationPlayer, " ", rr.PlayerMap[rr.CurrOperationPlayer].Uid)
rr.OnUserOperate(rr.PlayerMap[rr.CurrOperationPlayer].Uid, &protocol.OperateReq{
OperateCode: protocol.OperateStop,
})
@ -211,7 +207,7 @@ func (rr *Room) run() {
case protocol.STATE_SINGLE_RESULT_WAIT:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------ 开始单独结算 ", rr.RId)
log.Debug(" 桌子号", rr.RId, " ------------------------------ 开始单独结算 ")
// 先弄个长点的时间防止结算时间出问题
rr.CurrentOperationTimer = milliseconds + 30000
rr.OnEventGameSingeConclude(rr.CurrOperationPlayer)
@ -220,7 +216,7 @@ func (rr *Room) run() {
case protocol.STATE_SINGLE_RESULT:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------ 单独结算结束 继续下一个操作 ", rr.RId)
log.Debug(" 桌子号", rr.RId, " ------------------------------ 单独结算结束 继续下一个操作 ")
// 判断是不是只剩庄家了 如果是直接结算结束
AllUserEnd := true
@ -246,7 +242,7 @@ func (rr *Room) run() {
case protocol.STATE_BANKER_AUTO:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------ 庄家自动操作 ", rr.RId)
log.Debug(" 桌子号", rr.RId, " ------------------------------ 庄家自动操作 ")
rr.CurrentOperationTimer = milliseconds + 60000
rr.AutoBanker()
@ -255,7 +251,7 @@ func (rr *Room) run() {
case protocol.STATE_RESULT_WAIT:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------ 开始结算 ", rr.RId)
log.Debug(" 桌子号", rr.RId, " ------------------------------ 开始结算 ")
// 先弄个长点的时间防止结算时间出问题
rr.CurrentOperationTimer = milliseconds + 30000
@ -273,7 +269,9 @@ func (rr *Room) run() {
case protocol.STATE_RESULT:
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------等待开始", rr.RId)
log.Debug(" 桌子号", rr.RId, " ------------------------------等待开始")
// 先弄个长点的时间防止出问题
rr.CurrentOperationTimer = milliseconds + 30000
// 踢出用户
for _, player := range rr.PlayerMap {
@ -282,7 +280,20 @@ func (rr *Room) run() {
}
if player.OnlineState != USER_ON_LINE {
log.Debug(" 桌子号", rr.RId, " 用户 ", player.Nickname, " 不在线 ", rr.RId)
log.Debug(" 桌子号", rr.RId, " 用户 ", player.Nickname, " 不在线 ")
rr.OnGetOutRoom(player.Uid)
}
}
for _, player := range rr.PlayerWatchMap {
if player.IsRobot {
continue
}
if player.OnlineState != USER_ON_LINE {
log.Debug(" 桌子号", rr.RId, " 观战用户 ", player.Nickname, " 不在线 ")
rr.OnGetOutRoom(player.Uid)
} else if !player.IsRobot && player.PlayWatchCount >= int(3) {
log.Debug("用户 ", player.Nickname, " 连续观战了3局 ", rr.RId)
rr.OnGetOutRoom(player.Uid)
}
}
@ -317,44 +328,44 @@ func (rr *Room) run() {
}
}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
NextTimestamp: milliseconds,
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// NextTimestamp: milliseconds,
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
//设置游戏状态
rr.State = EN_TABLE_STATE_READY_TO_START

9
game-server/game/21Game/app/core/game/game_operate.go

@ -79,6 +79,15 @@ func (rr *Room) OnUserOperate(uid int64, msg interface{}) { // 用户操作
rr.NextPLayer(true)
}
case protocol.OperateDouble:
// 钱不够双倍
if player.Gold.IntPart() < player.CellScore {
log.Debug(" 桌子号", rr.RId, " 玩家", ChairId, "钱不够双倍 ")
OperateRes.Code = protocol.ErrorCodeOperateError
OperateRes.CodeMsg = "钱不够双倍 "
rr.Send(rr.PlayerMap[ChairId], route.OperateRes, OperateRes)
return
}
// 底注加倍 发一张牌 然后切换下一个玩家
player.CellScore *= 2

100
game-server/game/21Game/app/core/game/game_out_room.go

@ -47,7 +47,8 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
}
}
NotifyLeaveRoomRes.ChairID = 0xFF
NotifyLeaveRoomRes.Uid = uid
NotifyLeaveRoomRes.ChairID = -1
if OutUser == nil {
for TempIndex, pPlayer := range rr.PlayerWatchMap {
if pPlayer == nil {
@ -161,8 +162,9 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
} else {
if OutUser != nil {
NotifyLeaveRoomRes.ChairID = OutUser.ChairId
NotifyLeaveRoomRes.Uid = OutUser.Uid
} else {
NotifyLeaveRoomRes.ChairID = 0xFF
NotifyLeaveRoomRes.ChairID = -1
}
NotifyLeaveRoomRes.LeaveReason = 0
rr.Send(pPlayer, route.NotifyGetOutGame, NotifyLeaveRoomRes)
@ -174,6 +176,14 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
continue
}
if OutUser != nil {
NotifyLeaveRoomRes.ChairID = OutUser.ChairId
NotifyLeaveRoomRes.Uid = OutUser.Uid
} else {
NotifyLeaveRoomRes.ChairID = -1
}
NotifyLeaveRoomRes.LeaveReason = 0
rr.Send(pPlayer, route.NotifyGetOutGame, NotifyLeaveRoomRes)
}
@ -183,44 +193,44 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
// log.Debug(" 桌子号", rr.RId, "退出房间后,房间中的玩家", i, "的信息", v.Uid, ":", v)
//}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
NextTimestamp: time.Now().UnixMilli(),
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// NextTimestamp: time.Now().UnixMilli(),
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
if ret {
log.Debug(" 桌子号", rr.RId, "玩家", uid, "退出房间成功")
@ -231,6 +241,16 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
log.Debug(" 桌子号", rr.RId, "玩家人数", playerCount)
if playerCount == 0 || (rr.CreatorId != 0 && playerCount == robotCount) {
//退出所有观战玩家
for _, pPlayer := range rr.PlayerWatchMap {
if pPlayer == nil {
continue
}
rr.Send(pPlayer, route.LogoutTableRes, LeaveTableRes)
}
rr.PlayerWatchMap = rr.PlayerWatchMap[:0]
//关闭定时器
rr.GronTimer.Stop()
rr.RobotMgr.GronTimer.Stop()

11
game-server/game/21Game/app/core/game/game_over.go

@ -317,7 +317,7 @@ func (rr *Room) OnEventGameSingeConclude(SingleChairID int32) { // 结束-单独
WinScore = player.EndScore
}
if !player.IsRobot && (player.EndScore != 0) && (player.Ctx != nil) {
if !player.IsRobot && (player.Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(player, 2, player.CellScore+player.BXScore, WinBetScore, WinScore, rr.ReasonString, sArea, sPlayers, UserRealBet)
log.Debug("WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum, " GameID", rr.GameID, " RoomID", rr.RoomID)
rr.UserScore[player.ChairId] = decimal.NewFromInt(AfterGold)
@ -424,6 +424,7 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
TempBankerWin := int64(0) //庄家输赢
BankerUser := rr.PlayerMap[rr.CurrBanker]
for _, player := range rr.PlayerMap {
player.PlayWatchCount = 0
if !player.CanBet {
continue
}
@ -485,7 +486,7 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
WinScore = player.EndScore
}
if !player.IsRobot && (player.EndScore != 0) && (player.Ctx != nil) {
if !player.IsRobot && (player.Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(player, 2, player.CellScore+player.BXScore, WinBetScore, WinScore, rr.ReasonString, sArea, sPlayers, UserRealBet)
log.Debug("WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum, " GameID", rr.GameID, " RoomID", rr.RoomID)
rr.UserScore[player.ChairId] = decimal.NewFromInt(AfterGold)
@ -560,6 +561,10 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
}
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.State = EN_TABLE_STATE_FINISH //结算状态
rr.SendAllMessage(route.NotifyGameConclude, GameOver)
@ -626,7 +631,7 @@ func (rr *Room) OnEventGameConcludeBX() { // 结束-保险结算
UserRealBet = -player.EndScore
}
if !player.IsRobot && (player.EndScore != 0) && (player.Ctx != nil) {
if !player.IsRobot && (player.Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(player, 2, player.CellScore+player.BXScore, 0, WinScore, rr.ReasonString, sArea, sPlayers, UserRealBet)
log.Debug("WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum, " GameID", rr.GameID, " RoomID", rr.RoomID)
rr.UserScore[player.ChairId] = decimal.NewFromInt(AfterGold)

17
game-server/game/21Game/app/core/game/game_player.go

@ -32,12 +32,13 @@ type Player struct {
CheatValue int64 //控制值[CheatValue这个是数据库取出来的,石总那边配置]
CurrCheatValue decimal.Decimal //当前控制值[CheatValue这个是数据库取出来的,石总那边配置,CurrCheatValue这个是每局输赢计算,游戏开始之前都要与CheatValue比较用于确定是否点控该玩家]
PlayCount int //在桌子上呆了几局
CellScore int64 // 底注
BXOperate bool // 是否已经操作
BXScore int64 // 保险付出的分数
EndScore int64 // 本次结算分数
CanBet bool // 玩家是否需要等待下一局开始
GameState int32 // 1 玩家已投降 2 玩家杰克 3 玩家五小龙 4 玩家已爆牌
HandPoker types.PokerSlice // 玩家手牌
PlayCount int //在桌子上呆了几局
PlayWatchCount int //在桌子连续观战了几局
CellScore int64 // 底注
BXOperate bool // 是否已经操作
BXScore int64 // 保险付出的分数
EndScore int64 // 本次结算分数
CanBet bool // 玩家是否需要等待下一局开始
GameState int32 // 1 玩家已投降 2 玩家杰克 3 玩家五小龙 4 玩家已爆牌
HandPoker types.PokerSlice // 玩家手牌
}

47
game-server/game/21Game/app/core/game/game_robot.go

@ -88,22 +88,33 @@ func (r *RobotManager) OnInit(conf string, GameRoom *Room) {
//rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
//r.NextEnterTimer = nowMilliSeconds + rTime
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
if GameRoom.TableConfig != nil {
r.MaxCount = 0
if GameRoom.TableConfig.ZeroMaxNum <= GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(GameRoom.TableConfig.ZeroMinNum)
} else {
ProNow -= tempCount[1]
r.MaxCount = int(rand.Int63n(GameRoom.TableConfig.ZeroMaxNum-GameRoom.TableConfig.ZeroMinNum) + GameRoom.TableConfig.ZeroMinNum)
}
}
r.FlushCountTimer = nowMilliSeconds + GameRoom.TableConfig.CheckFrequency*1000
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", GameRoom.TableConfig.CheckFrequency)
} else {
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
}
r.GronTimer.Start()
}
@ -247,6 +258,10 @@ func (r *RobotManager) OnRobotMessage(msgId int32, player *Player, msg interface
log.Debug("开始游戏==>这不是一个机器人")
return
}
if !player.CanBet {
log.Debug("通知阶段倒计时==>此机器人没有参与本轮游戏")
return
}
message := msg.(*protocol.NotifyStateTime)
@ -301,10 +316,10 @@ func (r *RobotManager) OnRobotMessage(msgId int32, player *Player, msg interface
}
}
// 判断下注
if message.NextState == protocol.STATE_BET {
// 判断下注 不是庄家才下注
if message.NextState == protocol.STATE_BET && r.GameRoom.CurrBanker != player.ChairId {
go func() {
SelectTime := rand.Int63n(2000) + 2000
SelectTime := rand.Int63n(2000) + 5000
time.Sleep(time.Duration(SelectTime) * time.Millisecond)
r.GameRoom.OnUserBet(player.Uid, &protocol.BetReq{
BetAmount: r.GameRoom.Opt.BetAssetOptions[0],

142
game-server/game/21Game/app/core/game/game_robot_timer.go

@ -21,9 +21,29 @@ func (r *RobotManager) run() {
//r.Lock.Lock()
r.RobotsEnterGameRoom()
MinInterTime := r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[0] * 1000
MaxInterTime := r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[1] * 1000
rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
MinInterTime := 0
MaxInterTime := 0
if r.GameRoom.TableConfig != nil {
MinInterTime = int(r.GameRoom.TableConfig.RobotCheckMinFrequency) * 1000
MaxInterTime = int(r.GameRoom.TableConfig.RobotCheckMaxFrequency) * 1000
log.Debug(" 后台配置 机器人进入频率 最小 ", MinInterTime, " 最大 ", MaxInterTime)
} else {
MinInterTime = r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[0] * 1000
MaxInterTime = r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[1] * 1000
}
rTime := int64(0)
if MaxInterTime <= MinInterTime {
rTime = int64(MinInterTime)
} else {
rTime = int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
}
//处理个意外
if rTime == 0 {
rTime = 2000
log.Error(" 出现0了 是不行的 ", r.GameRoom.RoomID)
}
r.NextEnterTimer = milliseconds + rTime
//r.Lock.Unlock()
@ -31,41 +51,93 @@ func (r *RobotManager) run() {
}
}
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
if r.GameRoom.TableConfig != nil {
if milliseconds >= r.FlushCountTimer {
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
r.MaxCount = 0
if r.GameRoom.TableConfig.ZeroMaxNum <= r.GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ZeroMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ZeroMaxNum-r.GameRoom.TableConfig.ZeroMinNum) + r.GameRoom.TableConfig.ZeroMinNum)
}
case 1:
r.MaxCount = 0
if r.GameRoom.TableConfig.OneMaxNum <= r.GameRoom.TableConfig.OneMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.OneMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.OneMaxNum-r.GameRoom.TableConfig.OneMinNum) + r.GameRoom.TableConfig.OneMinNum)
}
case 2:
r.MaxCount = 0
if r.GameRoom.TableConfig.TwoMaxNum <= r.GameRoom.TableConfig.TwoMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.TwoMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.TwoMaxNum-r.GameRoom.TableConfig.TwoMinNum) + r.GameRoom.TableConfig.TwoMinNum)
}
case 3:
r.MaxCount = 0
if r.GameRoom.TableConfig.ThreeMaxNum <= r.GameRoom.TableConfig.ThreeMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ThreeMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ThreeMaxNum-r.GameRoom.TableConfig.ThreeMinNum) + r.GameRoom.TableConfig.ThreeMinNum)
}
case 4:
r.MaxCount = 0
if r.GameRoom.TableConfig.FourMaxNum <= r.GameRoom.TableConfig.FourMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FourMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FourMaxNum-r.GameRoom.TableConfig.FourMinNum) + r.GameRoom.TableConfig.FourMinNum)
}
case 5:
r.MaxCount = 0
if r.GameRoom.TableConfig.FiveMaxNum <= r.GameRoom.TableConfig.FiveMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FiveMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FiveMaxNum-r.GameRoom.TableConfig.FiveMinNum) + r.GameRoom.TableConfig.FiveMinNum)
}
}
r.FlushCountTimer = milliseconds + r.GameRoom.TableConfig.CheckFrequency*1000
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", r.GameRoom.TableConfig.CheckFrequency)
}
} else {
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
}
}
for Index, player := range r.PlayerMaps {

18
game-server/game/21Game/app/core/game/game_watch.go

@ -93,4 +93,22 @@ func (rr *Room) OnUserWatchToDown(uid int64, msg interface{}) { // 主动观战
break
}
}
//判断开场
if rr.State < EN_TABLE_STATE_PLAYING && rr.GetRoomPlayerCount() > 1 {
rr.State = EN_TABLE_STATE_PLAYING
milliseconds := time.Now().UnixMilli()
rr.CurrentGameState = protocol.STATE_GET_BANKER
rr.CurrentOperationTimer = milliseconds + rr.TimeOutGetBanker
rr.RepeatRoomUser()
log.Debug(" 桌子号", rr.RId, " 开始游戏 抢庄倒计时 ", rr.TimeOutGetBanker)
rr.SendAllMessage(route.NotifyStateTime, &protocol.NotifyStateTime{
NextState: protocol.STATE_GET_BANKER,
NextTimestamp: rr.CurrentOperationTimer,
})
// 抢庄做了加一秒的容错判断
rr.CurrentOperationTimer += 1000
}
}

2
game-server/game/21Game/app/core/protocol/protocol_msg.go

@ -50,6 +50,7 @@ type RoomInfoRes struct {
RoomStatus int32 `json:"roomStatus"` //房间的状态
CurrentOperateUser int32 `json:"currentOperateUser"` //当前操作用户
StatusChangeTimestamp int64 `json:"statusChangeTimestamp"` //下一次变更状态的时间戳
BankerLimit int64 `json:"bankerLimit"` //抢庄限制
}
// ResumeGameNotice 通知恢复游戏
@ -130,6 +131,7 @@ type NotifyCurrentBanker struct { // 通知庄家
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

72
game-server/game/21Game/app/core/room/roommgr.go

@ -7,12 +7,14 @@ import (
"github.com/roylee0704/gron"
"math/rand"
"sort"
"strconv"
"sync"
"time"
conf "xgame/game/21Game/app/config"
"xgame/game/21Game/app/core/game"
"xgame/game/21Game/app/core/protocol"
"xgame/game/21Game/app/route"
"xgame/game/service/rpc_client"
gameservice "xgame/internal/service/game"
gamepb "xgame/internal/service/game/pb"
)
@ -29,28 +31,34 @@ type Home struct {
BloodCtrl conf.BloodCtrl //血池控制
NextCreateTable int64 //下个机器人创建房间的时间
TableCount []int32 //各等级的房间个数
Rhb map[int64]HomeBase
RhbEx map[int64]int64
RhbRoom map[int64]*game.Room
EnterUser map[int64]*node.Context
NextId int64
lock sync.Mutex
RoomsReply *gamepb.FetchRoomsReply
TableNeedCount []int32 //各等级需要的房间个数
//TableNeedCount [][]int32 //各等级需要的房间个数
Rhb map[int64]HomeBase
RhbEx map[int64]int64
RhbRoom map[int64]*game.Room
EnterUser map[int64]*node.Context
NextId int64
lock sync.Mutex
RoomsReply *gamepb.FetchRoomsReply
TableConfig []*gamepb.GameTableTotal
}
var Gh *Home
func Init(GameProxy *node.Proxy) {
Gh = &Home{
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
TableNeedCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
//TableNeedCount: [][]int32{{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
}
Gh.GameProxy = GameProxy
Gh.InitBloodControl()
Gh.InitBloodControlByBackend()
milliseconds := time.Now().UnixMilli()
Gh.NextCreateTable = milliseconds + 300
@ -79,28 +87,44 @@ func (h *Home) InitBloodControl() {
}
}
func (h *Home) InitBloodControlByBackend() {
// 按等级从后台获取到配置
var replyOpt *gamepb.FetchGameTableTotalsReply
replyOpt = rpc_client.GetTableCtrlConfig(h.GameProxy, game.GAME_ID, "")
h.TableConfig = replyOpt.List
if len(h.TableConfig) == 0 {
log.Error(game.GAME_ID, " 21点后台获取桌子配置 无配置")
} else {
log.Debug(" 21点获取后台桌子配置 ", h.TableConfig)
}
}
func (h *Home) run() {
milliseconds := time.Now().UnixMilli()
if milliseconds >= h.NextCreateTable {
TableCreatePro := []int{0, 0, 0, 0, 0, 0}
for _, TempTableCreatePro := range h.BloodCtrl.AndroidOprateConfig.TableCreatePro {
for Index, _ := range TableCreatePro {
if TableCreatePro[Index] == 0 && h.TableCount[Index] < TempTableCreatePro[0] {
TableCreatePro[Index] = int(TempTableCreatePro[1])
for _, SingleTableConfig := range h.TableConfig {
tempRoomID, err := strconv.Atoi(SingleTableConfig.RoomId)
if err == nil {
if SingleTableConfig.TableMaxNum <= SingleTableConfig.TableMinNum {
h.TableNeedCount[tempRoomID] = int32(SingleTableConfig.TableMinNum)
} else {
h.TableNeedCount[tempRoomID] = int32(rand.Int63n(SingleTableConfig.TableMaxNum-SingleTableConfig.TableMinNum) + SingleTableConfig.TableMinNum)
}
}
log.Debug(" 场次 ", tempRoomID, " 个数 ", h.TableNeedCount[tempRoomID])
}
for Index, Pro := range TableCreatePro {
log.Debug(" 场次 ", Index, " 个数 ", h.TableCount[Index], " 概率", Pro)
if rand.Intn(10000) < Pro {
h.CreateRoom(0, int32(Index), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功")
go func() {
for LevelID, NeedCount := range h.TableNeedCount {
for h.TableCount[LevelID] < NeedCount {
h.CreateRoom(0, int32(LevelID), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功 当前等级 ", LevelID, " 个数 ", h.TableCount[LevelID])
}
}
}
}()
h.NextCreateTable = milliseconds + h.BloodCtrl.AndroidOprateConfig.CreateTableHZ
h.NextCreateTable = milliseconds + h.TableConfig[0].CheckFrequency*1000
}
}

12
game-server/game/21Game/app/gamemanage/gamemanage.go

@ -240,7 +240,17 @@ func UpdateUserGold(uid int64) { //更新用户的钱
r := room.Gh.GetRoomObject(uid)
if r != nil {
r.OnUpdateGold(uid)
fmt.Println(uid, "更新用户的钱")
log.Debug(uid, "更新用户的钱")
}
})
}
func UpdateTableConfig(gameID int64) { //更新桌子的配置
task.AddTask(func() {
log.Debug(gameID, " 更新桌子的配置 ", gameID)
if game.GAME_ID == gameID {
room.Gh.InitBloodControlByBackend()
log.Debug(gameID, " 更新桌子的配置")
}
})
}

1
game-server/game/AndarBahar/app/core/protocol/protocol_msg.go

@ -65,6 +65,7 @@ type LeaveTableRes struct { // 退出桌子返回
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

18
game-server/game/DZ/app/config/config.go

@ -19,16 +19,14 @@ type BloodCtrl struct {
MaxBei int64 `json:"MaxBei"`
ChipList []int64 `json:"ChipList"`
GearConfig []struct {
GearID int `json:"GearID"`
WinPro int `json:"WinPro"`
UserWinPokerPro [][]int `json:"UserWinPokerPro"`
UserLosePokerPro [][]int `json:"UserLosePokerPro"`
RobotWinPokerPro [][]int `json:"RobotWinPokerPro"`
RobotLosePokerPro [][]int `json:"RobotLosePokerPro"`
RobotWinDropPro [][]int `json:"RobotWinDropPro"`
RobotWinJiaPro [][]int `json:"RobotWinJiaPro"`
RobotLoseDropPro [][]int `json:"RobotLoseDropPro"`
RobotLoseJiaPro [][]int `json:"RobotLoseJiaPro"`
GearID int `json:"GearID"`
WinPro int `json:"WinPro"`
UserWinPokerPro [][]int `json:"UserWinPokerPro"`
RobotWinPokerPro [][]int `json:"RobotWinPokerPro"`
RobotWinDropPro [][]int `json:"RobotWinDropPro"`
RobotWinJiaPro [][]int `json:"RobotWinJiaPro"`
RobotLoseDropPro [][]int `json:"RobotLoseDropPro"`
RobotLoseJiaPro [][]int `json:"RobotLoseJiaPro"`
} `json:"GearConfig"`
AndroidOperateConfig struct {
InGold [][]int `json:"InGold"`

4
game-server/game/DZ/app/core/core.go

@ -50,6 +50,10 @@ func (c *Core) Init() {
userevt.SubscribeGoldChange(func(uid int64) {
gamemanage.UpdateUserGold(uid)
})
userevt.SubscribeTableConfigChange(func(gameID int64) {
gamemanage.UpdateTableConfig(gameID)
})
}
// Reconnect 掉线重连

43
game-server/game/DZ/app/core/game/game.go

@ -13,6 +13,7 @@ import (
"xgame/game/DZ/app/core/protocol"
"xgame/game/DZ/app/core/types"
"xgame/internal/option/room"
gamepb "xgame/internal/service/game/pb"
"github.com/roylee0704/gron"
"github.com/shopspring/decimal"
@ -65,7 +66,8 @@ type PokerUserType struct { // 用户牌型排序
type Room struct {
RoomProxy *node.Proxy
Ctx context.Context
Opt *room.Options //房间的参数
Opt *room.Options //房间的参数
TableConfig *gamepb.GameTableTotal
DestroyRoomFunc func(int64) //销毁房间回调
QuitRoomFunc func(int64) //退出房间回调
NotifyFunc func(int32, interface{}) //大厅通知回调
@ -567,10 +569,6 @@ func (rr *Room) SearchWinHandCard(WinType int) (types.PokerSlice, []int, types.P
// 再找二张其它牌 不重复
for i := 0; i < 2; i++ {
BuildPoker := types.Poker(rand.Intn(13) + 1)
if (WinType == protocol.PokerTypeOnePair || WinType == protocol.PokerTypeThree) && BuildPoker.Point() > ResultMaxPoker.Point() {
i--
continue
}
IsFind, _ := rr.FindPoker(NeedFindPoker, BuildPoker, false, nil)
if !IsFind {
@ -689,6 +687,11 @@ func (rr *Room) SearchTypeHandCard(WinType int, Count int32) []types.PokerSlice
TheBestHandPoker := make(types.PokerSlice, 5)
copy(TheBestHandPoker, OnePoker)
// 第一张是手牌
var TempHandPokerSlice types.PokerSlice
TempHandPokerSlice = append(TempHandPokerSlice, OnePoker[0])
OnePoker = OnePoker[1:]
for i := len(OnePoker) - 1; i > 0; i-- {
j := rand.Intn(i + 1) // 生成随机索引
OnePoker[i], OnePoker[j] = OnePoker[j], OnePoker[i] // 交换
@ -700,7 +703,10 @@ func (rr *Room) SearchTypeHandCard(WinType int, Count int32) []types.PokerSlice
}
// 两张是手牌
ResultPokerList = append(ResultPokerList, types.PokerSlice{OnePoker[3], OnePoker[4]})
TempHandPokerSlice = append(TempHandPokerSlice, OnePoker[3])
ResultPokerList = append(ResultPokerList, TempHandPokerSlice)
log.Debug("公牌是 ", rr.HandPoker, " 手牌是 ", ResultPokerList[0])
// 找剩余几家的牌
for tempCount := int32(0); tempCount < Count-1; tempCount++ {
@ -754,9 +760,28 @@ func (rr *Room) SearchTypeHandCard(WinType int, Count int32) []types.PokerSlice
BuildPoker := types.Poker(rand.Intn(13) + 1)
IsFind, _ := rr.FindPoker(rr.HandPoker, BuildPoker, false, nil)
if IsFind && BuildPoker.Point() > MaxPoker.Point() {
i--
continue
if IsFind {
SameCount := 1
for _, tempHandPoker := range rr.HandPoker {
if BuildPoker.Point() == tempHandPoker.Point() {
SameCount++
}
}
for _, tempHandPoker := range NeedFindPoker {
if BuildPoker.Point() == tempHandPoker.Point() {
SameCount++
}
}
if ((WinType == protocol.PokerTypeOnePair || WinType == protocol.PokerTypeTwoPair) && SameCount == 2) ||
((WinType == protocol.PokerTypeThree || WinType == protocol.PokerTypeFullHouse) && SameCount == 3) ||
(WinType == protocol.PokerTypeFour && SameCount == 4) {
if BuildPoker.Point() > MaxPoker.Point() {
i--
continue
}
}
}
NeedFindPoker = append(NeedFindPoker, BuildPoker)
}

10
game-server/game/DZ/app/core/game/game_disconnect.go

@ -1,6 +1,9 @@
package game
import "base/log"
import (
"base/log"
"xgame/game/DZ/app/core/protocol"
)
/*
OnReconnect(userId int64, proxy *node.Proxy) // 断线重连
@ -9,7 +12,6 @@ import "base/log"
// OnDisconnect 玩家离线 保存正在游戏的进度
func (rr *Room) OnDisconnect(userId int64) {
rr.roomRWLock.Lock()
defer rr.roomRWLock.Unlock()
log.Debug(" 桌子号", rr.RId, "玩家", userId, "离线")
@ -26,8 +28,12 @@ func (rr *Room) OnDisconnect(userId int64) {
if player != nil {
if player.Uid == userId {
player.OnlineState = USER_OFF_LINE
rr.roomRWLock.Unlock()
rr.OnGetOutRoom(player.Uid, protocol.ErrorKickUserOFFLine)
rr.roomRWLock.Lock()
break
}
}
}
rr.roomRWLock.Unlock()
}

9
game-server/game/DZ/app/core/game/game_get_room_info.go

@ -87,12 +87,21 @@ func (rr *Room) OnGetRoomInfo(uid int64, ctx *node.Context) interface{} {
PokerType := int32(0)
if rr.CurrGameRound == 0 {
PokerType = int32(player.ThreeKind.GetCardType())
for _, poker := range player.ThreeKind {
TableSeat.BestPoker = append(TableSeat.BestPoker, int32(poker))
}
log.Debug("UID ", player.Uid, " PokerType=", PokerType, " tempPlayer.ThreeKind=", player.ThreeKind)
} else if rr.CurrGameRound == 1 {
PokerType = int32(player.FourKind.GetCardType())
for _, poker := range player.FourKind {
TableSeat.BestPoker = append(TableSeat.BestPoker, int32(poker))
}
log.Debug("UID ", player.Uid, " PokerType=", PokerType, " tempPlayer.FourKind=", player.FourKind)
} else if rr.CurrGameRound == 2 {
PokerType = int32(player.BestKind.GetCardType())
for _, poker := range player.BestKind {
TableSeat.BestPoker = append(TableSeat.BestPoker, int32(poker))
}
log.Debug("UID ", player.Uid, " PokerType=", PokerType, " tempPlayer.BestKind=", player.BestKind)
}
TableSeat.PokerType = PokerType

9
game-server/game/DZ/app/core/game/game_init.go

@ -57,6 +57,15 @@ func (rr *Room) OnInit() bool {
// 读取配置文件
rr.InitBloodControl()
var gameTableConfig *gamepb.FetchGameTableTotalsReply
gameTableConfig = rpc_client.GetTableCtrlConfig(rr.RoomProxy, int64(rr.GameID), strconv.Itoa(int(rr.RoomID)))
if len(gameTableConfig.List) == 0 {
log.Error(" 21点后台获取桌子配置 无配置 房间等级 ", rr.RoomID)
} else {
rr.TableConfig = gameTableConfig.List[0]
log.Debug(" 21点后台获取桌子配置 房间等级 ", rr.RoomID, " 配置 ", rr.TableConfig)
}
//配置库存[房间的库存]
rr.StockValue = rr.BoolePool.BoolPoolSockNum

91
game-server/game/DZ/app/core/game/game_logic.go

@ -128,6 +128,8 @@ func (rr *Room) run() {
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug(" 桌子号", rr.RId, " ------------------------------等待开始", rr.RId)
// 先弄个长点的时间防止出问题
rr.CurrentOperationTimer = milliseconds + 30000
// 踢出用户
for _, player := range rr.PlayerMap {
@ -140,6 +142,19 @@ func (rr *Room) run() {
rr.OnGetOutRoom(player.Uid, protocol.ErrorKickUserOFFLine)
}
}
for _, player := range rr.PlayerWatchMap {
if player.IsRobot {
continue
}
if player.OnlineState != USER_ON_LINE {
log.Debug(" 桌子号", rr.RId, " 观战用户 ", player.Nickname, " 不在线 ", rr.RId)
rr.OnGetOutRoom(player.Uid, protocol.ErrorKickUserOFFLine)
} else if !player.IsRobot && player.PlayWatchCount >= int(3) {
log.Debug("用户 ", player.Nickname, " 连续观战了3局 ", rr.RId)
rr.OnGetOutRoom(player.Uid, protocol.ErrorKickUserWatchingTimes)
}
}
// 钱不够转为观战 然后观战人替补进来一个
for _, player := range rr.PlayerMap {
@ -171,44 +186,44 @@ func (rr *Room) run() {
}
}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
NextTimestamp: milliseconds,
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// NextTimestamp: milliseconds,
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
//设置游戏状态
rr.State = EN_TABLE_STATE_READY_TO_START

14
game-server/game/DZ/app/core/game/game_operate.go

@ -112,11 +112,13 @@ func (rr *Room) OnUserOperate(uid int64, msg interface{}) { // 用户操作
OperateRes.OperateCode = message.OperateCode
OperateRes.UserScore = TempCellScore
OperateRes.RoundScore = player.RoundScore
OperateRes.CellScore = player.CellScore
NotifyOperate.ChairID = ChairId
NotifyOperate.OperateCode = message.OperateCode
NotifyOperate.UserScore = TempCellScore
NotifyOperate.RoundScore = player.RoundScore
NotifyOperate.CellScore = player.CellScore
NoGameOverUserCount := 0
for _, TempPlayer := range rr.PlayerMap {
@ -221,15 +223,21 @@ func (rr *Room) OnUserOperate(uid int64, msg interface{}) { // 用户操作
for _, tempPlayer := range rr.PlayerMap {
if tempPlayer.CanBet && tempPlayer.GameState != 1 {
PokerType := int32(0)
NotifyPokerType := &protocol.NotifyPokerType{}
if rr.CurrGameRound == 1 {
PokerType = int32(tempPlayer.FourKind.GetCardType())
log.Debug("UID ", tempPlayer.Uid, " PokerType=", PokerType, " tempPlayer.ThreeKind=", tempPlayer.FourKind)
NotifyPokerType.PokerType = PokerType
for _, poker := range tempPlayer.FourKind {
NotifyPokerType.BestPoker = append(NotifyPokerType.BestPoker, int32(poker))
}
} else if rr.CurrGameRound == 2 {
PokerType = int32(tempPlayer.BestKind.GetCardType())
log.Debug("UID ", tempPlayer.Uid, " PokerType=", PokerType, " tempPlayer.BestKind=", tempPlayer.BestKind)
}
NotifyPokerType := &protocol.NotifyPokerType{
PokerType: PokerType,
NotifyPokerType.PokerType = PokerType
for _, poker := range tempPlayer.BestKind {
NotifyPokerType.BestPoker = append(NotifyPokerType.BestPoker, int32(poker))
}
}
rr.Send(tempPlayer, route.NotifyPokerType, NotifyPokerType)
log.Debug("UID ", tempPlayer.Uid, " CurrGameRound=", rr.CurrGameRound, " PokerType=", NotifyPokerType.PokerType)

85
game-server/game/DZ/app/core/game/game_out_room.go

@ -181,44 +181,44 @@ func (rr *Room) OnGetOutRoom(uid int64, Code int32) bool {
// log.Debug(" 桌子号", rr.RId, "退出房间后,房间中的玩家", i, "的信息", v.Uid, ":", v)
//}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
NextTimestamp: time.Now().UnixMilli(),
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// NextTimestamp: time.Now().UnixMilli(),
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
if ret {
log.Debug(" 桌子号", rr.RId, "玩家", uid, "退出房间成功")
@ -229,6 +229,15 @@ func (rr *Room) OnGetOutRoom(uid int64, Code int32) bool {
log.Debug(" 桌子号", rr.RId, "玩家人数", playerCount)
if playerCount == 0 || (rr.CreatorId != 0 && playerCount == robotCount) {
//退出所有观战玩家
for _, pPlayer := range rr.PlayerWatchMap {
if pPlayer == nil {
continue
}
rr.Send(pPlayer, route.LogoutTableRes, LeaveTableRes)
}
rr.PlayerWatchMap = rr.PlayerWatchMap[:0]
//关闭定时器
rr.GronTimer.Stop()
rr.RobotMgr.GronTimer.Stop()

7
game-server/game/DZ/app/core/game/game_over.go

@ -327,6 +327,7 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
}
for _, player := range rr.PlayerMap {
player.PlayWatchCount = 0
if !player.CanBet {
continue
}
@ -353,7 +354,7 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
player.EndScore = TempRateAfter + player.CellScore
}
if !player.IsRobot && (player.EndScore != 0) && (player.Ctx != nil) {
if !player.IsRobot && (player.Ctx != nil) {
AfterGold, BloodPool, StockNum := rr.WriteUserScore(player, 2, player.CellScore, WinBetScore, WinScore, rr.ReasonString, sArea, sPlayers, UserRealBet)
log.Debug("WriteUserScore 后 AfterGold=", AfterGold, " BloodPool=", BloodPool, " StockNum=", StockNum, " GameID", rr.GameID, " RoomID", rr.RoomID)
rr.UserScore[player.ChairId] = decimal.NewFromInt(AfterGold)
@ -387,6 +388,10 @@ func (rr *Room) OnEventGameConclude() { // 结束-结算
GameOver.PlayerList = append(GameOver.PlayerList, TableSeat)
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.State = EN_TABLE_STATE_FINISH //结算状态
rr.SendAllMessage(route.NotifyGameConclude, GameOver)

33
game-server/game/DZ/app/core/game/game_player.go

@ -32,20 +32,21 @@ type Player struct {
CheatValue int64 //控制值[CheatValue这个是数据库取出来的,石总那边配置]
CurrCheatValue decimal.Decimal //当前控制值[CheatValue这个是数据库取出来的,石总那边配置,CurrCheatValue这个是每局输赢计算,游戏开始之前都要与CheatValue比较用于确定是否点控该玩家]
PlayCount int //在桌子上呆了几局
CellScore int64 // 底注
WinTableScore int64 // 赢了的分池
RoundScore int64 // 用户本轮下注
EndScore int64 // 本次结算分数
CanBet bool // 玩家是否需要等待下一局开始
WinLose int32 // 1赢 2输 3和
NeedWinLose int32 // 1赢 2输 3和
GameState int32 // 1 玩家已弃牌 2 玩家已Allin
BetType int32 // 1 小盲注 2 大盲注
HandPoker types.PokerSlice // 玩家手牌
AllKind []types.PokerSlice // 玩家手牌加公牌的所有组合
BestKind types.PokerSlice // 最佳组合手牌
ThreeKind types.PokerSlice // 三张公牌的组合牌
FourKind types.PokerSlice // 四张公牌的最佳组合牌
RobotWin bool // true 赢 false 输
PlayCount int //在桌子上呆了几局
PlayWatchCount int //在桌子连续观战了几局
CellScore int64 // 底注
WinTableScore int64 // 赢了的分池
RoundScore int64 // 用户本轮下注
EndScore int64 // 本次结算分数
CanBet bool // 玩家是否需要等待下一局开始
WinLose int32 // 1赢 2输 3和
NeedWinLose int32 // 1赢 2输 3和
GameState int32 // 1 玩家已弃牌 2 玩家已Allin
BetType int32 // 1 小盲注 2 大盲注
HandPoker types.PokerSlice // 玩家手牌
AllKind []types.PokerSlice // 玩家手牌加公牌的所有组合
BestKind types.PokerSlice // 最佳组合手牌
ThreeKind types.PokerSlice // 三张公牌的组合牌
FourKind types.PokerSlice // 四张公牌的最佳组合牌
RobotWin bool // true 赢 false 输
}

37
game-server/game/DZ/app/core/game/game_robot.go

@ -88,22 +88,33 @@ func (r *RobotManager) OnInit(conf string, GameRoom *Room) {
//rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
//r.NextEnterTimer = nowMilliSeconds + rTime
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
if GameRoom.TableConfig != nil {
r.MaxCount = 0
if GameRoom.TableConfig.ZeroMaxNum <= GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(GameRoom.TableConfig.ZeroMinNum)
} else {
ProNow -= tempCount[1]
r.MaxCount = int(rand.Int63n(GameRoom.TableConfig.ZeroMaxNum-GameRoom.TableConfig.ZeroMinNum) + GameRoom.TableConfig.ZeroMinNum)
}
}
r.FlushCountTimer = nowMilliSeconds + GameRoom.TableConfig.CheckFrequency*1000
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOperateConfig.FlushHZ*1000)
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", GameRoom.TableConfig.CheckFrequency)
} else {
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOperateConfig.FlushHZ*1000)
}
r.GronTimer.Start()
}

142
game-server/game/DZ/app/core/game/game_robot_timer.go

@ -21,9 +21,29 @@ func (r *RobotManager) run() {
//r.Lock.Lock()
r.RobotsEnterGameRoom()
MinInterTime := r.GameRoom.BloodCtrl.AndroidOperateConfig.JoinHZ[0] * 1000
MaxInterTime := r.GameRoom.BloodCtrl.AndroidOperateConfig.JoinHZ[1] * 1000
rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
MinInterTime := 0
MaxInterTime := 0
if r.GameRoom.TableConfig != nil {
MinInterTime = int(r.GameRoom.TableConfig.RobotCheckMinFrequency) * 1000
MaxInterTime = int(r.GameRoom.TableConfig.RobotCheckMaxFrequency) * 1000
log.Debug(" 后台配置 机器人进入频率 最小 ", MinInterTime, " 最大 ", MaxInterTime)
} else {
MinInterTime = r.GameRoom.BloodCtrl.AndroidOperateConfig.JoinHZ[0] * 1000
MaxInterTime = r.GameRoom.BloodCtrl.AndroidOperateConfig.JoinHZ[1] * 1000
}
rTime := int64(0)
if MaxInterTime <= MinInterTime {
rTime = int64(MinInterTime)
} else {
rTime = int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
}
//处理个意外
if rTime == 0 {
rTime = 2000
log.Error(" 出现0了 是不行的 ", r.GameRoom.RoomID)
}
r.NextEnterTimer = milliseconds + rTime
//r.Lock.Unlock()
@ -31,41 +51,93 @@ func (r *RobotManager) run() {
}
}
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
if r.GameRoom.TableConfig != nil {
if milliseconds >= r.FlushCountTimer {
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
r.MaxCount = 0
if r.GameRoom.TableConfig.ZeroMaxNum <= r.GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ZeroMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ZeroMaxNum-r.GameRoom.TableConfig.ZeroMinNum) + r.GameRoom.TableConfig.ZeroMinNum)
}
case 1:
r.MaxCount = 0
if r.GameRoom.TableConfig.OneMaxNum <= r.GameRoom.TableConfig.OneMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.OneMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.OneMaxNum-r.GameRoom.TableConfig.OneMinNum) + r.GameRoom.TableConfig.OneMinNum)
}
case 2:
r.MaxCount = 0
if r.GameRoom.TableConfig.TwoMaxNum <= r.GameRoom.TableConfig.TwoMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.TwoMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.TwoMaxNum-r.GameRoom.TableConfig.TwoMinNum) + r.GameRoom.TableConfig.TwoMinNum)
}
case 3:
r.MaxCount = 0
if r.GameRoom.TableConfig.ThreeMaxNum <= r.GameRoom.TableConfig.ThreeMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ThreeMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ThreeMaxNum-r.GameRoom.TableConfig.ThreeMinNum) + r.GameRoom.TableConfig.ThreeMinNum)
}
case 4:
r.MaxCount = 0
if r.GameRoom.TableConfig.FourMaxNum <= r.GameRoom.TableConfig.FourMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FourMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FourMaxNum-r.GameRoom.TableConfig.FourMinNum) + r.GameRoom.TableConfig.FourMinNum)
}
case 5:
r.MaxCount = 0
if r.GameRoom.TableConfig.FiveMaxNum <= r.GameRoom.TableConfig.FiveMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FiveMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FiveMaxNum-r.GameRoom.TableConfig.FiveMinNum) + r.GameRoom.TableConfig.FiveMinNum)
}
}
r.FlushCountTimer = milliseconds + r.GameRoom.TableConfig.CheckFrequency*1000
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", r.GameRoom.TableConfig.CheckFrequency)
}
} else {
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOperateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOperateConfig.FlushHZ*1000)
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOperateConfig.FlushHZ*1000)
}
}
for Index, player := range r.PlayerMaps {

3
game-server/game/DZ/app/core/game/game_start.go

@ -134,6 +134,9 @@ func (rr *Room) OnGameStart() bool {
NotifyPokerType := &protocol.NotifyPokerType{
PokerType: int32(tempPlayer.ThreeKind.GetCardType()),
}
for _, poker := range tempPlayer.ThreeKind {
NotifyPokerType.BestPoker = append(NotifyPokerType.BestPoker, int32(poker))
}
rr.Send(tempPlayer, route.NotifyPokerType, NotifyPokerType)
log.Debug("UID ", tempPlayer.Uid, " PokerType=", NotifyPokerType.PokerType, " tempPlayer.ThreeKind=", tempPlayer.ThreeKind)
}

18
game-server/game/DZ/app/core/game/game_watch.go

@ -93,4 +93,22 @@ func (rr *Room) OnUserWatchToDown(uid int64, msg interface{}) { // 主动观战
break
}
}
//判断开场
if rr.State < EN_TABLE_STATE_PLAYING && rr.GetRoomPlayerCount() > 2 {
rr.State = EN_TABLE_STATE_PLAYING
milliseconds := time.Now().UnixMilli()
rr.CurrentGameState = protocol.STATE_GET_BANKER
rr.CurrentOperationTimer = milliseconds + rr.TimeOutGetBanker
rr.RepeatRoomUser()
log.Debug(" 桌子号", rr.RId, " 开始游戏 抢庄倒计时 ", rr.TimeOutGetBanker)
rr.SendAllMessage(route.NotifyStateTime, &protocol.NotifyStateTime{
NextState: protocol.STATE_GET_BANKER,
NextTimestamp: rr.CurrentOperationTimer,
})
// 抢庄做了加一秒的容错判断
rr.CurrentOperationTimer += 1000
}
}

6
game-server/game/DZ/app/core/protocol/protocol_msg.go

@ -71,6 +71,7 @@ type OperateRes struct { //操作返回
CodeMsg string `json:"codeMsg"` //错误内容
UserScore int64 `json:"userScore"` //操作的钱
RoundScore int64 `json:"roundScore"` //当轮的钱
CellScore int64 `json:"chipScore"` //用户当前下注
}
type NotifyOperate struct { //通知操作
@ -78,6 +79,7 @@ type NotifyOperate struct { //通知操作
OperateCode int32 `json:"operateCode"` //操作码
UserScore int64 `json:"userScore"` //操作的钱
RoundScore int64 `json:"roundScore"` //当轮的钱
CellScore int64 `json:"chipScore"` //用户当前下注
}
type NotifyRoomDestroy struct { // 通知房间销毁
@ -114,6 +116,7 @@ type NotifyGameStart struct { // 通知开始游戏的第一轮数据
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}
@ -129,7 +132,8 @@ type NotifyPoker struct { // 通知翻牌
}
type NotifyPokerType struct { // 通知牌类型
PokerType int32 `json:"pokerType"` //当前类型
PokerType int32 `json:"pokerType"` //当前类型
BestPoker []int32 `json:"bestPoker,omitempty"` // 最佳排列
}
type NotifyWhoOperate struct { // 通知到谁操作

2
game-server/game/DZ/app/core/protocol/protocol_struct.go

@ -10,6 +10,7 @@ const (
ErrorIsPlaying = 20010007 //游戏过程中不能离开房间
ErrorKickUserOFFLine = 20010008 //用户离开-离线
ErrorKickUserDestroyTable = 20010009 //用户离开-解散桌子
ErrorKickUserWatchingTimes = 20010010 //用户离开-观战次数过多
)
const (
@ -60,6 +61,7 @@ type RoomPlayer struct { //房间的用户信息
GameState int32 `json:"gameState"` // 1 玩家已弃牌 2 玩家已Allin
HandPoker []int32 `json:"handPoker,omitempty"` // 用户当前手牌
PokerType int32 `json:"pokerType" ` // 牌类型
BestPoker []int32 `json:"bestPoker,omitempty"` // 最佳排列
}
type TablePlayer struct { //桌子的用户信息

58
game-server/game/DZ/app/core/room/roommgr.go

@ -29,6 +29,7 @@ type Home struct {
BloodCtrl conf.BloodCtrl //血池控制
NextCreateTable int64 //下个机器人创建房间的时间
TableCount []int32 //各等级的房间个数
TableNeedCount []int32 //各等级需要的房间个数
Rhb map[int64]HomeBase
RhbEx map[int64]int64
RhbRoom map[int64]*game.Room
@ -36,21 +37,24 @@ type Home struct {
NextId int64
lock sync.Mutex
RoomsReply *gamepb.FetchRoomsReply
TableConfig []*gamepb.GameTableTotal
}
var Gh *Home
func Init(GameProxy *node.Proxy) {
Gh = &Home{
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
TableNeedCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
Gh.GameProxy = GameProxy
Gh.InitBloodControl()
Gh.InitBloodControlByBackend()
milliseconds := time.Now().UnixMilli()
Gh.NextCreateTable = milliseconds + 300
@ -79,32 +83,44 @@ func (h *Home) InitBloodControl() {
}
}
func (h *Home) InitBloodControlByBackend() {
// 按等级从后台获取到配置
var replyOpt *gamepb.FetchGameTableTotalsReply
replyOpt = rpc_client.GetTableCtrlConfig(h.GameProxy, game.GAME_ID, "")
h.TableConfig = replyOpt.List
if len(h.TableConfig) == 0 {
log.Error(game.GAME_ID, " 21点后台获取桌子配置 无配置")
} else {
log.Debug(" 21点获取后台桌子配置 ", h.TableConfig)
}
}
func (h *Home) run() {
milliseconds := time.Now().UnixMilli()
if milliseconds >= h.NextCreateTable {
TableCreatePro := []int{0, 0, 0, 0, 0, 0}
for _, TempTableCreatePro := range h.BloodCtrl.AndroidOperateConfig.TableCreatePro {
for Index, _ := range TableCreatePro {
if TableCreatePro[Index] == 0 && h.TableCount[Index] < TempTableCreatePro[0] {
TableCreatePro[Index] = int(TempTableCreatePro[1])
for _, SingleTableConfig := range h.TableConfig {
tempRoomID, err := strconv.Atoi(SingleTableConfig.RoomId)
if err == nil {
if SingleTableConfig.TableMaxNum <= SingleTableConfig.TableMinNum {
h.TableNeedCount[tempRoomID] = int32(SingleTableConfig.TableMinNum)
} else {
h.TableNeedCount[tempRoomID] = int32(rand.Int63n(SingleTableConfig.TableMaxNum-SingleTableConfig.TableMinNum) + SingleTableConfig.TableMinNum)
}
}
log.Debug(" 场次 ", tempRoomID, " 个数 ", h.TableNeedCount[tempRoomID])
}
for Index, Pro := range TableCreatePro {
// TODO: 测试添加只开初级场
if Index != 0 {
continue
}
log.Debug(" 场次 ", Index, " 个数 ", h.TableCount[Index], " 概率", Pro)
if rand.Intn(10000) < Pro {
h.CreateRoom(0, int32(Index), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功")
go func() {
for LevelID, NeedCount := range h.TableNeedCount {
for h.TableCount[LevelID] < NeedCount {
h.CreateRoom(0, int32(LevelID), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功 当前等级 ", LevelID, " 个数 ", h.TableCount[LevelID])
}
}
}
}()
h.NextCreateTable = milliseconds + h.BloodCtrl.AndroidOperateConfig.CreateTableHZ
h.NextCreateTable = milliseconds + h.TableConfig[0].CheckFrequency*1000
}
}

12
game-server/game/DZ/app/gamemanage/gamemanage.go

@ -245,6 +245,16 @@ func UpdateUserGold(uid int64) { //更新用户的钱
})
}
func UpdateTableConfig(gameID int64) { //更新桌子的配置
task.AddTask(func() {
log.Debug(gameID, " 更新桌子的配置 ", gameID)
if game.GAME_ID == gameID {
room.Gh.InitBloodControlByBackend()
log.Debug(gameID, " 更新桌子的配置")
}
})
}
func UserOperate(ctx *node.Context) { // 用户操作
Ctx := ctx.Clone()
task.AddTask(func() {
@ -324,7 +334,7 @@ func LogoutTable(ctx *node.Context) { // 用户退出游戏请求
log.Debug("LogoutTable 没有获取到用户 ", Ctx.Request.UID)
}
if RoomInfo != nil && (RoomInfo.CurrentGameState == protocol.STATE_INVALUE || (RoomInfo.CurrentGameState > protocol.STATE_GET_BANKER && RoomInfo.CurrentGameState != protocol.STATE_RESULT)) {
if RoomInfo != nil && TempPlayer.CanBet && (RoomInfo.CurrentGameState == protocol.STATE_INVALUE || (RoomInfo.CurrentGameState > protocol.STATE_GET_BANKER && RoomInfo.CurrentGameState != protocol.STATE_RESULT)) {
log.Debug("LogoutTable 游戏过程中不能离开房间 ", " Request", ctx.Request)
LeaveTableRes := &protocol.LeaveTableRes{
Code: protocol.ErrorIsPlaying,

112
game-server/game/DZ/config/blood.json

@ -11,133 +11,109 @@
"GearIDComment": "GearID 【输 3000档】",
"GearID": 3000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
},
{
"GearIDComment": "GearID 【输 2000档】",
"GearID": 2000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
},
{
"GearIDComment": "GearID 【输 1000档】",
"GearID": 1000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
},
{
"GearIDComment": "GearID 【赢 1000档】",
"GearID": -1000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
},
{
"GearIDComment": "GearID 【赢 2000档】",
"GearID": -2000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
},
{
"GearIDComment": "GearID 【赢 3000档】",
"GearID": -3000,
"WinProComment": "赢得概率 万分率",
"WinPro": 1000,
"WinPro": 4000,
"UserWinPokerProComment": "玩家获胜抽牌权重",
"UserWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserLosePokerProComment": "玩家失败抽牌权重",
"UserLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"UserWinPokerPro": [[1,3508],[2,4000],[3,1801],[4,350],[5,200],[6,100],[7,25],[8,10],[9,5],[10,1]],
"RobotWinPokerProComment": "机器人获胜抽牌权重",
"RobotWinPokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotLosePokerProComment": "机器人失败抽牌权重",
"RobotLosePokerPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000],[6,1000],[7,1000],[8,1000],[9,1000],[10,1000]],
"RobotWinPokerPro": [[1,2500],[2,3000],[3,2501],[4,801],[5,601],[6,501],[7,50],[8,30],[9,15],[10,1]],
"RobotWinDropProComment": "机器人赢的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinDropPro": [[1,500],[2,200],[3,50],[4,0],[5,0]],
"RobotWinJiaProComment": "机器人赢的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotWinJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotWinJiaPro": [[1,2500],[2,2500],[3,2500],[4,4800],[5,6700]],
"RobotLoseDropProComment": "机器人输的弃牌概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseDropPro": [[1,0],[2,1000],[3,1000],[4,1000],[5,1000]],
"RobotLoseDropPro": [[1,3000],[2,3000],[3,3000],[4,8000],[5,9000]],
"RobotLoseJiaProComment": "机器人输的加注概率 1:小盲注 2:大盲注 3:翻牌圈 4 转牌圈 5河牌圈",
"RobotLoseJiaPro": [[1,1000],[2,1000],[3,1000],[4,1000],[5,1000]]
"RobotLoseJiaPro": [[1,0],[2,0],[3,0],[4,0],[5,0]]
}
],
"CommentAndroidOperateConfig": "机器人的配置",
@ -147,7 +123,7 @@
"CommentCreateTableHZ": "创建桌子的频率",
"CreateTableHZ": 30000,
"CommentTableCreatePro": "低于多少桌时创建桌子的概率 高于最后一个配置不再创建桌子",
"TableCreatePro": [[1,10000]],
"TableCreatePro": [[1,10000],[7,6000],[10,3000]],
"CommentCountMax": "房间多少个真实玩家情况下 机器人的个数概率",
"CountMax0": [[0,0],[1,0],[2,30],[3,50000],[4,15],[5,0]],
"CountMax1": [[0,0],[1,3000],[2,3000],[3,5000],[4,1500],[5,500]],
@ -167,7 +143,7 @@
"CommentTimeOutBegin": "抢庄后到开始操作等待时间",
"TimeOutBegin" : 3000,
"CommentTimeOutOperate": "操作的时间",
"TimeOutOperate" : 15000,
"TimeOutOperate" : 20000,
"CommentTimeOutFinalResult": "最终结算倒计时",
"TimeOutFinalResult" : 2000,
"CommentTimeKickTimes": "多少次不下注踢出房间",

4
game-server/game/SixAndarBahar/app/core/core.go

@ -51,6 +51,10 @@ func (c *Core) Init() {
userevt.SubscribeGoldChange(func(uid int64) {
gamemanage.UpdateUserGold(uid)
})
userevt.SubscribeTableConfigChange(func(gameID int64) {
gamemanage.UpdateTableConfig(gameID)
})
}
// Reconnect 掉线重连

4
game-server/game/SixAndarBahar/app/core/game/game.go

@ -11,6 +11,7 @@ import (
"xgame/game/SixAndarBahar/app/core/protocol"
"xgame/game/SixAndarBahar/app/core/types"
"xgame/internal/option/room"
gamepb "xgame/internal/service/game/pb"
"github.com/roylee0704/gron"
"github.com/shopspring/decimal"
@ -57,7 +58,8 @@ const (
type Room struct {
RoomProxy *node.Proxy
Ctx context.Context
Opt *room.Options //房间的参数
Opt *room.Options //房间的参数
TableConfig *gamepb.GameTableTotal
DestroyRoomFunc func(int64) //销毁房间回调
QuitRoomFunc func(int64) //退出房间回调
NotifyFunc func(int32, interface{}) //大厅通知回调

5
game-server/game/SixAndarBahar/app/core/game/game_disconnect.go

@ -9,7 +9,6 @@ import "base/log"
// OnDisconnect 玩家离线 保存正在游戏的进度
func (rr *Room) OnDisconnect(userId int64) {
rr.roomRWLock.Lock()
defer rr.roomRWLock.Unlock()
log.Debug(" 桌子号", rr.RId, "玩家", userId, "离线")
@ -26,8 +25,12 @@ func (rr *Room) OnDisconnect(userId int64) {
if player != nil {
if player.Uid == userId {
player.OnlineState = USER_OFF_LINE
rr.roomRWLock.Unlock()
rr.OnGetOutRoom(player.Uid)
rr.roomRWLock.Lock()
break
}
}
}
rr.roomRWLock.Unlock()
}

10
game-server/game/SixAndarBahar/app/core/game/game_init.go

@ -3,6 +3,7 @@ package game
import (
"base/encoding/json"
"base/log"
"strconv"
"time"
"xgame/game/SixAndarBahar/app/core/protocol"
"xgame/game/service/rpc_client"
@ -57,6 +58,15 @@ func (rr *Room) OnInit() bool {
// 读取配置文件
rr.InitBloodControl()
var gameTableConfig *pb.FetchGameTableTotalsReply
gameTableConfig = rpc_client.GetTableCtrlConfig(rr.RoomProxy, int64(rr.GameID), strconv.Itoa(int(rr.RoomID)))
if len(gameTableConfig.List) == 0 {
log.Error(" 21点后台获取桌子配置 无配置 房间等级 ", rr.RoomID)
} else {
rr.TableConfig = gameTableConfig.List[0]
log.Debug(" 21点后台获取桌子配置 房间等级 ", rr.RoomID, " 配置 ", rr.TableConfig)
}
//配置库存[房间的库存]
rr.StockValue = rr.BoolePool.BoolPoolSockNum

79
game-server/game/SixAndarBahar/app/core/game/game_logic.go

@ -229,6 +229,8 @@ func (rr *Room) run() {
{
if milliseconds >= rr.CurrentOperationTimer {
log.Debug("------------------------------等待开始", rr.RId)
// 先弄个长点的时间防止出问题
rr.CurrentOperationTimer = milliseconds + 30000
// 踢出连续五局没下注的用户
for _, player := range rr.PlayerMap {
@ -262,6 +264,9 @@ func (rr *Room) run() {
if player.OnlineState != USER_ON_LINE {
log.Debug("观战用户 ", player.Nickname, " 不在线 ", rr.RId)
rr.OnGetOutRoom(player.Uid)
} else if !player.IsRobot && player.PlayWatchCount >= int(3) {
log.Debug("用户 ", player.Nickname, " 连续观战了3局 ", rr.RId)
rr.OnGetOutRoom(player.Uid)
}
}
@ -295,43 +300,43 @@ func (rr *Room) run() {
}
}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > rr.MinGameScore {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > rr.MinGameScore {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
//设置游戏状态
rr.State = EN_TABLE_STATE_READY_TO_START

83
game-server/game/SixAndarBahar/app/core/game/game_out_room.go

@ -154,43 +154,43 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
// log.Debug(" 桌子号", rr.RId, "退出房间后,房间中的玩家", i, "的信息", v.Uid, ":", v)
//}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > rr.MinGameScore {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > rr.MinGameScore {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
if ret {
log.Debug(" 桌子号", rr.RId, "玩家", uid, "退出房间成功")
@ -201,6 +201,15 @@ func (rr *Room) OnGetOutRoom(uid int64) bool {
log.Debug(" 桌子号", rr.RId, "玩家人数", playerCount)
if playerCount == 0 || (rr.CreatorId != 0 && playerCount == robotCount) {
//退出所有观战玩家
for _, pPlayer := range rr.PlayerWatchMap {
if pPlayer == nil {
continue
}
rr.Send(pPlayer, route.LogoutTableRes, LeaveTableRes)
}
rr.PlayerWatchMap = rr.PlayerWatchMap[:0]
//关闭定时器
rr.GronTimer.Stop()
rr.RobotMgr.GronTimer.Stop()

5
game-server/game/SixAndarBahar/app/core/game/game_over.go

@ -292,6 +292,7 @@ func (rr *Room) OnEventGameConclude(EndState int) { // 结束-结算
TempBankerNoWinBet := int64(0) //未压中区域闲家下注总额
TempBankerWinBet := int64(0) // 压中区域闲家下注总额
for _, player := range rr.PlayerMap {
player.PlayWatchCount = 0
player.PlayCount++
if player.ChairId != rr.CurrBanker && !player.CurrentRoundBet {
player.NoBetCount++
@ -435,6 +436,10 @@ func (rr *Room) OnEventGameConclude(EndState int) { // 结束-结算
// log.Debug("结束 现在有 ", len(rr.Record), " 个记录 当前第 ", index, " 个 值:", record)
//}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.State = EN_TABLE_STATE_FINISH //结算状态
rr.SendAllMessage(route.NotifyGameConclude, GameOver)

1
game-server/game/SixAndarBahar/app/core/game/game_player.go

@ -33,6 +33,7 @@ type Player struct {
CurrCheatValue decimal.Decimal //当前控制值[CheatValue这个是数据库取出来的,石总那边配置,CurrCheatValue这个是每局输赢计算,游戏开始之前都要与CheatValue比较用于确定是否点控该玩家]
PlayCount int //在桌子上呆了几局
PlayWatchCount int //在桌子连续观战了几局
CurrentRoundBet bool //本局是否下注了
CanBet bool //玩家是否可以下注
CurrentHHBet bool //本回合是否下注了

42
game-server/game/SixAndarBahar/app/core/game/game_robot.go

@ -80,22 +80,33 @@ func (r *RobotManager) OnInit(conf string, GameRoom *Room) {
//rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
//r.NextEnterTimer = nowMilliSeconds + rTime
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
if GameRoom.TableConfig != nil {
r.MaxCount = 0
if GameRoom.TableConfig.ZeroMaxNum <= GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(GameRoom.TableConfig.ZeroMinNum)
} else {
ProNow -= tempCount[1]
r.MaxCount = int(rand.Int63n(GameRoom.TableConfig.ZeroMaxNum-GameRoom.TableConfig.ZeroMinNum) + GameRoom.TableConfig.ZeroMinNum)
}
}
r.FlushCountTimer = nowMilliSeconds + GameRoom.TableConfig.CheckFrequency*1000
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", GameRoom.TableConfig.CheckFrequency)
} else {
ProMax := 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
ProMax += tempCount[1]
}
ProNow := rand.Intn(ProMax)
r.MaxCount = 0
for _, tempCount := range GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0 {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = nowMilliSeconds + int64(GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
}
r.GronTimer.Start()
}
@ -319,8 +330,11 @@ func (r *RobotManager) OnRobotMessage(msgId int32, player *Player, msg interface
}
}
//随机一个下次判断行为时间
//随机一个下次判断行为时间 第一轮要加7秒动动画
rTime := rand.Int63n(8000) + 2000
//if message.NextState == protocol.STATE_FIRST_BET {
// rTime += 7000
//}
r.Lock.Lock()
r.RobotTimer[player.ChairId] = milliseconds + rTime
r.Lock.Unlock()

142
game-server/game/SixAndarBahar/app/core/game/game_robot_timer.go

@ -20,9 +20,29 @@ func (r *RobotManager) run() {
//r.Lock.Lock()
r.RobotsEnterGameRoom()
MinInterTime := r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[0] * 1000
MaxInterTime := r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[1] * 1000
rTime := int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
MinInterTime := 0
MaxInterTime := 0
if r.GameRoom.TableConfig != nil {
MinInterTime = int(r.GameRoom.TableConfig.RobotCheckMinFrequency) * 1000
MaxInterTime = int(r.GameRoom.TableConfig.RobotCheckMaxFrequency) * 1000
log.Debug(" 后台配置 机器人进入频率 最小 ", MinInterTime, " 最大 ", MaxInterTime)
} else {
MinInterTime = r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[0] * 1000
MaxInterTime = r.GameRoom.BloodCtrl.AndroidOprateConfig.JoinHZ[1] * 1000
}
rTime := int64(0)
if MaxInterTime <= MinInterTime {
rTime = int64(MinInterTime)
} else {
rTime = int64(rand.Intn(MaxInterTime-MinInterTime) + MinInterTime)
}
//处理个意外
if rTime == 0 {
rTime = 2000
log.Error(" 出现0了 是不行的 ", r.GameRoom.RoomID)
}
r.NextEnterTimer = milliseconds + rTime
//r.Lock.Unlock()
@ -30,41 +50,93 @@ func (r *RobotManager) run() {
}
}
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
if r.GameRoom.TableConfig != nil {
if milliseconds >= r.FlushCountTimer {
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
r.MaxCount = 0
if r.GameRoom.TableConfig.ZeroMaxNum <= r.GameRoom.TableConfig.ZeroMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ZeroMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ZeroMaxNum-r.GameRoom.TableConfig.ZeroMinNum) + r.GameRoom.TableConfig.ZeroMinNum)
}
case 1:
r.MaxCount = 0
if r.GameRoom.TableConfig.OneMaxNum <= r.GameRoom.TableConfig.OneMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.OneMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.OneMaxNum-r.GameRoom.TableConfig.OneMinNum) + r.GameRoom.TableConfig.OneMinNum)
}
case 2:
r.MaxCount = 0
if r.GameRoom.TableConfig.TwoMaxNum <= r.GameRoom.TableConfig.TwoMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.TwoMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.TwoMaxNum-r.GameRoom.TableConfig.TwoMinNum) + r.GameRoom.TableConfig.TwoMinNum)
}
case 3:
r.MaxCount = 0
if r.GameRoom.TableConfig.ThreeMaxNum <= r.GameRoom.TableConfig.ThreeMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.ThreeMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.ThreeMaxNum-r.GameRoom.TableConfig.ThreeMinNum) + r.GameRoom.TableConfig.ThreeMinNum)
}
case 4:
r.MaxCount = 0
if r.GameRoom.TableConfig.FourMaxNum <= r.GameRoom.TableConfig.FourMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FourMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FourMaxNum-r.GameRoom.TableConfig.FourMinNum) + r.GameRoom.TableConfig.FourMinNum)
}
case 5:
r.MaxCount = 0
if r.GameRoom.TableConfig.FiveMaxNum <= r.GameRoom.TableConfig.FiveMinNum {
r.MaxCount = int(r.GameRoom.TableConfig.FiveMinNum)
} else {
r.MaxCount = int(rand.Int63n(r.GameRoom.TableConfig.FiveMaxNum-r.GameRoom.TableConfig.FiveMinNum) + r.GameRoom.TableConfig.FiveMinNum)
}
}
r.FlushCountTimer = milliseconds + r.GameRoom.TableConfig.CheckFrequency*1000
log.Debug("从后台配置 最大机器人数 ", r.MaxCount, " 刷新时间 ", r.GameRoom.TableConfig.CheckFrequency)
}
} else {
if milliseconds >= r.FlushCountTimer {
var TempCountMax [][]int
switch r.GameRoom.GetRoomRealPlayerCount() {
case 0:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax0
case 1:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax1
case 2:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax2
case 3:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax3
case 4:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax4
case 5:
TempCountMax = r.GameRoom.BloodCtrl.AndroidOprateConfig.CountMax5
}
ProMax := 0
for _, tempCount := range TempCountMax {
ProMax += tempCount[1]
}
ProNow := 0
if ProMax != 0 {
ProNow = rand.Intn(ProMax)
}
r.MaxCount = 0
for _, tempCount := range TempCountMax {
if ProNow < tempCount[1] {
r.MaxCount = tempCount[0]
break
} else {
ProNow -= tempCount[1]
}
}
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
r.FlushCountTimer = milliseconds + int64(r.GameRoom.BloodCtrl.AndroidOprateConfig.FlushHZ*1000)
}
}
for Index, player := range r.PlayerMaps {

17
game-server/game/SixAndarBahar/app/core/game/game_watch.go

@ -2,6 +2,7 @@ package game
import (
"base/log"
"time"
"xgame/game/SixAndarBahar/app/core/protocol"
"xgame/game/SixAndarBahar/app/route"
)
@ -91,4 +92,20 @@ func (rr *Room) OnUserWatchToDown(uid int64, msg interface{}) { // 主动观战
break
}
}
//判断开场
if rr.CurrentGameState < protocol.STATE_GET_BANKER && rr.GetRoomPlayerCount() > 1 {
rr.State = EN_TABLE_STATE_PLAYING
milliseconds := time.Now().UnixMilli()
rr.CurrentGameState = protocol.STATE_GET_BANKER
rr.CurrentOperationTimer = milliseconds + rr.TimeOutGetBanker
rr.RepeatRoomUser()
rr.SendAllMessage(route.NotifyStateTime, &protocol.NotifyStateTime{
NextState: protocol.STATE_GET_BANKER,
NextTimestamp: rr.CurrentOperationTimer,
})
// 抢庄做了加一秒的容错判断
rr.CurrentOperationTimer += 1000
}
}

1
game-server/game/SixAndarBahar/app/core/protocol/protocol_msg.go

@ -119,6 +119,7 @@ type NotifyCurrentBanker struct { // 通知庄家
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

56
game-server/game/SixAndarBahar/app/core/room/roommgr.go

@ -7,12 +7,14 @@ import (
"github.com/roylee0704/gron"
"math/rand"
"sort"
"strconv"
"sync"
"time"
conf "xgame/game/SixAndarBahar/app/config"
"xgame/game/SixAndarBahar/app/core/game"
"xgame/game/SixAndarBahar/app/core/protocol"
"xgame/game/SixAndarBahar/app/route"
"xgame/game/service/rpc_client"
gameservice "xgame/internal/service/game"
gamepb "xgame/internal/service/game/pb"
)
@ -29,6 +31,7 @@ type Home struct {
BloodCtrl conf.BloodCtrl //血池控制
NextCreateTable int64 //下个机器人创建房间的时间
TableCount []int32 //各等级的房间个数
TableNeedCount []int32 //各等级需要的房间个数
Rhb map[int64]HomeBase
RhbEx map[int64]int64
RhbRoom map[int64]*game.Room
@ -36,21 +39,24 @@ type Home struct {
NextId int64
lock sync.Mutex
RoomsReply *gamepb.FetchRoomsReply
TableConfig []*gamepb.GameTableTotal
}
var Gh *Home
func Init(GameProxy *node.Proxy) {
Gh = &Home{
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
TableNeedCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
Gh.GameProxy = GameProxy
Gh.InitBloodControl()
Gh.InitBloodControlByBackend()
milliseconds := time.Now().UnixMilli()
Gh.NextCreateTable = milliseconds + 300
@ -79,28 +85,44 @@ func (h *Home) InitBloodControl() {
}
}
func (h *Home) InitBloodControlByBackend() {
// 按等级从后台获取到配置
var replyOpt *gamepb.FetchGameTableTotalsReply
replyOpt = rpc_client.GetTableCtrlConfig(h.GameProxy, game.GAME_ID, "")
h.TableConfig = replyOpt.List
if len(h.TableConfig) == 0 {
log.Error(game.GAME_ID, " 21点后台获取桌子配置 无配置")
} else {
log.Debug(" 21点获取后台桌子配置 ", h.TableConfig)
}
}
func (h *Home) run() {
milliseconds := time.Now().UnixMilli()
if milliseconds >= h.NextCreateTable {
TableCreatePro := []int{0, 0, 0, 0, 0, 0}
for _, TempTableCreatePro := range h.BloodCtrl.AndroidOprateConfig.TableCreatePro {
for Index, _ := range TableCreatePro {
if TableCreatePro[Index] == 0 && h.TableCount[Index] < TempTableCreatePro[0] {
TableCreatePro[Index] = int(TempTableCreatePro[1])
for _, SingleTableConfig := range h.TableConfig {
tempRoomID, err := strconv.Atoi(SingleTableConfig.RoomId)
if err == nil {
if SingleTableConfig.TableMaxNum <= SingleTableConfig.TableMinNum {
h.TableNeedCount[tempRoomID] = int32(SingleTableConfig.TableMinNum)
} else {
h.TableNeedCount[tempRoomID] = int32(rand.Int63n(SingleTableConfig.TableMaxNum-SingleTableConfig.TableMinNum) + SingleTableConfig.TableMinNum)
}
}
log.Debug(" 场次 ", tempRoomID, " 个数 ", h.TableNeedCount[tempRoomID])
}
for Index, Pro := range TableCreatePro {
log.Debug(" 场次 ", Index, " 个数 ", h.TableCount[Index], " 概率", Pro)
if rand.Intn(10000) < Pro {
h.CreateRoom(0, int32(Index), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功")
go func() {
for LevelID, NeedCount := range h.TableNeedCount {
for h.TableCount[LevelID] < NeedCount {
h.CreateRoom(0, int32(LevelID), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功 当前等级 ", LevelID, " 个数 ", h.TableCount[LevelID])
}
}
}
}()
h.NextCreateTable = milliseconds + h.BloodCtrl.AndroidOprateConfig.CreateTableHZ
h.NextCreateTable = milliseconds + h.TableConfig[0].CheckFrequency*1000
}
}

20
game-server/game/SixAndarBahar/app/gamemanage/gamemanage.go

@ -105,6 +105,16 @@ func JoinTable(ctx *node.Context) {
log.Debug("玩家", Ctx.Request.UID, " 加入房间 req:", req)
if req.TableID == 1 && req.IsWatching == 1 {
res.Code = -4
res.CodeMsg = "不能以观战的身份创建桌子"
log.Debug(res.CodeMsg)
if err := Ctx.Response(res); err != nil {
log.Debugf("EnterGame ==> response message failed: %v", err)
}
return
}
//在房间中
var roomObj room.HomeBase
RoomID := room.Gh.GetRoomIdByUid(Ctx.Request.UID)
@ -244,6 +254,16 @@ func UpdateUserGold(uid int64) { //更新用户的钱
})
}
func UpdateTableConfig(gameID int64) { //更新桌子的配置
task.AddTask(func() {
log.Debug(gameID, " 更新桌子的配置 ", gameID)
if game.GAME_ID == gameID {
room.Gh.InitBloodControlByBackend()
log.Debug(gameID, " 更新桌子的配置")
}
})
}
func UserBet(ctx *node.Context) { // 用户下注
Ctx := ctx.Clone()
task.AddTask(func() {

1
game-server/game/dragonTiger/app/core/protocol/protocol_msg.go

@ -64,6 +64,7 @@ type LeaveTableRes struct { // 退出桌子返回
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

4
game-server/game/rummy/app/core/core.go

@ -56,6 +56,10 @@ func (c *Core) Init() {
userevt.SubscribeGoldChange(func(uid int64) {
gamemanage.UpdateUserGold(uid)
})
userevt.SubscribeTableConfigChange(func(gameID int64) {
gamemanage.UpdateTableConfig(gameID)
})
}
// Reconnect 掉线重连

4
game-server/game/rummy/app/core/game/game.go

@ -12,6 +12,7 @@ import (
"xgame/game/rummy/app/core/blood"
"xgame/game/rummy/app/core/types"
"xgame/internal/option/room"
gamepb "xgame/internal/service/game/pb"
"github.com/roylee0704/gron"
"github.com/shopspring/decimal"
@ -76,7 +77,8 @@ const (
type Room struct {
RoomProxy *node.Proxy
Ctx context.Context
Opt *room.Options //房间的参数
Opt *room.Options //房间的参数
TableConfig *gamepb.GameTableTotal
DestroyRoomFunc func(int64) //销毁房间回调
QuitRoomFunc func(int64) //退出房间回调
NotifyFunc func(int32, interface{}) //大厅通知回调

10
game-server/game/rummy/app/core/game/game_disconnect.go

@ -1,6 +1,9 @@
package game
import "base/log"
import (
"base/log"
"xgame/game/rummy/app/core/protocol"
)
/*
OnReconnect(userId int64, proxy *node.Proxy) // 断线重连
@ -9,7 +12,6 @@ import "base/log"
// OnDisconnect 玩家离线 保存正在游戏的进度
func (rr *Room) OnDisconnect(userId int64) {
rr.roomRWLock.Lock()
defer rr.roomRWLock.Unlock()
log.Debug(" 桌子号", rr.RId, "玩家", userId, "离线")
@ -26,8 +28,12 @@ func (rr *Room) OnDisconnect(userId int64) {
if player != nil {
if player.Uid == userId {
player.OnlineState = USER_OFF_LINE
rr.roomRWLock.Unlock()
rr.OnGetOutRoom(player.Uid, protocol.LEAVE_REASON_2)
rr.roomRWLock.Lock()
break
}
}
}
rr.roomRWLock.Unlock()
}

10
game-server/game/rummy/app/core/game/game_init.go

@ -3,6 +3,7 @@ package game
import (
"base/encoding/json"
"base/log"
"strconv"
"time"
"xgame/game/service/rpc_client"
optionRoom "xgame/internal/option/room"
@ -56,6 +57,15 @@ func (rr *Room) OnInit() bool {
// 读取配置文件
rr.InitBloodControl()
var gameTableConfig *gamepb.FetchGameTableTotalsReply
gameTableConfig = rpc_client.GetTableCtrlConfig(rr.RoomProxy, int64(rr.GameID), strconv.Itoa(int(rr.RoomID)))
if len(gameTableConfig.List) == 0 {
log.Error(" 21点后台获取桌子配置 无配置 房间等级 ", rr.RoomID)
} else {
rr.TableConfig = gameTableConfig.List[0]
log.Debug(" 21点后台获取桌子配置 房间等级 ", rr.RoomID, " 配置 ", rr.TableConfig)
}
//配置库存[房间的库存]
rr.StockValue = rr.BoolePool.BoolPoolSockNum

5
game-server/game/rummy/app/core/game/game_logic.go

@ -225,6 +225,8 @@ func (rr *Room) run() {
case TIME_ID_END_SHOW:
{
if milliseconds >= rr.CurrentOperationTimer {
// 先弄个长点的时间防止出问题
rr.CurrentOperationTimer = milliseconds + 30000
// 退出离线用户
for _, player := range rr.PlayerMap {
if player.OnlineState != USER_ON_LINE || player.AutoGiveUpCount >= 3 {
@ -243,6 +245,9 @@ func (rr *Room) run() {
if player.Gold.IntPart() <= rr.MinGameScore {
log.Debug("用户 ", player.Nickname, " 钱不够 踢出去 拥有钱:", player.Gold.IntPart(), " 需要的钱:", rr.MinGameScore)
rr.OnGetOutRoom(player.Uid, protocol.LEAVE_REASON_3)
} else if !player.IsRobot && player.PlayWatchCount >= int(3) {
log.Debug("用户 ", player.Nickname, " 连续观战了3局 ", rr.RId)
rr.OnGetOutRoom(player.Uid, protocol.LEAVE_REASON_2)
}
}

86
game-server/game/rummy/app/core/game/game_out_room.go

@ -2,7 +2,6 @@ package game
import (
"base/log"
"time"
"xgame/game/rummy/app/core/protocol"
"xgame/game/rummy/app/route"
)
@ -169,44 +168,44 @@ func (rr *Room) OnGetOutRoom(uid int64, reason int32) bool {
// log.Debug(" 桌子号", rr.RId, "退出房间后,房间中的玩家", i, "的信息", v.Uid, ":", v)
//}
// 观战转坐下
TempChairID := int32(0)
for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
if _, exists := rr.PlayerMap[TempChairID]; !exists {
for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// 金币足才可以自动坐下
if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
WatchUser := rr.PlayerWatchMap[TempIndex]
WatchUser.ChairId = TempChairID
rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
Uid: WatchUser.Uid,
ChairID: TempChairID,
NextTimestamp: time.Now().UnixMilli(),
})
// 通知大厅有人坐下
NotifySitDown := &protocol.NotifyDTSitDown{
Uid: WatchUser.Uid,
RoomID: rr.RoomID,
TableID: rr.RId,
ChairID: TempChairID,
Avatar: WatchUser.Avatar,
State: rr.CurrentGameState,
}
rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
if TempIndex == len(rr.PlayerWatchMap)-1 {
rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
} else {
rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
}
break
}
}
}
}
//// 观战转坐下
//TempChairID := int32(0)
//for TempChairID = 0; TempChairID < MAX_USER_NUM; TempChairID++ {
// if _, exists := rr.PlayerMap[TempChairID]; !exists {
// for TempIndex, TempWatchPlayer := range rr.PlayerWatchMap {
// // 金币足才可以自动坐下
// if TempWatchPlayer.Gold.IntPart() > MIN_GAME_SCORE {
// WatchUser := rr.PlayerWatchMap[TempIndex]
// WatchUser.ChairId = TempChairID
// rr.SendAllMessage(route.NotifyWatchToDown, &protocol.NotifyWatchToDown{
// Uid: WatchUser.Uid,
// ChairID: TempChairID,
// NextTimestamp: time.Now().UnixMilli(),
// })
//
// // 通知大厅有人坐下
// NotifySitDown := &protocol.NotifyDTSitDown{
// Uid: WatchUser.Uid,
// RoomID: rr.RoomID,
// TableID: rr.RId,
// ChairID: TempChairID,
// Avatar: WatchUser.Avatar,
// State: rr.CurrentGameState,
// }
// rr.NotifyFunc(route.NotifyDTSitDown, NotifySitDown)
//
// rr.PlayerMap[TempWatchPlayer.ChairId] = TempWatchPlayer
//
// if TempIndex == len(rr.PlayerWatchMap)-1 {
// rr.PlayerWatchMap = rr.PlayerWatchMap[:TempIndex]
// } else {
// rr.PlayerWatchMap = append(rr.PlayerWatchMap[:TempIndex], rr.PlayerWatchMap[TempIndex+1:]...)
// }
// break
// }
// }
// }
//}
if ret {
log.Debug(" 桌子号", rr.RId, "玩家", uid, "退出房间成功")
@ -217,6 +216,15 @@ func (rr *Room) OnGetOutRoom(uid int64, reason int32) bool {
log.Debug(" 桌子号", rr.RId, "玩家人数", playerCount)
if playerCount == 0 || (rr.CreatorId != 0 && playerCount == robotCount) {
//退出所有观战玩家
for _, pPlayer := range rr.PlayerWatchMap {
if pPlayer == nil {
continue
}
rr.Send(pPlayer, route.LogoutTableRes, LeaveTableRes)
}
rr.PlayerWatchMap = rr.PlayerWatchMap[:0]
//关闭定时器
rr.GronTimer.Stop()
rr.RobotMgr.GronTimer.Stop()

24
game-server/game/rummy/app/core/game/game_over.go

@ -85,6 +85,8 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
WinPlayerScore := int64(0)
for i, p := range rr.PlayerMap {
p.PlayCount++
p.PlayWatchCount = 0
Seats := &protocol.PBRMTableSeat{}
Seats.Hand_tiles = make([]int32, 0)
Seats.Index = i
@ -169,6 +171,10 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
}
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.SendAllMessage(route.NotifyGameConclude, RMGameOver)
} else {
@ -195,6 +201,8 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
RMGameOver.Seats = make([]*protocol.PBRMTableSeat, 0)
for idx, p := range rr.PlayerMap {
p.PlayCount++
p.PlayWatchCount = 0
RMTableSeat := &protocol.PBRMTableSeat{}
RMTableSeat.Index = idx
RMTableSeat.State = 1
@ -218,6 +226,10 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
RMGameOver.Seats = append(RMGameOver.Seats, RMTableSeat)
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
log.Debug("黄庄结算====>", RMGameOver)
rr.SendAllMessage(route.NotifyGameConclude, RMGameOver)
}
@ -234,6 +246,8 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
RMGameOver.Seats = make([]*protocol.PBRMTableSeat, 0)
for i, p := range rr.PlayerMap {
p.PlayCount++
p.PlayWatchCount = 0
Seats := &protocol.PBRMTableSeat{}
Seats.Hand_tiles = make([]int32, 0)
Seats.Index = i
@ -315,6 +329,10 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
}
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.SendAllMessage(route.NotifyGameConclude, RMGameOver)
}
case USER_GIVEUP_END:
@ -327,6 +345,8 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
RMGameOver.Seats = make([]*protocol.PBRMTableSeat, 0)
for i, p := range rr.PlayerMap {
p.PlayCount++
p.PlayWatchCount = 0
Seats := &protocol.PBRMTableSeat{}
Seats.Hand_tiles = make([]int32, 0)
Seats.Index = i
@ -402,6 +422,10 @@ func (rr *Room) OnEventGameConclude(chairID int32, reason int32) {
}
}
for _, player := range rr.PlayerWatchMap {
player.PlayWatchCount++
}
rr.SendAllMessage(route.NotifyGameConclude, RMGameOver)
}
}

1
game-server/game/rummy/app/core/game/game_player.go

@ -44,6 +44,7 @@ type Player struct {
LastAction protocol.PBRMAction //动作
ActionChoice protocol.PBRMActionChoice //动作选项
PlayCount int //在桌子上呆了几局
PlayWatchCount int //在桌子连续观战了几局
CanBet bool // 玩家是否需要等待下一局开始
}

3
game-server/game/rummy/app/core/game/game_watch.go

@ -93,4 +93,7 @@ func (rr *Room) OnUserWatchToDown(uid int64, msg interface{}) { // 主动观战
break
}
}
rr.CheckRoomStart()
}

1
game-server/game/rummy/app/core/protocol/protocol_msg.go

@ -129,6 +129,7 @@ type NotifyCurrentBanker struct { // 通知庄家
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

56
game-server/game/rummy/app/core/room/roommgr.go

@ -7,12 +7,14 @@ import (
"github.com/roylee0704/gron"
"math/rand"
"sort"
"strconv"
"sync"
"time"
conf "xgame/game/rummy/app/config"
"xgame/game/rummy/app/core/game"
"xgame/game/rummy/app/core/protocol"
"xgame/game/rummy/app/route"
"xgame/game/service/rpc_client"
gameservice "xgame/internal/service/game"
gamepb "xgame/internal/service/game/pb"
)
@ -29,6 +31,7 @@ type Home struct {
BloodCtrl conf.BloodCtrl //血池控制
NextCreateTable int64 //下个机器人创建房间的时间
TableCount []int32 //各等级的房间个数
TableNeedCount []int32 //各等级需要的房间个数
Rhb map[int64]HomeBase
RhbEx map[int64]int64
RhbRoom map[int64]*game.Room
@ -36,21 +39,24 @@ type Home struct {
NextId int64
lock sync.Mutex
RoomsReply *gamepb.FetchRoomsReply
TableConfig []*gamepb.GameTableTotal
}
var Gh *Home
func Init(GameProxy *node.Proxy) {
Gh = &Home{
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Rhb: make(map[int64]HomeBase),
RhbEx: make(map[int64]int64),
RhbRoom: make(map[int64]*game.Room),
EnterUser: make(map[int64]*node.Context),
TableCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
TableNeedCount: []int32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
Gh.GameProxy = GameProxy
Gh.InitBloodControl()
Gh.InitBloodControlByBackend()
milliseconds := time.Now().UnixMilli()
Gh.NextCreateTable = milliseconds + 300
@ -79,28 +85,44 @@ func (h *Home) InitBloodControl() {
}
}
func (h *Home) InitBloodControlByBackend() {
// 按等级从后台获取到配置
var replyOpt *gamepb.FetchGameTableTotalsReply
replyOpt = rpc_client.GetTableCtrlConfig(h.GameProxy, game.GAME_ID, "")
h.TableConfig = replyOpt.List
if len(h.TableConfig) == 0 {
log.Error(game.GAME_ID, " 21点后台获取桌子配置 无配置")
} else {
log.Debug(" 21点获取后台桌子配置 ", h.TableConfig)
}
}
func (h *Home) run() {
milliseconds := time.Now().UnixMilli()
if milliseconds >= h.NextCreateTable {
TableCreatePro := []int{0, 0, 0, 0, 0, 0}
for _, TempTableCreatePro := range h.BloodCtrl.AndroidOprateConfig.TableCreatePro {
for Index, _ := range TableCreatePro {
if TableCreatePro[Index] == 0 && h.TableCount[Index] < TempTableCreatePro[0] {
TableCreatePro[Index] = int(TempTableCreatePro[1])
for _, SingleTableConfig := range h.TableConfig {
tempRoomID, err := strconv.Atoi(SingleTableConfig.RoomId)
if err == nil {
if SingleTableConfig.TableMaxNum <= SingleTableConfig.TableMinNum {
h.TableNeedCount[tempRoomID] = int32(SingleTableConfig.TableMinNum)
} else {
h.TableNeedCount[tempRoomID] = int32(rand.Int63n(SingleTableConfig.TableMaxNum-SingleTableConfig.TableMinNum) + SingleTableConfig.TableMinNum)
}
}
log.Debug(" 场次 ", tempRoomID, " 个数 ", h.TableNeedCount[tempRoomID])
}
for Index, Pro := range TableCreatePro {
log.Debug(" 场次 ", Index, " 个数 ", h.TableCount[Index], " 概率", Pro)
if rand.Intn(10000) < Pro {
h.CreateRoom(0, int32(Index), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功")
go func() {
for LevelID, NeedCount := range h.TableNeedCount {
for h.TableCount[LevelID] < NeedCount {
h.CreateRoom(0, int32(LevelID), game.GAME_ID, 0, h.GameProxy)
log.Debug("创建房间成功 当前等级 ", LevelID, " 个数 ", h.TableCount[LevelID])
}
}
}
}()
h.NextCreateTable = milliseconds + h.BloodCtrl.AndroidOprateConfig.CreateTableHZ
h.NextCreateTable = milliseconds + h.TableConfig[0].CheckFrequency*1000
}
}

10
game-server/game/rummy/app/gamemanage/gamemanage.go

@ -251,6 +251,16 @@ func UpdateUserGold(uid int64) { //更新用户的钱
})
}
func UpdateTableConfig(gameID int64) { //更新桌子的配置
task.AddTask(func() {
log.Debug(gameID, " 更新桌子的配置 ", gameID)
if game.GAME_ID == gameID {
room.Gh.InitBloodControlByBackend()
log.Debug(gameID, " 更新桌子的配置")
}
})
}
func WatchToDown(ctx *node.Context) { // 主动观战转坐下
Ctx := ctx.Clone()
task.AddTask(func() {

14
game-server/game/service/rpc_client/rpc_game.go

@ -58,6 +58,20 @@ func GetSrcRoomByLevel(ctx *node.Proxy, gameID, agentID, srcRoomLevel int32) *ga
return reply
}
// GetSrcRoom 获取桌子控制的配置
func GetTableCtrlConfig(ctx *node.Proxy, gameID int64, roomLevel string) *gamepb.FetchGameTableTotalsReply {
client, err := gameservice.NewClient(ctx.NewServiceClient)
if err != nil {
return nil
}
reply, err := client.FetchGameTableTotals(context.Background(), &gamepb.FetchGameTableTotalsArgs{
GameId: gameID,
RoomId: roomLevel,
})
return reply
}
// HallEnterGame 推送 大厅进入游戏
func HallEnterGame(ctx *node.Proxy, gameID, UID, agentID, srcRoomId int64, roomId string, gameName string) {
client, err := gameservice.NewClient(ctx.NewServiceClient)

1
game-server/game/sevenUpSevenDown/app/core/protocol/protocol_msg.go

@ -71,6 +71,7 @@ type LeaveTableRes struct { // 退出桌子返回
}
type NotifyLeaveRoomRes struct { // 通知退出桌子
Uid int64 `json:"uid"` // userId
ChairID int32 `json:"chairId"` // 座位号
LeaveReason int32 `json:"leaveReason"` // 离开原因 0主动离开 1踢出房间
}

1
move.sh

@ -8,6 +8,7 @@ chmod 777 *
mv mesh "$TARGET_DIR/../games/app/mesh"
mv login "$TARGET_DIR/../games/app/login"
mv hall "$TARGET_DIR/../games/app/hall"
mv halltwo "$TARGET_DIR/../games/app/halltwo"
mv gate "$TARGET_DIR/../games/app/gate"
mv commServer "$TARGET_DIR/../games/app/https/commServer"
mv payment "$TARGET_DIR/../games/app//https/payment"

1
startserver.sh

@ -5,6 +5,7 @@ docker-compose up -d
supervisorctl start mesh
supervisorctl start login
supervisorctl start hall
supervisorctl start halltwo
supervisorctl start gate
supervisorctl start commServer
supervisorctl start payment

Loading…
Cancel
Save