| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- package combomatch
- import (
- "os"
- "bet24.com/log"
- "bet24.com/servers/common"
- //gameHistory "bet24.com/servers/micros/gameHistory/proto"
- "encoding/json"
- "fmt"
- "sort"
- "strconv"
- "sync"
- "time"
- 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"
- pb "bet24.com/servers/micros/matches/proto"
- platformconfig "bet24.com/servers/micros/platformconfig/proto"
- robot "bet24.com/servers/micros/userservices/proto"
- user "bet24.com/servers/micros/userservices/proto"
- )
- const config_key = "combomatch_config"
- const refresh_config_sec = 600
- const match_time_out_ended = 120
- type combomatchMgr struct {
- MatchConfigs []*matchconfig
- matches map[int][]*matchInfo
- lock *sync.RWMutex
- lockConfig *sync.RWMutex
- lockWating *sync.RWMutex
- waitingNextRoundMatches []*matchInfo
- lastConfigString string
- }
- var matchMgr *combomatchMgr
- func getMatchManager() *combomatchMgr {
- if matchMgr == nil {
- matchMgr = new(combomatchMgr)
- matchMgr.lock = &sync.RWMutex{}
- matchMgr.lockConfig = &sync.RWMutex{}
- matchMgr.matches = make(map[int][]*matchInfo)
- matchMgr.lockWating = &sync.RWMutex{}
- }
- return matchMgr
- }
- func (mm *combomatchMgr) run() {
- mm.loadConfig()
- go mm.checkTimeout()
- }
- func (mm *combomatchMgr) loadConfig() {
- defer func() {
- time.AfterFunc(refresh_config_sec*time.Second, mm.loadConfig)
- }()
- configString := platformconfig.GetConfig(config_key)
- if configString == "" {
- data, err := os.ReadFile("serviceconf/combomatch.json")
- if err != nil {
- log.Release("combomatch.combomatchMgr.loadData read json failed")
- return
- }
- configString = string(data)
- platformconfig.SetConfig(config_key, configString)
- }
- if configString == mm.lastConfigString {
- return
- }
- mm.lastConfigString = configString
- var configs []*matchconfig
- err := json.Unmarshal([]byte(configString), &configs)
- if err != nil {
- log.Release("combomatch.combomatchMgr.loadData Unmarshal failed err:%v", err)
- return
- }
- for _, v := range configs {
- v.calTotalPrize()
- mm.updateConfig(v)
- }
- // 有比赛删除
- mm.checkDeleteConfig(configs)
- }
- func (mm *combomatchMgr) updateConfig(config *matchconfig) {
- mm.lockConfig.Lock()
- defer mm.lockConfig.Unlock()
- for i := 0; i < len(mm.MatchConfigs); i++ {
- v := mm.MatchConfigs[i]
- if v.MatchId == config.MatchId {
- config.OnlineUser = v.OnlineUser
- mm.MatchConfigs[i] = config
- return
- }
- }
- // 没有
- mm.MatchConfigs = append(mm.MatchConfigs, config)
- }
- func (mm *combomatchMgr) checkDeleteConfig(configs []*matchconfig) {
- var toRemoveMatchIds []int
- mm.lockConfig.RLock()
- for _, v := range mm.MatchConfigs {
- found := false
- for _, v1 := range configs {
- if v.MatchId == v1.MatchId {
- found = true
- break
- }
- }
- if !found {
- toRemoveMatchIds = append(toRemoveMatchIds, v.MatchId)
- }
- }
- mm.lockConfig.RUnlock()
- if len(toRemoveMatchIds) == 0 {
- return
- }
- log.Release("combomatchMgr.checkDeleteConfig %v", toRemoveMatchIds)
- mm.lockConfig.Lock()
- for _, v := range toRemoveMatchIds {
- for i := 0; i < len(mm.MatchConfigs); {
- if mm.MatchConfigs[i].MatchId == v {
- mm.MatchConfigs = append(mm.MatchConfigs[:i], mm.MatchConfigs[i+1:]...)
- } else {
- i++
- }
- }
- }
- mm.lockConfig.Unlock()
- }
- func (mm *combomatchMgr) checkTimeout() {
- time.AfterFunc(30*time.Second, mm.checkTimeout)
- mm.lock.Lock()
- for k, v := range mm.matches {
- for i := 0; i < len(v); {
- if v[i].isTimeout() {
- v = append(v[:i], v[i+1:]...)
- } else {
- i++
- }
- }
- mm.matches[k] = v
- }
- mm.lock.Unlock()
- }
- func (mm *combomatchMgr) dump(param1, param2 string) {
- log.Release("-------------------------------")
- log.Release("combomatch.combomatchMgr.dump[%s,%s]", param1, param2)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param1 == "config" {
- mm.lockConfig.RLock()
- defer mm.lockConfig.RUnlock()
- for _, v := range mm.MatchConfigs {
- v.dump()
- }
- return
- }
- if param1 == "history" {
- getHistoryManager().dump(param2)
- return
- }
- if param1 == "user" {
- userId, err := strconv.Atoi(param2)
- if err != nil {
- log.Release("invalid param %s", param2)
- return
- }
- ms := mm.getUserMatchId(userId)
- for _, v := range ms {
- log.Release(" %d,%d,%d", v.MatchId, v.MatchType, v.MatchNo)
- }
- return
- }
- if param1 == "dismiss" {
- matchNo, err := strconv.Atoi(param2)
- if err != nil {
- log.Release("invalid param %s", param2)
- return
- }
- mm.dismissMatch(matchNo)
- return
- }
- matchId, _ := strconv.Atoi(param1)
- mm.lock.RLock()
- for k, v := range mm.matches {
- if matchId != 0 && matchId != k {
- continue
- }
- config := mm.getConfig(k)
- startInfo := ""
- if config != nil && config.RangeTime != nil {
- startInfo = fmt.Sprintf("%d", config.RangeTime.Start)
- }
- log.Release(" MatchId[%d] %s", k, startInfo)
- for _, v1 := range v {
- v1.dump(matchId != 0)
- }
- log.Release(" -------------")
- }
- mm.lock.RUnlock()
- }
- func (mm *combomatchMgr) dismissMatch(matchNo int) {
- mi := mm.getMatchByMatchNo(matchNo)
- if mi == nil {
- log.Release("combomatchMgr.dismissMatch [%d] not found", matchNo)
- return
- }
- config := mm.getConfig(mi.MatchId)
- if config == nil {
- log.Release("combomatchMgr.dismissMatch matchId[%d] not found", mi.MatchId)
- return
- }
- if mi.getStatus() == matchbase.MatchStatus_Ended {
- log.Release("combomatchMgr.dismissMatch matchId[%d] ended", mi.MatchId)
- return
- }
- userList := mi.getUserList()
- for _, v := range userList {
- // 退钱
- if len(config.EnrollFee) > 0 {
- itm := mi.getAndRemoveUserFee(v)
- if itm.Count > 0 {
- inventory.AddItems(v, []item.ItemPack{itm},
- "combomatch fee return", common.LOGTYPE_COMBOMATCH_ENTER_RETURN)
- } else if config.DailyFreeCount > 0 {
- getFreeCountManager().reduceFreeCount(v, config.MatchId)
- }
- }
- }
- switch mi.getCurrentMatchType() {
- case matchbase.MatchType_SimpleMatch:
- simplematch.DismissMatch(matchNo)
- case matchbase.MatchType_PointMatch:
- pointmatch.DismissMatch(matchNo)
- case matchbase.MatchType_SetsMatch:
- setsmatch.DismissMatch(matchNo)
- }
- }
- func (mm *combomatchMgr) enrollComboMatch(matchId int, userId int, nickname string, faceId int, faceUrl string, feeIndex int, isRobot bool) (int, string) {
- config := mm.getConfig(matchId)
- if config == nil {
- log.Release("combomatchMgr.enrollComboMatch matchId[%d] not found", matchId)
- return 0, "Wrong MatchId"
- }
- if !config.IsInTime() {
- log.Debug("combomatchMgr.enrollComboMatch matchId[%d] not open", matchId)
- return 0, "Not in match time"
- }
- // 不是预报名的,不能同时报多个
- if !config.IsPreEnroll() && mm.isUserPlaying(userId) {
- return 0, "Already in a match"
- }
- mi := mm.getOrCreateMatch(matchId, config)
- if mi == nil {
- log.Release("combomatchMgr.enrollComboMatch matchId[%d] getOrCreateMatch failed", matchId)
- return 0, "Serve error"
- }
- // 预报名,并且已经到达上线
- if !mi.canEnroll() {
- return 0, "Quota is full"
- }
- if feeIndex >= len(config.EnrollFee) {
- feeIndex = len(config.EnrollFee) - 1
- }
- // 如果有免费次数
- if config.DailyFreeCount > 0 && getFreeCountManager().getUserFreeCount(userId, config.MatchId) < config.DailyFreeCount {
- getFreeCountManager().addFreeCount(userId, config.MatchId)
- } else {
- // 扣钱
- if len(config.EnrollFee) > 0 && !robot.IsRobot(userId) {
- ok, err := inventory.Consume(userId, config.EnrollFee[feeIndex].ItemId, common.LOGTYPE_COMBOMATCH_ENTER, config.EnrollFee[feeIndex].Count, 0)
- if !ok {
- errMsg := fmt.Sprintf("not enough fee[%v] for play err = %s", config.EnrollFee[feeIndex], err)
- log.Release("combomatch.enrollComboMatch failed %s", errMsg)
- return 0, errMsg
- }
- mi.setUserFee(userId, config.EnrollFee[feeIndex])
- }
- }
- // 如果是提前报名,则不创建比赛,本地保存
- //if config.IsPreEnroll() {
- mi.addEnrollUser(userId, nickname, faceId, faceUrl, isRobot)
- // 发送通知
- //postUserEnterNotification(userId, matchId, nickname, faceId, faceUrl)
- ni := ComboMatch_notificationInfo{Msg: ComboMatch_noti_userenter, UserId: userId, MatchId: matchId, FaceId: faceId, FaceUrl: faceUrl, Nickname: nickname}
- d, _ := json.Marshal(ni)
- mi.sendNotification(-1, string(d))
- return 1, "OK"
- //}
- /*
- // 玩家加入
- var retCode int
- var errMsg string
- if mi.isSimpleMatch() {
- retCode, errMsg = simplematch.EnrollMatch(userId, nickname, faceId, faceUrl, mi.getMatchNo())
- } else {
- retCode, errMsg = pointmatch.EnrollMatch(userId, nickname, faceId, faceUrl, mi.getMatchNo())
- }
- if retCode != 1 {
- return 0, errMsg
- }
- config.addOnline(1)
- return mi.getMatchNo(), "OK"
- */
- }
- func (mm *combomatchMgr) quitComboMatch(matchId int, userId int) bool {
- config := mm.getConfig(matchId)
- if config == nil {
- log.Release("combomatchMgr.quitComboMatch matchId[%d] not found", matchId)
- return false
- }
- // 查询我的比赛
- mm.lock.RLock()
- matches, ok := mm.matches[matchId]
- mm.lock.RUnlock()
- if !ok || len(matches) == 0 {
- log.Release("combomatchMgr.quitComboMatch matchId[%d] no match found", matchId)
- return false
- }
- for _, v := range matches {
- //if v.getStatus() == matchbase.MatchStatus_Free && v.isUserEnrolled(userId) {
- // 退出当前比赛
- if v.isUserEnrolled(userId) {
- return v.quitUser(userId, true)
- }
- }
- log.Release("quitComboMatch MatchId[%d] UserId[%d] not in match", matchId, userId)
- return false
- }
- func (mm *combomatchMgr) getConfig(matchId int) *matchconfig {
- mm.lockConfig.RLock()
- defer mm.lockConfig.RUnlock()
- for _, v := range mm.MatchConfigs {
- if v.MatchId == matchId {
- return v
- }
- }
- return nil
- }
- func (mm *combomatchMgr) getCurrentMatch(matchId int) *matchInfo {
- mm.lock.RLock()
- matches, ok := mm.matches[matchId]
- mm.lock.RUnlock()
- if ok {
- for _, v := range matches {
- if v.getStatus() == matchbase.MatchStatus_Free && !v.isFull() {
- return v
- }
- }
- }
- return nil
- }
- func (mm *combomatchMgr) createMatch(matchId int, config *matchconfig, mi *matchInfo, totalUser int) *matchInfo {
- round := 0
- if mi != nil {
- round = mi.CurrentRound + 1
- }
- var matchNo int
- var matchInstance matchbase.MatchInstance
- var err string
- // 创建一个比赛,报名期间,先不创建比赛实例,等人满后再创建
- if mi != nil {
- switch config.getMatchType(round) {
- case matchbase.MatchType_SimpleMatch:
- matchNo, err = simplematch.CreateMatch(-1, config.GameId, config.GameRule, totalUser, config.getTarget(round),
- config.TableUser, 0, 0, config.PlayTime, config.isEleminateByScore(round), config.getWinnerCount(round))
- if matchNo == 0 {
- log.Release("combomatchMgr.getOrCreateMatch simplematch.CreateMatch failed %s", err)
- return nil
- }
- matchInstance = simplematch.GetMatchInstance(matchNo)
- case matchbase.MatchType_PointMatch:
- e, ssec, sscore, w := config.getPointMatchParams(round)
- 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 nil
- }
- 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(round))
- if matchNo == 0 {
- log.Release("combomatchMgr.getOrCreateMatch setsmatch.CreateMatch failed %s", err)
- return nil
- }
- matchInstance = setsmatch.GetMatchInstance(matchNo)
- }
- if matchInstance == nil {
- log.Release("combomatchMgr.getOrCreateMatch GetMatchInstance == nil")
- return nil
- }
- matchInstance.RegisterReceiver(mm)
- }
- if mi == nil {
- mi = newMatchInfo(config.MatchId, mm, config.RobotConfig, config)
- } else {
- mi.addMatchInfo(matchNo, matchInstance)
- }
- return mi
- }
- func (mm *combomatchMgr) getOrCreateMatch(matchId int, config *matchconfig) *matchInfo {
- ret := mm.getCurrentMatch(matchId)
- if ret != nil {
- return ret
- }
- ret = mm.createMatch(matchId, config, nil, config.TotalUser)
- if ret == nil {
- return nil
- }
- mm.lock.Lock()
- mm.matches[matchId] = append(mm.matches[matchId], ret)
- mm.lock.Unlock()
- return ret
- }
- // MatchInstanceReceiver
- func (mm *combomatchMgr) OnMatchStart(matchNo int) {
- log.Debug("combomatchMgr.OnMatchStart [%d]", matchNo)
- mi := mm.getMatchByMatchNo(matchNo)
- if mi == nil {
- log.Release("combomatchMgr.OnMatchStart [%d] matchInfo not found", matchNo)
- return
- }
- mi.setStartTime(matchNo)
- }
- func (mm *combomatchMgr) OnMatchCancelled(matchNo int) {
- log.Debug("combomatchMgr.OnMatchCancelled [%d]", matchNo)
- mi := mm.getMatchByMatchNo(matchNo)
- if mi == nil {
- log.Release("combomatchMgr.OnMatchCancelled [%d] matchInfo not found", matchNo)
- return
- }
- config := mm.getConfig(mi.MatchId)
- if config == nil {
- log.Release("combomatchMgr.OnMatchCancelled [%d] config not found", matchNo)
- return
- }
- var matchInstance matchbase.MatchInstance
- switch mi.getCurrentMatchType() {
- case matchbase.MatchType_SimpleMatch:
- matchInstance = simplematch.GetMatchInstance(matchNo)
- case matchbase.MatchType_PointMatch:
- matchInstance = pointmatch.GetMatchInstance(matchNo)
- case matchbase.MatchType_SetsMatch:
- matchInstance = setsmatch.GetMatchInstance(matchNo)
- }
- if matchInstance == nil {
- log.Release("combomatchMgr.OnMatchCancelled [%d] matchInstance not found", matchNo)
- return
- }
- // 退费
- userList := matchInstance.GetUserList()
- for _, userId := range userList {
- // 退钱
- if len(config.EnrollFee) > 0 {
- 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)
- }
- }
- }
- }
- func (mm *combomatchMgr) OnMatchEnd(matchNo int) {
- log.Debug("combomatchMgr.OnMatchEnd [%d]", matchNo)
- mi := mm.getMatchByMatchNo(matchNo)
- if mi == nil {
- log.Release("combomatchMgr.OnMatchEnd [%d] matchInfo not found", matchNo)
- return
- }
- mi.setEndTime(matchNo)
- config := mm.getConfig(mi.MatchId)
- if config == nil {
- log.Release("combomatchMgr.OnMatchEnd matchId[%d] not found", mi.MatchId)
- return
- }
- // 找出胜利者给发奖励
- var matchInstance matchbase.MatchInstance
- switch mi.getCurrentMatchType() {
- case matchbase.MatchType_SimpleMatch:
- matchInstance = simplematch.GetMatchInstance(matchNo)
- case matchbase.MatchType_PointMatch:
- matchInstance = pointmatch.GetMatchInstance(matchNo)
- case matchbase.MatchType_SetsMatch:
- matchInstance = setsmatch.GetMatchInstance(matchNo)
- }
- if matchInstance == nil {
- log.Release("combomatchMgr.OnMatchEnd [%d] matchInstance not found", matchNo)
- return
- }
- winners := matchInstance.GetWinners()
- if len(winners) == 0 {
- log.Release("combomatchMgr.OnMatchEnd [%d] no winners", matchNo)
- return
- }
- // 把名词更新一下
- currentMatchUsers := matchInstance.GetAllMatchUsers()
- for _, v := range currentMatchUsers {
- mi.updateRankAndScore(v.UserId, v.Rank, v.Score, v.WinCount)
- }
- if mi.isEnded() {
- config.addOnline(-mi.getOnline())
- // 加入历史记录
- var h combohistory
- h.Name = config.Name
- h.MatchId = config.MatchId
- h.GameId = config.GameId
- h.GameName = config.GameName
- h.GameRule = config.GameRule
- h.Prizes = config.Prizes
- h.TableUser = config.TableUser
- h.TotalUser = config.TotalUser
- h.EnrollFee = config.EnrollFee
- //h.matchconfig = *config
- for i := 0; i < len(config.Rounds); i++ {
- h.Rounds = append(h.Rounds, historyRound{
- MatchType: config.Rounds[i].MatchType,
- Target: config.Rounds[i].Target,
- WinnerCount: config.Rounds[i].WinnerCount,
- MatchNo: mi.Rounds[i].MatchNo,
- StartTime: mi.Rounds[i].StartTime,
- EndTime: mi.Rounds[i].EndTime,
- })
- }
- h.StartTime = mi.getStartTime()
- h.EndTime = mi.getEndTime()
- h.Winners = winners
- enrollUsers := mi.getAllMatchUsers()
- for _, v := range enrollUsers {
- h.EnrollUsers = append(h.EnrollUsers, historyUser{
- MatchUserBrief: *v.ToBrief(),
- enrollTime: int(v.EnrollTime),
- prize: config.getPrizes(v.Rank),
- })
- }
- // 所有参与人员
- sort.Slice(h.EnrollUsers, func(i, j int) bool {
- return h.EnrollUsers[i].Rank < h.EnrollUsers[j].Rank
- })
- for _, v := range h.EnrollUsers {
- // 已淘汰用户不再发奖励
- if mi.isUserAwarded(v.UserId) {
- continue
- }
- prize := config.getPrizes(v.Rank)
- if len(prize) > 0 {
- inventory.AddItems(v.UserId, prize, "配置赛奖励", common.LOGTYPE_COMBOMATCH_PRIZE)
- log.Debug("OnMatchEnd 发送通知和奖励 [%d] Rank:[%d] %v", v.UserId, v.Rank, prize)
- }
- mi.postUserRankNotification(v.UserId, v.Rank, prize)
- /*gameHistory.MyMatch_Write(v.UserId, &gameHistory.MyMatchInfo{
- UserId: v.UserId, //int `json:"UserId, omitempty"` // 用户ID
- NickName: v.NickName, //string `json:"NickName, omitempty"` // 昵称
- MatchName: config.Name, //string // 比赛名称
- Rank: v.Rank, //int // 名次
- Items: prize, //int // 道具ID
- })*/
- mi.setUserAwarded(v.UserId)
- }
- // 最后把所有报名记录都加上
- h.setAllEnrolledUsers(mi.enrolledUsers)
- getHistoryManager().addHistory(h)
- go writeRoomRecordToDB(&h)
- mi.dump(true)
- return
- }
- mi.setRoundWinners(winners)
- mm.lockWating.Lock()
- mm.waitingNextRoundMatches = append(mm.waitingNextRoundMatches, mi)
- mm.lockWating.Unlock()
- log.Debug("combomatchMgr.OnMatchEnd match[%d] waiting to enter next round", matchNo)
- mi.dump(false)
- time.AfterFunc(6*time.Second, mm.enterNextRound)
- }
- func (mm *combomatchMgr) OnUserEliminated(matchNo int, userId int, rank int) {
- log.Debug("combomatchMgr.OnUserEliminated [%d] UserId[%d] Rank[%d]", matchNo, userId, rank)
- mi := mm.getMatchByMatchNo(matchNo)
- if mi == nil {
- log.Release("combomatchMgr.OnUserEliminated [%d] matchInfo not found", matchNo)
- return
- }
- config := mm.getConfig(mi.MatchId)
- if config == nil {
- log.Release("combomatchMgr.OnUserEliminated matchId[%d] not found", mi.MatchId)
- return
- }
- prize := config.getPrizes(rank)
- if len(prize) > 0 {
- inventory.AddItems(userId, prize, "配置赛奖励", common.LOGTYPE_COMBOMATCH_PRIZE)
- mi.postUserRankNotification(userId, rank, prize)
- log.Debug("OnMatchEnd 发送通知和奖励 [%d] %v", userId, prize)
- }
- mi.setUserAwarded(userId)
- /*usr := mi.getUser(userId)
- var myInfo gameHistory.MyMatchInfo
- myInfo.UserId = userId
- myInfo.MatchName = config.Name
- myInfo.Rank = rank
- myInfo.Items = prize
- if usr != nil {
- myInfo.NickName = usr.NickName
- }
- gameHistory.MyMatch_Write(userId, &myInfo)*/
- }
- func (mm *combomatchMgr) getAWatingNextRoundMatch() *matchInfo {
- var ret *matchInfo
- mm.lockWating.Lock()
- defer mm.lockWating.Unlock()
- if len(mm.waitingNextRoundMatches) > 0 {
- ret = mm.waitingNextRoundMatches[0]
- mm.waitingNextRoundMatches = mm.waitingNextRoundMatches[1:]
- }
- return ret
- }
- func (mm *combomatchMgr) enterNextRound() {
- mi := mm.getAWatingNextRoundMatch()
- if mi == nil {
- log.Release("combomatchMgr.enterNextRound no match waiting to next round")
- return
- }
- log.Debug("combomatchMgr.enterNextRound find a wating match [%d]", mi.getMatchNo())
- config := mm.getConfig(mi.MatchId)
- if config == nil {
- log.Release("combomatchMgr.enterNextRound matchId[%d] not found", mi.MatchId)
- return
- }
- // 进行下一轮
- newMatch := mm.createMatch(mi.MatchId, config, mi, len(mi.currentRoundWinners))
- if newMatch == nil {
- log.Release("combomatchMgr.enterNextRound open new match failed")
- return
- } else {
- log.Debug("combomatchMgr.enterNextRound new match [%d] created userCount = %d", newMatch.getMatchNo(), len(mi.currentRoundWinners))
- }
- for i := 0; i < len(mi.currentRoundWinners); i++ {
- var retCode int
- var errMsg string
- matchUser := &mi.currentRoundWinners[i]
- if matchUser == nil {
- log.Release("combomatchMgr.enterNextRound winners %v not found", mi.currentRoundWinners[i])
- continue
- }
- switch mi.getCurrentMatchType() {
- case matchbase.MatchType_SimpleMatch:
- retCode, errMsg = simplematch.EnrollMatchWithInitialScore(matchUser.UserId, matchUser.NickName, matchUser.FaceId, matchUser.FaceUrl, mi.getMatchNo(), matchUser.Score)
- case matchbase.MatchType_PointMatch:
- retCode, errMsg = pointmatch.EnrollMatch(matchUser.UserId, matchUser.NickName, matchUser.FaceId, matchUser.FaceUrl, mi.getMatchNo())
- case matchbase.MatchType_SetsMatch:
- retCode, errMsg = setsmatch.EnrollMatch(matchUser.UserId, matchUser.NickName, matchUser.FaceId, matchUser.FaceUrl, mi.getMatchNo())
- }
- if retCode != 1 {
- log.Release("combomatchMgr.enterNextRound enrollMatch failed [%v] [%s]", mi.currentRoundWinners[i], errMsg)
- }
- }
- mi.setRoundWinners([]int{})
- }
- func (mm *combomatchMgr) getMatchByMatchNo(matchNo int) *matchInfo {
- mm.lock.RLock()
- defer mm.lock.RUnlock()
- for _, v := range mm.matches {
- for _, v1 := range v {
- if v1.getMatchNo() == matchNo {
- return v1
- }
- }
- }
- return nil
- }
- func (mm *combomatchMgr) getMatchList(userId int) string {
- var configs []matchconfig
- mm.lockConfig.RLock()
- for _, v := range mm.MatchConfigs {
- configs = append(configs, *v)
- }
- mm.lockConfig.RUnlock()
- for i := 0; i < len(configs); i++ {
- configs[i].setLeftFreeCount(userId)
- }
- d, _ := json.Marshal(configs)
- return string(d)
- }
- func (mm *combomatchMgr) getUserMatchId(userId int) []pb.UserComboMatchId {
- var ret []pb.UserComboMatchId
- mm.lock.RLock()
- defer mm.lock.RUnlock()
- for _, v := range mm.matches {
- for _, v1 := range v {
- if v1.isUserPlaying(userId) {
- ret = append(ret, pb.UserComboMatchId{
- MatchId: v1.MatchId,
- MatchType: v1.getCurrentMatchType(),
- MatchNo: v1.getMatchNo(),
- SecsToStart: v1.getStartSeconds(),
- })
- }
- }
- }
- return ret
- }
- func (mm *combomatchMgr) addARobot(matchId int) int {
- m := mm.getCurrentMatch(matchId)
- if m == nil {
- log.Release("combomatchMgr.addARobot matchId[%d] has no live match", matchId)
- return 0
- }
- // 如果比赛没那么快开始
- forceRemove := m.getStartSeconds() > 1800
- // 如果没有真人了
- if m.tryRemoveOneRobot(forceRemove) {
- return -1
- }
- if forceRemove {
- return 0
- }
- loopCount := 0
- for {
- loopCount++
- if loopCount > 20 {
- log.Release("combomatchMgr.addARobot matchId[%d] get a robot failed", matchId)
- return 0
- }
- robotId := robot.GetARobot()
- if mm.isUserPlaying(robotId) {
- continue
- }
- usr := user.GetUserInfo(robotId)
- if usr == nil {
- continue
- }
- mm.enrollComboMatch(matchId, robotId, usr.NickName, usr.FaceId, usr.FaceUrl, 0, true)
- break
- }
- return 1
- }
- func (mm *combomatchMgr) isUserPlaying(robotId int) bool {
- mm.lock.RLock()
- defer mm.lock.RUnlock()
- for _, m := range mm.matches {
- for _, mi := range m {
- if mi.isUserPlaying(robotId) {
- return true
- }
- }
- }
- return false
- }
- func (mm *combomatchMgr) getUserMatchInfo(matchId int, userId int) string {
- var mi *matchInfo
- mm.lock.RLock()
- matches, ok := mm.matches[matchId]
- mm.lock.RUnlock()
- if !ok {
- log.Debug("combomatchMgr.getUserMatchInfo matchId[%d] has no match instance", matchId)
- return ""
- }
- for _, v := range matches {
- if v.isUserPlaying(userId) {
- mi = v
- break
- }
- }
- if mi == nil {
- //log.Debug("combomatchMgr.getMatchInfo matchId[%d] userId[%d] has no match enrolled", matchId, userId)
- return ""
- }
- return mi.getMatchInfo()
- }
- func (mm *combomatchMgr) getConfirmCount(matchId int) int {
- mi := mm.getCurrentMatch(matchId)
- if mi == nil {
- //log.Release("combomatchMgr.getConfirmCount [%d] not found", matchId)
- return 0
- }
- return mi.getConfirmCount()
- }
- func (mm *combomatchMgr) confirmMatch(matchId int, userId int) bool {
- mi := mm.getCurrentMatch(matchId)
- if mi == nil {
- log.Release("combomatchMgr.confirmMatch [%d] not found", matchId)
- return false
- }
- return mi.confirmMatch(userId)
- }
|