| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- package frame
- import (
- "fmt"
- "strings"
- "time"
- "bet24.com/log"
- "bet24.com/servers/insecureframe/gate"
- "bet24.com/servers/insecureframe/message"
- privateroom "bet24.com/servers/micros/privateroom/proto"
- task "bet24.com/servers/micros/task/proto"
- "bet24.com/servers/user"
- "bet24.com/utils"
- )
- func (t *ThreadsafeTable) AddUser_safe(userIndex int32, chairId int, replay bool, toWatch bool) bool {
- // 我本身就在里面?
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == userIndex {
- log.Debug("ThreadsafeTable.AddUser already in table %d chair[%d] prefered ChairId[%d]", userIndex, i, chairId)
- return false
- }
- }
- usr := gate.GetUserInfo(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.AddUser invalid userIndex %d", userIndex)
- return false
- }
- if t.isPrivate() && !toWatch {
- if !t.isValidChair(chairId) {
- log.Release("ThreadsafeTable.AddUser invalid chairId %d for privateRoom", chairId)
- return false
- }
- // 是否能坐下
- if privateroom.UserSit(t.roomNo, usr.GetUserId(), chairId) != 1 {
- log.Release("ThreadsafeTable.AddUser PrivateRoomUserSit failed roomNo:%d,userId:%d,chairId:%d",
- t.roomNo, usr.GetUserId(), chairId)
- return false
- }
- }
- watchString := ""
- if toWatch {
- watchString = "Watching"
- }
- log.Debug("ThreadsafeTable.AddUser [%d,%d],[%d.%d] %s", userIndex, usr.GetUserId(), t.tableId, chairId, watchString)
- if chairId == -1 {
- if toWatch {
- chairId = 0
- } else {
- chairId = t.getEmptyChair()
- if chairId == -1 {
- log.Debug("ThreadsafeTable.AddUser no empty chair %d", t.tableId)
- return false
- }
- }
- }
- if !t.isValidChair(chairId) {
- log.Debug("ThreadsafeTable.AddUser invalid chairId %d", chairId)
- return false
- }
- if !toWatch {
- // 本身就有人了
- if t.users[chairId] != -1 {
- log.Debug("ThreadsafeTable.AddUser chair[%d] taken[%d]", chairId, t.users[chairId])
- return false
- }
- t.users[chairId] = userIndex
- // 删除旁观用户
- t.removeWatchUser(userIndex, 0)
- }
- usr.SetTableChairId(t.tableId, chairId)
- if toWatch {
- gameFrame.setUserStatus(userIndex, user.UserStatus_Watch)
- } else {
- if replay && t.IsPlaying() {
- gameFrame.setUserStatus(userIndex, user.UserStatus_Play)
- } else {
- gameFrame.setUserStatus(userIndex, user.UserStatus_Sit)
- }
- }
- // 先发自己
- t.sendUserEnter(usr, userIndex)
- // 发其他人
- for i := 0; i < t.chairCount; i++ {
- if i == chairId && !toWatch {
- continue
- }
- if t.users[i] == -1 {
- continue
- }
- otherUser := t.getPlayer(t.users[i])
- if otherUser == nil {
- log.Debug("ThreadsafeTable.AddUser otherUser == nil %d:%d", i, t.users[i])
- continue
- }
- t.sendUserEnter(otherUser, userIndex)
- // 发给其他人
- if !replay {
- go t.sendUserEnter(usr, t.users[i])
- }
- }
- // 不需要发旁观用户给玩家,但要把玩家发给旁观用户
- if !replay {
- for _, v := range t.watchUsers {
- t.sendUserEnter(usr, v.UserIndex)
- // 语音房先特殊处理
- if gameFrame.GetGameID() == 70 {
- watcher, _ := t.GetUser(v.UserIndex)
- if watcher != nil {
- t.sendUserEnter(watcher, userIndex)
- }
- }
- }
- }
- if toWatch {
- t.addWatchUser(userIndex, chairId, usr.GetUserId())
- }
- // 如果是私人场,并且是房主
- if t.isPrivate() {
- // 获取玩家分数信息
- roomUser := privateroom.GetUserRoomInfo(usr.GetUserId(), t.roomNo)
- if roomUser != nil {
- log.Debug("ThreadsafeTable.AddUser 私人场玩家信息 %v", roomUser)
- usr.SetScore(roomUser.Score)
- usr.SetBaseScore(roomUser.BaseScore)
- usr.SetSetCount(roomUser.SetCount)
- } else {
- log.Release("ThreadsafeTable.AddUser 获取私人场信息失败")
- }
- gate.SendMessage(userIndex, message.Frame_PrivateRoom_No, fmt.Sprintf("%d", t.roomNo))
- }
- if !replay {
- t.tableSink.OnUserEnterTable(userIndex, chairId)
- } else {
- t.tableSink.OnUserReplay(chairId)
- }
- // 发送场景
- if t.IsPlaying() {
- t.sendGameSceneToUser(userIndex)
- }
- return true
- }
- func (t *ThreadsafeTable) RemoveUser_safe(userIndex int32, toWatch bool, changeChair bool) {
- log.Debug("ThreadsafeTable.RemoveUser_safe[%d] %d toWatch = %v changeChair = %v", t.tableId, userIndex, toWatch, changeChair)
- usr, isPlayer := t.GetUser(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.RemoveUser invalid userIndex %d", userIndex)
- return
- }
- chairId := usr.GetUserChairId()
- if !t.isValidChair(chairId) {
- log.Debug("ThreadsafeTable.RemoveUser invalid chairId %d", chairId)
- return
- }
- userId := usr.GetUserId()
- // 设置玩家状态
- if toWatch {
- gameFrame.setUserStatus(userIndex, user.UserStatus_Watch)
- t.addWatchUser(userIndex, chairId, userId)
- } else {
- gameFrame.setUserStatus(userIndex, user.UserStatus_Free)
- }
- t.sendUserExit(userId, chairId, userIndex, toWatch)
- //先回调再删
- t.tableSink.OnUserExitTable(userIndex, chairId)
- if isPlayer {
- t.users[chairId] = -1
- } else {
- t.removeWatchUser(userIndex, usr.GetUserId())
- }
- // 发其他人
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- if i == chairId {
- continue
- }
- t.sendUserExit(userId, chairId, t.users[i], toWatch)
- }
- for _, v := range t.watchUsers {
- // 不发给自己
- if v.UserIndex == userIndex {
- continue
- }
- t.sendUserExit(userId, chairId, v.UserIndex, toWatch)
- }
- // 不是玩家,不需要检查空桌
- if !isPlayer {
- return
- }
- if t.isPrivate() {
- status := privateroom.GetRoomStatus(t.roomNo)
- if status == privateroom.PrivateRoomStatus_Ended {
- t.checkEmpty(true)
- }
- if status != privateroom.PrivateRoomStatus_Playing && !changeChair {
- privateroom.UserLeave(t.roomNo, userId)
- }
- } else {
- if t.checkEmpty(true) {
- return
- }
- if t.isTableCloseByLogic() {
- return
- }
- // 如果桌子已经超时,并且只有机器人了
- isOvertime := time.Now().Unix()-t.createTime >= 3600
- if isOvertime && t.onlyRobot() {
- go t.dismiss()
- }
- }
- }
- func (t *ThreadsafeTable) onlyRobot() bool {
- for i := 0; i < t.chairCount; i++ {
- p := t.GetUserByChair(i)
- if p != nil && !p.IsRobot() {
- return false
- }
- }
- return true
- }
- func (t *ThreadsafeTable) dismiss_safe() {
- t.EndGame()
- t.removeAllWatchUsers()
- var toRemove []int32
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] != -1 {
- toRemove = append(toRemove, t.users[i])
- }
- }
- for _, v := range toRemove {
- t.RemoveUser_safe(v, false, false)
- }
- }
- func (t *ThreadsafeTable) userReplay_safe(oldUserIndex, newUserIndex int32) {
- usr := gate.GetUserInfo(newUserIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.userReplay usr == nil %d", newUserIndex)
- return
- }
- log.Debug("ThreadsafeTable.userReplay %d,%d", oldUserIndex, usr.GetUserId())
- // 该玩家是否处于这个桌子
- chairId := -1
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == oldUserIndex {
- chairId = i
- break
- }
- }
- if chairId == -1 {
- log.Debug("ThreadsafeTable.userReplay offlineUser not exist tableId %d oldUserIndex %d", t.tableId, oldUserIndex)
- return
- }
- t.users[chairId] = -1
- t.AddUser_safe(newUserIndex, chairId, true, false)
- }
- func (t *ThreadsafeTable) dumpScene_safe() {
- t.tableSink.DumpScene()
- }
- func (t *ThreadsafeTable) dumpTimers_safe() {
- t.timerLock.RLock()
- for k, v := range t.timers {
- if v == nil {
- continue
- }
- log.Release(" TimerId[%d] %v", k, v)
- }
- t.timerLock.RUnlock()
- }
- func (t *ThreadsafeTable) dump_safe() {
- log.Release(" tableId %d status %d data %s", t.tableId, t.tableStatus, t.privateData)
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- usr := t.GetUserByChair(i)
- if usr == nil {
- log.Release(" Chair[%d] userIndex[%d] not exist", i, t.users[i])
- continue
- }
- gold := 0
- goldDesc := "gold"
- privateRoomNo := ""
- if t.isPrivate() {
- privateRoomNo = fmt.Sprintf("{RoomNo:%d}", t.roomNo)
- }
- if gameFrame.gameSink.IsChipRoom() {
- gold = usr.GetChip()
- goldDesc = "chip"
- } else {
- gold = usr.GetUserGold()
- }
- log.Release(" Chair[%d] %d:%d:%s status[%d] %s[%d] %s", i, usr.GetUserIndex(), usr.GetUserId(), usr.GetUserNickName(),
- usr.GetUserStatus(), goldDesc, gold, privateRoomNo)
- }
- //var toRemove []int32
- if len(t.watchUsers) > 0 {
- log.Release(" ==== wach users")
- for _, v := range t.watchUsers {
- usr, _ := t.GetUser(v.UserIndex)
- if usr == nil {
- log.Release(" %d:%d is nil", v.UserIndex, v.ChairId)
- continue
- }
- gold := 0
- goldDesc := "gold"
- if gameFrame.gameSink.IsChipRoom() {
- gold = usr.GetChip()
- goldDesc = "chip"
- } else {
- gold = usr.GetUserGold()
- }
- log.Release(" %d:%d:%s status[%d] %s[%d]", usr.GetUserIndex(), usr.GetUserId(), usr.GetUserNickName(),
- usr.GetUserStatus(), goldDesc, gold)
- }
- }
- }
- func (t *ThreadsafeTable) getUserCount_safe() int {
- return t.getPlayerCount() + t.getWatcherCount()
- }
- func (t *ThreadsafeTable) onTableMessage_safe(userIndex int32, msg, data string) bool {
- usr := gate.GetUserInfo(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.onTableMessage user not found %d", userIndex)
- return false
- }
- if gameFrame.gameSink.GetChairCount() >= 2 && !usr.IsPlayer() {
- log.Debug("ThreadsafeTable.onTableMessage not a player %d", usr.GetUserIndex())
- return false
- }
- switch {
- default:
- // 如果是发送表情道具,则加入任务
- if msg == "CMD_TABLECHAT" {
- if strings.Contains(data, "3/") {
- task.DoTaskAction(usr.GetUserId(), task.TaskAction_gameinteract, 1, task.TaskScope{})
- }
- }
- return t.tableSink.OnGameMessage(userIndex, msg, data)
- }
- }
- func (t *ThreadsafeTable) UserWatch(userIndex int32) {
- // 如果用户不是playing状态,直接转换成watch即可
- usr := t.GetPlayer(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.UserWatch user %d not exist", userIndex)
- return
- }
- toWatch := true
- if usr.IsRobot() {
- toWatch = false
- }
- chairId := usr.GetUserChairId()
- if chairId < 0 || chairId >= t.chairCount {
- return
- }
- if usr.GetUserStatus() != user.UserStatus_Play {
- //gameFrame.setUserStatus(userIndex, user.UserStatus_Watch)
- t.RemoveUser_safe(userIndex, toWatch, false)
- return
- }
- }
- func (t *ThreadsafeTable) SetUserReadyStatus(userIndex int32, isReady bool) bool {
- defer utils.TimeCost(fmt.Sprintf("ThreadsafeTable.SetUserReadyStatus %d", userIndex))()
- usr := t.GetPlayer(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.SetUserReadyStatus failed user[%d] not exist", userIndex)
- return false
- }
- chairId := usr.GetUserChairId()
- if chairId < 0 {
- log.Debug("ThreadsafeTable.SetUserReadyStatus failed chairId = %d", chairId)
- return false
- }
- curStatus := usr.GetUserStatus()
- if isReady && curStatus != user.UserStatus_Sit {
- log.Debug("ThreadsafeTable.SetUserReady %d user status[%d] not sit", userIndex, curStatus)
- return false
- }
- if !isReady && curStatus != user.UserStatus_Ready {
- log.Debug("ThreadsafeTable.CancelUserReady %d user status[%d] not ready", userIndex, curStatus)
- return false
- }
- newStatus := user.UserStatus_Ready
- if !isReady {
- newStatus = user.UserStatus_Sit
- }
- if isReady && t.isPrivate() {
- // 游戏已经结束,不能再开始了
- if privateroom.GetRoomStatus(t.roomNo) == privateroom.PrivateRoomStatus_Ended {
- log.Release("ThreadsafeTable.SetUserReadyStatus to ready failed privateroom ended")
- return false
- }
- }
- // 设置状态并广播状态变化
- gameFrame.setUserStatus(userIndex, newStatus)
- // 回调给游戏
- t.onUserReady(userIndex, chairId, isReady)
- return true
- }
- func (t *ThreadsafeTable) setBaseScore_safe(baseScore int) {
- t.tableSink.OnBaseScoreChanged(baseScore)
- }
- func (t *ThreadsafeTable) Destroy() {
- t.stopped = true
- close(t.stopChan)
- }
- func (t *ThreadsafeTable) addWatchUser(userIndex int32, chair int, userId int) {
- if chair < 0 || chair >= t.chairCount {
- log.Debug("addWatchUser %d,%d", userIndex, chair)
- chair = 0
- }
- for _, v := range t.watchUsers {
- if v.UserIndex == userIndex {
- log.Debug("ThreadsafeTable.addWatchUser userIndex %d already exist", userIndex)
- v.ChairId = chair
- return
- }
- }
- t.watchUsers = append(t.watchUsers, WatchUser{UserIndex: userIndex, ChairId: chair, UserId: userId})
- }
- func (t *ThreadsafeTable) removeWatchUser(userIndex int32, userId int) {
- for i := 0; i < len(t.watchUsers); {
- if t.watchUsers[i].UserIndex == userIndex {
- if userId > 0 {
- t.sendUserExit(userId, 0, userIndex, false)
- t.broadcastUserExit(userId, 0, false)
- }
- t.watchUsers = append(t.watchUsers[:i], t.watchUsers[i+1:]...)
- if gameFrame.gameSink.GetChairCount() >= 2 {
- t.checkEmpty(false)
- }
- return
- } else {
- i++
- }
- }
- log.Debug("ThreadsafeTable.removeWatchUser userIndex %d not exist", userIndex)
- }
- func (t *ThreadsafeTable) isTableCloseByLogic() bool {
- gameSink_FishRoom, ok := gameFrame.gameSink.(GameSink_FishRoom)
- if !ok {
- return false
- }
- return gameSink_FishRoom.IsTableCloseByLogic()
- }
- func (t *ThreadsafeTable) ignoreSameIP() bool {
- gameSink_FishRoom, ok := gameFrame.gameSink.(GameSink_FishRoom)
- if !ok {
- return false
- }
- return gameSink_FishRoom.IgnoreSameIP()
- }
- func (t *ThreadsafeTable) enterPlayingRoomFirst() bool {
- gameSink_FishRoom, ok := gameFrame.gameSink.(GameSink_FishRoom)
- if !ok {
- return false
- }
- return gameSink_FishRoom.EnterPlayingRoomFirst()
- }
- func (t *ThreadsafeTable) checkEmpty(playerLeft bool) bool {
- if t.isTableCloseByLogic() {
- return false
- }
- // 私人场旁观离开不检查
- if gameFrame.gameSink.IsPrivateRoom() && !playerLeft {
- return false
- }
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- return false
- }
- if len(t.watchUsers) > 0 {
- return false
- }
- go gameFrame.removeTable(t.tableId)
- return true
- }
- func (t *ThreadsafeTable) privateRoomStatusChanged_safe(oldStatus int, newStatus int) {
- t.tableSink_privateRoom.OnPrivateRoomStatusChanged(oldStatus, newStatus)
- }
- func (t *ThreadsafeTable) privateRoomDismissed_safe() {
- t.tableSink_privateRoom.OnPrivateRoomDismissed()
- t.SendGameData(-1, message.Frame_PrivateRoom_Dismissed, "")
- // 如果是百人游戏,先不要解散
- if gameFrame.gameSink.GetChairCount() < 2 {
- return
- }
- t.dismiss_safe()
- }
- func (t *ThreadsafeTable) kickUser(toUserIndex int32) bool {
- ret := false
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == toUserIndex {
- ret = t.KickUserByChair(i, false)
- break
- }
- }
- return ret
- }
|