474 lines
16 KiB
Lua
474 lines
16 KiB
Lua
|
|
local skynet = require "skynet"
|
||
|
|
local mysql = require "skynet.db.mysql"
|
||
|
|
local oo = require "Class"
|
||
|
|
local cmd = require "GameCmd"
|
||
|
|
local errorInfo = require "ErrorInfo"
|
||
|
|
local pb = require "pb"
|
||
|
|
local log = require "Log"
|
||
|
|
local serverId = tonumber(skynet.getenv "serverId")
|
||
|
|
|
||
|
|
local ClusterServer = oo.class()
|
||
|
|
--中心服简称C 主服简称M 登陆服L 游戏服G
|
||
|
|
|
||
|
|
ClusterServer.centerServerID = 0 --中心服
|
||
|
|
ClusterServer.routerServerMinID = 1 --路由服 1-5
|
||
|
|
ClusterServer.routerServerMaxID = 5 --路由服 1-5
|
||
|
|
ClusterServer.monitorServerID = 6 --监控服和防黑功能
|
||
|
|
ClusterServer.multiServerID = 7 --多功能服
|
||
|
|
ClusterServer.rankServerID = 8 --榜单服
|
||
|
|
ClusterServer.payServerID = 9 --充值服
|
||
|
|
ClusterServer.gameServerMinID = 100 --游戏服开始
|
||
|
|
ClusterServer.gameServerMaxID = 199 --游戏服结束
|
||
|
|
|
||
|
|
--通用消息
|
||
|
|
ClusterServer.All_Start = 1000
|
||
|
|
ClusterServer.All_Reg = 1001 --注册
|
||
|
|
ClusterServer.All_UnReg = 1002 --注销
|
||
|
|
ClusterServer.All_Ping = 1003 --Ping
|
||
|
|
ClusterServer.All_SyncServerInfoToCenter = 1004 --同步服务器信息到中心服
|
||
|
|
ClusterServer.All_ErrorInfo = 1005 --错误信息
|
||
|
|
ClusterServer.All_End = 1999
|
||
|
|
|
||
|
|
--中心服消息
|
||
|
|
ClusterServer.CenterServer_Start = 1100
|
||
|
|
ClusterServer.Center2All_ServerManageCmd = 1101 --发送管理命令
|
||
|
|
ClusterServer.Center2All_SyncClusterInfo = 1102 --同步集群服信息
|
||
|
|
ClusterServer.Center2All_SyncServerConfig = 1103 --同步服务器配置
|
||
|
|
ClusterServer.Center2All_WebMsg = 1104 --后台数据
|
||
|
|
ClusterServer.CenterServer_End = 1199
|
||
|
|
|
||
|
|
--路由服消息
|
||
|
|
ClusterServer.RouteServer_Start = 1200
|
||
|
|
ClusterServer.Route2Monitor_VerifyValid = 1201 --验证该连接是否有效
|
||
|
|
ClusterServer.Route2Game_QueryUserOnline = 1202 --查询用户是否在线
|
||
|
|
ClusterServer.Route2Game_UserLoginToken = 1203 --发送登陆Token
|
||
|
|
ClusterServer.RouteServer_End = 1299
|
||
|
|
|
||
|
|
--监控服消息
|
||
|
|
ClusterServer.MoniterServer_Start = 1300
|
||
|
|
ClusterServer.All2Moniter_AddAccountToBlack = 1301 --添加账号到黑名单
|
||
|
|
ClusterServer.All2Moniter_AddIPToBlack = 1302 --添加IP到黑名单
|
||
|
|
ClusterServer.MoniterServer_End = 1399
|
||
|
|
|
||
|
|
--多功能服消息
|
||
|
|
ClusterServer.MultiServer_Start = 1400
|
||
|
|
ClusterServer.MultiServer_End = 1499
|
||
|
|
|
||
|
|
--榜单服消息
|
||
|
|
ClusterServer.RankServer_Start = 1500
|
||
|
|
ClusterServer.RankServer_End = 1599
|
||
|
|
|
||
|
|
--充值服消息
|
||
|
|
ClusterServer.PayServer_Start = 1600
|
||
|
|
ClusterServer.Pay2Game_AddPayInfo = 1601 --新增充值信息
|
||
|
|
ClusterServer.PayServer_End = 1699
|
||
|
|
|
||
|
|
--游戏服消息
|
||
|
|
ClusterServer.GameServer_Start = 2000
|
||
|
|
---------------------------------------------------------------------------------------------------------------游戏服发往帐号服消息-----------------------------------------
|
||
|
|
ClusterServer.GameToMonitor_UpdateUserStatus = 2001 --修改玩家状态 1-正常玩家 2-白名单 3-灰名单 4-黑名单
|
||
|
|
ClusterServer.GameToMulti_GetRedeemBonus = 2100 --获取兑换码奖励
|
||
|
|
ClusterServer.GameToMulti_GetMailList = 2101 --获取邮件列表
|
||
|
|
ClusterServer.GameToMulti_GetMailBonus = 2102 --获取邮件奖励
|
||
|
|
|
||
|
|
ClusterServer.GameToRank_UpdateScore = 3100 --更新玩家的分数
|
||
|
|
ClusterServer.GameToRank_GetRankData = 3101 --获取排行榜数据
|
||
|
|
|
||
|
|
ClusterServer.GameServer_End = 3999
|
||
|
|
|
||
|
|
ClusterServer.Status_Running = 1 --服务器运行
|
||
|
|
ClusterServer.Status_PingTimeout = 2 --PING超时
|
||
|
|
ClusterServer.Status_Stop = 3 --服务器停止
|
||
|
|
|
||
|
|
function ClusterServer:Init()
|
||
|
|
self.clusterInfo = {} --集群服所有服务器的信息
|
||
|
|
self.serverInfo = {} --当前服务器的信息
|
||
|
|
|
||
|
|
self.platformInfo = {} --平台信息
|
||
|
|
|
||
|
|
self.allServerConfig = {} --所有服务器配置
|
||
|
|
self.curClusterConfig = {} --当前集群配置
|
||
|
|
self.curServerConfig = {} --当前服务器配置
|
||
|
|
|
||
|
|
self.serverName = self:GetServerTypeName( serverId ) --服务器名称
|
||
|
|
self.isConnectCenter = false --是否连接中心服
|
||
|
|
self.lastSendPingTime = skynet.GetTime()
|
||
|
|
self.lastSyncServerInfoTime = skynet.GetTime()
|
||
|
|
self.isConnectCenterServer = false --是否连接中心服务器
|
||
|
|
self.isForceDisconnectCenter =false --是否强制断开中心服务器的连接
|
||
|
|
self.isTodayDeleteLog = false --今日是否删除日志
|
||
|
|
self.isTodayDeleteDB = false --今日是否删除数据库无用的记录
|
||
|
|
end
|
||
|
|
|
||
|
|
--跨天
|
||
|
|
function ClusterServer:OnNewDay()
|
||
|
|
self.isTodayDeleteLog = false
|
||
|
|
self.isTodayDeleteDB = false
|
||
|
|
end
|
||
|
|
|
||
|
|
--1秒Timer
|
||
|
|
function ClusterServer:On1SecTimer()
|
||
|
|
end
|
||
|
|
|
||
|
|
--5秒Timer
|
||
|
|
function ClusterServer:On5SecTimer()
|
||
|
|
function Do()
|
||
|
|
--删除日志文件
|
||
|
|
self:DeleteLogFile()
|
||
|
|
|
||
|
|
if self:IsCenterServer( serverId ) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
--连接断开 或者 未强制断开可以注册
|
||
|
|
if not self.isConnectCenterServer and not self.isForceDisconnectCenter then
|
||
|
|
--注册服务器
|
||
|
|
self:Reg()
|
||
|
|
else
|
||
|
|
|
||
|
|
--向中心服发送ping消息
|
||
|
|
if skynet.GetTime() - self.lastSendPingTime >= self.curClusterConfig.ClusterSlaveSendPingTime then
|
||
|
|
self:Ping()
|
||
|
|
end
|
||
|
|
|
||
|
|
--向中心服同步服务器信息
|
||
|
|
if skynet.GetTime() - self.lastSyncServerInfoTime >= self.curClusterConfig.SyncServerInfoTime then
|
||
|
|
self:SyncServerInfoToCenter()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local isSuc,err = pcall(Do)
|
||
|
|
if not isSuc then
|
||
|
|
self.isConnectCenterServer = false
|
||
|
|
log.info("与上级服务器断开连接,准备重新注册",err)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--接收集群服的消息
|
||
|
|
function ClusterServer:ClusterRecv( ... )
|
||
|
|
local cmd , clusterMsg = ...
|
||
|
|
local s2sData = {}
|
||
|
|
s2sData.code = errorInfo.Suc
|
||
|
|
s2sData.data = {}
|
||
|
|
|
||
|
|
if 0 == serverId and clusterMsg.serverId == serverId then
|
||
|
|
--主服不接收主服发来的消息
|
||
|
|
return s2sData
|
||
|
|
end
|
||
|
|
|
||
|
|
if not cmd or not clusterMsg then
|
||
|
|
s2sData.code = errorInfo.ErrorCode.ErrRequestParam
|
||
|
|
return s2sData
|
||
|
|
end
|
||
|
|
|
||
|
|
local serverName = self:GetServerTypeName( serverId )
|
||
|
|
serverName = serverName:gsub("^%u",string.lower) --将首字母从大写变成小写
|
||
|
|
s2sData = skynet.server[ serverName ]:ClusterRecv(...)
|
||
|
|
s2sData.desc = errorInfo.ErrorMsg[ s2sData.code ] or "暂无消息提示"
|
||
|
|
return s2sData
|
||
|
|
end
|
||
|
|
|
||
|
|
--向主服务器注册
|
||
|
|
function ClusterServer:Reg()
|
||
|
|
local s2sData = {}
|
||
|
|
local cfgCluster = skynet.server.common:GetClusterConfig( serverId )
|
||
|
|
if not cfgCluster then
|
||
|
|
s2sData.code = -1
|
||
|
|
return s2sData
|
||
|
|
end
|
||
|
|
|
||
|
|
local clusterMsg = {}
|
||
|
|
clusterMsg.serverId = serverId
|
||
|
|
clusterMsg.serverName = self.serverName.."_"..serverId
|
||
|
|
|
||
|
|
local clusterName = self:GetServerTypeClusterName( serverId )
|
||
|
|
local s2sData = self:CallMsgToCenterServer( self.All_Reg , clusterMsg)
|
||
|
|
|
||
|
|
if errorInfo.Suc == s2sData.code then
|
||
|
|
self.isConnectCenterServer = true
|
||
|
|
self.isForceDisconnectCenter = false
|
||
|
|
--同步服务器信息到中心服
|
||
|
|
self:SyncServerInfoToCenter()
|
||
|
|
log.info(string.format("集群服务器 %s 向中心服注册成功", clusterName))
|
||
|
|
else
|
||
|
|
log.info(string.format("集群服务器 %s 向中心服注册失败", clusterName))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--向主服务器注销
|
||
|
|
function ClusterServer:UnReg()
|
||
|
|
local s2sData = {}
|
||
|
|
local cfgCluster = skynet.server.common:GetClusterConfig( serverId )
|
||
|
|
if not cfgCluster then
|
||
|
|
s2sData.code = -1
|
||
|
|
return s2sData
|
||
|
|
end
|
||
|
|
|
||
|
|
local clusterMsg = {}
|
||
|
|
clusterMsg.serverId = serverId
|
||
|
|
clusterMsg.serverName = self.serverName.."_"..serverId
|
||
|
|
|
||
|
|
local clusterName = self:GetServerTypeClusterName( serverId )
|
||
|
|
local s2sData = self:CallMsgToCenterServer( self.All_UnReg , clusterMsg)
|
||
|
|
|
||
|
|
if errorInfo.Suc == s2sData.code then
|
||
|
|
self.isConnectCenterServer = false
|
||
|
|
self.isForceDisconnectCenter = true
|
||
|
|
self:SyncServerInfoToCenter()
|
||
|
|
log.info(string.format("集群服务器 %s 向中心服注销成功", clusterName))
|
||
|
|
else
|
||
|
|
log.info(string.format("集群服务器 %s 向中心服注销失败", clusterName))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--向主服务器发心跳包
|
||
|
|
function ClusterServer:Ping()
|
||
|
|
self.lastSendPingTime = skynet.GetTime()
|
||
|
|
|
||
|
|
local clusterMsg = {}
|
||
|
|
clusterMsg.serverId = serverId
|
||
|
|
|
||
|
|
local clusterName = self:GetServerTypeClusterName( serverId )
|
||
|
|
local s2sData,srcServerName,dstServerName = self:CallMsgToCenterServer( self.All_Ping , clusterMsg)
|
||
|
|
|
||
|
|
if errorInfo.Suc ~= s2sData.code then
|
||
|
|
log.info(string.format("集群服务器 %s 向中心服Ping失败", clusterName))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--同步服务器信息
|
||
|
|
function ClusterServer:SyncServerInfoToCenter()
|
||
|
|
self.lastSyncServerInfoTime = skynet.GetTime()
|
||
|
|
|
||
|
|
local c2sData = {}
|
||
|
|
c2sData.serverId = serverId
|
||
|
|
c2sData.serverInfo = self.serverInfo
|
||
|
|
self:SendMsgToCenterServer( self.All_SyncServerInfoToCenter , c2sData)
|
||
|
|
end
|
||
|
|
|
||
|
|
--错误信息发送到中心服
|
||
|
|
function ClusterServer:SendErrorInfoToCenter( errorCode , errorText )
|
||
|
|
local c2sData = {}
|
||
|
|
c2sData.serverId = serverId
|
||
|
|
c2sData.errorCode = errorCode
|
||
|
|
c2sData.errorText = errorText
|
||
|
|
self:SendMsgToCenterServer( self.All_ErrorInfo , c2sData)
|
||
|
|
end
|
||
|
|
|
||
|
|
function ClusterServer:GetServerName()
|
||
|
|
return self.serverName
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为中心服务器
|
||
|
|
function ClusterServer:IsCenterServer( serverId )
|
||
|
|
if self.centerServerID == tonumber(serverId) then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为路由服务器
|
||
|
|
function ClusterServer:IsRouteServer( serverId )
|
||
|
|
if tonumber(serverId) >= self.routerServerMinID and tonumber(serverId) <= self.routerServerMaxID then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为监视服务器
|
||
|
|
function ClusterServer:IsMonitorServer( serverId )
|
||
|
|
if self.monitorServerID == tonumber(serverId) then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为多功能服务器
|
||
|
|
function ClusterServer:IsMultiServer( serverId )
|
||
|
|
if self.multiServerID == tonumber(serverId) then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为排行榜服务器
|
||
|
|
function ClusterServer:IsRankServer( serverId )
|
||
|
|
if self.rankServerID == tonumber(serverId) then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为多功能服务器
|
||
|
|
function ClusterServer:IsPayServer( serverId )
|
||
|
|
if self.payServerID == tonumber(serverId) then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--是否为游戏服务器
|
||
|
|
function ClusterServer:IsGameServer( serverId )
|
||
|
|
if tonumber(serverId) >= self.gameServerMinID and tonumber(serverId) <= self.gameServerMaxID then
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--根据服务器ID获取类型名称
|
||
|
|
function ClusterServer:GetServerTypeName( serverId )
|
||
|
|
serverId = tonumber(serverId)
|
||
|
|
|
||
|
|
for k, v in pairs(skynet.server.gameConfig.ClusterServerConfig) do
|
||
|
|
if serverId == v.serverId then
|
||
|
|
return v.serverName
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
log.info("获取集群配置出错",serverId )
|
||
|
|
return ""
|
||
|
|
end
|
||
|
|
|
||
|
|
--根据服务器ID获取类型集群名称
|
||
|
|
function ClusterServer:GetServerTypeClusterName( serverId )
|
||
|
|
local serverName = self:GetServerTypeName(serverId)
|
||
|
|
return serverName.."_"..serverId
|
||
|
|
end
|
||
|
|
|
||
|
|
--接收同步集群信息
|
||
|
|
function ClusterServer:RecvSyncClusterInfo( c2sData )
|
||
|
|
--这类接收操作必须要按下面方式赋值,否则基类的地址会改变,导致基类无法调用
|
||
|
|
self.clusterInfo = {}
|
||
|
|
for k, v in pairs( c2sData.clusterInfo ) do
|
||
|
|
self.clusterInfo[ k ] = v
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--接收同步服务器配置
|
||
|
|
function ClusterServer:RecvSyncServerConfig( c2sData )
|
||
|
|
--这类接收操作必须要按下面方式赋值,否则基类的地址会改变,导致基类无法调用
|
||
|
|
for k, v in pairs( c2sData.allServerConfig[ "ClusterServer" ] ) do
|
||
|
|
self.curClusterConfig[ k ] = v
|
||
|
|
end
|
||
|
|
|
||
|
|
--这类接收操作必须要按下面方式赋值,否则基类的地址会改变,导致基类无法调用
|
||
|
|
if c2sData.allServerConfig[ skynet.ServerName ] then
|
||
|
|
for k, v in pairs( c2sData.allServerConfig[ skynet.ServerName ] ) do
|
||
|
|
self.curServerConfig[ k ] = v
|
||
|
|
end
|
||
|
|
end
|
||
|
|
log.info("接收同步服务器配置")
|
||
|
|
end
|
||
|
|
|
||
|
|
--重新注册最新的节点
|
||
|
|
function ClusterServer:ReloadClusterNode()
|
||
|
|
skynet.server.gameConfig:LoadConfig()
|
||
|
|
skynet.server.gameConfig:LoadJson()
|
||
|
|
log.info("成功载入集群信息 ")
|
||
|
|
|
||
|
|
local clusterList = {}
|
||
|
|
local serverName = ""
|
||
|
|
for k, v in pairs(skynet.server.gameConfig.ClusterServerConfig) do
|
||
|
|
serverName = self:GetServerTypeClusterName( v.serverId )
|
||
|
|
clusterList[ serverName ] = string.format("%s:%s",v.internalIp ,v.clusterPort)
|
||
|
|
end
|
||
|
|
skynet.server.cluster.reload(clusterList)
|
||
|
|
log.info("成功载入集群信息 ",skynet.server.common:TableToString(clusterList))
|
||
|
|
end
|
||
|
|
|
||
|
|
--根据登陆和游戏服的ID获取网关服务器ID
|
||
|
|
function ClusterServer:GetGameServerID( serverId )
|
||
|
|
serverId = tonumber(serverId)
|
||
|
|
local gameServerId = nil
|
||
|
|
if serverId >= self.loginServerMinID and serverId <= self.loginServerMaxID then
|
||
|
|
gameServerId = math.floor((serverId % 100) / 2)
|
||
|
|
gameServerId = gameServerId + self.gameServerMinID
|
||
|
|
elseif serverId >= self.gameServerMinID and serverId <= self.gameServerMaxID then
|
||
|
|
gameServerId = math.floor((serverId % 100) / 10)
|
||
|
|
gameServerId = gameServerId + self.gameServerMinID
|
||
|
|
end
|
||
|
|
return gameServerId
|
||
|
|
end
|
||
|
|
|
||
|
|
--发向中心服
|
||
|
|
function ClusterServer:SendMsgToCenterServer( cmd , msg )
|
||
|
|
local centerName = "CenterServer_0"
|
||
|
|
skynet.server.cluster.send(centerName,"@"..centerName, "ClusterMsg", cmd , msg or {} )
|
||
|
|
end
|
||
|
|
|
||
|
|
--调用中心服
|
||
|
|
function ClusterServer:CallMsgToCenterServer( cmd , msg )
|
||
|
|
local centerName = "CenterServer_0"
|
||
|
|
return skynet.server.cluster.call(centerName,"@"..centerName, "ClusterMsg", cmd , msg or {})
|
||
|
|
end
|
||
|
|
|
||
|
|
--发向指定服务器
|
||
|
|
function ClusterServer:SendMsgToServer( serverId , cmd , msg )
|
||
|
|
if self.clusterInfo[ serverId ] then
|
||
|
|
local serverName = self:GetServerTypeClusterName( serverId )
|
||
|
|
skynet.server.cluster.send(serverName,"@"..serverName, "ClusterMsg", cmd , msg or {})
|
||
|
|
return true
|
||
|
|
else
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--调用指定服务器
|
||
|
|
function ClusterServer:CallMsgToServer( serverId , cmd , msg )
|
||
|
|
local isDo,s2cData = false,nil
|
||
|
|
function Do( serverId , cmd , msg )
|
||
|
|
local serverName = self:GetServerTypeClusterName( serverId )
|
||
|
|
return skynet.server.cluster.call(serverName,"@"..serverName, "ClusterMsg", cmd , msg or {} )
|
||
|
|
end
|
||
|
|
|
||
|
|
if self.clusterInfo[ serverId ] then
|
||
|
|
isDo,s2cData = pcall( Do , serverId , cmd , msg )
|
||
|
|
if isDo then
|
||
|
|
return s2cData
|
||
|
|
else
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
else
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--删除过期日志文件
|
||
|
|
function ClusterServer:DeleteLogFile()
|
||
|
|
function Do()
|
||
|
|
local nowTime = skynet.GetTime()
|
||
|
|
--凌晨3点删除3天前的日志
|
||
|
|
if 3 == os.date("*t", nowTime).hour and not self.isTodayDeleteLog then
|
||
|
|
self.isTodayDeleteLog = true
|
||
|
|
log.info("开始删除文件夹")
|
||
|
|
local nowTime = skynet.GetTime()
|
||
|
|
local delTime=os.time({year=os.date("*t", nowTime).year, month=os.date("*t", nowTime).month, day=os.date("*t", nowTime).day - self.curClusterConfig.DeleteLogDayNum})
|
||
|
|
local path = string.format("rm -rf log/Server_%d/%d-%d-%d-%d",serverId,serverId,os.date("*t", delTime).year ,os.date("*t", delTime).month,os.date("*t", delTime).day)
|
||
|
|
os.execute(path)
|
||
|
|
log.info("删除文件"..path)
|
||
|
|
log.info("结束删除文件夹")
|
||
|
|
end
|
||
|
|
|
||
|
|
--主服才执行
|
||
|
|
if 4 == os.date("*t", nowTime).hour and not self.isTodayDeleteDB then
|
||
|
|
self.isTodayDeleteDB = true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local isSuc,err = pcall(Do)
|
||
|
|
if not isSuc then
|
||
|
|
log.info("删除过期文件内部错误 DeleteLogFile",err)
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
skynet.server.clusterServer= ClusterServer
|
||
|
|
return ClusterServer
|