---------------------------------------------------------------- -- 竞技场db ---------------------------------------------------------------- local JjcExcel = require("excel.jjc") local LuaMongo = _G.lua_mongo local Config = require("Config") local DB = require("common.DB") local Util = require("common.Util") local CommonDB = require("common.CommonDB") local ObjHuman = require("core.ObjHuman") local JjcLogic = require("jjc.JjcLogic") local RoleDefine = require("role.RoleDefine") local CombatDefine = require("combat.CombatDefine") local CombatPosLogic = require("combat.CombatPosLogic") local CombatVideo = require("combat.CombatVideo") local CreateRole = require("role.CreateRole") UUID_2_RANK = UUID_2_RANK or {} RANK_2_JJCDATA = RANK_2_JJCDATA or {} ROBOT_LIST = ROBOT_LIST or {} MAX_RECORD_CNT = 5 -- 保留5条对战记录 SEASON_KEEP_DAY = 7 -- 7天一个赛季 ROBOT_LIST_MAXLEN = 100 -- 100个机器人 JJC_INIT_POINT = 1000 -- 竞技场初始分 local QueryByUuid = {_id = nil} function getRank(uuid) local index = UUID_2_RANK[uuid] return index or 0 end function getJjcData(uuid) local rank = UUID_2_RANK[uuid] if not rank then return end return RANK_2_JJCDATA[rank] end function getJjcPoint(uuid) local jjcData = getJjcData(uuid) if not jjcData then return JJC_INIT_POINT end return jjcData.point end function getWorshipCnt(uuid) local jjcData = getJjcData(uuid) if not jjcData then return 0 end return jjcData.worshipCnt end function getJjcTotalFight(uuid) local jjcData = getJjcData(uuid) if not jjcData then return 0 end return jjcData.jjcTotalFight or 0 end function getTotalFightCnt(uuid) local jjcData = getJjcData(uuid) if not jjcData then return 0 end return jjcData.totalFightCnt or 0 end function getJjcSeasonBox(uuid) local jjcData = getJjcData(uuid) if not jjcData then return {} end return jjcData.jjcSeasonBox or {} end function getJjcRival(uuid) local jjcData = getJjcData(uuid) if not jjcData then return {} end return jjcData.rival or {} end function isNpc(jjcData) if jjcData.point and jjcData.monsterOutID then return true end end function getSeasonCnt() local openDay = CommonDB.getServerOpenDay() if openDay == nil then return end return math.ceil(openDay / SEASON_KEEP_DAY) end function getSeasonEndTime() local openDay = CommonDB.getServerOpenDay() local openServerTime = CommonDB.getServerOpenTime() if openDay == nil then return 0 end local championEndTime = CommonDB.getChampionEndTime() local nowTime = os.time() if championEndTime == 0 then local dayStartTime = Util.getDayStartTime(openServerTime) local endTime = dayStartTime + SEASON_KEEP_DAY * 86400 - 10800 CommonDB.setChampionEndTime(endTime) championEndTime = endTime end local startTime = championEndTime - SEASON_KEEP_DAY * 86400 local firstEndTime = SEASON_KEEP_DAY * 86400 + openServerTime - 10800 if openDay <= SEASON_KEEP_DAY and firstEndTime == championEndTime then startTime = openServerTime end return championEndTime,startTime end function setSeasonEndTime() local openDay = CommonDB.getServerOpenDay() local openServerTime = CommonDB.getServerOpenTime() if openDay == nil then return end local championEndTime = CommonDB.getChampionEndTime() if championEndTime == 0 then local nowTime = os.time() local dayStartTime = Util.getDayStartTime(openServerTime) championEndTime = dayStartTime + SEASON_KEEP_DAY * 86400 - 10800 else championEndTime = championEndTime + SEASON_KEEP_DAY * 86400 end CommonDB.setChampionEndTime(championEndTime) end function getGodSeasonEndTime() local openTime = CommonDB.getServerOpenTime() if openTime == 0 then return end local nowTime = os.time() local dayStartTime = Util.getDayStartTime(openTime) local time = math.max(nowTime - dayStartTime, 1) local openDay = math.ceil(time / 86400) local seasonCnt = math.ceil(openDay / SEASON_KEEP_DAY) - 1 local startTime = dayStartTime + seasonCnt * SEASON_KEEP_DAY * 86400 local seasonStartTime = startTime - 3 * 3600 local seasonEndTime = seasonStartTime + SEASON_KEEP_DAY * 86400 if nowTime > seasonEndTime then seasonStartTime = seasonEndTime seasonEndTime = seasonStartTime + SEASON_KEEP_DAY * 86400 end return seasonEndTime, math.max(seasonStartTime, openTime), startTime end function updateJJCData(jjcData) if not jjcData._id then return end QueryByUuid._id = jjcData._id LuaMongo.update(DB.db_jjc, QueryByUuid, jjcData) end function removeJJCData(uuid) if not uuid then return end QueryByUuid._id = uuid LuaMongo.remove(DB.db_jjc, QueryByUuid) end function initJJCDB() RANK_2_JJCDATA = {} UUID_2_RANK = {} ROBOT_LIST = {} resetJJCDB(true) end function isEmpty() LuaMongo.find(DB.db_jjc) local data = {} if not LuaMongo.next(data) then return true end end function resetJJCDB(init) -- 删除假人 留下真人 ROBOT_LIST = {} UUID_2_RANK = {} local count = #RANK_2_JJCDATA local reallyCount = 0 for i = 1, count do local jjcData = RANK_2_JJCDATA[i] RANK_2_JJCDATA[i] = nil if isNpc(jjcData) and init then removeJJCData(jjcData._id) else jjcData.point = math.floor(jjcData.point*7/10) if jjcData.point < JJC_INIT_POINT then jjcData.point = JJC_INIT_POINT end jjcData.recordList = nil jjcData.jjcSeasonBox = {} jjcData.rival = nil jjcData.jjcTotalFight = 0 jjcData.worshipCnt = 0 reallyCount = reallyCount + 1 RANK_2_JJCDATA[reallyCount] = jjcData updateJJCData(jjcData) end end CombatVideo.cleanJJCVideo() -- 插入假人 if init then for _, npcConfig in ipairs(JjcExcel.npc) do for i = 1, npcConfig.cnt do addNpc(npcConfig) end end end sortRank() end function loadJJCData() LuaMongo.find(DB.db_jjc) while true do local data = {} if not LuaMongo.next(data) then break end if data.point then RANK_2_JJCDATA[#RANK_2_JJCDATA + 1] = data else return end end sortRank() for i = 1, #RANK_2_JJCDATA do if #ROBOT_LIST >= ROBOT_LIST_MAXLEN then break end local jjcData = RANK_2_JJCDATA[i] if isNpc(jjcData) then ROBOT_LIST[#ROBOT_LIST + 1] = jjcData end end return true end function initAfterStart() if _G.is_middle == true then return end -- 检查赛季 checkReset() checkSeasonTime() if isEmpty() then initJJCDB() else loadJJCData() end end local function ownCmp(a, b) if a.point ~= b.point then return a.point > b.point end return a.time < b.time end function sortRank() if #RANK_2_JJCDATA > 1 then table.sort(RANK_2_JJCDATA, ownCmp) end for rank = 1, #RANK_2_JJCDATA do local uuid = RANK_2_JJCDATA[rank]._id UUID_2_RANK[uuid] = rank end end function addPlayer(human) local rank = UUID_2_RANK[human.db._id] if rank then return end local jjcData = {} jjcData._id = human.db._id jjcData.point = JJC_INIT_POINT jjcData.recordList = nil jjcData.totalFightCnt = 0 -- 为所有赛季战斗次数总和,超过20次则不再累计,赛季结束不清0 jjcData.time = os.time() LuaMongo.insert(DB.db_jjc, jjcData) RANK_2_JJCDATA[#RANK_2_JJCDATA + 1] = jjcData sortRank() end function addNpc(config) local jjcData = {} local r = math.random(1, #config.monsterOutID) jjcData.monsterOutID = config.monsterOutID[r] jjcData.lv = 20 jjcData.head = CreateRole.getRandomHead() jjcData.name = CreateRole.getRandomName() jjcData.body = CreateRole.getRandomBody() jjcData.identity = CreateRole.getFakeIdentityMax() jjcData.point = config.initPoint jjcData.zhandouli = math.random(config.zhandouli[1], config.zhandouli[2]) jjcData.time = os.time() LuaMongo.insert(DB.db_jjc, jjcData) RANK_2_JJCDATA[#RANK_2_JJCDATA + 1] = jjcData if #ROBOT_LIST < ROBOT_LIST_MAXLEN then ROBOT_LIST[#ROBOT_LIST + 1] = jjcData end end function updatePlayerPoint(uuid, point, nosort) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] if jjcData.point == point then return end jjcData.point = point jjcData.time = os.time() updateJJCData(jjcData) if not nosort then sortRank() end end -- 更新总战斗次数 function updateTotalFight(uuid) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] jjcData.jjcTotalFight = jjcData.jjcTotalFight or 0 jjcData.jjcTotalFight = jjcData.jjcTotalFight + 1 updateJJCData(jjcData) end -- 更新所有赛季总战斗次数 function updateTotalFightCnt(uuid) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] jjcData.totalFightCnt = jjcData.totalFightCnt or 0 if jjcData.totalFightCnt >= 20 then return end jjcData.totalFightCnt = jjcData.totalFightCnt + 1 updateJJCData(jjcData) end -- 更新总膜拜次数 function updateWorshipCnt(uuid) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] jjcData.worshipCnt = jjcData.worshipCnt or 0 jjcData.worshipCnt = jjcData.worshipCnt + 1 updateJJCData(jjcData) end -- 更新赛季盒子信息 function updateSeasonBox(uuid,index) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] if jjcData.jjcSeasonBox and jjcData.jjcSeasonBox[index] ~= nil then return end jjcData.jjcSeasonBox = jjcData.jjcSeasonBox or {} jjcData.jjcSeasonBox[index] = 2 updateJJCData(jjcData) end -- 更新对手 function updateRival(uuid,index,uuid2) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] jjcData.rival = jjcData.rival or {} jjcData.rival[index] = uuid2 updateJJCData(jjcData) end -- 清空对手 function cleanRival(uuid) local rank = UUID_2_RANK[uuid] if not rank then return end local jjcData = RANK_2_JJCDATA[rank] if jjcData.rival and jjcData.rival[index] ~= nil then return end jjcData.rival = nil updateJJCData(jjcData) end local function addRocord(jjcData, videoUuid) if isNpc(jjcData) then return end jjcData.recordList = jjcData.recordList or {} table.insert(jjcData.recordList, 1, videoUuid) local removeUuid = jjcData.recordList[MAX_RECORD_CNT + 1] if removeUuid then jjcData.recordList[MAX_RECORD_CNT + 1] = nil CombatVideo.delJJCVideoCnt(removeUuid) end updateJJCData(jjcData) end local QueryByUuidAtk = {} function addJjcRecord(atkUuid, defUuid, combatInfo) local atkData = getJjcData(atkUuid) local defData = getJjcData(defUuid) if not atkData or not defData then return end local cnt = (not isNpc(atkData)) and 1 or 0 cnt = cnt + ((not isNpc(defData)) and 1 or 0 ) if cnt < 1 then return end local combatVideo = CombatVideo.createCombatVideo(CombatVideo.VIDEOTYPE_JJC, combatInfo, cnt) if not combatVideo then return end addRocord(atkData, combatVideo._id) addRocord(defData, combatVideo._id) end function getJjcRecordList(uuid) local jjcData = getJjcData(uuid) if not jjcData then return end return jjcData.recordList end function checkReset() local endTime = getSeasonEndTime() local now = os.time() if now >= endTime then resetJJCDB() setSeasonEndTime() end end function checkSeasonTime() local endTime = getSeasonEndTime() local openServerTime = CommonDB.getServerOpenTime() if openServerTime == 0 then -- 备服,服务器启动中,但服务器未开放 -- 清除已计算的竞技场时间 CommonDB.setChampionEndTime() return end local now = os.time() local day = Util.diffDayByTimes(openServerTime,now) local trueDay = day + 1 local day2 = trueDay % SEASON_KEEP_DAY local day3 = 0 if day2 ~= 0 then day3 = SEASON_KEEP_DAY - day2 end local dayStartTime = Util.getDayStartTime(now) local trueEndTime = dayStartTime + day3*86400 + 21*60*60 CommonDB.setChampionEndTime(trueEndTime) end function cleanOldVideos() local delTime = os.time() - 3*86400 -- 删除三天前的记录 local field = {["combatInfo.time"]=1} for rank, jjcData in ipairs(RANK_2_JJCDATA) do local recordLen = jjcData.recordList and #jjcData.recordList or 0 local realRecordLen = 0 for i = 1, recordLen do local videoUuid = jjcData.recordList[i] jjcData.recordList[i] = nil local combatVideo = CombatVideo.getCombatVideo(videoUuid, field) if combatVideo and combatVideo.combatInfo.time > delTime then realRecordLen = realRecordLen + 1 jjcData.recordList[realRecordLen] = videoUuid else CombatVideo.removeCombatVideo(videoUuid) end end if recordLen ~= realRecordLen then updateJJCData(jjcData) end end end