| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- package frame
- import (
- "encoding/json"
- "fmt"
- "math/rand"
- "sync"
- "time"
- //utils2 "bet24.com/servers/insecureframe/gate/Utils"
- "bet24.com/log"
- "bet24.com/redis"
- "bet24.com/servers/insecureframe/gate"
- "bet24.com/servers/insecureframe/message"
- "bet24.com/servers/insecureframe/robot"
- "bet24.com/servers/user"
- )
- func NewGameFrame(gameSink GameSink) *GameFrame {
- f := new(GameFrame)
- f.gameSink = gameSink
- f.tables = make(map[int]*ThreadsafeTable)
- f.lock_table = &sync.RWMutex{}
- f.lock_user = &sync.RWMutex{}
- f.lock_changeTable = &sync.RWMutex{}
- f.tableIndex = 1
- f.offlineUsers = make(map[int]offlineUser)
- time.AfterFunc(10*time.Second, f.checkOfflineUsers)
- f.changeTableCount = make(map[int32]int)
- f.roomDatas = gameSink.GetRoomDatas()
- if len(f.roomDatas) > 0 {
- time.AfterFunc(10*time.Second, f.checkCreateRobotRoom)
- }
- log.Debug("gameframe running...")
- return f
- }
- type offlineUser struct {
- userInfo *user.UserInfo
- offlineTime int64
- tableId int
- userIndex int32
- }
- type GameFrame struct {
- gameSink GameSink
- tableIndex int
- // --GameTable++
- tables map[int]*ThreadsafeTable
- lock_table *sync.RWMutex
- lock_user *sync.RWMutex
- offlineUsers map[int]offlineUser
- roomDatas []string
- lock_changeTable *sync.RWMutex
- changeTableCount map[int32]int
- }
- func (f *GameFrame) CreateBacTable() {
- // 如果是百人游戏,不是私人场
- if f.gameSink.GetChairCount() < 2 && !f.gameSink.IsPrivateRoom() {
- // 创建一张默认桌子
- f.createTable("")
- }
- }
- // implement GateSink
- func (f *GameFrame) GetServerPort() int {
- return f.gameSink.GetServerPort()
- }
- func (f *GameFrame) checkCreateRobotRoom() {
- if !robot.IsRunning() {
- return
- }
- if stopping {
- return
- }
- for _, v := range f.roomDatas {
- minRoomCount := f.gameSink.GetMinRoomCount(v)
- //log.Debug("checkCreateRobotRoom %s:%d", v, minRoomCount)
- if minRoomCount == 0 {
- continue
- }
- existCount := f.getTableCount(v)
- for i := 0; i < minRoomCount-existCount; i++ {
- t := f.createTable(v)
- if t == nil {
- log.Debug("checkCreateRobotRoom creating table failed %s", v)
- continue
- }
- min, max := f.gameSink.GetRoomRobotGoldLimit(v)
- enterRobotCount := 2
- if f.gameSink.GetChairCount() == 1 {
- enterRobotCount = f.gameSink.GetRoomRobotCount(v)
- }
- for i := 0; i < enterRobotCount; i++ {
- go robot.GetOneRobotEnterTableAndReady(t.tableId, min, max)
- }
- }
- }
- time.AfterFunc(60*time.Second, f.checkCreateRobotRoom)
- }
- func (f *GameFrame) checkAndCreateTable(roomData string) {
- }
- func (f *GameFrame) checkOfflineUsers() {
- offlineSeconds := f.gameSink.GetOfflineSeconds()
- if offlineSeconds <= 0 {
- log.Debug("GameFrame.checkOfflineUsers 不支持断线续玩")
- return
- }
- //log.Debug("GameFrame.checkOfflineUsers offlineSeconds = %d", offlineSeconds)
- time.AfterFunc(10*time.Second, f.checkOfflineUsers)
- now := time.Now().Unix()
- f.lock_user.RLock()
- for k, v := range f.offlineUsers {
- if now-v.offlineTime >= offlineSeconds {
- go f.removeOfflineUser(k, v.userInfo)
- }
- }
- f.lock_user.RUnlock()
- }
- func (f *GameFrame) OnUserEnter(userIndex int32) {
- }
- func (f *GameFrame) delayUserWatchTable(userIndex int32, tableId int) {
- table := f.getTable(1)
- if table == nil {
- return
- }
- //time.Sleep(50 * time.Millisecond)
- go table.AddTableUser(userIndex, 0, false, true)
- }
- func (f *GameFrame) OnUserLogined(userIndex int32) {
- // 是否属于断线玩家
- usr := gate.GetUserInfo(userIndex)
- if usr == nil {
- log.Debug("GameFrame.OnUserLogined user not exist")
- return
- }
- // 发送一下自己进入的消息
- //user2 := utils2.GetUserInfoData(1)
- // fmt.Printf("用户登录成功==",user2)
- // usr.SetUserNickName(user2.Data[0].NickName)
- // usr.SetUserGold(user2.Data[0].GoldCoins)
- info := usr.GetUserInfo_Table(true)
- d, _ := json.Marshal(info)
- fmt.Println("获取用户信息=====",info)
- gate.SendMessage(userIndex, message.Frame_UserEnter, string(d))
- // 如果是百人场,直接进入旁观
- /*if f.gameSink.GetChairCount() < 2 && !f.gameSink.IsPrivateRoom() {
- go f.delayUserWatchTable(userIndex, 1)
- return
- }*/
- //发送场次列表
- // d, _ = json.Marshal(f.gameSink.GetRoomList())
- // gate.SendMessage(userIndex, message.Frame_GetRoomList, string(d))
- userId := usr.GetUserId()
- f.lock_user.RLock()
- offlineUser, ok := f.offlineUsers[userId]
- f.lock_user.RUnlock()
- if !ok {
- return
- }
- table := f.getTable(offlineUser.tableId)
- if table == nil /*table.tableStatus != TableStatus_Playing*/ {
- log.Debug("GameFrame.OnUserLogined replay table[%d] not found", offlineUser.tableId)
- return
- }
- log.Debug("GameFrame.OnUserLogined 用户 %d 断线回来了", userId)
- usr.SetUserStatus(user.UserStatus_Offline)
- table.userReplay(offlineUser.userInfo.GetUserIndex(), usr)
- // 通知完桌子后再删除断线用户信息
- f.lock_user.Lock()
- delete(f.offlineUsers, userId)
- f.lock_user.Unlock()
- }
- func (f *GameFrame) OnUserExit(userIndex int32) {
- if robot.IsRunning() {
- robot.UserExit(userIndex)
- }
- f.lock_changeTable.Lock()
- delete(f.changeTableCount, userIndex)
- f.lock_changeTable.Unlock()
- usr := gate.GetUserInfo(userIndex)
- if usr == nil {
- log.Debug("GameFrame.OnUserExit user[%d] not exist", userIndex)
- return
- }
- table := f.getTable(usr.GetUserTableId())
- if table == nil {
- log.Debug("GameFrame.OnUserExit user[%d] table[%d] not found", userIndex, usr.GetUserTableId())
- return
- }
- // 是否断线?
- oldStatus := usr.GetUserStatus()
- if oldStatus == user.UserStatus_Play {
- if f.addOfflineUser(usr) {
- table.tableSink.OnUserOffline(usr.GetUserChairId())
- // 广播玩家断线状态
- d, _ := json.Marshal(message.UserStatusChange{UserId: usr.GetUserId(),
- OldStatus: oldStatus,
- NewStatus: user.UserStatus_Offline,
- TableId: usr.GetUserTableId(),
- ChairId: usr.GetUserChairId()})
- gate.BroadcastData(message.Frame_UserStatusChange, string(d))
- return
- }
- }
- f.setOfflineStatus(usr.GetUserId(), false, table.privateData)
- table.RemoveUser(userIndex, false, false)
- }
- func (f *GameFrame) addOfflineUser(usr *user.UserInfo) bool {
- if f.gameSink.GetOfflineSeconds() <= 0 {
- return false
- }
- userId := usr.GetUserId()
- f.lock_user.Lock()
- defer f.lock_user.Unlock()
- _, ok := f.offlineUsers[userId]
- if ok {
- log.Debug("GameFrame.addOfflineUser userId[%d] already exist", userId)
- return false
- }
- log.Debug("addOfflineUser %d", userId)
- usr.SetUserStatus(user.UserStatus_Offline)
- f.offlineUsers[userId] = offlineUser{userInfo: usr.GetCopy(), offlineTime: time.Now().Unix(),
- tableId: usr.GetUserTableId(), userIndex: usr.GetUserIndex()}
- return true
- }
- func (f *GameFrame) removeOfflineUser(userIdKey int, usr *user.UserInfo) {
- userId := usr.GetUserId()
- userIndex := usr.GetUserIndex()
- f.lock_user.Lock()
- ou, ok := f.offlineUsers[userIdKey]
- if !ok {
- log.Debug("GameFrame.removeOfflineUser userId[%d] not found,userIdKey = %d", userId, userIdKey)
- delete(f.offlineUsers, userIdKey)
- f.lock_user.Unlock()
- return
- }
- f.lock_user.Unlock()
- log.Debug("GameFrame.removeOfflineUser removing %d %d %d ", userId, userIndex, ou.userIndex)
- table := f.getTable(ou.tableId)
- if table != nil {
- table.RemoveUser(userIndex, false, false)
- }
- log.Debug("GameFrame.removeOfflineUser removed %d ", userId)
- f.lock_user.Lock()
- delete(f.offlineUsers, userIdKey)
- f.lock_user.Unlock()
- }
- func (f *GameFrame) removeOfflineByTableId(tableId int) {
- f.lock_user.RLock()
- defer f.lock_user.RUnlock()
- for k, v := range f.offlineUsers {
- if v.tableId == tableId {
- go f.removeOfflineUser(k, v.userInfo)
- go f.setOfflineStatus(k, false, "")
- }
- }
- }
- func (f *GameFrame) OnGameMessage(userIndex int32, userID int, msg, data string) bool {
- switch msg {
- case message.Frame_AutoSit:
- return f.recvAutoSit(userIndex, data, false, false)
- case message.Frame_NewUserAutoSit:
- return f.recvAutoSit(userIndex, data, false, true)
- case message.Frame_ChangeTable:
- return f.recvChangeTable(userIndex, data)
- case message.Frame_Sit:
- return f.recvSitTable(userIndex, data)
- case message.Frame_WatchTable:
- return f.recvWatchTable(userIndex, data)
- case message.Frame_Standup:
- return f.recvStandup(userIndex, data)
- case message.Frame_Watch:
- return f.recvWatch(userIndex, data)
- case message.Frame_Ready:
- return f.recvReady(userIndex, true)
- case message.Frame_CancelReady:
- return f.recvReady(userIndex, false)
- // case message.Frame_GetRoomList:
- // return f.recvGetRoomList(userIndex, msg)
- case message.Frame_ADReward:
- return f.recvAdReward(userIndex, data)
- case message.Frame_Ping:
- return f.recvFramePing(userIndex, data)
- /*case message.Frame_CreatePrivateRoom:
- return f.createPrivateRoom(userIndex, data)
- case message.Frame_PrivateRoom_SetBaseScore:
- return f.privateRoomSetBaseScore(userIndex, data)*/
- case message.Frame_PrivateRoom_RequestDismiss:
- return f.recvPrivateRoomRequestDismiss(userIndex, msg, data)
- case message.Frame_PrivateRoom_DismissResp:
- return f.recvPrivateRoomDismissResp(userIndex, msg, data)
- case message.Frame_Voice:
- return f.recvFrameVoiceMessage(userIndex, userID, msg, data)
- case message.Frame_PrivateRoom_KickUser:
- return f.recvPrivateRoomKick(userIndex, msg, data)
- default:
- return f.recvTableMessage(userIndex, userID, msg, data)
- }
- }
- func (f *GameFrame) GetGameID() int {
- return f.gameSink.GetGameID()
- }
- func (f *GameFrame) GetGameName() string {
- return f.gameSink.GetGameName()
- }
- func (f *GameFrame) GetRoomName() string {
- return f.gameSink.GetRoomName()
- }
- func (f *GameFrame) GetCertFile() string {
- return f.gameSink.GetCertFile()
- }
- func (f *GameFrame) GetKeyFile() string {
- return f.gameSink.GetKeyFile()
- }
- // 机器人配置
- func (f *GameFrame) GetRobotCount() int {
- return f.gameSink.GetRobotCount()
- }
- func (f *GameFrame) GetRobotGoldLimit() (min, max int) {
- min, max = f.gameSink.GetRobotGoldLimit()
- return
- }
- func (f *GameFrame) GetRobotOnlineSec() int {
- return f.gameSink.GetRobotOnlineSec()
- }
- func (f *GameFrame) IsChipRoom() bool {
- return f.gameSink.IsChipRoom()
- }
- func (f *GameFrame) IsLadderRoom() bool {
- gameSink_LadderRoom, ok := f.gameSink.(GameSink_LadderRoom)
- return ok && gameSink_LadderRoom.IsLadderRoom()
- }
- func (f *GameFrame) GetChipRoom() int {
- if f.gameSink.IsChipRoom() {
- return 1
- } else {
- return 0
- }
- }
- func (f *GameFrame) OnPlatformConfig(key string) {
- f.gameSink.OnPlatformConfig(key)
- }
- func (f *GameFrame) IsPrivateRoom() bool {
- return f.gameSink.IsPrivateRoom()
- }
- func (f *GameFrame) GetVersionID() int {
- return f.gameSink.GetVersionID()
- }
- func (f *GameFrame) setUserStatus(userIndex int32, status int) {
- usr := gate.GetUserInfo(userIndex)
- if usr == nil {
- log.Debug("GameFrame.setUserStatus user not exist %d", userIndex)
- return
- }
- if status == user.UserStatus_Free {
- usr.SetTableChairId(-1, -1)
- }
- oldStatus := usr.GetUserStatus()
- if oldStatus == status {
- log.Debug("GameFrame.setUserStatus user[%d] status not changed status = %d", userIndex, status)
- return
- }
- usr.SetUserStatus(status)
- //go func() {
- // 取消协程,保证按顺序发送用户状态
- d, _ := json.Marshal(message.UserStatusChange{UserId: usr.GetUserId(),
- OldStatus: oldStatus,
- NewStatus: status,
- TableId: usr.GetUserTableId(),
- ChairId: usr.GetUserChairId()})
- gate.BroadcastData(message.Frame_UserStatusChange, string(d))
- if status == user.UserStatus_Play {
- t := f.getTable(usr.GetUserTableId())
- data := ""
- if t != nil {
- data = t.privateData
- if t.isPrivate() {
- // 私人场不写断线信息
- return
- }
- }
- f.setOfflineStatus(usr.GetUserId(), true, data)
- } else {
- f.setOfflineStatus(usr.GetUserId(), false, "")
- }
- //}()
- }
- func (f *GameFrame) dump() {
- log.Release("----------GameFrame.dump----------")
- log.Release(" current table index : %d", f.tableIndex)
- defer func() {
- log.Release("++++++++++GameFrame.dump++++++++++")
- }()
- f.lock_table.RLock()
- defer f.lock_table.RUnlock()
- for _, v := range f.tables {
- log.Release(" table[%d] status[%d] usercount[%d] started[%d] Room[%s]", v.tableId, v.tableStatus, v.getUserCount(), v.getStartTime(), v.privateData)
- }
- }
- func (f *GameFrame) dumpTable(tableId int) {
- log.Release("----------GameFrame.dumpTable----------")
- defer func() {
- log.Release("++++++++++GameFrame.dumpTable++++++++++")
- }()
- table := f.getTable(tableId)
- if table == nil {
- log.Release(" table %d not exist", tableId)
- return
- }
- table.dump()
- }
- func (f *GameFrame) dumpTimers(tableId int) {
- log.Release("----------GameFrame.dumpTimers----------")
- defer func() {
- log.Release("++++++++++GameFrame.dumpTimers++++++++++")
- }()
- table := f.getTable(tableId)
- if table == nil {
- log.Release(" table %d not exist", tableId)
- return
- }
- table.dumpTimers()
- }
- func (f *GameFrame) dumpScene(tableId int) {
- log.Release("----------GameFrame.dumpScene----------")
- defer func() {
- log.Release("++++++++++GameFrame.dumpScene++++++++++")
- }()
- table := f.getTable(tableId)
- if table == nil {
- log.Release(" table %d not exist", tableId)
- return
- }
- table.dumpScene()
- }
- func (f *GameFrame) dumpOffline() {
- log.Release("----------GameFrame.dumpOffline----------")
- defer func() {
- log.Release("++++++++++GameFrame.dumpOffline++++++++++")
- }()
- f.lock_user.RLock()
- defer f.lock_user.RUnlock()
- log.Release(" count %d", len(f.offlineUsers))
- for _, v := range f.offlineUsers {
- log.Release(" %d:%d %s offline:%d", v.userIndex, v.userInfo.GetUserId(), v.userInfo.GetUserNickName(), time.Now().Unix()-v.offlineTime)
- }
- }
- func (f *GameFrame) dismissTable(tableId int) {
- table := f.getTable(tableId)
- if table != nil {
- table.dismiss()
- }
- }
- func (f *GameFrame) getOfflineUser(userIndex int32) *user.UserInfo {
- f.lock_user.RLock()
- defer f.lock_user.RUnlock()
- for _, v := range f.offlineUsers {
- if v.userIndex == userIndex {
- return v.userInfo
- }
- }
- return nil
- }
- func (f *GameFrame) setOfflineStatus(userId int, offline bool, roomName string) {
- keyName := fmt.Sprintf("UserGameStatus:UserID:%v:", userId)
- if offline {
- o := struct {
- GameName string
- RoomName string
- ServerAddr string
- GameId int
- }{
- GameName: f.gameSink.GetGameName(),
- RoomName: roomName,
- ServerAddr: f.gameSink.GetServerAddr(),
- GameId: f.gameSink.GetGameID(),
- }
- d, _ := json.Marshal(o)
- redis.String_SetEx(keyName, string(d), int(f.gameSink.GetOfflineSeconds()))
- } else {
- redis.Key_Del(keyName)
- }
- }
- func (f *GameFrame) getUserCount(privateData string) int {
- ret := 0
- f.lock_table.RLock()
- defer f.lock_table.RUnlock()
- for _, v := range f.tables {
- if v.privateData != privateData {
- continue
- }
- ret += v.getUserCount()
- }
- return ret
- }
- func (f *GameFrame) GetVirtualUserCount(userCount int, roomType int) int {
- if roomType < 0 {
- roomType = 0
- } else {
- roomType = roomType % 8
- }
- userCounts := [][]int{}
- userCounts = append(userCounts, []int{72, 134, 326, 265, 534})
- userCounts = append(userCounts, []int{52, 168, 287, 201, 384})
- userCounts = append(userCounts, []int{11, 76, 163, 143, 176})
- userCounts = append(userCounts, []int{13, 42, 76, 103, 202})
- userCounts = append(userCounts, []int{43, 86, 126, 134, 286})
- userCounts = append(userCounts, []int{25, 62, 96, 76, 146})
- userCounts = append(userCounts, []int{10, 32, 62, 53, 76})
- userCounts = append(userCounts, []int{8, 21, 72, 62, 92})
- hour := time.Now().Hour()
- hourIndex := 0
- if hour >= 18 {
- hourIndex = 4
- } else if hour >= 14 {
- hourIndex = 3
- } else if hour >= 11 {
- hourIndex = 2
- } else if hour >= 6 {
- hourIndex = 1
- }
- param := 10
- return userCount*param + userCounts[roomType][hourIndex]*4 - 10 + rand.Intn(20)
- }
|