| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- package handler
- import (
- "bet24.com/log"
- "bet24.com/servers/common"
- cash "bet24.com/servers/micros/money/proto"
- game_client "bet24.com/servers/micros/privateroom/game/client"
- pb "bet24.com/servers/micros/privateroom/proto"
- rule_status "bet24.com/servers/micros/privateroom/status/client"
- "encoding/json"
- "fmt"
- "sort"
- "sync"
- "time"
- )
- type servermgr struct {
- lock *sync.RWMutex
- serverList map[string]*serverInfo
- recvMgr *receiverMgr
- }
- var s_mgr *servermgr
- func getServerManager() *servermgr {
- if s_mgr == nil {
- s_mgr = new(servermgr)
- s_mgr.ctor()
- }
- return s_mgr
- }
- func (sm *servermgr) ctor() {
- sm.lock = &sync.RWMutex{}
- sm.serverList = make(map[string]*serverInfo)
- sm.recvMgr = newReceiverMgr()
- }
- func (sm *servermgr) run() {
- go sm.checkTimeout()
- }
- func (sm *servermgr) checkTimeout() {
- time.AfterFunc(5*time.Second, sm.checkTimeout)
- var toRemove []string
- sm.lock.RLock()
- for _, v := range sm.serverList {
- if v.isTimeout() {
- toRemove = append(toRemove, v.Addr)
- }
- }
- sm.lock.RUnlock()
- if len(toRemove) <= 0 {
- return
- }
- log.Debug("servermgr.checkTimeout removing servers %v", toRemove)
- for _, v := range toRemove {
- sm.removeServer(v, true)
- }
- }
- func (sm *servermgr) getServer(addr string) *serverInfo {
- sm.lock.RLock()
- defer sm.lock.RUnlock()
- ret, ok := sm.serverList[addr]
- if !ok {
- return nil
- }
- return ret
- }
- func (sm *servermgr) addServer(addr string, gameId int, gameName string, rules []gameRule) bool {
- if sm.getServer(addr) != nil {
- log.Release("servermgr.addServer server[%s] exists", addr)
- return false
- }
- s := &serverInfo{
- GameId: gameId,
- GameName: gameName,
- Addr: addr,
- OnlineUser: 0,
- lastPing: time.Now().Unix(),
- GameRules: rules,
- isOnline: true,
- }
- for i := 0; i < len(s.GameRules); i++ {
- s.GameRules[i].queryOptions()
- }
- sm.lock.Lock()
- sm.serverList[addr] = s
- sm.lock.Unlock()
- return true
- }
- func (sm *servermgr) addGameRule(addr string, gameId int, gameName string, ruleName, ruleDesc, ruleData string) {
- //log.Debug("servermgr.addGameRule %s", ruleData)
- s := sm.getServer(addr)
- if s == nil {
- sm.addServer(addr, gameId, gameName, []gameRule{{Name: ruleName, Desc: ruleDesc, Data: ruleData}})
- s = sm.getServer(addr)
- } else {
- s.addGameRule(ruleName, ruleDesc, ruleData)
- }
- rule := s.getRule(ruleName)
- if rule == nil {
- log.Release("servermgr.addGameRule ruleName[%s] not found", ruleName)
- return
- }
- receivers := sm.recvMgr.getActiveReceivers()
- for _, v := range receivers {
- ok := rule_status.OnGameRuleRegistered(v, gameId, ruleName, ruleDesc,
- rule.Options.TargetOptions,
- rule.Options.UserCountOptions,
- rule.Options.PlayTimeOptions)
- if !ok {
- log.Debug("failed to send messsage to %s", v)
- //sm.receivers = append(sm.receivers[:i], sm.receivers[i+1:]...)
- sm.recvMgr.setReceiver(v, false)
- }
- }
- }
- func (sm *servermgr) updateServerOnline(addr string, online int) {
- s := sm.getServer(addr)
- if s == nil {
- log.Release("servermgr.updateServerOnline server %s not exist", addr)
- return
- }
- s.updateOnline(online)
- }
- func (sm *servermgr) removeServer(addr string, removeRoom bool) {
- s := sm.getServer(addr)
- if s == nil {
- return
- }
- // 删除房间
- if removeRoom {
- getRoomManager().removeRoomsByServerAddr(addr)
- }
- sm.lock.Lock()
- delete(sm.serverList, addr)
- sm.lock.Unlock()
- if !removeRoom {
- return
- }
- // 判断是否需要广播删除规则
- var toRemoveRules []string
- for _, v := range s.GameRules {
- toRemoveRules = append(toRemoveRules, v.Name)
- }
- for i := 0; i < len(toRemoveRules); {
- if sm.isGameRuleExist(s.GameId, toRemoveRules[i]) {
- toRemoveRules = append(toRemoveRules[:i], toRemoveRules[i+1:]...)
- } else {
- i++
- }
- }
- if len(toRemoveRules) == 0 {
- return
- }
- receivers := sm.recvMgr.getActiveReceivers()
- for _, v := range receivers {
- ok := true
- for _, rule := range toRemoveRules {
- ok = rule_status.OnGameRuleDeregistered(v, s.GameId, rule)
- if !ok {
- break
- }
- }
- if !ok {
- log.Debug("failed to send messsage(OnGameRuleDeregistered) to %s", v)
- sm.recvMgr.setReceiver(v, false)
- }
- }
- }
- func (sm *servermgr) isGameRuleExist(gameId int, ruleName string) bool {
- sm.lock.RLock()
- defer sm.lock.RUnlock()
- for _, v := range sm.serverList {
- if v.GameId != gameId {
- continue
- }
- if v.getRule(ruleName) != nil {
- return true
- }
- }
- return false
- }
- func (sm *servermgr) getAServerAddr(gameId int, ruleName string) (addr string, rule *gameRule) {
- addr = ""
- rule = nil
- var ret []*serverInfo
- sm.lock.RLock()
- for _, v := range sm.serverList {
- if v.GameId == gameId {
- ret = append(ret, v)
- }
- }
- sm.lock.RUnlock()
- if len(ret) == 0 {
- return
- }
- if len(ret) > 1 {
- sort.Slice(ret, func(i, j int) bool {
- return ret[i].OnlineUser < ret[j].OnlineUser
- })
- }
- for _, v := range ret {
- rule = v.getRule(ruleName)
- if rule != nil {
- addr = v.Addr
- return
- }
- }
- return
- }
- func (sm *servermgr) dump(param string) {
- log.Release("-------------------------------")
- log.Release("privateroom.servermgr.dump")
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param == "receiver" {
- sm.recvMgr.dump()
- return
- }
- sm.lock.RLock()
- for _, v := range sm.serverList {
- v.dump()
- }
- sm.lock.RUnlock()
- }
- func (sm *servermgr) getRules(gameId int) string {
- var ret []gameRule
- usedGameRules := make(map[string]int)
- sm.lock.RLock()
- defer sm.lock.RUnlock()
- for _, v := range sm.serverList {
- if gameId != 0 && v.GameId != gameId {
- continue
- }
- for _, rule := range v.GameRules {
- if usedGameRules[rule.Name] > 0 {
- continue
- }
- usedGameRules[rule.Name] = 1
- ret = append(ret, rule)
- }
- }
- d, _ := json.Marshal(ret)
- return string(d)
- }
- func (sm *servermgr) createRoom(userId int, gameId int, ruleName string, target int, userCount int, fee int, prize int, roomType string, playTimeout int, isPublic bool, extraInfo string,yyfUid int) (roomNo int, errMsg string) {
- roomNo = 0
- errMsg = "ok"
- if roomType != pb.RoomType_Normal {
- isPublic = false
- }
- // 找出有此规则的server
- addr, rule := sm.getAServerAddr(gameId, ruleName)
- if addr == "" {
- errMsg = fmt.Sprintf("server not found [%d:%s]", gameId, ruleName)
- log.Release("createRoom failed %s", errMsg)
- return
- }
- if rule == nil {
- errMsg = fmt.Sprintf("game rule not found [%d:%s]", gameId, ruleName)
- log.Release("createRoom failed %s", errMsg)
- return
- }
- // 检查创建参数是否存在
- if !rule.isOptionValid(target, userCount, playTimeout, fee, roomType) {
- errMsg = fmt.Sprintf("invalid option parameter [%d:%d:%d]", target, userCount, playTimeout)
- log.Release("createRoom failed %s options[%v]", errMsg, rule.Options)
- return
- }
- createFee := prize
- if createFee > 0 && !cash.ReduceMoney2(userId, createFee, common.LOGTYPE_PRIVATEROOM_OWNER, "privateroom", "create", "",yyfUid) {
- //if createFee > 0 && !cash.ReduceMoney(userId, createFee, common.LOGTYPE_PRIVATEROOM_OWNER, "privateroom", "create", "") {
- errMsg = fmt.Sprintf("not enough cash for create room[%d]", createFee)
- log.Release("createRoom failed %s", errMsg)
- return
- }
- // 连接服务器
- roomNo = game_client.CreatePrivateRoom(addr, game_client.Request_Create{
- Creator: userId,
- GameRule: rule.Data,
- Target: target,
- UserCount: userCount,
- PlayTimeout: playTimeout,
- })
- if roomNo == 0 {
- errMsg = "sever error,please try agrain"
- log.Release("servermgr.createRoom roomNo = 0, gameId = %d,ruleName = %s,userId = %d", gameId, ruleName, userId)
- // 加回去
- if createFee > 0 {
- cash.GiveMoney2(userId, createFee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "create return", "",yyfUid)
- //cash.GiveMoney(userId, createFee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "create return", "")
- }
- return
- }
- // 设置房间的userCount,ruleName和fee
- getRoomManager().setRoomExtra(roomNo, ruleName, rule.Data, userCount, target,
- fee, addr, createFee, rule.isDual(userCount), prize, roomType, isPublic, playTimeout, extraInfo)
- return
- }
- func (sm *servermgr) isGameRuleValid(gameId int, gameRule string, target int, userCount, playTime int) bool {
- _, rule := sm.getAServerAddr(gameId, gameRule)
- if rule == nil {
- log.Release("privateroom.servermgr.isGameRuleValid %d:%s not found", gameId, gameRule)
- return false
- }
- return rule.isOptionValid(target, userCount, playTime, 0, pb.RoomType_SimpleMatch)
- }
- func (sm *servermgr) registerServerStatus(addr string) {
- sm.recvMgr.setReceiver(addr, true)
- }
|