178 lines
6.0 KiB
Lua
178 lines
6.0 KiB
Lua
local skynet = require "skynet"
|
||
local oo = require "Class"
|
||
local gameCmd = require "GameCmd"
|
||
local json =require "json"
|
||
local log = require "Log"
|
||
local sqlUrl = require "SqlUrl"
|
||
local defense = require "Defense"
|
||
local playerFields = require "PlayerFields"
|
||
local errorInfo = require "ErrorInfo"
|
||
local serverId = tonumber(skynet.getenv "serverId")
|
||
local redisKeyUrl = require "RedisKeyUrl"
|
||
local clusterServer = require "ClusterServer"
|
||
local RankServer = oo.class(clusterServer)
|
||
|
||
--初始化
|
||
RankServer.SaveDataToDBHour = 3 --凌晨3点保存数据到DB
|
||
RankServer.PerSaveUserCount = 100 --每次保存用户数量
|
||
|
||
RankServer.RankType_Personal = 1 --个人排行榜
|
||
RankServer.RankType_Prestige = 2 --国家排行榜(家国情怀)
|
||
RankServer.RankType_Country = 3 --声望排行榜(广招贤士)
|
||
|
||
RankServer.CountryType_Start = 0
|
||
RankServer.CountryType_Wei = 1 --魏
|
||
RankServer.CountryType_Shu = 2 --蜀
|
||
RankServer.CountryType_Wu = 3 --吴
|
||
RankServer.CountryType_Wu = 4 --汉
|
||
RankServer.CountryType_Wu = 5 --群
|
||
RankServer.CountryType_End = 6
|
||
|
||
RankServer.MaxScoreCount = 5 --最大分数数量
|
||
function RankServer:Init()
|
||
self:GetAllRankData( nil , {})
|
||
end
|
||
|
||
--跨天
|
||
function RankServer:OnNewDay()
|
||
if not self:IsRankServer( serverId ) then
|
||
return
|
||
end
|
||
end
|
||
|
||
--1秒Timer
|
||
function RankServer:On1SecTimer()
|
||
if not self:IsRankServer( serverId ) then
|
||
return
|
||
end
|
||
end
|
||
|
||
--5秒Timer
|
||
function RankServer:On5SecTimer()
|
||
if not self:IsRankServer( serverId ) then
|
||
return
|
||
end
|
||
|
||
local time = os.date("*t", skynet.GetTime())
|
||
|
||
if self.SaveDataToDBHour == time.hour then
|
||
--指定时间到了就写数据库
|
||
self:SaveDataToDB()
|
||
end
|
||
|
||
end
|
||
|
||
--接收集群数据
|
||
function RankServer:ClusterRecv(...)
|
||
local cmd , c2sData = ...
|
||
local s2cData = {}
|
||
s2cData.code = errorInfo.Suc
|
||
|
||
if self.Center2All_ServerManageCmd == cmd then
|
||
elseif self.GateToRank_UpdateScore == cmd then
|
||
self:UpdateScore( c2sData , s2cData )
|
||
elseif self.GateToRank_GetAllRankData == cmd then
|
||
self:GetAllRankData( c2sData , s2cData )
|
||
elseif self.GateToRank_GetUserRankData == cmd then
|
||
self:GetUserRankData( c2sData , s2cData )
|
||
else
|
||
log.info(string.format("集群服务器 消息接口 %d 不存在", cmd))
|
||
s2cData.code = 2
|
||
end
|
||
|
||
log.info("集群服务器 消息接口", cmd , "返回信息",s2cData.code)
|
||
return s2cData
|
||
end
|
||
|
||
--更新分数
|
||
function RankServer:UpdateScore( c2sData , s2cData )
|
||
local userId = c2sData.userId
|
||
local score = c2sData.score
|
||
local countryType = c2sData.countryType
|
||
|
||
--更新一些玩家排行榜需要的基本信息
|
||
skynet.server.redis:hset( redisKeyUrl.RankUserInfo , userId , json:encode( c2sData ))
|
||
|
||
--同步玩家数据到Redis
|
||
skynet.server.redis:zincrby( redisKeyUrl.PersonalRankKey , score , userId )
|
||
skynet.server.redis:zincrby( redisKeyUrl.CountryRankKey..countryType , score , userId )
|
||
skynet.server.redis:zincrby( redisKeyUrl.PrestigeRankKey , score , userId )
|
||
|
||
skynet.server.redis:sadd( redisKeyUrl.RankUpdateUser , userId )
|
||
end
|
||
|
||
--获取所有排行榜数据
|
||
function RankServer:GetAllRankData( c2sData , s2cData )
|
||
s2cData.personalRank = skynet.server.redis:zrevrange( redisKeyUrl.PersonalRankKey , 0 , self.MaxScoreCount - 1 )
|
||
s2cData.prestigeRank = skynet.server.redis:zrevrange( redisKeyUrl.PrestigeRankKey , 0 , self.MaxScoreCount - 1 )
|
||
|
||
for i = self.CountryType_Start + 1, self.CountryType_End - 1, 1 do
|
||
s2cData[ "countryRank"..i ] = skynet.server.redis:zrevrange( redisKeyUrl.CountryRankKey..i , 0 , self.MaxScoreCount - 1 )
|
||
end
|
||
end
|
||
|
||
--获取用户排行榜数据
|
||
function RankServer:GetUserRankData( c2sData , s2cData )
|
||
local userId = c2sData.userId
|
||
end
|
||
|
||
--保存数据落地
|
||
function RankServer:SaveDataToDB()
|
||
local userCount = skynet.server.redis:scard( redisKeyUrl.RankUpdateUser )
|
||
if userCount < self.PerSaveUserCount then
|
||
--小于指定数量就不保存数据库
|
||
return
|
||
end
|
||
|
||
local score = 0
|
||
local userCount = 0
|
||
local sqlPersonal = ""
|
||
local sqlPrestige = ""
|
||
local sqlCountry = ""
|
||
local t = skynet.GetTime()
|
||
local allUser = skynet.server.redis:smembers( redisKeyUrl.RankUpdateUser )
|
||
|
||
for k, v in pairs(allUser) do
|
||
score = skynet.server.redis:zscore( redisKeyUrl.PersonalRankKey , v)
|
||
sqlPersonal = sqlPersonal .. string.format(sqlUrl.updateScoreToPersonalRank , v , score , score ) .. ";"
|
||
score = skynet.server.redis:zscore( redisKeyUrl.PrestigeRankKey , v)
|
||
sqlPrestige = sqlPrestige .. string.format(sqlUrl.updateScoreToPrestigeRank , v , score , score ) .. ";"
|
||
score = skynet.server.redis:zscore( redisKeyUrl.CountryRankKey..1 , v)
|
||
|
||
for i = self.CountryType_Start + 1, self.CountryType_End - 1, 1 do
|
||
score = skynet.server.redis:zscore( redisKeyUrl.CountryRankKey..i , v)
|
||
if score then
|
||
sqlCountry = sqlCountry .. string.format(sqlUrl.updateScoreToCountryRank, v , i , score , score ) .. ";"
|
||
end
|
||
end
|
||
|
||
userCount = userCount + 1
|
||
skynet.server.redis:srem(redisKeyUrl.RankUpdateUser , v)
|
||
--有1000条数据就写一次数据库
|
||
if userCount >= self.PerSaveUserCount then
|
||
break
|
||
end
|
||
end
|
||
|
||
--有数据时才写数据库
|
||
if userCount > 0 then
|
||
sqlPersonal = string.sub(sqlPersonal , 1,-2 ) --去掉最后一个逗号
|
||
sqlPrestige = string.sub(sqlPrestige , 1,-2 ) --去掉最后一个逗号
|
||
sqlCountry = string.sub(sqlCountry , 1,-2 ) --去掉最后一个逗号
|
||
|
||
skynet.server.db:Query(sqlPersonal)
|
||
skynet.server.db:Query(sqlPrestige)
|
||
skynet.server.db:Query(sqlCountry)
|
||
--清除保存的玩家
|
||
end
|
||
|
||
--os.execute("sleep 1")
|
||
end
|
||
|
||
--如果是当前服务器ID,那么就加入进来
|
||
if serverId == clusterServer.rankServerID then
|
||
skynet.server.rankServer = RankServer
|
||
end
|
||
|
||
return RankServer
|