HomeServer/lualib-src/Server-main/AllServer/RankServer/RankServer.lua

178 lines
6.0 KiB
Lua
Raw Normal View History

2024-11-20 15:41:09 +08:00
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