local skynet = require "skynet" local harbor = require "skynet.harbor" local json = require("shared.json") local redisproxy = require("shared.redisproxy") require "shared.init" require "utils.init" require "RedisKeys" require "skynet.manager" require "GlobalVar" local ipairs = ipairs local table_insert = table.insert local tarr2tab = table.array2Table local string_format = string.format local CHECK_MAIL_STATUS_INTERVAL = 100 * 60 local CHECK_BATTLE_ACT_CLOSE_INTERVAL = 100 * 1 local function mailQuene() local delayEmail = tonum(redisproxy:hget("autoincrement_set", "delay_email")) if delayEmail == 0 then return end local begin = math.max(delayEmail - 100, 1) local mails = redisproxy:pipelining(function (red) for id = begin, delayEmail do red:hgetall(string.format("delayEmail:%s", id)) end end) if not mails then return end local now = skynet.timex() local mailList = {} for index, data in ipairs(mails) do if next(data) then local email = tarr2tab(data) if tonum(email.startTime) <= now then table_insert(mailList, email) if #mailList > 100 then break end end end end if #mailList == 0 then return end redisproxy:pipelining(function (red) for _, email in ipairs(mailList) do red:del(string_format("delayEmail:%s", email.id)) end end) table.sort(mailList, function(a, b) return tonum(a.id) < tonum(b.id) end) for _, email in ipairs(mailList) do local gid = redisproxy:hincrby("autoincrement_set", "email", 1) if email.mid then redisproxy:hmset(string_format("globalEmail:%s", gid), "id", gid, "createtime", email.startTime, "title", email.title, "stitle", email.stitle, "content", email.content, "attachments", email.attachments, "endtime", email.endTime, "mid", email.mid, "timestamp", now, "delayType", email.delayType ) else redisproxy:hmset(string_format("globalEmail:%s", gid), "id", gid, "createtime", email.startTime, "title", email.title, "stitle", email.stitle, "content", email.content, "attachments", email.attachments, "endtime", email.endTime, "timestamp", now, "delayType", email.delayType ) end end redisproxy:hset("autoincrement_set", "emailTimestamp", now) end -- @desc: 定时邮件队列检测 local function check_mail_queue() pcall(mailQuene) skynet.timeout(CHECK_MAIL_STATUS_INTERVAL, check_mail_queue) end -- @desc: 检测关卡活动结束 排行榜奖励发放 local lastCheckBattleActTs = 0 local function check_battle_act_close() local csvdb = require "shared.csvdata" local act = require "models.Activity" local st = 0 local et = 0 local actId = 0 local timeNow = skynet.timex() for k, v in pairs(csvdb["activity_ctrlCsv"]) do if v.showType == act.ActivityType.ChallengeLevel then local openTimes = v.time:toArray(false, "=") if openTimes[1] ~= "0" then st = toUnixtime(openTimes[1]..string_format("%02x", RESET_TIME)) end if openTimes[2] ~= "0" then et = toUnixtime(openTimes[2]..string_format("%02x", RESET_TIME)) end actId = k break end end if st ~= 0 and et ~= 0 and actId ~= 0 then -- close if lastCheckBattleActTs < et and timeNow >= et then -- check rank key exist local rankKey = RANK_COMMON..RANK_TYPE.ActBattleBoss local flag = redisproxy:exists(rankKey) if flag then local actData = csvdb["activity_groupCsv"][actId] local lastRank = actData[#actData].rank local ids = redisproxy:zrevrange(rankKey, 0 , lastRank - 1) local rankIndex = 0 for roleId in pairs(ids) do rankIndex = rankIndex + 1 for _, cfg in pairs(actData) do if rankIndex <= cfg.rank then redisproxy:insertEmail({ roleId = roleId, emailId = cfg.email_1, attachments = cfg.reward_1, contentPms = {rankIndex}, }) break end end end redisproxy:del(rankKey..":bak") redisproxy:rename(rankKey, rankKey..":bak") end end end lastCheckBattleActTs = skynet.timex() skynet.timeout(CHECK_BATTLE_ACT_CLOSE_INTERVAL, check_battle_act_close) end -- @desc: 检查海港贸易开启、关闭 local function check_trade_seaport_status() local nowTime = skynet.timex() local nextTime = dayLater(nowTime) local interval = 100 * (nextTime - nowTime + 1) local curTm = os.date("*t", nowTime) if curTm.wday == 7 and curTm.hour >= 4 then -- 周六 local oldTime = tonumber(redisproxy:hget("autoincrement_set", "seaportTime0")) or 0 local cur4Time = specTime({hour = 4},nowTime) if cur4Time ~= oldTime then redisproxy:hset("autoincrement_set", "seaportTime0", cur4Time) redisproxy:hset("autoincrement_set", "seaportTime1", 1) redisproxy:del(SEAPORT_TRADE_TASK_1) redisproxy:del(SEAPORT_TRADE_TASK_2) end end if curTm.wday == 1 and curTm.hour >= 4 then -- 周日 if (tonumber(redisproxy:hget("autoincrement_set", "seaportTime1")) or 0) == 1 then redisproxy:hset("autoincrement_set", "seaportTime2", 1) end end if curTm.wday == 2 and curTm.hour >= 4 then -- 周一 -- redisproxy:hset("autoincrement_set", "seaportTime0", 0) redisproxy:hset("autoincrement_set", "seaportTime1", 0) redisproxy:hset("autoincrement_set", "seaportTime2", 0) end skynet.timeout(interval, check_trade_seaport_status) end -- @desc: 海港贸易捐赠作弊 local seaportTimes = {} local function check_trade_seaport_donate() local time1 = tonumber(redisproxy:hget("autoincrement_set", "seaportTime1")) or 0 local time2 = tonumber(redisproxy:hget("autoincrement_set", "seaportTime2")) or 0 if time1 == 0 and time2 == 0 then seaportTimes = {} skynet.timeout(360000, check_trade_seaport_donate) return end local csvdb = require "shared.csvdata" local donateCsv = csvdb["seaport_purchaseCsv"] local times = {time1, time2} for phase, open in ipairs(times) do if open == 1 and not seaportTimes[phase] then seaportTimes[phase] = {} for _, _ in ipairs(donateCsv[phase]) do table.insert(seaportTimes[phase],math.randomInt(1800, 3600)) end end end local interval = 3600 local phase, id = 0, 0 for key1, data in ipairs(seaportTimes) do for key2, temp in pairs(data) do if times[key1] == 1 and temp < interval then interval = temp phase = key1 id = key2 end end end for _, data in ipairs(seaportTimes) do for id, temp in pairs(data) do data[id] = temp - interval if data[id] == 0 then data[id] = math.randomInt(1800, 3600) end end end if phase ~= 0 and id ~= 0 then local redisKeys = {SEAPORT_TRADE_TASK_1,SEAPORT_TRADE_TASK_2} local all = donateCsv[phase][id].need_num local old = tonumber(redisproxy:hget(redisKeys[phase],id)) or 0 local add = math.min(math.randomInt(math.floor(all/20),math.floor(all/12)),all - old) if add > 0 then redisproxy:hincrby(redisKeys[phase],id,add) else seaportTimes[phase][id] = nil end end skynet.timeout(interval * 100, check_trade_seaport_donate) end local function check_work_battle() local csvdb = require "shared.csvdata" local now = skynet.timex() local day = weekday(now) local workMainCsv = csvdb["work_mainCsv"][day] if workMainCsv and isSpecTime(now - RESET_TIME * 3600, csvdb["time_resetCsv"][TimeReset["WorkBattle1"]].start / 3600, 24) then local round = math.floor((now - START_RESET_TIME) / 604800) local field = round * 10 + day local count = tonum(redisproxy:hget(WORK_BATTLE_COUNT, field)) if count < workMainCsv.target_num then local add = math.floor(workMainCsv.target_num * math.randomInt(3125, 5000) / 100000) redisproxy:hincrby(WORK_BATTLE_COUNT, field, add) end end skynet.timeout(math.randomInt(10 * 60, 15 * 60) * 100, check_work_battle) end local CMD = {} -- 服务器缓存50条消息 local cacheWorldMsg = {} local CACHE_WORLD_MSG_COUNT = 50 function CMD.sendWorldMsg(channel, msg) cacheWorldMsg[channel] = cacheWorldMsg[channel] or {} table.insert(cacheWorldMsg[channel], msg) for i = #cacheWorldMsg[channel] - CACHE_WORLD_MSG_COUNT, 1, -1 do table.remove(cacheWorldMsg[channel], i) end end function CMD.getWorldMsg(channel) local msgs = cacheWorldMsg[channel] or {} return msgs end function CMD.start() math.randomInit(skynet.timex()) check_mail_queue() --check_battle_act_close() check_trade_seaport_status() check_trade_seaport_donate() check_work_battle() end local function __init__() skynet.dispatch("lua", function(_, _, command, ...) local f = CMD[command] if f then if command == "sendWorldMsg" then skynet.ignoreret() f(...) else skynet.ret(skynet.pack(f(...))) end end end) skynet.register(".globald") end skynet.start(__init__)