--------------------------------
-- 文件名       ：  MiddleCommonRank.lua
-- 文件说明     ：  跨服相关-跨服排行榜
-- 创建时间     :   2025/04/02
-- 创建人       :   FC
--------------------------------

local Msg = require("core.Msg")
local Timer = require("core.Timer")
local DB = require("common.DB")
local CommonDB = require("common.CommonDB")
local CommonDefine = require("common.CommonDefine")
local Log = require("common.Log")
local LuaMongo = _G.lua_mongo
local Util = require("common.Util")
local Grid = require("bag.Grid")
local MiddleConnect = require("middle.MiddleConnect")
local InnerMsg = require("core.InnerMsg")
local MiddleManager = require("middle.MiddleManager")
local ServerCommerceRankConf = require("excel.ServerCommerce").CommerceRank

-- 缓存的排行榜数据
local MIDDLE_COMMON_RANK = {
--[[
    [nRankType] = 
    {
        [nRankSubType] = 
        {
            [nServerKey] = {
                nRankType = xx,
                nRankSubType = xx,
                nServerKey = xx,
                -- 根据UUID获取名次   
                uuid2rank = {               
                    [uuid] = rank,          -- 玩家uuid = 排行名次
                },

                -- 根据UUID获取发送名次
                sendUuid2rank = {           
                    [uuid] = rank,          -- 玩家uuid = 真实发送的排行名次
                },

                -- 根据名次获取DATA (DB存储的数据相同)
                rank2data = {   
                     [nRank] = {
                        uuid,           -- 玩家UID
                        name,           -- 玩家name
                        head,           -- 玩家头像
                        headFrame,      -- 玩家头像框
                        nSrcServerID,   -- 玩家所属服务器
                        nValue,         -- 玩家排行值
                        nTime,          -- 更新时间
                    }            
                }
            }
        }
    }
]]

}

-- 缓存已经要处理的战区个人邮件
local MIDDLE_SENDSERVER_MAIL = 
{
}

-- 上榜的最小条件
local MIDDLE_COMMON_MIN_RANK = nil

-- 对应排名需要上榜条件
local MIDDLE_RANK_NEED_VALUES = nil

-- 通过 排行榜类型，排行榜子类型，所属战区服务器key(WarZone中的nMinServerID)，uuid查找DB数据
MiddleRankQueryForData = {nRankType = 1, nRankSubType = 1, nServerKey = 1 ,uuid = 1}

-- 通过排行榜类型，排行榜子类型，所属战区服务器key(WarZone中的nMinServerID),DB的uuid更新DB数据
MiddleRankQueryByUuid = {nRankType = 1, nRankSubType = 1, nServerKey = 1, _id = 1}             

-- 通过排行榜类型，排行榜子类型，所属战区服务器key(WarZone中的nMinServerID)
MiddleRankQueryByRankType = {nRankType = 1, nRankSubType = 1, nServerKey = 1}  

-- 获取配置
local function MiddleCommonRank_GetConfByType(nRankType)
    if CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE == nRankType then
        return ServerCommerceRankConf
    end

    return nil
end

-- 设置处理的战区个人邮件
local function MiddleCommonRank_SetSendHumanMail(nServerKey, nValue)
    MIDDLE_SENDSERVER_MAIL[nServerKey] = nValue
end

-- 获取处理的战区个人邮件
local function MiddleCommonRank_GetSendHumanMail(nServerKey)
    if not MIDDLE_SENDSERVER_MAIL[nServerKey] then
        MIDDLE_SENDSERVER_MAIL[nServerKey] = 0
    end

    return MIDDLE_SENDSERVER_MAIL[nServerKey]
end

local function MiddleCommonRank_GetMinValue(nRankType, nRankSubType)
    local tRankConf = MiddleCommonRank_GetConfByType(nRankType)
    if not tRankConf then
        -- print("[MiddleCommonRank_GetMinValue] 获取不到配置 nRankType = "..nRankType.." nRankSubType = "..nRankSubType)
        return nil
    end

    -- print("[MiddleCommonRank_GetMinValue] nRankType = "..nRankType.." nRankSubType = "..nRankSubType)
    local nMinRankValue
    if CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE == nRankType then
        for _, v in pairs(tRankConf) do
            if v.nRankType == nRankSubType then
                if not nMinRankValue then
                    nMinRankValue = v.nPoint
                else
                    nMinRankValue = math.min(v.nPoint, nMinRankValue)
                end
                -- print("[MiddleCommonRank_GetMinValue] v.nPoint = "..v.nPoint.." nMinRankValue = "..nMinRankValue)
            end
        end
    end

    if nMinRankValue then
        -- print("[MiddleCommonRank_GetMinValue] nMinRankValue = "..nMinRankValue)
    end
    return nMinRankValue
end

-- 获取最小上榜条件
local function MiddleCommonRank_GetMinRankValue(nRankType, nRankSubType)
    if MIDDLE_COMMON_MIN_RANK and MIDDLE_COMMON_MIN_RANK[nRankType] and MIDDLE_COMMON_MIN_RANK[nRankType][nRankSubType] then
        -- print("[MiddleCommonRank_GetMinRankValue] 存在缓存直接返回")
        return MIDDLE_COMMON_MIN_RANK[nRankType][nRankSubType]
    end

    local nMinValue = MiddleCommonRank_GetMinValue(nRankType, nRankSubType)
    if nil == nMinValue then
        -- print("[MiddleCommonRank_GetMinRankValue] 根据配置获取不到最小上榜条件值")
        return nil
    end

    -- print("[MiddleCommonRank_GetMinRankValue] 获取到的 nMinValue = "..nMinValue)
    if not MIDDLE_COMMON_MIN_RANK then
        MIDDLE_COMMON_MIN_RANK = {}
    end

    if not MIDDLE_COMMON_MIN_RANK[nRankType] then
        MIDDLE_COMMON_MIN_RANK[nRankType] = {}
    end

    MIDDLE_COMMON_MIN_RANK[nRankType][nRankSubType] = nMinValue

    return nMinValue
end

-- 获取最大排行榜长度
local function MiddleCommonRank_GetMaxRankLen()
    return CommonDefine.COMMONRANK_SAVE_DB_LEN
end

-- 获取对应名次上榜所需要求值
local function MiddleCommonRank_GetRankNeedValue(nRankType, nRankSubType, nRank)
	MIDDLE_RANK_NEED_VALUES = MIDDLE_RANK_NEED_VALUES or {}

	local minRankValue = MiddleCommonRank_GetMinRankValue(nRankType, nRankSubType)
    if nil == minRankValue then
    --    print("[MiddleCommonRank_GetRankNeedValue] 获取最小上排行榜值失败 nRankType = "..nRankType.." nRankSubType = "..nRankSubType) 
       return
    end

    -- print("[MiddleCommonRank_GetRankNeedValue] 获取到的最小上榜值 minRankValue = "..minRankValue.." nRank = "..nRank)

	if MIDDLE_RANK_NEED_VALUES[nRankType] and MIDDLE_RANK_NEED_VALUES[nRankType][nRankSubType] then 
		local nValue = nil
        for _, tData in ipairs(MIDDLE_RANK_NEED_VALUES[nRankType][nRankSubType]) do
            if tData.nMinRank <= nRank and tData.nMaxRank >= nRank then
                nValue = tData.nValue
                break
            end
        end

        if nValue then
            print("[MiddleCommonRank_GetRankNeedValue] 获取到的最小上榜值 minRankValue = "..minRankValue.." nValue = "..nValue)
        end
        return nValue or minRankValue
	end

    local tRankConfig = MiddleCommonRank_GetConfByType(nRankType)
    if not tRankConfig then
        print("[MiddleCommonRank_GetRankNeedValue] 获取不到对应的配置")
        return minRankValue
    end

    if not MIDDLE_RANK_NEED_VALUES[nRankType] then
        MIDDLE_RANK_NEED_VALUES[nRankType] = {}
    end

    if not MIDDLE_RANK_NEED_VALUES[nRankType][nRankSubType] then
        MIDDLE_RANK_NEED_VALUES[nRankType][nRankSubType] = {}
    end

    local nValue = nil
    for _, v in pairs(tRankConfig) do
        if v.nRankType == nRankSubType then
            local nMinRank = v.nOrder[1]
            local nMaxRank = v.nOrder[2]
            table.insert(MIDDLE_RANK_NEED_VALUES[nRankType][nRankSubType], {nMinRank = nMinRank, nMaxRank = nMaxRank, nValue = v.nPoint})
    
            if not nValue then
                nValue = v.nPoint
            else
                if nMinRank <= nRank and nMaxRank >= nRank then
                    nValue = v.nPoint
                end
            end
        end
    end
 
    if nValue then
        print("[MiddleCommonRank_GetRankNeedValue] 获取到的最小上榜值 minRankValue = "..minRankValue.." nValue = "..nValue)
    else
        print("[MiddleCommonRank_GetRankNeedValue] 获取不到对应排名所需的值 nRank = "..nRank)
    end
	return nValue or minRankValue
end

-- 获取指定排名类型缓存数据
local function MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not MIDDLE_COMMON_RANK or not MIDDLE_COMMON_RANK[nRankType] or 
        not MIDDLE_COMMON_RANK[nRankType][nRankSubType] or not MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey] then
        return nil
    end


    return MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey]
end

-- -- 获取指定排名类型、指定用户的排名
local function MiddleCommonRank_GetRankDataByUid(nRankType, nRankSubType, nServerKey, uuid)
    local tRankCacheData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not tRankCacheData then
        return
    end

    return tRankCacheData.uuid2rank[uuid]
end

-- 获取指定排名类型、指定用户的发送排名
local function MiddleCommonRank_GetSendRank(nRankType, nRankSubType, nServerKey, uuid)
    local tRankCacheData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not tRankCacheData then
        return
    end

    return tRankCacheData.sendUuid2rank[uuid]
end

-- 排序
local function MiddleCommonRank_CmpRank(data1, data2)
    if data1.nValue ~= data2.nValue then
        return data1.nValue > data2.nValue
    end

    return data1.nTime < data2.nTime
end

-- 更新排名
local function MiddleCommonRank_UpdateRank(tRankData)
    if not tRankData then
        return
    end

    -- 清空普通排名和发送排名玩家数据
    for uuid in pairs(tRankData.uuid2rank) do
        tRankData.uuid2rank[uuid] = nil
        tRankData.sendUuid2rank[uuid] = nil
    end

    -- 设置普通排名
    for rank, data in ipairs(tRankData.rank2data) do
		tRankData.uuid2rank[data.uuid] = rank
	end

    -- 清空发送排名
    for rank in ipairs(tRankData.sendRank2data) do
        tRankData.sendRank2data[rank] = nil
    end

    local minRankValue = MiddleCommonRank_GetMinRankValue(tRankData.nRankType, tRankData.nRankSubType)                -- 排名最小需要的排名值
    local aleadyRankCnt = 0                                             -- 已经排好的玩家数
    local maxRank = MiddleCommonRank_GetMaxRankLen()  -- 最多排名玩家数量
    for rank = 1, maxRank do
        -- 取当前排名需要的排名值
        local rankNeedValue = MiddleCommonRank_GetRankNeedValue(tRankData.nRankType, tRankData.nRankSubType, rank)
        if rankNeedValue then
            -- print("[MiddleCommonRank_UpdateRank] rankNeedValue = "..rankNeedValue)
        end


        local rank2data = tRankData.rank2data[aleadyRankCnt + 1]        -- 当前排的玩家
        if rank2data then                                               -- 还有玩家需要排
            if rank2data.nValue >= rankNeedValue then                    -- 达到排名值,可以排名
    		    tRankData.sendUuid2rank[rank2data.uuid] = rank              -- 设置玩家发送排名
    		    tRankData.sendRank2data[rank] = rank2data                   -- 设置发送排名数据
    		    aleadyRankCnt = aleadyRankCnt + 1                       -- 排名玩家数量+1
                -- if "table" == type(rank2data) then
                --     Log.write(Log.LOGID_OSS_COMMON_ACT, "当前的排名情况 rank = "..rank.." nRankType = "..rank2data.nRankType.." nRankSubType = "..rank2data.nRankSubType.." name = "..rank2data.name)
                -- end
            elseif rankNeedValue <= minRankValue then                   -- 未达到排名值 且 当前排名值 小于等于 最小需要的排名值了,则后面的玩家都不需要排了
                    break
            else                                                       -- 未到达最低排名值,当前名次未有玩家达到
                tRankData.sendRank2data[rank] = -1
            end
        else                                                            -- 没玩家排了直接停止
            break
        end
    end
end

-- 更新数据
local function MiddleCommonRank_UpdateData(nRankType, nRankSubType, nServerKey, data)
    local tRankData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not tRankData then
        return
    end

    local uuid = data.uuid
    local oldRank = MiddleCommonRank_GetRankDataByUid(nRankType, nRankSubType, nServerKey, uuid) or (#tRankData.rank2data + 1)
    tRankData.rank2data[oldRank] = data

    -- 向后比较(data.value 减少时),往排名低方向->
    for i = oldRank + 1, #tRankData.rank2data do
        local data1 = tRankData.rank2data[i - 1]
        local data2 = tRankData.rank2data[i]
        if MiddleCommonRank_CmpRank(data1, data2) then
            break
        end
        tRankData.rank2data[i - 1] = data2
        tRankData.rank2data[i] = data1
    end

    -- 向前比较(data.value 增加时),往排名高方向<-
    for i = oldRank - 1, 1, -1 do
        local data1 = tRankData.rank2data[i]
        local data2 = tRankData.rank2data[i + 1]
        if MiddleCommonRank_CmpRank(data1, data2) then
            break
        end
        tRankData.rank2data[i] = data2
        tRankData.rank2data[i + 1] = data1
    end  

    local maxRank = MiddleCommonRank_GetMaxRankLen()
    tRankData.rank2data[maxRank + 1] = nil
    return true
end

-- 起服将数据插入排行榜
local function MiddleCommonRank_InsertCacheData(data)
    local tRankData = MiddleCommonRank_GetRankDataByType(data.nRankType, data.nRankSubType, data.nServerKey)
    if not tRankData then
        print("[MiddleCommonRank_InsertCacheData] 不存在对应的排行榜数据")
        return
    end

    table.insert(tRankData.rank2data, data)
end

-- 对整个排行榜进行排序
local function MiddleCommonRank_SortAllRank(nRankType, nRankSubType, nServerKey)
    local tRankData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not tRankData then
        print("[MiddleCommonRank_SortAllRank] 不存在对应的排行榜数据")
        return false
    end

    table.sort(tRankData.rank2data, MiddleCommonRank_CmpRank)

    local maxRank = MiddleCommonRank_GetMaxRankLen()
    local nNowLen = #tRankData.rank2data

    -- 大于了排行榜最大缓存数据
    if maxRank < nNowLen then
        for i = maxRank + 1, nNowLen, 1 do
            tRankData.rank2data[i] = nil
        end
    end

    return true
end

-- 重置排行数据
local function MiddleCommonRank_ResertCacheData(nRankType, nRankSubType, nServerKey)
    if not MIDDLE_COMMON_RANK[nRankType] then
        MIDDLE_COMMON_RANK[nRankType] = {}
    end

    if not MIDDLE_COMMON_RANK[nRankType][nRankSubType] then
        MIDDLE_COMMON_RANK[nRankType][nRankSubType] = {}
    end

    if not MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey] then
        MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey]  = {}
    end

    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].nRankType = nRankType
    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].nRankSubType = nRankSubType
    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].nServerKey = nServerKey

    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].uuid2rank = {}        -- 根据UUID获取名次   
    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].sendUuid2rank = {}    -- 根据UUID获取发送名次   
    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].rank2data = {}        -- 根据名次获取DATA
    MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey].sendRank2data = {}    -- 根据名次获取发送DATA
end

-- 初始排行榜
local function MiddleCommonRank_InitCacheData(nRankType, nRankSubType)
   if not MIDDLE_COMMON_RANK[nRankType] then
        MIDDLE_COMMON_RANK[nRankType] = {}
   end

   if not MIDDLE_COMMON_RANK[nRankType][nRankSubType] then
        MIDDLE_COMMON_RANK[nRankType][nRankSubType] = {}
   end
end

-- 加载排行榜
local function MiddleCommonRank_LoadDBData()
    local cnt = 0
    LuaMongo.find(DB.db_middle_rank, nil)
    local tNeedSortRank = {}
    while true do
        local data = {}
        if not LuaMongo.next(data) then
            break
        end

        cnt = cnt + 1
        if cnt % 1000 == 0 then
            _G.collectgarbage("step", 100000)
        end
        
        if not tNeedSortRank[data.nRankType] then
            tNeedSortRank[data.nRankType] = {}
        end

        if not tNeedSortRank[data.nRankType][data.nRankSubType] then
            tNeedSortRank[data.nRankType][data.nRankSubType] = {}
        end

        if not tNeedSortRank[data.nRankType][data.nRankSubType][data.nServerKey] then
            tNeedSortRank[data.nRankType][data.nRankSubType][data.nServerKey] = 1
            MiddleCommonRank_ResertCacheData(data.nRankType, data.nRankSubType, data.nServerKey)
        end
        -- print("[MiddleCommonRank_LoadDBData] 获取到数据")
        -- table.print_lua_table(data)
        -- 先插入数据, 后排序
        MiddleCommonRank_InsertCacheData(data)
    end

    for nRankType, v1 in pairs(tNeedSortRank) do
        for nRankSubType, v2 in pairs(v1) do
            for nServerKey, _ in pairs(v2) do
                local bRet = MiddleCommonRank_SortAllRank(nRankType, nRankSubType, nServerKey)
                if true == bRet then
                    -- print("[MiddleCommonRank_LoadDBData] 排序成功 nRankType = "..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
                else
                    -- print("[MiddleCommonRank_LoadDBData] 排序失败 nRankType = "..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
                end
            end
        end
    end

    for nRankType, v1 in pairs(MIDDLE_COMMON_RANK) do
        for nRankSubType, v2 in pairs(v1) do
            for nServerKey, tData in pairs(v2) do
                MiddleCommonRank_UpdateRank(tData)
            end
        end
    end
end

-- 根据类型+uuid从db中取data
local function MiddleCommonRank_GetDBDataByUid(nRankType, nRankSubType, nServerKey, uuid)
    -- MiddleRankQueryForData = {nRankType = 1, nRankSubType = 1, nServerKey = 1 ,uuid = 1}
    MiddleRankQueryForData.nRankType = nRankType
    MiddleRankQueryForData.nRankSubType = nRankSubType
    MiddleRankQueryForData.nServerKey = nServerKey
    MiddleRankQueryForData.uuid = uuid

    local data = {}
    LuaMongo.find(DB.db_middle_rank, MiddleRankQueryForData)
    return LuaMongo.next(data) and data
end

-- 更新DB数据
local function MiddleCommonRank_UpdateDBData(data)
    local oldData = MiddleCommonRank_GetDBDataByUid(data.nRankType, data.nRankSubType, data.nServerKey, data.uuid)
    if oldData then
        MiddleRankQueryForData.nRankType = data.nRankType
        MiddleRankQueryForData.nRankSubType = data.nRankSubType
        MiddleRankQueryForData.nServerKey = data.nServerKey
        MiddleRankQueryForData.uuid = data.uuid
        LuaMongo.update(DB.db_middle_rank, MiddleRankQueryForData, data)
        print("[MiddleCommonRank_UpdateDBData] 存在久数据进行更新")
    else
        LuaMongo.insert(DB.db_middle_rank, data)
        print("[MiddleCommonRank_UpdateDBData] 不存在久数据直接进行插入")
    end
end

-- 设置排名数据
local function MiddleCommonRank_SetRankInfo(data)
    local tRankData = MiddleCommonRank_GetRankDataByType(data.nRankType, data.nRankSubType, data.nServerKey)
    if not tRankData then
        print("[MiddleCommonRank_SetRankInfo] 获取不到缓存的排行数据")
        return
    end

    MiddleCommonRank_UpdateData(data.nRankType, data.nRankSubType, data.nServerKey, data)
    MiddleCommonRank_UpdateRank(tRankData)
    MiddleCommonRank_UpdateDBData(data)
end

-- 检查缓存
local function MiddleCommonRank_CheckHaveCache(nRankType, nRankSubType, nServerKey)
    if not MIDDLE_COMMON_RANK[nRankType] then
        MiddleCommonRank_ResertCacheData(nRankType, nRankSubType, nServerKey)
        print("[MiddleCommonRank_CheckHaveCache] 检查缓存 不存在对应 nRankType 缓存,重新创建 nRankType = "
                    ..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
        return
    end

    if not MIDDLE_COMMON_RANK[nRankType][nRankSubType] then
        MiddleCommonRank_ResertCacheData(nRankType, nRankSubType, nServerKey)
        print("[MiddleCommonRank_CheckHaveCache] 检查缓存 不存在对应 nRankSubType 缓存,重新创建 nRankType = "
                    ..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
        return
    end

    if not MIDDLE_COMMON_RANK[nRankType][nRankSubType][nServerKey] then
        MiddleCommonRank_ResertCacheData(nRankType, nRankSubType, nServerKey)
        print("[MiddleCommonRank_CheckHaveCache] 检查缓存 不存在对应 nServerKey 缓存,重新创建 nRankType = "
                    ..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
        return
    end
end

-------------------------------------------------- 外部调用 -----------------------------------------
-- 启动就初始化
function MiddleCommonRank_InitAfterStart()
    -- 不是中心服不用处理
    if _G.is_middle ~= true then
        return
    end

   -- 先初始化一下
    MiddleCommonRank_InitCacheData(CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE, CommonDefine.COMMONRANK_SUB_TYPE_SERVERCOMMERCE_SERVER)
    MiddleCommonRank_InitCacheData(CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE, CommonDefine.COMMONRANK_SUB_TYPE_SERVERCOMMERCE_HUMAN)

    -- 加载DB数据
    print("[MiddleCommonRank_InitAfterStart] 开始加载DB数据")
    MiddleCommonRank_LoadDBData()
end

-- 获取到跨服数据
function MiddleCommonRank_ReceiveRankData(tMsgData)
    if _G.is_middle ~= true then
        return
    end

    local nConfServerID = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(tMsgData.nSrcServerID)
    local nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nConfServerID)
    local tDBData = MiddleCommonRank_GetDBDataByUid(tMsgData.nRankType, tMsgData.nRankSubType, nServerKey, tMsgData.uuid)
    if not tDBData then
        tDBData = {}
    end

    -- 检查缓存, 主要是 nConfServerID 这个对应的排行数据可能需要建立
    MiddleCommonRank_CheckHaveCache(tMsgData.nRankType, tMsgData.nRankSubType, nServerKey)

    tDBData.uuid = tMsgData.uuid
    tDBData.name = tMsgData.name
    tDBData.head = tMsgData.head
    tDBData.headFrame = tMsgData.headFrame
    tDBData.nSrcServerID = tMsgData.nSrcServerID
    tDBData.nRankType = tMsgData.nRankType
    tDBData.nRankSubType = tMsgData.nRankSubType
    tDBData.nServerKey = nServerKey
    tDBData.servername = tMsgData.servername

    -- 已经存在数据的用之前上榜的时间
    tDBData.nTime = tDBData.nTime or os.time()

    -- 排行的value值需要判断
    tDBData.nValue = tDBData.nValue or 0

    -- print("[MiddleCommonRank_ReceiveRankData] 获取到数据 name = "..tDBData.name.." nDBValue = "..tDBData.nValue.." nValue = "..tMsgData.nValue)
    local nMinValue = MiddleCommonRank_GetMinValue(tMsgData.nRankType, tMsgData.nRankSubType)
    if not nMinValue then
        print("[MiddleCommonRank_ReceiveRankData] 获取不到对应的最小上榜条件")
        return
    end

    local bUpRank = false
    if CommonDefine.COMMONRANK_VALUE_REPLACE == tMsgData.nOperate then
        -- 直接替换，对应nValue在普通服有存储，发上来都是最终的值，不满足条件可以不存
        tDBData.nValue = tMsgData.nValue
        if tDBData.nValue >= nMinValue then
            bUpRank = true
        end
    elseif CommonDefine.COMMONRANK_VALUE_ADD == tMsgData.nOperate then
        -- 直接增加的操作需要存库
        tDBData.nValue = tDBData.nValue + tMsgData.nValue
        bUpRank = true
    end

    if true == bUpRank then
        MiddleCommonRank_SetRankInfo(tDBData)
        print("[MiddleCommonRank_ReceiveRankData] 玩家上榜进行成功")
    end
end

function MiddleCommonRank_QueryRankInfo(tMsgData)
    if _G.is_middle ~= true then
        return
    end

    local nRankType = tMsgData.nRankType
    local nRankSubType = tMsgData.nRankSubType
    local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(tMsgData.nSrcServerID)
    nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)
    local nSrcFD = MiddleManager.getFDBySvrIndex(tMsgData.nSrcServerID)
    if not nSrcFD then
        print("[MiddleCommonRank_QueryRankInfo] 获取不到对应的 服务器的 fd nSrcServerID = "..tMsgData.nSrcServerID)
        return
    end

    -- 检查缓存, 主要是 nServerKey 这个对应的排行数据可能需要建立
    MiddleCommonRank_CheckHaveCache(tMsgData.nRankType, tMsgData.nRankSubType, nServerKey)

    local tSendMsgData = InnerMsg.wl.WL_COMMERCE_QUERY_RANK_INFO
    tSendMsgData.nRankType = nRankType
    tSendMsgData.nRankSubType = nRankSubType
    tSendMsgData.nServerKey = nServerKey
    tSendMsgData.nBegin = 1
    tSendMsgData.nEnd = 0
    tSendMsgData.tRankData = {}
    tSendMsgData.tRankData[0] = 0

    local tRankCacheData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if not tRankCacheData or nil == _G.next(tRankCacheData) then
        tSendMsgData.nEnd = 1
    else
        for nRank, v in pairs(tRankCacheData.sendRank2data) do
            tSendMsgData.tRankData[0] = tSendMsgData.tRankData[0] + 1
            tSendMsgData.tRankData[tSendMsgData.tRankData[0]] = {
                nRank = nRank,
                tRankData = v,
            }

            if tSendMsgData.tRankData[0] >= CommonDefine.COMMONRANK_ONE_SEND_LEN then
                InnerMsg.sendMsg(nSrcFD, tSendMsgData)
                tSendMsgData.tRankData[0] = 0
                tSendMsgData.nBegin = 0
            end
        end

        tSendMsgData.nEnd = 1
    end
    InnerMsg.sendMsg(nSrcFD, tSendMsgData)
    print("[MiddleCommonRank_QueryRankInfo] 向普通服发送排行榜数据完成")
end

-- 请求服务器排行榜对应服务器排名
function MiddleCommonRank_QueryServerRank(msg)
    local nSrcFD = MiddleManager.getFDBySvrIndex(msg.nSrcServerID)
    if not nSrcFD then
        print("[MiddleCommonRank_QueryServerRank] 获取不到对应的 服务器的 fd nSrcServerID = "..msg.nSrcServerID)
        return
    end

    -- print("[MiddleCommonRank_QueryServerRank] 请求服务器排行榜对应服务器排名 nOperate = "..msg.nOperate.." nServerUuid = "..msg.nServerUuid)
    local tMsgData = InnerMsg.wl.WL_COMMERCE_GET_SERVERRANK_PRIZE
    tMsgData.nOperate = msg.nOperate

    local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(msg.nSrcServerID)
    nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)

    -- print("[MiddleCommonRank_QueryServerRank] 请求服务器排行榜对应服务器排名 nServerKey = "..nServerKey)

    local tRankCacheData = MiddleCommonRank_GetRankDataByType(CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE,
                            CommonDefine.COMMONRANK_SUB_TYPE_SERVERCOMMERCE_SERVER, nServerKey)
    local nNowRank = -1
    if not tRankCacheData then
        print("[MiddleCommonRank_QueryServerRank] 不存在缓存数据")
        nNowRank = MiddleCommonRank_GetMaxRankLen() + 1
    else
        -- print("[MiddleCommonRank_QueryServerRank] 存在缓存数据")
        for nRank, v in pairs(tRankCacheData.sendRank2data) do
            -- print("[MiddleCommonRank_QueryServerRank] nRank = "..nRank)
            if "table"== type(v) then
                -- print("[MiddleCommonRank_QueryServerRank] nRank = "..nRank.." uuid = "..v.uuid.." type1 = "..type(v.uuid).." type2 = "..type(msg.nServerUuid))
            end

            if "table"== type(v) and v.uuid == msg.nServerUuid then
                -- print("[MiddleCommonRank_QueryServerRank] nRank = "..nRank.." uuid = "..v.uuid.." nServerUuid = "..msg.nServerUuid)
                nNowRank = nRank
                break
            end
        end
    end

    if -1 >= nNowRank then
        nNowRank = MiddleCommonRank_GetMaxRankLen() + 1
    end

    tMsgData.nRank = nNowRank

    -- print("[MiddleCommonRank_QueryServerRank] 获取到rank = "..nNowRank.." nSrcServerID = "..msg.nSrcServerID.." nServerKey = "..nServerKey)

    InnerMsg.sendMsg(nSrcFD, tMsgData)
end

-- 延迟发送个人奖励
function MiddleCommonRank_SendHumanRankPrize(nRankType, nRankSubType, nServerKey)
    -- print("[MiddleCommonRank_SendHumanRankPrize] 开始处理对应的个人排行榜奖励 nRankType = "..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
    Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_SendHumanRankPrize] 开始处理对应的个人排行榜奖励 nRankType = "..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
    
    local tRankData = MiddleCommonRank_GetRankDataByType(nRankType, nRankSubType, nServerKey)
    if tRankData then
        local tMsgData = InnerMsg.wl.WL_COMMERCE_SEND_HUMAN_PRIZE
        for nRank, v in ipairs(tRankData.sendRank2data) do
            if v and type(v) == "table" then
                tMsgData.nRank = nRank
                tMsgData.uuid = v.uuid
                local nSrcFD = MiddleManager.getFDBySvrIndex(v.nSrcServerID)
                if nSrcFD then
                    -- print("[MiddleCommonRank_SendHumanRankPrize] nRank = "..nRank.." uuid = "..v.uuid.." nSrcServerID = "..v.nSrcServerID)
                    Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_SendHumanRankPrize] nRank = "..nRank.." uuid = "..v.uuid.." nSrcServerID = "..v.nSrcServerID)
                    InnerMsg.sendMsg(nSrcFD, tMsgData)
                else
                    -- print("[MiddleCommonRank_SendHumanRankPrize] 获取不到对应服务器的FD nSrcServerID = "..v.nSrcServerID)
                    Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_SendHumanRankPrize]  获取不到对应服务器的FD nSrcServerID = "..v.nSrcServerID)
                end
            end
        end
    else
        print("[MiddleCommonRank_SendHumanRankPrize] 不存在对应的个人排行榜数据 nRankType = "..nRankType.." nRankSubType = "..nRankSubType.." nServerKey = "..nServerKey)
    end

    print("[MiddleCommonRank_SendHumanRankPrize] 开始处理对应的个人排行榜奖励完成")

    Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_SendHumanRankPrize] 处理对应的个人排行榜奖励完成")
end

-- 服务器发送全服邮件结束
function MiddleCommonRank_ServerMailOk(msg)
    -- 先获取对应配置ID，再获取最小的ID
    local nConfServerID = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(msg.nSrcServerID)
    local nServerKey, nMaxServerID = MiddleConnect.MiddleConnect_GetWarZoneServer(nConfServerID)

    Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_ServerMailOk] 处理全服邮件结束 nSrcServerID = "..msg.nSrcServerID)
    if 0 == MiddleCommonRank_GetSendHumanMail(nServerKey) then
        MiddleCommonRank_SetSendHumanMail(nServerKey, 1)
        -- print("[MiddleCommonRank_ServerMailOk] 直接发送个人邮件奖励开始 nServerKey = "..nServerKey)
        Log.write(Log.LOGID_OSS_COMMON_ACT, "[MiddleCommonRank_ServerMailOk] 发送个人邮件奖励开始 nSrcServerID = "..msg.nSrcServerID)
        -- 延迟处理对应个人排行榜奖励
        MiddleCommonRank_SendHumanRankPrize(CommonDefine.COMMONRANK_TYPE_SERVERCOMMERCE, CommonDefine.COMMONRANK_SUB_TYPE_SERVERCOMMERCE_HUMAN, nServerKey)
    end
end

function MiddleCommonRank_ClearRank(msg)
    local nConfServerID = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(msg.nSrcServerID)
    local nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nConfServerID)

    MiddleCommonRank_ResertCacheData(msg.nRankType, msg.nRankSubType, nServerKey)
    -- print("[MiddleCommonRank_ClearRank] 清理排行榜开始 nRankType = "..msg.nRankType.." nRankSubType = "..msg.nRankSubType.." nServerKey = "..nServerKey)
    MiddleRankQueryByRankType.nRankType = msg.nRankType
    MiddleRankQueryByRankType.nRankSubType = msg.nRankSubType
    MiddleRankQueryByRankType.nServerKey = nServerKey

    MiddleCommonRank_SetSendHumanMail(nServerKey, 0)
    LuaMongo.find(DB.db_middle_rank, MiddleRankQueryByRankType)
    local tData = {}
    if not LuaMongo.next(tData) then
        print("[MiddleCommonRank_ClearRank] 不存在对应的数据")
        return
    end

    LuaMongo.remove(DB.db_middle_rank, MiddleRankQueryByRankType)
    -- print("[MiddleCommonRank_ClearRank] 清理排行榜数据完成")
end

function MiddleCommonRank_GMClearMail(msg)
    local nConfServerID = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(msg.nSrcServerID)
    local nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nConfServerID)

    MiddleCommonRank_SetSendHumanMail(nServerKey, 0)
    -- print("[MiddleCommonRank_GMClearMail] GM清理命令结束 nNowValue = "..MIDDLE_SENDSERVER_MAIL[nServerKey])
end