HomeServer/lualib-src/Server-main/AllServer/RankServer/RankServer.lua
2024-11-20 15:41:37 +08:00

178 lines
6.0 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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