diff --git a/src/ProtocolCode.lua b/src/ProtocolCode.lua index a90171b..2479ac4 100644 --- a/src/ProtocolCode.lua +++ b/src/ProtocolCode.lua @@ -5,8 +5,6 @@ actionCodes = { Sys_innerErrorMsg = 4, Sys_commonNotice = 5, Sys_maintainNotice = 6, - Sys_kickdown = 7, - Sys_runningHorse = 8, Gm_clientRequest = 20, Gm_receiveResponse = 21, @@ -162,6 +160,12 @@ actionCodes = { Pvp_endBattleHRpc = 511, Pvp_highDivisionGiftRpc = 512, Pvp_shopBuyRpc = 513, + Pvp_crossInfoRpc = 514, + Pvp_crossRoleInfoRpc = 515, + Pvp_crossRoleInfoDetailRpc = 516, + Pvp_crossMatchRecordRpc = 517, + Pvp_crossBetInfoRpc = 518, + Pvp_crossBetRpc = 519, Store_rechargeRpc = 550, diff --git a/src/actions/HttpAction.lua b/src/actions/HttpAction.lua index 9941434..f2910ed 100644 --- a/src/actions/HttpAction.lua +++ b/src/actions/HttpAction.lua @@ -189,7 +189,6 @@ function _M.broadcast(query) ["maintain"] = actionCodes.Sys_maintainNotice, } if not codes[query.cmd] then return "错误" end - mcast_util.pub_world(codes[query.cmd], bin) return "广播成功" end diff --git a/src/actions/PvpAction.lua b/src/actions/PvpAction.lua index bcf261f..76c4e54 100644 --- a/src/actions/PvpAction.lua +++ b/src/actions/PvpAction.lua @@ -97,6 +97,7 @@ function _M.formatHighRpc(agent , data) end role:savePvpHTeam(pvpTH) + role:changeCrossServerPvpSelfInfo("format") SendPacket(actionCodes.Pvp_formatHighRpc, '') return true end @@ -615,6 +616,7 @@ function _M.endBattleHRpc(agent, data) -- 加入战斗记录 local selfTeam = {} local enemyTeam = {} + for _idx, info in ipairs(_pvpStartBattleCacheH.result) do info.winId = info.isWin and roleId or match.id info.isWin = nil @@ -623,7 +625,10 @@ function _M.endBattleHRpc(agent, data) battleV = role:getTeamBattleValue(_pvpStartBattleCacheH.pvpTH[_idx].heros) } if match.t == 1 and _pvpStartBattleCacheH.enemyT then - enemyTeam[_idx] = _pvpStartBattleCacheH.enemyT[_idx] + enemyTeam[_idx] = { + heros = _pvpStartBattleCacheH.enemyT["heros"][_idx], + battleV = _pvpStartBattleCacheH.enemyT["battleV"][_idx] + } end end local recordBattle = { @@ -864,4 +869,98 @@ function _M.shopBuyRpc(agent, data) return true end + +----------------------------跨服竞技场---------------------------------- + +function _M.crossInfoRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return end + + local result = role:getCrossServerPvpMatchInfo() + if not result then return end + + SendPacket(actionCodes.Pvp_crossInfoRpc, MsgPack.pack(result)) + return true +end + +function _M.crossRoleInfoRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return end + + local result = role:getCrossServerPvpRoleInfo() + if not result then return end + + SendPacket(actionCodes.Pvp_crossRoleInfoRpc, MsgPack.pack({roleInfo = result})) + return true +end + + +function _M.crossRoleInfoDetailRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return end + local msg = MsgPack.unpack(data) + if not msg.ids or not next(msg.ids) then return end + + local result = role:getCrossServerPvpRoleInfoDeatil(msg.ids) + if not result then return end + + SendPacket(actionCodes.Pvp_crossRoleInfoDetailRpc, MsgPack.pack(result)) + return true +end + + +function _M.crossMatchRecordRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return 1 end + local msg = MsgPack.unpack(data) + if not msg.round then return 2 end + if not msg.matchIdx then return 3 end + + local result = role:getCrossServerPvpMatchRecord(msg.round, msg.matchIdx) + if not result then return 4 end + + SendPacket(actionCodes.Pvp_crossMatchRecordRpc, MsgPack.pack(result)) + return true +end + +function _M.crossBetInfoRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return end + + local result = role:getCrossServerPvpBetInfo() + if not result then return end + + + SendPacket(actionCodes.Pvp_crossBetInfoRpc, MsgPack.pack(result)) + return true +end + +function _M.crossBetRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + + if not role:isTimeResetOpen(TimeReset.PvpCross) then return end + if msg.idx ~= 1 and msg.idx ~= 2 then return end + + local result = role:getCrossServerPvpBet(msg.idx) + if not result then return end + + SendPacket(actionCodes.Pvp_crossBetRpc, MsgPack.pack(result)) + return true +end + + + + return _M \ No newline at end of file diff --git a/src/actions/RoleAction.lua b/src/actions/RoleAction.lua index 39a8832..a95034e 100644 --- a/src/actions/RoleAction.lua +++ b/src/actions/RoleAction.lua @@ -54,11 +54,11 @@ local _M = {} function _M.loginRpc( agent, data ) local msg = MsgPack.unpack(data) local response = {} - -- if msg.version ~= globalCsv.version then - -- response.result = "UPDATE_TIP" - -- SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) - -- return true - -- end + if msg.codeVersion ~= globalCsv.codeVersion then + response.result = "UPDATE_TIP" + SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) + return true + end -- 1. local roleId = redisproxy:get(string_format("user:%s", string.upper(msg.name))) @@ -345,6 +345,8 @@ function _M.changeNameRpc(agent, data) role:updateProperties({ ["name"] = newName, }) + + role:changeCrossServerPvpSelfInfo("name") SendPacket(actionCodes.Role_changeNameRpc, MsgPack.pack({result = 0})) return true end @@ -938,6 +940,7 @@ function _M.changeHeadRpc(agent, data) return end role:updateProperty({field = "headId" ,value = id}) + role:changeCrossServerPvpSelfInfo("headId") SendPacket(actionCodes.Role_changeHeadRpc, "") return true end diff --git a/src/adv/Adv.lua b/src/adv/Adv.lua index 6043a4d..f98ff8f 100644 --- a/src/adv/Adv.lua +++ b/src/adv/Adv.lua @@ -1563,11 +1563,12 @@ function Adv:mapItemChange(ctype) for blockId, block in pairs(room.blocks) do if block:getEventType() == AdvEventType.Drop and block.event.item then local id = block.event.item[1] + local count = block.event.item[2] local changeTo = nil if clist[id] then - changeTo = {clist[id].toId, clist[id].num} + changeTo = {clist[id].toId, math.ceil(count * clist[id].num)} elseif clist[-1] then - changeTo = {clist[-1].toId, clist[-1].num} + changeTo = {clist[-1].toId, math.ceil(count * clist[-1].num)} end if changeTo and changeTo[1] ~= 0 and changeTo[2] ~= 0 then block.event.item = changeTo diff --git a/src/agent.lua b/src/agent.lua index b4ea7c9..2b34a8a 100644 --- a/src/agent.lua +++ b/src/agent.lua @@ -308,6 +308,7 @@ skynet.start(function() cs = queue() csvdb = sharedata.query("csvdata") + pvpd = skynet.localname(".PVPCROSS") -- 错误码特殊处理 -- todo -- for key, value in pairs(csvdb["sys_codesCsv"]) do diff --git a/src/config b/src/config index e3566c0..16c2670 100644 --- a/src/config +++ b/src/config @@ -8,6 +8,7 @@ logd = 0 -- 是否开启日志 servId = 1 baseId = 0 codeurl = "120.26.43.151:9090" +cluster = "./src/nodenames.lua" lua_path = root .."skynet/lualib/?.lua;"..root.."src/?.lua;"..root.."tools/?.lua" luaservice = root.."skynet/service/?.lua;"..root.."src/?.lua" diff --git a/src/models/Pvpd.lua b/src/models/Pvpd.lua new file mode 100644 index 0000000..8bc95f1 --- /dev/null +++ b/src/models/Pvpd.lua @@ -0,0 +1,14 @@ +-- pvpd 需要的内容 +local Pvpd = class("Pvpd", require("shared.ModelBase")) + +function Pvpd:ctor( properties ) + Pvpd.super.ctor(self, properties) +end + + +Pvpd.schema = { + betInfo = {"table", {}}, -- 押注的场次信息 {[round] = matchIdx} + betNum = {"table", {}}, -- 押注[1]的人数 +} + +return Pvpd \ No newline at end of file diff --git a/src/models/Role.lua b/src/models/Role.lua index f7f6640..a81669b 100644 --- a/src/models/Role.lua +++ b/src/models/Role.lua @@ -40,6 +40,7 @@ Role.schema = { device = {"string", ""}, banTime = {"number", 0}, banType = {"number", 0}, + heartWarning = {"number", 0}, ltime = {"number", 0}, -- 最后登录时间 ctime = {"number", skynet.timex()}, -- 创建时间 ignoreMt = {"number", 0}, -- 忽略维护拦截 @@ -113,7 +114,7 @@ Role.schema = { pvpHGift = {"table", {}}, -- pvp 高级段位每小时奖励缓存 pvpHGTime = {"number", 0}, -- pvp 高级段位上次奖励刷新时间 pvpShop = {"table", {}}, -- pvp 商店{id = count} 对应商店id 购买次数 - + pvpBet = {"table", {}}, -- 跨服竞技场押注信息 {[round] = {1, 1000}} potionBag = {"table", {}}, -- 营养剂背包 diff --git a/src/models/RoleLog.lua b/src/models/RoleLog.lua index fed641e..f3f85b4 100644 --- a/src/models/RoleLog.lua +++ b/src/models/RoleLog.lua @@ -4,6 +4,7 @@ local LogType = { create = "common", login = "common", logout = "common", + gm = "common", } -- 如要修改 要提前修改 _template mapping -- 对应 mapping 为 gamelog-* @@ -45,10 +46,10 @@ local function checkType(logType, field, value, ctype) --长度不超过256 if type(value) ~= "string" then value = tostring(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [keyword]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [keyword], value : %s", logType, field, value)) else if #value > 256 then - print(string.format("LOG ERROR: logType [%s] field [%s] [keyword] type to long.", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] [keyword] type to long. value : %s", logType, field, value)) end end return value @@ -56,26 +57,26 @@ local function checkType(logType, field, value, ctype) text = function() if type(value) ~= "string" then value = tostring(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [text]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [text], value : %s", logType, field, value)) end return value end, integer = function() if type(value) ~= "number" then value = tonumber(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then local oldValue = value value = math.floor(value) if value ~= oldValue then - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], is float", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], is float, value : %s", logType, field, value)) end end if -2147483648 > value or value > 2147483647 then value = nil - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], too big", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], too big, value : %s", logType, field, value)) end end return value @@ -83,20 +84,20 @@ local function checkType(logType, field, value, ctype) short = function() if type(value) ~= "number" then value = tonumber(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then local oldValue = value value = math.floor(value) if value ~= oldValue then - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], is float", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], is float, value : %s", logType, field, value)) end end if -32768 > value or value > 32768 then value = nil - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], too big", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], too big, value : %s", logType, field, value)) end end return value @@ -104,7 +105,7 @@ local function checkType(logType, field, value, ctype) long = function() if type(value) ~= "number" then value = tonumber(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then @@ -112,9 +113,9 @@ local function checkType(logType, field, value, ctype) value = math.floor(value) if type(value) ~= "integer" then value = nil - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], too big", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], too big, value : %s", logType, field, value)) elseif value ~= oldValue then - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], is float", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], is float, value : %s", logType, field, value)) end end end @@ -123,7 +124,7 @@ local function checkType(logType, field, value, ctype) float = function() if type(value) ~= "number" then value = tonumber(value) - print(string.format("LOG ERROR: logType [%s] field [%s] isn't [float]", logType, field)) + print(string.format("LOG ERROR: logType [%s] field [%s] isn't [float], value : %s", logType, field, value)) end return value end, diff --git a/src/models/RolePlugin.lua b/src/models/RolePlugin.lua index 4d7750c..095cd76 100644 --- a/src/models/RolePlugin.lua +++ b/src/models/RolePlugin.lua @@ -156,6 +156,7 @@ function RolePlugin.bind(Role) end end self:updateProperties({level = level, exp = newExp}) + self:changeCrossServerPvpSelfInfo("level") end function Role:addItem(params) @@ -528,19 +529,40 @@ function RolePlugin.bind(Role) function Role:warningHeartTooQuick() -- 加速器检测 - -- local heartWarning = self:getProperty("heartWarning") - -- heartWarning = heartWarning + 1 - -- self:setProperty("heartWarning", heartWarning) - -- if heartWarning == 50 then - -- self:setProperty("delete", 1) - -- self:sendGmMsg("系统检测到你多次使用加速器,已经将你封杀,请联系管理员。") - -- self:log("gmAction",{desc = "ban"}) - -- return - -- end - -- if heartWarning < 50 and heartWarning % 5 == 0 then - -- self:sendGmMsg("警告!系统检测到你使用加速器,请立即停止使用!否则我们将封杀此账号!") - -- self:log("gmAction",{desc = "heartWarning", count = heartWarning}) - -- end + local heartWarning = self:getProperty("heartWarning") + heartWarning = heartWarning + 1 + self:setProperty("heartWarning", heartWarning) + if heartWarning == 50 then + self:setProperty("delete", 1) + self:sendGmMsg("server_accountBanned_inGame_1") + self:log("gm",{desc = "ban"}) + return + end + if heartWarning < 50 and heartWarning % 5 == 0 then + self:sendGmMsg("server_accountBanned_warning") + self:log("gm",{desc = "heartWarning", int1 = heartWarning}) + end + end + + function Role:setBan(time, banType) + time = time or 0 + banType = banType or 0 + local now = skynet.timex() + if time == 0 then + self:setProperty("banTime", 0) + self:setProperty("banType", 0) + self:setProperty("heartWarning", 0) + + self:log("gm", {desc = "ban_rm"}) + else + self:setProperty("banTime", now + 86400 * time) + self:setProperty("banType", banType) + self:log("gm",{desc = "ban", int1 = time, int2 = banType}) + end + end + + function Role:sendGmMsg(text, isNotKey) + SendPacket(actionCodes.Sys_maintainNotice, MsgPack.pack({ body = text, iskey = not isNotKey})) end function Role:getHeroActiveRelationData(heros) diff --git a/src/models/RolePvp.lua b/src/models/RolePvp.lua index 60fa64c..71b0c75 100644 --- a/src/models/RolePvp.lua +++ b/src/models/RolePvp.lua @@ -352,6 +352,167 @@ end + + +-------------------- 跨服竞技场相关 ----------------------- +local serverId = tonumber(skynet.getenv("servId")) +-- 自己是否参赛 -- 更换头像 名字 队伍 需要上传 +function Role:isCrossServerPvpPlayer() + if not self:isTimeResetOpen(TimeReset.PvpCross) then + self._isCrossServerPvpPlayer = nil + return false + end + if self._isCrossServerPvpPlayer == nil then + self:getCrossServerPvpMatchInfo() + end + return self._isCrossServerPvpPlayer +end + +function Role:changeCrossServerPvpSelfInfo(cType) + if not self:isCrossServerPvpPlayer() then return end + local change = {id = self:packPvpCrossRoleId(serverId, self:getProperty("id"))} + if cType == "name" or cType == "level" or cType == "headId" then + change[cType] = self:getProperty(cType) + elseif cType == "format" then + -- 是否过了时间 + local crossTime = skynet.timex() - self:getTimeResetStartTime(TimeReset.PvpCross) + local aday = 3600 * 24 + local day = math.ceil(crossTime / aday) -- 当前是第几个比赛日 + local ctime = crossTime % aday -- 当前在本天 经过多少时间 + + if day > globalCsv.pvp_cross_server_day or ctime >= globalCsv.pvp_cross_server_stop_format then + return + end + change.battleV = self:getProperty("pvpTBVH") + change.heros = self:getProperty("pvpTSH") + change.battleInfo = self:getProperty("pvpTBH") + end + + pcall(skynet.call, pvpd, "lua", "updateRoleInfo", change) +end + +-- 获取当前阵容信息 +function Role:getCrossServerPvpMatchInfo() + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + local ok, result = pcall(skynet.call, pvpd, "lua", "getMatchInfo") + if ok then + local cur = result.roleInfo and result.roleInfo[self:packPvpCrossRoleId(serverId, self:getProperty("id"))] + self._isCrossServerPvpPlayer = cur and true or false + return result + else + print(result) + end +end + +-- 获取角色信息 简略 +function Role:getCrossServerPvpRoleInfo() + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + + local ok, result = pcall(skynet.call, pvpd, "lua", "getRoleInfo") + if ok then + return result + else + print(result) + end +end + +function Role:getCrossServerPvpRoleInfoDeatil(pIds) + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + + local ok, result = pcall(skynet.call, pvpd, "lua", "getRoleDetail", pIds) + if ok then + return result + else + print(result) + end +end + +function Role:getCrossServerPvpMatchRecord(round, matchIdx) + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + + local ok, result = pcall(skynet.call, pvpd, "lua", "getMatchRecord", round, matchIdx) + if ok then + return result + else + print(result) + end +end + +function Role:getCrossServerPvpBetInfo() + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + local pvpBet = self:getProperty("pvpBet") + local back = {} + + local ok, result = pcall(skynet.call, pvpd, "lua", "getBetInfo") + + if ok then + if result.betInfo then + local maxRound = 0 + for round, matchIdx in pairs(result.betInfo) do + if round > maxRound then + maxRound = round + end + back[round] = { + matchIdx = matchIdx, + bet = pvpBet[round] + } + end + if maxRound ~= 0 then + back[maxRound].betNum = result.betNum + end + end + return back + else + print(result) + end +end + +function Role:getCrossServerPvpBet(idx) + if not self:isTimeResetOpen(TimeReset.PvpCross) then return end + local crossTime = skynet.timex() - self:getTimeResetStartTime(TimeReset.PvpCross) + local aday = 3600 * 24 + local day = math.ceil(crossTime / aday) -- 当前是第几个比赛日 + local ctime = crossTime % aday -- 当前在本天 经过多少时间 + + if day > globalCsv.pvp_cross_server_day or ctime >= globalCsv.pvp_cross_server_stop_stake then + return + end + local pvpBet = self:getProperty("pvpBet") + if pvpBet[day] then return end + + local cost = {[ItemId.Gold] = self:getProperty("level") * globalCsv.pvp_cross_bet_pre_level} + if not self:checkItemEnough(cost) then return end + + local ok, result = pcall(skynet.call, pvpd, "lua", "setBet", idx) + if ok then + if result then + self:costItems(cost) + pvpBet[day] = {idx, cost[ItemId.Gold]} + self:setProperty("pvpBet", pvpBet) + end + return result + else + print(result) + end +end + + + +function Role:packPvpCrossRoleId(servId, roleId) + return roleId * 1000 + servId +end + +function Role:unpackPvpCrossRoleId(tempId) + local servId = tempId % 1000 + local roleId = math.floor(tempId / 1000) + return servId, roleId +end + +-- -- 获取参赛玩家详情 +-- function Role: + + + end diff --git a/src/models/RoleTimeReset.lua b/src/models/RoleTimeReset.lua index 05925f2..899981c 100644 --- a/src/models/RoleTimeReset.lua +++ b/src/models/RoleTimeReset.lua @@ -34,6 +34,10 @@ ResetFunc["PvpShop"] = function(self, notify, response) response.pvpShop = {} end +ResetFunc["PvpCross"] = function(self, notify, response) + self:setProperty("pvpBet", {}) +end + function Role:updateTimeReset(now, notify) local timeReset = self:getProperty("timeReset") diff --git a/src/models/Rune.lua b/src/models/Rune.lua index e6d6c88..ff8a6d6 100644 --- a/src/models/Rune.lua +++ b/src/models/Rune.lua @@ -71,6 +71,9 @@ end function Rune:generateAttrs() local runeData = csvdb["runeCsv"][self:getProperty("type")][self:getProperty("id")] + if not runeData then + print(self:getProperty("type"), self:getProperty("id")) + end local attrs = "" local typ, value = getRandomValue(runeData.attr1,runeData.range1) attrs = attrs:setv(typ, value) diff --git a/src/services/httpweb.lua b/src/services/httpweb.lua index 8b5b762..2243dce 100644 --- a/src/services/httpweb.lua +++ b/src/services/httpweb.lua @@ -94,6 +94,18 @@ local function start() end socket.close(id) end) + + -- 注册全服广播 + local channels = {} + for i = 1, 10 do + local channel = datacenter.get("MC_W_CHANNEL" .. i) + if channel then + table.insert(channels, channel) + end + end + if #channels > 0 then + mcast_util.sub_worlds(channels) + end end local function __init__() diff --git a/src/services/logd.lua b/src/services/logd.lua index fd1a6c2..682cdfa 100644 --- a/src/services/logd.lua +++ b/src/services/logd.lua @@ -75,7 +75,7 @@ function CMD.log(logType, doc, index_suffix) local now = skynet.timex() doc["timestamp"] = now - doc["@timestamp"] = os.date("%Y-%m-%d %H:%M:%S", now) + doc["timestamp_f"] = os.date("%Y-%m-%d %H:%M:%S", now) doc["server"] = serverId -- 自己加好 index diff --git a/src/services/pvpd.lua b/src/services/pvpd.lua index 90c3a57..3429f89 100644 --- a/src/services/pvpd.lua +++ b/src/services/pvpd.lua @@ -1,8 +1,10 @@ -local skynet = require "skynet" +skynet = require "skynet" local json = require("shared.json") -local redisproxy = require("shared.redisproxy") +redisproxy = require("shared.redisproxy") local cluster = require "skynet.cluster" - +local serverId = tonumber(skynet.getenv("servId")) +local sharedata = require "skynet.sharedata" +datacenter = require "skynet.datacenter" require "shared.init" require "utils.init" require "RedisKeys" @@ -11,10 +13,32 @@ globalCsv = require "csvdata/GlobalDefine" require "GlobalVar" +local MatchCache = {} -- 比赛记录 缓存 { [roundIdx] = {{rolesId, rolesId, winId = roleId}, {rolesId, rolesId}}, ... } +local RoleInfo = {} -- 角色信息缓存 {[rolesId] = info} +local pvpInfo = nil + +local ROBOT_SERV_ID = 999 +local function packRoleId(servId, roleId) + return roleId * 1000 + servId +end + +local function unpackRoleId(tempId) + local servId = tempId % 1000 + local roleId = math.floor(tempId / 1000) + return servId, roleId +end +skynet.register_protocol { + name = "role", + id = 13, + pack = skynet.pack, + unpack = skynet.unpack, + dispatch = function(session, address, submethod, ...) + end, +} -function rpcRole(roleId, funcName, ...) +local function rpcRole(roleId, funcName, ...) local fields = ... local agent = datacenter.get("agent", roleId) if agent and agent.serv then @@ -33,72 +57,203 @@ function rpcRole(roleId, funcName, ...) end end -local function upLoadTeams() - local chatd = cluster.query("center", "chatd") - if not chatd then - return +local function getDBKey() + local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross] + local curRound = math.floor((skynet.timex() - START_RESET_TIME - resetData.start) / resetData.interval) + local idx = 1 + if curRound % 2 == 1 then + idx = 2 end - return pcall(cluster.call, "center", chatd, "test", {serverId = 123, hehe = "asd"}) + return RANK_PVP_HIGHT_KEY[idx] +end + + +local function getStartTime() + local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross] + local curRound = math.floor((skynet.timex() - START_RESET_TIME - resetData.start) / resetData.interval) + local startTime = START_RESET_TIME + curRound * resetData.interval + resetData.start + return startTime end +local CMD = {} + +------------------- 角色调用 -------------------------- + +function CMD.updateRoleInfo(change) + CMD.refreshRoleInfo(change) + local pvpd = cluster.query("center", "pvpd") + if pvpd then + pcall(cluster.call, "center", pvpd, "updateRoleInfo", change) + end +end -local function update() +local function getDayAndTime() + local startTime = getStartTime() local now = skynet.timex() - local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross] - - local oldRound = tonum(redisproxy:hget("pvp_cross", "round"), -100) - - local startTime = START_RESET_TIME + curRound * resetData.interval + resetData.start - local endTime = startTime + (resetData.duration == 0 and resetData.interval or math.min(resetData.interval, resetData.duration)) - local nextStartTime = startTime + resetData.interval - - local updateTime = math.max((nextStartTime - now) / 2, CHECK_PVP_STATUS_INTERVAL) - -- 已经 上传过阵容了 - if curRound ~= oldRound then - -- 跨服竞技场已经结束了 - if now >= endTime then - redisproxy:hset("pvp_cross", "round", curRound) - else - -- 上传信息 - local status, back = upLoadTeams() - if status and back == "success" then --上传成功 - redisproxy:hset("pvp_cross", "round", curRound) - else - updateTime = CHECK_PVP_STATUS_INTERVAL + + local crossTime = now - startTime + local aday = 3600 * 24 + local day = math.ceil(crossTime / aday) -- 当前是第几个比赛日 + local ctime = crossTime % aday -- 当前在本天 经过多少时间 + + return day, ctime +end + +local function hideMatchInfo() + local day, ctime = getDayAndTime() + local tempMatchCache = {} + if day > globalCsv.pvp_cross_server_day then + return MatchCache + else + for round, tempData in pairs(MatchCache) do + if round == day and ctime < globalCsv.pvp_cross_server_show_result - 1 then + tempMatchCache[round] = {} + for idx, match in pairs(tempData) do + tempMatchCache[round][idx] = { + [1] = match[1], + [2] = match[2], + } + end + elseif round <= day then + tempMatchCache[round] = {} + for idx, match in pairs(tempData) do + tempMatchCache[round][idx] = { + [1] = match[1], + [2] = match[2], + win = match.win, + battleV = { + [match[1]] = (match.teams[match[1]] or {}).battleV, + [match[2]] = (match.teams[match[2]] or {}).battleV, + } + } + end end end end - return updateTime + return tempMatchCache end +local function hideRoleInfo() + local day, ctime = getDayAndTime() + local needInfo = {} + local tempRoleInfo = {} + for pId, roleInfo in pairs(RoleInfo) do + tempRoleInfo[pId] = { + name = roleInfo.name, + level = roleInfo.level, + headId = roleInfo.headId, + } + end + return tempRoleInfo +end -local CMD = {} +function CMD.getMatchInfo() + if not next(MatchCache) then + local pvpd = cluster.query("center", "pvpd") + if pvpd then + local status, result = pcall(cluster.call, "center", pvpd, "getMatchInfo", {serverId = serverId}) + MatchCache = result.matchInfo or {} + RoleInfo = result.roleInfo or {} + end + end -function CMD.start() - -- check_pvp_update() + return {matchInfo = hideMatchInfo(), roleInfo = hideRoleInfo()} end -local function getDBKey() - local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross] - local curRound = math.floor((skynet.timex() - START_RESET_TIME - resetData.start) / resetData.interval) - local idx = 1 - if curRound % 2 == 1 then - idx = 2 +function CMD.getRoleInfo() + if not next(MatchCache) then + CMD.getMatchInfo() end - return RANK_PVP_HIGHT_KEY[idx] + return hideRoleInfo() +end + +function CMD.getRoleDetail(pIds) + if not next(MatchCache) then + CMD.getMatchInfo() + end + local result = {} + for _, pId in ipairs(pIds) do + result[pId] = RoleInfo[pId] + end + return result +end + +function CMD.getMatchRecord(round, matchIdx) + if not next(MatchCache) then + CMD.getMatchInfo() + end + local day, ctime = getDayAndTime() + if round > day or (round == day and ctime < globalCsv.pvp_cross_server_show_result) then return end -- 还么结算 + if not (MatchCache[round] or {})[matchIdx] then return end + return { + videos = MatchCache[round][matchIdx].video, + teams = MatchCache[round][matchIdx].teams, + } end -function CMD.loadRoleInfo(roleIds) +function CMD.getBetInfo() + if not next(MatchCache) then + CMD.getMatchInfo() + end + local day, ctime = getDayAndTime() + local change = false + local lastDay = math.min(day, globalCsv.pvp_cross_server_day) + local betInfo = pvpInfo:getProperty("betInfo") + local betNum = pvpInfo:getProperty("betNum") + for cday = 1, lastDay do + if not betInfo[cday] then + change = true + betInfo[cday] = math.randomInt(1, #(MatchCache[cday] or {1})) + if cday == lastDay then + betNum = {} + end + end + end + if change then + pvpInfo:setProperties({ + betInfo = betInfo, + betNum = betNum + }) + end + + return pvpInfo:getProperties({"betInfo", "betNum"}) +end + +function CMD.setBet(idx) + local day, ctime = getDayAndTime() + if day > globalCsv.pvp_cross_server_day or ctime >= globalCsv.pvp_cross_server_stop_stake then return end + + local betInfo = pvpInfo:getProperty("betInfo") + if not betInfo[day] then return end + + local betNum = pvpInfo:getProperty("betNum") + betNum[idx] = (betNum[idx] or 0) + 1 + pvpInfo:setProperty("betNum", betNum) + return {betNum = betNum} +end + + +-------------------中心服务器 调用---------------------- +function CMD.loadRoles(roleIds) roleIds = roleIds or {} local infos = {} + RoleInfo[serverId] = RoleInfo[serverId] or {} for _, roleId in ipairs(roleIds) do infos[roleId] = rpcRole(roleId, "pvpHInfo") + local temp = {} + for _field, _v in pairs(infos[roleId]) do + if _field ~= "battleInfo" then + temp[_field] = _v + end + end + RoleInfo[packRoleId(serverId, roleId)] = temp end return infos end +-- 新赛季了 清掉缓存 function CMD.loadTeams() local dbKey = getDBKey() local redret = redisproxy:zrevrange(dbKey, 0, 15) @@ -106,12 +261,43 @@ function CMD.loadTeams() for _, roleId in ipairs(redret) do table.insert(roleIds, tonumber(roleId)) end + MatchCache = {} + RoleInfo = {} + local infos = CMD.loadRoles(roleIds) + pvpInfo:setProperties({ + betInfo = {}, + betNum = {}, + }) + return {roleIds = roleIds, infos = infos} +end - local infos = CMD.loadRoleInfo(roleIds) +-- 刷新缓存 +function CMD.refreshMatchCache(info) + MatchCache = info.matchInfo + RoleInfo = info.roleInfo +end - return {roleIds = roleIds, infos = infos} +-- 刷新 玩家数据 +function CMD.refreshRoleInfo(change) + if not next(RoleInfo) then return end + if RoleInfo[change.id] then + for field, value in pairs(change) do + if field ~= "id" then + RoleInfo[change.id][field] = value + end + end + end end +------------------------------------------------------ +function CMD.start() + redisd = skynet.localname(".REDIS") + pvpInfo = require("models.Pvpd").new({key = "cross:pvpInfo"}) + pvpInfo:load() +end + +--------------------------------------------------------- + local function __init__() skynet.dispatch("lua", function(_, _, command, ...) local f = CMD[command] @@ -119,7 +305,8 @@ local function __init__() skynet.ret(skynet.pack(f(...))) end end) - redisd = skynet.localname(".REDIS") + csvdb = sharedata.query("csvdata") + skynet.register(".PVPCROSS") end diff --git a/src/services/watchdog.lua b/src/services/watchdog.lua index cb04815..4ffae30 100644 --- a/src/services/watchdog.lua +++ b/src/services/watchdog.lua @@ -68,6 +68,7 @@ function CMD.start(conf) if use_logd == 1 then skynet.call(logd, "lua", "open") end + skynet.call(pvpd, "lua", "start") -- 开启agent状态检测定时器 check_agent_status() -- 创建广播服务 @@ -83,8 +84,6 @@ function CMD.start(conf) globald = skynet.newservice("services/globald") skynet.call(globald, "lua", "start") - pvpd = skynet.newservice("services/pvpd") - cluster.register("pvpd", pvpd) local servId = tonumber(skynet.getenv("servId")) cluster.open("server" .. servId) end @@ -120,6 +119,9 @@ skynet.start(function() if use_logd == 1 then logd = skynet.newservice("services/logd") end + -- pvp 服务 + pvpd = skynet.newservice("services/pvpd") + cluster.register("pvpd", pvpd) local poold = skynet.newservice("services/poold") local obj = skynet.call(poold, "lua", "start", pool_size) -- libgit2 0.21.2