| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793 |
- package combomatch
- import (
- "bet24.com/log"
- "bet24.com/servers/common"
- inventory "bet24.com/servers/micros/item_inventory/proto"
- item "bet24.com/servers/micros/item_inventory/proto"
- "bet24.com/servers/micros/matches/handler/matchbase"
- "bet24.com/servers/micros/matches/handler/pointmatch"
- "bet24.com/servers/micros/matches/handler/setsmatch"
- "bet24.com/servers/micros/matches/handler/simplematch"
- notification "bet24.com/servers/micros/notification/proto"
- task "bet24.com/servers/micros/task/proto"
- "encoding/json"
- "sync"
- "time"
- )
- type matchround struct {
- MatchType int
- MatchNo int
- matchInstance matchbase.MatchInstance
- EndTime int64
- StartTime int64
- createTime int64
- }
- func (mr *matchround) getStatus() int {
- if mr.matchInstance == nil {
- return matchbase.MatchStatus_Invalid
- }
- return mr.matchInstance.GetStatus()
- }
- type matchInfo struct {
- MatchId int
- Rounds []*matchround
- CurrentRound int // 当前轮次
- mm *combomatchMgr
- lock *sync.RWMutex
- userFee map[int]item.ItemPack
- robotConfig *matchbase.Robot_config
- robotCount int
- config *matchconfig
- allUsers []matchbase.MatchUser // 本次赛事所有用户,比赛开始后才有
- currentRoundWinners []matchbase.MatchUser // 本轮胜者,用于延迟进行下一轮缓存数据
- enrollUsers []combomatchuser // 预报名用户
- lockEnroll *sync.RWMutex
- userAwarded map[int]bool
- startFailed bool
- enrolledUsers []matchbase.EnrollUser
- }
- func newMatchInfo(matchId int, mm *combomatchMgr, robotConfig *matchbase.Robot_config, config *matchconfig) *matchInfo {
- ret := &matchInfo{
- MatchId: matchId,
- mm: mm,
- config: config,
- CurrentRound: -1, // 预报名
- }
- ret.userFee = make(map[int]item.ItemPack)
- ret.userAwarded = make(map[int]bool)
- ret.lock = &sync.RWMutex{}
- ret.lockEnroll = &sync.RWMutex{}
- ret.robotConfig = robotConfig
- if robotConfig != nil && robotConfig.Max > 0 {
- sec := robotConfig.GetWaitSec()
- time.AfterFunc(time.Second*time.Duration(sec), ret.checkRobot)
- }
- // 如果是预先报名,则启动定时器开始
- if config.IsPreEnroll() {
- nextGame := config.GetNextStartTime() - int(time.Now().Unix())
- log.Debug("combomatch.newMatchInfo MatchId[%d] [%d] seconds to start", matchId, nextGame)
- time.AfterFunc(time.Second*time.Duration(nextGame), ret.onMatchStart)
- // 最后一次
- if config.EnrollRange.End > 0 {
- go func(startTime int, beforeTime int) {
- delaySec := startTime - beforeTime
- if delaySec > 0 {
- time.Sleep(time.Second * time.Duration(delaySec))
- ret.onMatchLocked(beforeTime, true)
- }
- }(nextGame, config.EnrollRange.End)
- }
- // 额外的
- for _, v := range config.ExtraNotifySecs {
- go func(startTime int, beforeTime int) {
- delaySec := startTime - beforeTime
- if delaySec > 0 {
- time.Sleep(time.Second * time.Duration(delaySec))
- ret.onMatchLocked(beforeTime, false)
- }
- }(nextGame, v)
- }
- }
- return ret
- }
- func (mi *matchInfo) getMatchRound() *matchround {
- if mi.CurrentRound >= len(mi.Rounds) || mi.CurrentRound < 0 {
- return nil
- }
- return mi.Rounds[mi.CurrentRound]
- }
- func (mi *matchInfo) getCurrentInstance() matchbase.MatchInstance {
- mr := mi.getMatchRound()
- if mr == nil {
- return nil
- }
- return mr.matchInstance
- }
- func (mi *matchInfo) isEnded() bool {
- if mi.startFailed {
- return true
- }
- if mi.CurrentRound < mi.config.getTotalRound()-1 {
- return false
- }
- instance := mi.getCurrentInstance()
- if instance == nil {
- return false
- }
- return instance.GetStatus() == matchbase.MatchStatus_Ended
- }
- func (mi *matchInfo) getStatus() int {
- if mi.isEnded() {
- return matchbase.MatchStatus_Ended
- }
- // 报名
- if mi.CurrentRound < 0 {
- return matchbase.MatchStatus_Free
- }
- instance := mi.getCurrentInstance()
- if instance == nil {
- return matchbase.MatchStatus_Free
- }
- // 第一场如果未开,取第一场状态
- if mi.CurrentRound == 0 {
- return instance.GetStatus()
- }
- return matchbase.MatchStatus_Playing
- }
- func (mi *matchInfo) isFull() bool {
- if mi.config.IsPreEnroll() {
- //return len(mi.enrollUsers) >= mi.config.EnrollMax
- return false // 如果预报名,则不需要根据人满重开一个
- }
- if mi.CurrentRound == -1 {
- mi.lockEnroll.RLock()
- enrollCount := len(mi.enrollUsers)
- mi.lockEnroll.RUnlock()
- return enrollCount >= mi.config.TotalUser
- }
- instance := mi.getCurrentInstance()
- if instance == nil {
- return true
- }
- return instance.IsFull()
- }
- func (mi *matchInfo) canEnroll() bool {
- mi.lockEnroll.RLock()
- defer mi.lockEnroll.RUnlock()
- if mi.config.IsPreEnroll() {
- return len(mi.enrollUsers) < mi.config.EnrollMax
- }
- return len(mi.enrollUsers) < mi.config.TotalUser
- }
- func (mi *matchInfo) isUserEnrolled(userId int) bool {
- mi.lockEnroll.RLock()
- for _, v := range mi.enrollUsers {
- if v.UserId == userId {
- mi.lockEnroll.RUnlock()
- return true
- }
- }
- mi.lockEnroll.RUnlock()
- instance := mi.getCurrentInstance()
- if instance == nil {
- return false
- }
- return instance.IsUserEnrolled(userId)
- }
- func (mi *matchInfo) isUserPlaying(userId int) bool {
- if mi.getStatus() == matchbase.MatchStatus_Ended {
- return false
- }
- if !mi.isUserEnrolled(userId) {
- return false
- }
- instance := mi.getCurrentInstance()
- // 这里存在比赛还没开始的情况
- if instance == nil {
- // 超过一轮,看是否在上一轮晋级中
- if mi.CurrentRound < 0 {
- return true
- }
- // 在不在晋级列表
- for _, v := range mi.currentRoundWinners {
- if v.UserId == userId {
- return true
- }
- }
- return false
- }
- userlist := instance.GetUserList()
- for _, v := range userlist {
- if v == userId {
- return true
- }
- }
- return false
- }
- func (mi *matchInfo) isTimeout() bool {
- if !mi.isEnded() {
- return false
- }
- return time.Now().Unix()-mi.getEndTime() >= match_time_out_ended
- }
- func (mi *matchInfo) dump(isDetail bool) {
- log.Release(" MatchId[%d] CurrentRound[%d]", mi.MatchId, mi.CurrentRound)
- // 还没开始
- if len(mi.Rounds) == 0 {
- mi.lockEnroll.RLock()
- log.Release(" EnrollUserCount:%d", len(mi.enrollUsers))
- if isDetail {
- for _, v := range mi.enrollUsers {
- log.Release(" UserId:%d Nickname:%s", v.UserId, v.NickName)
- }
- }
- mi.lockEnroll.RUnlock()
- return
- } else {
- log.Release(" EnrollUserCount:%d", len(mi.allUsers))
- if isDetail {
- for _, v := range mi.allUsers {
- log.Release(" UserId:%d Nickname:%s,Score:%d,WinCount:%d,EnrollTime:%d", v.UserId, v.NickName, v.Score, v.WinCount, v.EnrollTime)
- }
- }
- }
- for i := 0; i < len(mi.Rounds); i++ {
- r := mi.Rounds[i]
- if i < len(mi.Rounds)-1 {
- log.Release(" Round[%d] MatchNo[%d] StartTime[%s] EndTime[%s]", i, r.MatchNo,
- common.TimeStampToString(r.StartTime), common.TimeStampToString(r.EndTime))
- continue
- }
- log.Release(" Round[%d] MatchNo[%d] Status[%s] StartTime[%s] EndTime[%s]", i, r.MatchNo, matchbase.GetMatchStatusDesc(r.getStatus()),
- common.TimeStampToString(r.StartTime), common.TimeStampToString(r.EndTime))
- }
- }
- func (mi *matchInfo) checkRobot() {
- if mi.getStatus() > matchbase.MatchStatus_Free || mi.robotCount >= mi.robotConfig.Max {
- return
- }
- if mi.isFull() {
- return
- }
- sec := mi.robotConfig.GetWaitSec()
- time.AfterFunc(time.Second*time.Duration(sec), mi.checkRobot)
- mi.robotCount += mi.mm.addARobot(mi.MatchId)
- }
- func (mi *matchInfo) sendNotification(userId int, data string) {
- if userId == -1 {
- // send all
- if mi.CurrentRound < 0 {
- mi.lockEnroll.RLock()
- for _, v := range mi.enrollUsers {
- notification.AddNotification(v.UserId, notification.Notification_Match, data)
- }
- mi.lockEnroll.RUnlock()
- } else {
- mi.lock.RLock()
- for _, v := range mi.allUsers {
- notification.AddNotification(v.UserId, notification.Notification_Match, data)
- }
- mi.lock.RUnlock()
- }
- return
- }
- notification.AddNotification(userId, notification.Notification_Match, data)
- }
- func (mi *matchInfo) setUserFee(userId int, fee item.ItemPack) {
- mi.lock.Lock()
- mi.userFee[userId] = fee
- mi.lock.Unlock()
- }
- func (mi *matchInfo) getAndRemoveUserFee(userId int) item.ItemPack {
- mi.lock.Lock()
- defer mi.lock.Unlock()
- ret, ok := mi.userFee[userId]
- if !ok {
- return item.ItemPack{}
- }
- delete(mi.userFee, userId)
- return ret
- }
- func (mi *matchInfo) isUserAwarded(userId int) bool {
- mi.lock.RLock()
- defer mi.lock.RUnlock()
- ret, ok := mi.userAwarded[userId]
- if !ok {
- return false
- }
- return ret
- }
- func (mi *matchInfo) setUserAwarded(userId int) {
- mi.lock.Lock()
- defer mi.lock.Unlock()
- mi.userAwarded[userId] = true
- }
- func (mi *matchInfo) getUserList() []int {
- instance := mi.getCurrentInstance()
- if instance == nil {
- return []int{}
- }
- return instance.GetUserList()
- }
- func (mi *matchInfo) getEndTime() int64 {
- if !mi.isEnded() {
- return 0
- }
- if len(mi.Rounds) <= 0 {
- return 0
- }
- return mi.Rounds[len(mi.Rounds)-1].EndTime
- }
- func (mi *matchInfo) getStartTime() int64 {
- if len(mi.Rounds) == 0 {
- return 0
- }
- return mi.Rounds[0].StartTime
- }
- func (mi *matchInfo) getMatchNo() int {
- if len(mi.Rounds) == 0 {
- return 0
- }
- return mi.Rounds[len(mi.Rounds)-1].MatchNo
- }
- func (mi *matchInfo) getStartSeconds() int {
- nextStartTime := mi.config.GetNextStartTime()
- if nextStartTime == 0 {
- return 0
- }
- return nextStartTime - int(time.Now().Unix())
- }
- func (mi *matchInfo) setStartTime(matchNo int) {
- if len(mi.Rounds) == 0 {
- log.Release("matchInfo.setStartTime no rounds")
- return
- }
- r := mi.Rounds[len(mi.Rounds)-1]
- if r.MatchNo != matchNo {
- log.Release("matchInfo.setStartTime MatchNo not match %d != %d", r.MatchNo, matchNo)
- return
- }
- r.StartTime = time.Now().Unix()
- if mi.CurrentRound == 0 {
- instance := mi.getCurrentInstance()
- if instance == nil {
- return
- }
- mi.allUsers = instance.GetAllMatchUsers()
- // 赋值enrollTime
- for k, v := range mi.allUsers {
- go task.DoTaskAction(v.UserId, task.TaskAction_playComboMatch, 1, task.TaskScope{})
- for _, v1 := range mi.enrollUsers {
- if v.UserId == v1.UserId {
- mi.allUsers[k].EnrollTime = v1.EnrollTime
- break
- }
- }
- }
- }
- }
- func (mi *matchInfo) setEndTime(matchNo int) {
- if len(mi.Rounds) == 0 {
- log.Release("matchInfo.setEndTime no rounds")
- return
- }
- r := mi.Rounds[len(mi.Rounds)-1]
- if r.MatchNo != matchNo {
- log.Release("matchInfo.setEndTime MatchNo not match %d != %d", r.MatchNo, matchNo)
- return
- }
- r.EndTime = time.Now().Unix()
- }
- func (mi *matchInfo) getAllMatchUsers() []matchbase.MatchUser {
- return mi.allUsers
- }
- func (mi *matchInfo) addMatchInfo(matchNo int, matchInstance matchbase.MatchInstance) {
- mi.CurrentRound++
- mi.Rounds = append(mi.Rounds, &matchround{
- MatchType: mi.config.getMatchType(mi.CurrentRound),
- MatchNo: matchNo,
- matchInstance: matchInstance,
- createTime: time.Now().Unix(),
- })
- //mi.currentRoundWinners = []int{}
- }
- func (mi *matchInfo) getMatchUser(userId int) *matchbase.MatchUser {
- for _, v := range mi.allUsers {
- if v.UserId == userId {
- return &v
- }
- }
- return nil
- }
- func (mi *matchInfo) getCurrentMatchType() int {
- if mi.CurrentRound == -1 {
- return matchbase.MatchType_Invalid
- }
- return mi.config.getMatchType(mi.CurrentRound)
- }
- func (mi *matchInfo) setRoundWinners(winners []int) {
- ni := ComboMatch_notificationInfo{Msg: ComboMatch_noti_promoted}
- d, _ := json.Marshal(ni)
- data := string(d)
- for _, v := range winners {
- mi.sendNotification(v, data)
- usr := mi.getMatchUser(v)
- if usr != nil {
- usr.Score = mi.config.getScorePercentToNext(mi.CurrentRound) * usr.Score / 100
- if usr.Score < 0 {
- usr.Score = 0
- }
- }
- mi.currentRoundWinners = append(mi.currentRoundWinners, *usr)
- }
- }
- func (mi *matchInfo) onMatchLocked(secsToStart int, finalCall bool) {
- if !mi.config.IsPreEnroll() {
- return
- }
- log.Debug("combomatch.matchInfo.onMatchLocked matchId[%d] secsToStart[%d]", mi.MatchId, secsToStart)
- mi.lockEnroll.Lock()
- totalUser := len(mi.enrollUsers)
- for i := 0; i < totalUser; i++ {
- mi.enrollUsers[i].confirmed = mi.enrollUsers[i].isRobot
- }
- mi.lockEnroll.Unlock()
- /*
- // 最后一次如果不满人,则不通知
- if totalUser < mi.config.EnrollMin && secsToStart <= mi.config.EnrollRange.End {
- mi.onMatchStart()
- return
- }
- */
- //postMatchLockNotification(mi.MatchId, secsToStart)
- callMsg := ComboMatch_noti_matchcall
- if finalCall {
- callMsg = ComboMatch_noti_matchlocked
- }
- ni := ComboMatch_notificationInfo{Msg: callMsg, MatchId: mi.MatchId, Seconds: secsToStart}
- d, _ := json.Marshal(ni)
- mi.sendNotification(-1, string(d))
- }
- func (mi *matchInfo) onMatchStart() {
- log.Debug("combomatch.matchInfo.onMatchStart matchId[%d]", mi.MatchId)
- // 把没有confirm的人清理
- var toRemove []int
- mi.lockEnroll.Lock()
- for i := 0; i < len(mi.enrollUsers); {
- if mi.enrollUsers[i].confirmed {
- i++
- } else {
- log.Debug(" removing unconfirmed user[%d]", mi.enrollUsers[i].UserId)
- toRemove = append(toRemove, mi.enrollUsers[i].UserId)
- mi.enrollUsers = append(mi.enrollUsers[:i], mi.enrollUsers[i+1:]...)
- }
- }
- mi.lockEnroll.Unlock()
- for _, v := range toRemove {
- // 退还报名费
- mi.quitUser(v, false)
- }
- // 看下人数够不够
- mi.lockEnroll.RLock()
- totalUser := len(mi.enrollUsers)
- mi.lockEnroll.RUnlock()
- // 如果是提前报名的,并且人数不够下限,则不开始比赛
- if totalUser < mi.config.EnrollMin && mi.config.IsPreEnroll() {
- mi.startFailed = true
- //postMatchFailedNotification(mi.MatchId)
- ni := ComboMatch_notificationInfo{Msg: ComboMatch_noti_matchfailed, MatchId: mi.MatchId}
- d, _ := json.Marshal(ni)
- mi.sendNotification(-1, string(d))
- mi.quitAllUsers()
- return
- }
- config := mi.config
- var matchNo int
- var err string
- var matchInstance matchbase.MatchInstance
- switch config.getMatchType(0) {
- case matchbase.MatchType_SimpleMatch:
- matchNo, err = simplematch.CreateMatch(-1, config.GameId, config.GameRule, totalUser, config.getTarget(0),
- config.TableUser, 0, 0, config.PlayTime, config.isEleminateByScore(mi.CurrentRound), config.getWinnerCount(0))
- if matchNo == 0 {
- log.Release("combomatchMgr.getOrCreateMatch simplematch.CreateMatch failed %s", err)
- return
- }
- matchInstance = simplematch.GetMatchInstance(matchNo)
- case matchbase.MatchType_PointMatch:
- e, ssec, sscore, w := config.getPointMatchParams(0)
- matchNo, err = pointmatch.CreateMatch(-1, config.GameId, config.GameRule, totalUser, config.TableUser, 0, 0, config.PlayTime,
- e, ssec, sscore, w)
- if matchNo == 0 {
- log.Release("combomatchMgr.getOrCreateMatch pointmatch.CreateMatch failed %s", err)
- return
- }
- matchInstance = pointmatch.GetMatchInstance(matchNo)
- case matchbase.MatchType_SetsMatch:
- matchNo, err = setsmatch.CreateMatch(-1, config.GameId, config.GameRule, totalUser, config.TableUser,
- 0, 0, config.PlayTime, config.getWinnerCount(0))
- if matchNo == 0 {
- log.Release("combomatchMgr.getOrCreateMatch setsmatch.CreateMatch failed %s", err)
- return
- }
- matchInstance = setsmatch.GetMatchInstance(matchNo)
- }
- if matchInstance == nil {
- log.Release("combomatchMgr.getOrCreateMatch GetMatchInstance == nil")
- return
- }
- matchInstance.RegisterReceiver(mi.mm)
- mi.CurrentRound = -1
- mi.addMatchInfo(matchNo, matchInstance)
- // 把报名玩家都拉进去
- mi.lockEnroll.RLock()
- for _, v := range mi.enrollUsers {
- switch mi.getCurrentMatchType() {
- case matchbase.MatchType_SimpleMatch:
- simplematch.EnrollMatch(v.UserId, v.NickName, v.FaceId, v.FaceUrl, matchNo)
- case matchbase.MatchType_PointMatch:
- pointmatch.EnrollMatch(v.UserId, v.NickName, v.FaceId, v.FaceUrl, matchNo)
- case matchbase.MatchType_SetsMatch:
- setsmatch.EnrollMatch(v.UserId, v.NickName, v.FaceId, v.FaceUrl, matchNo)
- }
- }
- mi.lockEnroll.RUnlock()
- }
- func (mi *matchInfo) quitAllUsers() {
- for _, v := range mi.enrollUsers {
- mi.quitUser(v.UserId, false)
- }
- mi.lockEnroll.Lock()
- mi.enrollUsers = []combomatchuser{}
- mi.lockEnroll.Unlock()
- }
- func (mi *matchInfo) quitUser(userId int, check bool) bool {
- config := mi.config
- if check {
- found := false
- mi.lockEnroll.Lock()
- for i := 0; i < len(mi.enrollUsers); {
- if mi.enrollUsers[i].UserId == userId {
- found = true
- mi.enrollUsers = append(mi.enrollUsers[:i], mi.enrollUsers[i+1:]...)
- } else {
- i++
- }
- }
- mi.lockEnroll.Unlock()
- if !found {
- log.Release("combomatch.matchInfo.quitUser[%d] not found in matchId[%d]", userId, mi.MatchId)
- return false
- }
- }
- mi.config.addOnline(-1)
- // 如果比赛已开始
- status := mi.getStatus()
- if status == matchbase.MatchStatus_Playing {
- // 按淘汰处理
- // ...
- }
- // 退钱
- if len(config.EnrollFee) > 0 && status < matchbase.MatchStatus_Playing {
- itm := mi.getAndRemoveUserFee(userId)
- if itm.Count > 0 {
- inventory.AddItems(userId, []item.ItemPack{itm},
- "combomatch fee return", common.LOGTYPE_COMBOMATCH_ENTER_RETURN)
- } else if config.DailyFreeCount > 0 {
- getFreeCountManager().reduceFreeCount(userId, config.MatchId)
- }
- }
- //postUserExitNotification(userId, mi.MatchId)
- ni := ComboMatch_notificationInfo{Msg: ComboMatch_noti_userexit, UserId: userId, MatchId: mi.MatchId}
- d, _ := json.Marshal(ni)
- mi.sendNotification(-1, string(d))
- return true
- }
- func (mi *matchInfo) addEnrollUser(userId int, nickname string, faceId int, faceUrl string, isRobot bool) {
- if mi.isUserEnrolled(userId) {
- log.Release("combomatch.addEnrollUser user[%d] already exist in matchId[%d]", userId, mi.MatchId)
- return
- }
- found := false
- for k, v := range mi.enrolledUsers {
- if v.UserId == userId {
- mi.enrolledUsers[k].EnrollTime = time.Now().Unix()
- found = true
- break
- }
- }
- if !found {
- mi.enrolledUsers = append(mi.enrolledUsers, matchbase.EnrollUser{UserId: userId, EnrollTime: time.Now().Unix()})
- }
- var usr combomatchuser
- usr.UserId = userId
- usr.NickName = nickname
- usr.FaceId = faceId
- usr.FaceUrl = faceUrl
- usr.EnrollTime = time.Now().Unix()
- usr.isRobot = isRobot
- usr.confirmed = true
- mi.lockEnroll.Lock()
- mi.enrollUsers = append(mi.enrollUsers, usr)
- userCount := len(mi.enrollUsers)
- mi.lockEnroll.Unlock()
- mi.config.addOnline(1)
- // 如果报名人满,则开始比赛,预报名除外
- if userCount == mi.config.TotalUser && !mi.config.IsPreEnroll() {
- mi.onMatchStart()
- }
- }
- func (mi *matchInfo) getMatchInfo() string {
- var ret struct {
- CurrentRound int
- Users []matchbase.MatchUser
- }
- ret.CurrentRound = mi.CurrentRound
- if mi.CurrentRound < 0 {
- for i := 0; i < len(mi.enrollUsers); i++ {
- ret.Users = append(ret.Users, mi.enrollUsers[i].MatchUser)
- }
- } else {
- ret.Users = mi.allUsers
- }
- d, _ := json.Marshal(ret)
- return string(d)
- }
- func (mi *matchInfo) getOnline() int {
- return len(mi.allUsers)
- }
- func (mi *matchInfo) updateRankAndScore(userId, rank, score int, winCount int) {
- for i := 0; i < len(mi.allUsers); i++ {
- if mi.allUsers[i].UserId == userId {
- mi.allUsers[i].Rank = rank
- mi.allUsers[i].Score = score
- mi.allUsers[i].WinCount += winCount
- return
- }
- }
- log.Release("combomatch.matchInfo.updateRankAndScore MatchNo[%d] UserId [%d] not found", mi.getMatchNo(), userId)
- }
- func (mi *matchInfo) getUser(userId int) *matchbase.MatchUser {
- ci := mi.getCurrentInstance()
- if ci != nil {
- return ci.GetUser(userId)
- }
- return nil
- }
- func (mi *matchInfo) postUserRankNotification(userId int, rank int, items []item.ItemPack) {
- ni := ComboMatch_notificationInfo{Msg: ComboMatch_noti_rank, UserId: userId, MatchId: mi.MatchId, Rank: rank, Prize: items}
- d, _ := json.Marshal(ni)
- mi.sendNotification(userId, string(d))
- }
- func (mi *matchInfo) getConfirmCount() int {
- ret := 0
- mi.lock.RLock()
- for _, v := range mi.enrollUsers {
- if v.confirmed {
- ret++
- }
- }
- mi.lock.RUnlock()
- return ret
- }
- func (mi *matchInfo) confirmMatch(userId int) bool {
- mi.lock.Lock()
- defer mi.lock.Unlock()
- for k, v := range mi.enrollUsers {
- if v.UserId == userId {
- mi.enrollUsers[k].confirmed = true
- return true
- }
- }
- return false
- }
- func (mi *matchInfo) tryRemoveOneRobot(forceRemove bool) bool {
- var robotId int
- realUserCount := 0
- totalUserCount := 0
- mi.lock.RLock()
- totalUserCount = len(mi.enrollUsers)
- for _, v := range mi.enrollUsers {
- if !v.isRobot {
- realUserCount++
- } else {
- if robotId == 0 {
- robotId = v.UserId
- }
- }
- }
- mi.lock.RUnlock()
- if !forceRemove {
- if totalUserCount < 5 || realUserCount > 0 {
- return false
- }
- }
- if robotId > 0 {
- return mi.quitUser(robotId, true)
- }
- return false
- }
|