| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- package handler
- import (
- "bet24.com/log"
- "bet24.com/servers/common"
- coreservice "bet24.com/servers/coreservice/client"
- cash "bet24.com/servers/micros/money/proto"
- notification "bet24.com/servers/micros/notification/proto"
- pb "bet24.com/servers/micros/privateroom/proto"
- "encoding/json"
- "fmt"
- "sync"
- "time"
- //db2 "bet24.com/servers/micros/privateroom/config"
- )
- const (
- room_timeout_none = iota // 没有超时
- room_timeout_empty // 人走光了
- room_timeout // 超时了
- )
- type roomUserInfo struct {
- pb.RoomUser
- isUserEntered bool
- requestSitTime int64
- tax int
- prize int
- }
- func newRoomInfo(roomNo int, serverAddr string, tableId int, creator int, gameId int, gameName string) *roomInfo {
- ri := &roomInfo{
- RoomInfo: pb.RoomInfo{
- RoomNo: roomNo,
- ServerAddr: serverAddr,
- GameId: gameId,
- GameName: gameName,
- TableId: tableId,
- },
- Owner: creator,
- createTime: time.Now().Unix(),
- }
- ri.ctor()
- return ri
- }
- type roomInfo struct {
- pb.RoomInfo
- userList []*roomUserInfo
- Owner int
- StartTime string
- RuleData string
- RoomType string
- service_addr string
- lock *sync.RWMutex
- createTime int64
- endedTime int64
- createFee int
- isDual bool
- Winners []int
- gameStartTime int64
- changeChairFlag []bool
- Room *GameRoom
- }
- type GameRoom struct {
- Status int `xorm:"INT(11)" ` //1代表空闲 2代表使用中
- Id int `xorm:"not null pk autoincr INT(11)" json:"id"`
- PlayerNum int `xorm:"INT(11)" ` //加入游戏房间人数
- GameEnd int `xorm:"INT(11)" ` //0未开始,1进行中,2已结束
- Mode int `xorm:"INT(11)" ` //游戏模式,1是经典,2是匹配
- Logo string `xorm:"VARCHAR(255)"` //游戏logo
- Type int `xorm:"INT(11)" ` //1是lodo,2 baloot
- TableId int `xorm:"INT(11)" ` //1是lodo,2 baloot
- }
- func (ri *roomInfo) ctor() {
- ri.lock = &sync.RWMutex{}
- }
- func (ri *roomInfo) isTimeout(timeoutFree, timeoutPlay, timeoutEnd int64) int {
- // 如果是百人场,不计入超时
- if len(ri.userList) < 2 {
- return room_timeout_none
- }
- now := time.Now().Unix()
- // 如果是比赛房间,不判断用户超时
- if !ri.isMatch() {
- ri.lock.RLock()
- var toRemove []int
- for i := 0; i < len(ri.userList); i++ {
- if ri.userList[i] == nil {
- continue
- }
- if ri.userList[i].isUserEntered {
- continue
- }
- if now-ri.userList[i].requestSitTime >= 60 {
- toRemove = append(toRemove, ri.userList[i].UserId)
- }
- }
- ri.lock.RUnlock()
- if len(toRemove) > 0 {
- log.Debug("roomInfo.isTimeout[%d] removing user %v", ri.RoomNo, toRemove)
- for _, v := range toRemove {
- ri.removeUser(v)
- }
- if ri.isEmpty() {
- return room_timeout_empty
- }
- }
- }
- if ri.Status == pb.PrivateRoomStatus_Playing {
- if now-ri.createTime >= timeoutPlay {
- return room_timeout
- }
- } else if ri.Status == pb.PrivateRoomStatus_Ended {
- if now-ri.endedTime >= timeoutEnd {
- return room_timeout
- }
- } else {
- if now-ri.createTime >= timeoutFree {
- return room_timeout
- }
- }
- return room_timeout_none
- }
- func (ri *roomInfo) getIdle() int64 {
- return time.Now().Unix() - ri.createTime
- }
- func (ri *roomInfo) isMatch() bool {
- return ri.RoomType == pb.RoomType_SimpleMatch
- }
- func (ri *roomInfo) dump() {
- log.Release(" Room[%d] Owner[%d] Idled[%d] Rule[%s] UserCount[%d] Fee[%d] Stats[%d] IsPublic[%v]",
- ri.RoomNo, ri.Owner, ri.getIdle(), ri.RuleName, ri.UserCount, ri.Fee, ri.Status, ri.IsPublic)
- for k, v := range ri.userList {
- if v == nil {
- log.Release(" [%d:]nil", k)
- continue
- }
- log.Release(" [%d:]User [%d:%s ChairId:%d Score:%d] entered?%v Prize[%d]",
- k, v.UserId, v.NickName, v.ChairId, v.Score, v.isUserEntered, v.prize)
- }
- if len(ri.Winners) > 0 {
- log.Release(" Winners :%v", ri.Winners)
- }
- }
- func (ri *roomInfo) setExtra(ruleName string, ruleData string, userCount int, fee int, target int, serviceAddr string, isDual bool, playTime int) {
- ri.RuleName = ruleName
- ri.RuleData = ruleData
- ri.UserCount = userCount
- ri.Fee = fee
- ri.Target = target
- ri.service_addr = serviceAddr
- ri.isDual = isDual
- ri.userList = make([]*roomUserInfo, userCount)
- ri.UserList = make([]*pb.RoomUser, userCount)
- ri.PlayTime = playTime
- ri.changeChairFlag = make([]bool, userCount)
- }
- func (ri *roomInfo) getUserChair(userId int) int {
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- break
- }
- if v.UserId == userId {
- return v.ChairId
- }
- }
- return -1
- }
- // 请求进入,输出椅子号,椅子号为-1表示没有空位了
- func (ri *roomInfo) userRequestSit(userId int, nickName string, faceId int, faceUrl string,
- prefferedChairId int, score, baseScore, setCount int,yyfUid int) (chairId int, errMsg string, blackUsers []int) {
- log.Debug("roomInfo.onUserEnter %d prefered chairId %d,score[%d],baseScore[%d]", userId, prefferedChairId, score, baseScore)
- chairId = -1
- errMsg = "ok"
- blackUsers = []int{}
- index := -1
- var existUserIds []int
- ri.lock.RLock()
- // 如果不是随机椅子
- for _, v := range ri.userList {
- if v != nil {
- existUserIds = append(existUserIds, v.UserId)
- }
- }
- if prefferedChairId < 0 || prefferedChairId >= len(ri.userList) {
- for k, v := range ri.userList {
- if v == nil {
- chairId = k
- index = k
- continue
- }
- if v.UserId == userId {
- ri.lock.RUnlock()
- log.Release("privateroom.roomInfo.onUserEnter userId[%d] or chairId[%d] already exist", userId, chairId)
- chairId = v.ChairId
- return
- }
- }
- } else {
- if ri.userList[prefferedChairId] == nil {
- // 有空位
- index = prefferedChairId
- chairId = prefferedChairId
- }
- }
- ri.lock.RUnlock()
- if chairId == -1 {
- log.Release("privateroom.roomInfo.onUserEnter roomNo[%d] no empty chair", ri.RoomNo)
- errMsg = "no empty chair"
- return
- }
- if ri.isDual && 1 == chairId {
- chairId = 2
- index = 1
- }
- ri.lock.Lock()
- ru := roomUserInfo{
- RoomUser: pb.RoomUser{
- UserId: userId,
- NickName: nickName,
- ChairId: chairId,
- FaceId: faceId,
- FaceUrl: faceUrl,
- Score: score,
- BaseScore: baseScore,
- SetCount: setCount,
- YyfUid: yyfUid,
- },
- requestSitTime: time.Now().Unix(),
- }
- ri.userList[index] = &ru
- ri.UserList[index] = &ru.RoomUser
- // ri.Room.PlayerNum=ri.Room.PlayerNum+1
- // db2.Engine.ID(ri.Room.Id).Update(ri.Room)
- ri.lock.Unlock()
- if len(existUserIds) > 0 {
- blackUsers = coreservice.FriendGetBlackListUserIn(userId, existUserIds)
- if len(blackUsers) > 0 {
- log.Debug("userRequestSit blackUserIn userId[%d] existUserIds%v blacklist%v", userId, existUserIds, blackUsers)
- }
- }
- return
- }
- func (ri *roomInfo) removeUser(userId int) bool {
- log.Debug("roomInfo.removeUser %d", userId)
- idx := -1
- ri.lock.RLock()
- for k, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- idx = k
- break
- }
- }
- // ri.Room.PlayerNum=ri.Room.PlayerNum-1
- // fmt.Printf("减少玩家人数")
- // db2.Engine.ID(ri.Room.Id).Update(ri.Room)
- ri.lock.RUnlock()
- if idx == -1 {
- log.Release("privateroom.roomInfo.removeUser userId[%d] not exist", userId)
- return false
- }
- ri.lock.Lock()
- ri.UserList[idx] = nil
- ri.userList[idx] = nil
- ri.lock.Unlock()
- return true
- }
- func (ri *roomInfo) updateUserScore(userId int, scoreDelta int) bool {
- var u *roomUserInfo
- ri.lock.RLock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- u = v
- break
- }
- }
- ri.lock.RUnlock()
- if u == nil {
- log.Release("privateroom.roomInfo.addUserScore userId[%d] not exist", userId)
- return false
- }
- if ri.Owner == -1 {
- u.Score += scoreDelta
- } else {
- u.Score = scoreDelta
- }
- ri.postUserScore(userId, scoreDelta)
- return true
- }
- func (ri *roomInfo) userSit(userId int, chairId int) int {
- ret := 0
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId && v.ChairId == chairId {
- v.isUserEntered = true
- ret = 1
- }
- // 如果是换桌就不提示黑名单
- if ri.changeChairFlag[chairId] {
- continue
- }
- if coreservice.FriendIsBlackListUser(v.UserId, userId) {
- go ri.sendBlackUserEnterNotification(v.UserId, userId)
- }
- }
- if ret == 0 {
- log.Release("privateroom.roomInfo.userSit [%d] not found", userId)
- ri.dump()
- } else {
- ri.changeChairFlag[chairId] = false
- }
- return ret
- }
- func (ri *roomInfo) sendBlackUserEnterNotification(userId int, enteredUserId int) {
- log.Debug("sendBlackUserEnterNotification userId[%d],enteredUserId[%d]", userId, enteredUserId)
- msg := Match_notificationInfo{Msg: room_blasklist_user, UserId: enteredUserId}
- d, _ := json.Marshal(msg)
- notification.AddNotification(userId, notification.Notification_PrivateRoom, string(d))
- }
- func (ri *roomInfo) changeChair(userId int, chairId int) bool {
- // 比赛房间不允许换椅子
- if ri.Owner == -1 {
- return false
- }
- if chairId < 0 || chairId >= len(ri.userList) {
- log.Release("roomInfo.changeChair [%d] chairId[%d] invalid", userId, chairId)
- return false
- }
- ri.lock.RLock()
- oldChairId := -1
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- oldChairId = v.ChairId
- }
- }
- ri.lock.RUnlock()
- if oldChairId == -1 {
- log.Release("privateroom.roomInfo.changeChair [%d] not found", userId)
- ri.dump()
- return false
- }
- if oldChairId == chairId {
- log.Release("roomInfo.changeChair [%d] chairId[%d] same chair", userId, chairId)
- return false
- }
- ri.lock.Lock()
- defer ri.lock.Unlock()
- if ri.userList[chairId] != nil {
- log.Release("roomInfo.changeChair [%d] chairId[%d] chair taken", userId, chairId)
- return false
- }
- ri.userList[chairId] = ri.userList[oldChairId]
- ri.userList[chairId].isUserEntered = false
- ri.userList[chairId].ChairId = chairId
- ri.userList[oldChairId] = nil
- ri.UserList[oldChairId] = nil
- ri.UserList[chairId] = &ri.userList[chairId].RoomUser
- log.Debug("roomInfo.changeChair [%d] chairId[%d] changed to [%d]", userId, oldChairId, chairId)
- ri.changeChairFlag[chairId] = true
- return true
- }
- func (ri *roomInfo) isUserExist(userId int) bool {
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- return true
- }
- }
- return false
- }
- func (ri *roomInfo) isUserPlaying(userId int) bool {
- if ri.Status != pb.PrivateRoomStatus_Playing &&
- ri.Status != pb.PrivateRoomStatus_Free {
- return false
- }
- return ri.isUserExist(userId)
- }
- func (ri *roomInfo) roomStart() {
- now := time.Now()
- ri.gameStartTime = now.Unix()
- ri.StartTime = now.Format(common.Layout)
- // 房主不设置奖金,表示奖金为报名费
- if ri.Fee > 0 && ri.Prize > 0 && ri.createFee > 0 {
- //cash.GiveMoney(ri.Owner, ri.Fee*len(ri.userList), common.LOGTYPE_PRIVATEROOM_OWNER, "privateroom", "owner", "")
- for _, v := range ri.UserList {
- if v.UserId==ri.Owner{
- //cash.GiveMoney2(r.Owner, r.Fee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "fee return", "",r.Owner.yyfUid)
- cash.GiveMoney2(v.UserId, ri.Fee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "fee return", "",v.YyfUid)
- }
- }
- }
- ri.postRoomStart()
- }
- func (ri *roomInfo) getWinners() []int {
- return ri.Winners
- }
- func (ri *roomInfo) setWinners(winners []int) bool {
- // 如果是百人场
- if len(ri.userList) < 2 {
- ri.postRoomEnd()
- return true
- }
- if len(ri.Winners) > 0 {
- log.Release("roomInfo.setWinners already set")
- return false
- }
- for _, v := range winners {
- if !ri.isUserExist(v) {
- log.Release("roomInfo.setWinners user[%d] not found", v)
- ri.dump()
- return false
- }
- }
- ri.Winners = winners
- ri.postRoomEnd()
- return true
- }
- func (ri *roomInfo) getTotalTax() int {
- ret := 0
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- ret += v.tax
- }
- return ret
- }
- func (ri *roomInfo) setPrizeAndTax(userId int, prize, tax int) {
- ri.lock.Lock()
- defer ri.lock.Unlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- v.tax = tax
- v.prize = prize
- return
- }
- }
- }
- func (ri *roomInfo) getUsersDesc() string {
- type userDesc struct {
- UserId int
- ChairId int
- Score int
- Prize int
- }
- var users []userDesc
- ri.lock.Lock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- users = append(users, userDesc{UserId: v.UserId, ChairId: v.ChairId, Score: v.Score, Prize: v.prize})
- }
- ri.lock.Unlock()
- d, _ := json.Marshal(users)
- return string(d)
- }
- func (ri *roomInfo) getUsersDescForDB() string {
- var ret string
- ri.lock.Lock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- ret = fmt.Sprintf("%s%d,%d,%d,%d,%d,%d;", ret, v.ChairId, v.UserId, ri.Fee, v.tax, v.prize, v.Score)
- }
- ri.lock.Unlock()
- return ret
- }
- func (ri *roomInfo) postRoomStart() {
- getRoomManager().postRoomStart(ri.RoomNo)
- }
- func (ri *roomInfo) postRoomEnd() {
- getRoomManager().postRoomEnd(ri.RoomNo, ri.Winners)
- }
- func (ri *roomInfo) postUserScore(userId int, scoreDelta int) {
- getRoomManager().postUserScore(ri.RoomNo, userId, scoreDelta)
- }
- func (ri *roomInfo) postAllUserScores() {
- for i := 0; i < len(ri.userList); i++ {
- if ri.userList[i] == nil {
- continue
- }
- ri.postUserScore(ri.userList[i].UserId, ri.userList[i].Score)
- }
- }
- func (ri *roomInfo) getAUserId() int {
- ret := 0
- ri.lock.RLock()
- for i := 0; i < len(ri.userList); i++ {
- if ri.userList[i] == nil {
- continue
- }
- if ri.userList[i].isUserEntered {
- ret = ri.userList[i].UserId
- }
- }
- if ret == 0 {
- for i := 0; i < len(ri.userList); i++ {
- if ri.userList[i] == nil {
- continue
- }
- ret = ri.userList[i].UserId
- }
- }
- ri.lock.RUnlock()
- return ret
- }
- func (ri *roomInfo) isEmpty() bool {
- for i := 0; i < len(ri.userList); i++ {
- if ri.userList[i] != nil {
- return false
- }
- }
- return true
- }
- func (ri *roomInfo) getUserInfo(userId int) *pb.RoomUser {
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- return &v.RoomUser
- }
- }
- return nil
- }
- func (ri *roomInfo) getPrize(userId int) int {
- ri.lock.RLock()
- defer ri.lock.RUnlock()
- for _, v := range ri.userList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- return v.prize
- }
- }
- return 0
- }
|