servermgr.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. package handler
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/servers/common"
  5. cash "bet24.com/servers/micros/money/proto"
  6. game_client "bet24.com/servers/micros/privateroom/game/client"
  7. pb "bet24.com/servers/micros/privateroom/proto"
  8. rule_status "bet24.com/servers/micros/privateroom/status/client"
  9. "encoding/json"
  10. "fmt"
  11. "sort"
  12. "sync"
  13. "time"
  14. )
  15. type servermgr struct {
  16. lock *sync.RWMutex
  17. serverList map[string]*serverInfo
  18. recvMgr *receiverMgr
  19. }
  20. var s_mgr *servermgr
  21. func getServerManager() *servermgr {
  22. if s_mgr == nil {
  23. s_mgr = new(servermgr)
  24. s_mgr.ctor()
  25. }
  26. return s_mgr
  27. }
  28. func (sm *servermgr) ctor() {
  29. sm.lock = &sync.RWMutex{}
  30. sm.serverList = make(map[string]*serverInfo)
  31. sm.recvMgr = newReceiverMgr()
  32. }
  33. func (sm *servermgr) run() {
  34. go sm.checkTimeout()
  35. }
  36. func (sm *servermgr) checkTimeout() {
  37. time.AfterFunc(5*time.Second, sm.checkTimeout)
  38. var toRemove []string
  39. sm.lock.RLock()
  40. for _, v := range sm.serverList {
  41. if v.isTimeout() {
  42. toRemove = append(toRemove, v.Addr)
  43. }
  44. }
  45. sm.lock.RUnlock()
  46. if len(toRemove) <= 0 {
  47. return
  48. }
  49. log.Debug("servermgr.checkTimeout removing servers %v", toRemove)
  50. for _, v := range toRemove {
  51. sm.removeServer(v, true)
  52. }
  53. }
  54. func (sm *servermgr) getServer(addr string) *serverInfo {
  55. sm.lock.RLock()
  56. defer sm.lock.RUnlock()
  57. ret, ok := sm.serverList[addr]
  58. if !ok {
  59. return nil
  60. }
  61. return ret
  62. }
  63. func (sm *servermgr) addServer(addr string, gameId int, gameName string, rules []gameRule) bool {
  64. if sm.getServer(addr) != nil {
  65. log.Release("servermgr.addServer server[%s] exists", addr)
  66. return false
  67. }
  68. s := &serverInfo{
  69. GameId: gameId,
  70. GameName: gameName,
  71. Addr: addr,
  72. OnlineUser: 0,
  73. lastPing: time.Now().Unix(),
  74. GameRules: rules,
  75. isOnline: true,
  76. }
  77. for i := 0; i < len(s.GameRules); i++ {
  78. s.GameRules[i].queryOptions()
  79. }
  80. sm.lock.Lock()
  81. sm.serverList[addr] = s
  82. sm.lock.Unlock()
  83. return true
  84. }
  85. func (sm *servermgr) addGameRule(addr string, gameId int, gameName string, ruleName, ruleDesc, ruleData string) {
  86. //log.Debug("servermgr.addGameRule %s", ruleData)
  87. s := sm.getServer(addr)
  88. if s == nil {
  89. sm.addServer(addr, gameId, gameName, []gameRule{{Name: ruleName, Desc: ruleDesc, Data: ruleData}})
  90. s = sm.getServer(addr)
  91. } else {
  92. s.addGameRule(ruleName, ruleDesc, ruleData)
  93. }
  94. rule := s.getRule(ruleName)
  95. if rule == nil {
  96. log.Release("servermgr.addGameRule ruleName[%s] not found", ruleName)
  97. return
  98. }
  99. receivers := sm.recvMgr.getActiveReceivers()
  100. for _, v := range receivers {
  101. ok := rule_status.OnGameRuleRegistered(v, gameId, ruleName, ruleDesc,
  102. rule.Options.TargetOptions,
  103. rule.Options.UserCountOptions,
  104. rule.Options.PlayTimeOptions)
  105. if !ok {
  106. log.Debug("failed to send messsage to %s", v)
  107. //sm.receivers = append(sm.receivers[:i], sm.receivers[i+1:]...)
  108. sm.recvMgr.setReceiver(v, false)
  109. }
  110. }
  111. }
  112. func (sm *servermgr) updateServerOnline(addr string, online int) {
  113. s := sm.getServer(addr)
  114. if s == nil {
  115. log.Release("servermgr.updateServerOnline server %s not exist", addr)
  116. return
  117. }
  118. s.updateOnline(online)
  119. }
  120. func (sm *servermgr) removeServer(addr string, removeRoom bool) {
  121. s := sm.getServer(addr)
  122. if s == nil {
  123. return
  124. }
  125. // 删除房间
  126. if removeRoom {
  127. getRoomManager().removeRoomsByServerAddr(addr)
  128. }
  129. sm.lock.Lock()
  130. delete(sm.serverList, addr)
  131. sm.lock.Unlock()
  132. if !removeRoom {
  133. return
  134. }
  135. // 判断是否需要广播删除规则
  136. var toRemoveRules []string
  137. for _, v := range s.GameRules {
  138. toRemoveRules = append(toRemoveRules, v.Name)
  139. }
  140. for i := 0; i < len(toRemoveRules); {
  141. if sm.isGameRuleExist(s.GameId, toRemoveRules[i]) {
  142. toRemoveRules = append(toRemoveRules[:i], toRemoveRules[i+1:]...)
  143. } else {
  144. i++
  145. }
  146. }
  147. if len(toRemoveRules) == 0 {
  148. return
  149. }
  150. receivers := sm.recvMgr.getActiveReceivers()
  151. for _, v := range receivers {
  152. ok := true
  153. for _, rule := range toRemoveRules {
  154. ok = rule_status.OnGameRuleDeregistered(v, s.GameId, rule)
  155. if !ok {
  156. break
  157. }
  158. }
  159. if !ok {
  160. log.Debug("failed to send messsage(OnGameRuleDeregistered) to %s", v)
  161. sm.recvMgr.setReceiver(v, false)
  162. }
  163. }
  164. }
  165. func (sm *servermgr) isGameRuleExist(gameId int, ruleName string) bool {
  166. sm.lock.RLock()
  167. defer sm.lock.RUnlock()
  168. for _, v := range sm.serverList {
  169. if v.GameId != gameId {
  170. continue
  171. }
  172. if v.getRule(ruleName) != nil {
  173. return true
  174. }
  175. }
  176. return false
  177. }
  178. func (sm *servermgr) getAServerAddr(gameId int, ruleName string) (addr string, rule *gameRule) {
  179. addr = ""
  180. rule = nil
  181. var ret []*serverInfo
  182. sm.lock.RLock()
  183. for _, v := range sm.serverList {
  184. if v.GameId == gameId {
  185. ret = append(ret, v)
  186. }
  187. }
  188. sm.lock.RUnlock()
  189. if len(ret) == 0 {
  190. return
  191. }
  192. if len(ret) > 1 {
  193. sort.Slice(ret, func(i, j int) bool {
  194. return ret[i].OnlineUser < ret[j].OnlineUser
  195. })
  196. }
  197. for _, v := range ret {
  198. rule = v.getRule(ruleName)
  199. if rule != nil {
  200. addr = v.Addr
  201. return
  202. }
  203. }
  204. return
  205. }
  206. func (sm *servermgr) dump(param string) {
  207. log.Release("-------------------------------")
  208. log.Release("privateroom.servermgr.dump")
  209. defer func() {
  210. log.Release("+++++++++++++++++++++++++++++++")
  211. log.Release("")
  212. }()
  213. if param == "receiver" {
  214. sm.recvMgr.dump()
  215. return
  216. }
  217. sm.lock.RLock()
  218. for _, v := range sm.serverList {
  219. v.dump()
  220. }
  221. sm.lock.RUnlock()
  222. }
  223. func (sm *servermgr) getRules(gameId int) string {
  224. var ret []gameRule
  225. usedGameRules := make(map[string]int)
  226. sm.lock.RLock()
  227. defer sm.lock.RUnlock()
  228. for _, v := range sm.serverList {
  229. if gameId != 0 && v.GameId != gameId {
  230. continue
  231. }
  232. for _, rule := range v.GameRules {
  233. if usedGameRules[rule.Name] > 0 {
  234. continue
  235. }
  236. usedGameRules[rule.Name] = 1
  237. ret = append(ret, rule)
  238. }
  239. }
  240. d, _ := json.Marshal(ret)
  241. return string(d)
  242. }
  243. 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) {
  244. roomNo = 0
  245. errMsg = "ok"
  246. if roomType != pb.RoomType_Normal {
  247. isPublic = false
  248. }
  249. // 找出有此规则的server
  250. addr, rule := sm.getAServerAddr(gameId, ruleName)
  251. if addr == "" {
  252. errMsg = fmt.Sprintf("server not found [%d:%s]", gameId, ruleName)
  253. log.Release("createRoom failed %s", errMsg)
  254. return
  255. }
  256. if rule == nil {
  257. errMsg = fmt.Sprintf("game rule not found [%d:%s]", gameId, ruleName)
  258. log.Release("createRoom failed %s", errMsg)
  259. return
  260. }
  261. // 检查创建参数是否存在
  262. if !rule.isOptionValid(target, userCount, playTimeout, fee, roomType) {
  263. errMsg = fmt.Sprintf("invalid option parameter [%d:%d:%d]", target, userCount, playTimeout)
  264. log.Release("createRoom failed %s options[%v]", errMsg, rule.Options)
  265. return
  266. }
  267. createFee := prize
  268. if createFee > 0 && !cash.ReduceMoney2(userId, createFee, common.LOGTYPE_PRIVATEROOM_OWNER, "privateroom", "create", "",yyfUid) {
  269. //if createFee > 0 && !cash.ReduceMoney(userId, createFee, common.LOGTYPE_PRIVATEROOM_OWNER, "privateroom", "create", "") {
  270. errMsg = fmt.Sprintf("not enough cash for create room[%d]", createFee)
  271. log.Release("createRoom failed %s", errMsg)
  272. return
  273. }
  274. // 连接服务器
  275. roomNo = game_client.CreatePrivateRoom(addr, game_client.Request_Create{
  276. Creator: userId,
  277. GameRule: rule.Data,
  278. Target: target,
  279. UserCount: userCount,
  280. PlayTimeout: playTimeout,
  281. })
  282. if roomNo == 0 {
  283. errMsg = "sever error,please try agrain"
  284. log.Release("servermgr.createRoom roomNo = 0, gameId = %d,ruleName = %s,userId = %d", gameId, ruleName, userId)
  285. // 加回去
  286. if createFee > 0 {
  287. cash.GiveMoney2(userId, createFee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "create return", "",yyfUid)
  288. //cash.GiveMoney(userId, createFee, common.LOGTYPE_PRIVATEROOM_ENTER, "privateroom", "create return", "")
  289. }
  290. return
  291. }
  292. // 设置房间的userCount,ruleName和fee
  293. getRoomManager().setRoomExtra(roomNo, ruleName, rule.Data, userCount, target,
  294. fee, addr, createFee, rule.isDual(userCount), prize, roomType, isPublic, playTimeout, extraInfo)
  295. return
  296. }
  297. func (sm *servermgr) isGameRuleValid(gameId int, gameRule string, target int, userCount, playTime int) bool {
  298. _, rule := sm.getAServerAddr(gameId, gameRule)
  299. if rule == nil {
  300. log.Release("privateroom.servermgr.isGameRuleValid %d:%s not found", gameId, gameRule)
  301. return false
  302. }
  303. return rule.isOptionValid(target, userCount, playTime, 0, pb.RoomType_SimpleMatch)
  304. }
  305. func (sm *servermgr) registerServerStatus(addr string) {
  306. sm.recvMgr.setReceiver(addr, true)
  307. }