From edf2ee12a3461caaa9af524aebe7db4cf86631e9 Mon Sep 17 00:00:00 2001 From: zhouhaihai Date: Tue, 19 Jan 2021 19:56:38 +0800 Subject: [PATCH] 防作弊 --- src/actions/ActivityAction.lua | 13 +++++++++++++ src/actions/GmAction.lua | 32 ++++++++++---------------------- src/actions/HangAction.lua | 22 ++++++++++++++++++++++ src/actions/PvpAction.lua | 21 ++++++++++++++++++++- src/actions/TowerAction.lua | 9 +++++++++ src/models/Role.lua | 1 + src/models/RoleBattle.lua | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/models/RoleLog.lua | 1 + src/models/RolePlugin.lua | 41 ++++++++++++++++++++++++++++++++++++----- 9 files changed, 255 insertions(+), 31 deletions(-) diff --git a/src/actions/ActivityAction.lua b/src/actions/ActivityAction.lua index e09d663..c0bc6c3 100644 --- a/src/actions/ActivityAction.lua +++ b/src/actions/ActivityAction.lua @@ -511,6 +511,7 @@ function _M.startBattleRpc(agent, data) key = tostring(math.random()), actid = actid, id = id, + format = msg.format, } SendPacket(actionCodes.Activity_startBattleRpc, MsgPack.pack({key = role.__actBattleCache.key})) else @@ -579,6 +580,18 @@ function _M.endBattleRpc(agent, data) SendPacket(actionCodes.Activity_endBattleRpc, MsgPack.pack({errorCode = 1})) end + -- 防作弊 + if not role:checkBattleCheat("act_battle", { + id = id, + isWin = isWin, + info = msg.info, + format = role.__actBattleCache.format + }) then + SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({errorCode = 1})) + return true + end + role.__actBattleCache = nil + local actCfg = csvdb["activity_battleCsv"][actid] if not actCfg then return 3 end diff --git a/src/actions/GmAction.lua b/src/actions/GmAction.lua index d94c1df..49a79c4 100644 --- a/src/actions/GmAction.lua +++ b/src/actions/GmAction.lua @@ -36,26 +36,15 @@ function _M.ban(role, pms) local time = tonum(pms.pm1, 1) local ctype = tonum(pms.pm2, 0) - local isBan = role:getProperty("banTime") <= now role:setBan(time, ctype) - if time > 0 then - role:sendGmMsg("server_accountBanned_1") - local agent = datacenter.get("agent", role:getProperty("id")) - if agent then - skynet.timeout(50, function () - skynet.call(agent.gate_serv, "lua", "forcekick", agent.fd) - end) - end - end - role:mylog("gm_action", {desc = "ban", int1 = time, int2 = ctype, key1 = pms.sender}) - - return isBan and "解封杀成功" or "封杀成功" + return "封杀成功" end + function _M.unban(role, pms) role:setBan(0, 0) - + role:setProperty("cheatCount", 0) -- 清除作弊次数 role:mylog("gm_action", {desc = "unban", key1 = pms.sender}) return "解封杀成功" @@ -63,18 +52,17 @@ end function _M.gmmsg(role, pms) role:sendGmMsg(pms.pm1, true) - - local agent = datacenter.get("agent", role:getProperty("id")) - if agent then - skynet.timeout(50, function () - skynet.call(agent.gate_serv, "lua", "forcekick", agent.fd) - end) - end role:mylog("gm_action", {desc = "gmmsg", text1 = pms.pm1, key1 = pms.sender}) - return "指令成功" end + +function _M.reset_rank(role, pms) + role:resetRank() + role:mylog("gm_action", {desc = "reset_rank", key1 = pms.sender}) + return "封杀成功" +end + function _M.silent(role, pms) local pm1 = tonum(pms.pm1) if pm1 < 1 then diff --git a/src/actions/HangAction.lua b/src/actions/HangAction.lua index d28969b..d4d87e5 100644 --- a/src/actions/HangAction.lua +++ b/src/actions/HangAction.lua @@ -235,6 +235,16 @@ function _M.endBattleRpc(agent, data) return 4 end + -- 防作弊 + if not role:checkBattleCheat("hang", { + id = carbonId, + isWin = isWin, + info = msg.info + }) then + SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({errorCode = 1})) + return true + end + local reward, change if isWin then --win role:hangFinish(carbonId) @@ -607,6 +617,18 @@ function _M.endBonusBattleRpc(agent, data) SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({errorCode = 1})) return true end + role.__bonusBattleCache = nil + + -- 防作弊 + if not role:checkBattleCheat("bonus", { + id = id, + isWin = starNum and starNum > 0, + info = msg.info + }) then + SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({errorCode = 1})) + return true + end + local bonusData = csvdb["bonus_battleCsv"][id] local reward, change = {} diff --git a/src/actions/PvpAction.lua b/src/actions/PvpAction.lua index 1da85ec..6471375 100644 --- a/src/actions/PvpAction.lua +++ b/src/actions/PvpAction.lua @@ -372,6 +372,16 @@ function _M.endBattleRpc(agent, data) if not match then return end + -- 防作弊 + if not role:checkBattleCheat("pvpc", { + isWin = isWin, + info = msg.info, + format = _pvpStartBattleCacheC.pvpTC, + }) then + SendPacket(actionCodes.Pvp_endBattleRpc, MsgPack.pack({errorCode = 1})) + return true + end + local temp = string.randWeight(csvdb["player_expCsv"][role:getProperty("level")].pvpBonus, true) local reward, change = role:award({[temp[1]] = temp[2]}, {log = {desc = "pvpBattleC"}}) local myScore, matchScore, oldmyScore, oldMatchScore, myRank, oldMyRank = 0, 0, 0, 0, -1, -1 @@ -652,13 +662,22 @@ function _M.endBattleHRpc(agent, data) end end + -- 防作弊 + if not role:checkBattleCheat("pvph", { + isWin = isWin, + info = msg.info, + format = _pvpStartBattleCacheH.pvpTH[#_pvpStartBattleCacheH.result] + }) then + SendPacket(actionCodes.Pvp_endBattleHRpc, MsgPack.pack({errorCode = 1})) + return true + end + if winCount >= 2 then isWin = true elseif loseCount >= 2 then isWin = false else -- 没结束 -- 返回继续战斗 - local key = tostring(math.random()) _pvpStartBattleCacheH.key = key local round = #_pvpStartBattleCacheH.result + 1 diff --git a/src/actions/TowerAction.lua b/src/actions/TowerAction.lua index c1c073b..094b0bd 100644 --- a/src/actions/TowerAction.lua +++ b/src/actions/TowerAction.lua @@ -65,6 +65,15 @@ function _M.endBattleRpc(agent, data) local curTower = csvdb["tower_battleCsv"][id] if not curTower then return 2 end + -- 防作弊 + if not role:checkBattleCheat("tower", { + isWin = msg.starNum and msg.starNum > 0, + info = msg.info + }) then + SendPacket(actionCodes.Tower_endBattleRpc, MsgPack.pack({errorCode = 1})) + return true + end + local curCount, nextTime = getUpdateTime(towerInfo.c, towerInfo.t) diff --git a/src/models/Role.lua b/src/models/Role.lua index 6ad8695..2e57c0f 100644 --- a/src/models/Role.lua +++ b/src/models/Role.lua @@ -53,6 +53,7 @@ Role.schema = { banTime = {"number", 0}, banType = {"number", 0}, heartWarning = {"number", 0}, + cheatCount = {"number", 0}, ltime = {"number", 0}, -- 最后登录时间 ctime = {"number", skynet.timex()}, -- 创建时间 ignoreMt = {"number", 0}, -- 忽略维护拦截 diff --git a/src/models/RoleBattle.lua b/src/models/RoleBattle.lua index b3afd25..5182c43 100644 --- a/src/models/RoleBattle.lua +++ b/src/models/RoleBattle.lua @@ -21,13 +21,153 @@ local BattleType = { RoleBattle.bind = function (Role) +local checkCheatAttrs = { + ["hp"] = 1, + ["atk"] = 1, + ["def"] = 1, + ["hit"] = 1, + ["miss"] = 1, + ["crit"] = 1, + ["atkSpeed"] = 1, + ["critHurt"] = 1, + -- ["vampire"] = 1, + -- ["pierce"] = 1, +} --- TODO 检查战斗是否作弊 -local function checkBattleCheat() - +local function checkOneCheat(selfTeamClient, selfTeamServer, enemyClient, enemyServer) + if not selfTeamClient or type(selfTeamClient) ~= "table" then return end + for unitType, clientInfo in pairs(selfTeamClient) do + local serverInfo = selfTeamServer[unitType] + if not serverInfo then return end + for attr, pm in pairs(checkCheatAttrs) do + if not clientInfo[attr] then return end + end + local b1 = ((clientInfo["hp"] + clientInfo["def"] * 7 + clientInfo["miss"] * 4) * (clientInfo["atk"] * 4 + clientInfo["hit"] * 2) * (1 + clientInfo["crit"]/100 * clientInfo["critHurt"]/100) * clientInfo["atkSpeed"] / 600000) ^ 0.8 + local b2 = ((serverInfo["hp"] + serverInfo["def"] * 7 + serverInfo["miss"] * 4) * (serverInfo["atk"] * 4 + serverInfo["hit"] * 2) * (1 + serverInfo["crit"]/100 * serverInfo["critHurt"]/100) * serverInfo["atkSpeed"] / 600000) ^ 0.8 + if b1 >= b2 * 2 then + return + end + end + return true end +-- local function getRobotAttrs(info, strength) +-- strength = strength or 10000 +-- local unitData = csvdb["unitCsv"][info.unitType] +-- local enemy = {} +-- for arr, _ in pairs(checkCheatAttrs) do +-- enemy[arr] = unitData[attr] * info[attr] * strength / 10000 +-- end +-- return enemy +-- end + +-- --通过配表构建敌人队伍 通用 +-- function BattleEnter:packBattleEnemyCommon( carbonData ) +-- local enemys = {} +-- local monsterSet = csvdb[carbonData.monster:match("/([^/]*)$") .. "Csv"] +-- for phase = 1, #monsterSet do +-- local allEnemys = table.values(monsterSet[phase]) +-- table.sort(allEnemys, function(a, b) return a.id < b.id end) +-- local heros = {} +-- for idx, enemy in ipairs(allEnemys) do +-- local info = getRobotAttrs(enemy, carbonData.strength) +-- enemys[idx] = info +-- end +-- break +-- end +-- return enemys +-- end + +-- 检查战斗是否作弊 +function Role:checkBattleCheat(battleType, params) + if not params.isWin then return true end + local clientInfo = params.info or {} + + if not BattleType[battleType] then + print(string.format("NO find battleType: %s", battleType)) + return true + end + local selfTeamServer = {} + local enemyServer = {} + + local cheat = {} + cheat["hang"] = function() + local team = self:getTeamBattleInfo(self:getTeamFormatByType(TeamSystemType.Hang)) + for slot, hero in pairs(team.heros) do + local temp = {} + for arr, _ in pairs(checkCheatAttrs) do + temp[arr] = hero[arr] + end + selfTeamServer[hero.type] = temp + end + -- local carbonData = csvdb["idle_battleCsv"][params.id] + -- enemyServer = packBattleEnemyCommon(carbonData) + end + cheat["tower"] = function() + local team = self:getTeamBattleInfo(self:getTeamFormatByType(TeamSystemType.Tower)) + for slot, hero in pairs(team.heros) do + local temp = {} + for arr, _ in pairs(checkCheatAttrs) do + temp[arr] = hero[arr] + end + selfTeamServer[hero.type] = temp + end + -- local carbonData = csvdb["tower_battleCsv"][params.id] + -- enemyServer = packBattleEnemyCommon(carbonData) + end + cheat["bonus"] = function() + local team = self:getTeamBattleInfo(self:getTeamFormatByType(TeamSystemType.BonusBattle)) + for slot, hero in pairs(team.heros) do + local temp = {} + for arr, _ in pairs(checkCheatAttrs) do + temp[arr] = hero[arr] + end + selfTeamServer[hero.type] = temp + end + -- local carbonData = csvdb["bonus_battleCsv"][params.id] + -- enemyServer = packBattleEnemyCommon(carbonData) + end + cheat["pvpc"] = function() + if not params.format then return end + local team = self:getTeamBattleInfo(params.format) + for slot, hero in pairs(team.heros) do + local temp = {} + for arr, _ in pairs(checkCheatAttrs) do + temp[arr] = hero[arr] + end + selfTeamServer[hero.type] = temp + end + end + cheat["pvph"] = cheat["pvpc"] + cheat["act_battle"] = cheat["pvpc"] + + cheat[battleType]() + local status = checkOneCheat(clientInfo.selfAttr, selfTeamServer, clientInfo.enemyAttr, enemyServer) + if not status then + local cheatCount = self:getProperty("cheatCount") + cheatCount = cheatCount + 1 + self:setProperty("cheatCount", cheatCount) + + local result = {clientSelf = {}, serverSelf = {}} + for k , v in pairs(clientInfo.selfAttr) do + result.clientSelf[tostring(k)] = v + end + for k , v in pairs(selfTeamServer) do + result.serverSelf[tostring(k)] = v + end + result = json.encode(result) + self:mylog("cheat", {desc = battleType, int1 = cheatCount, text1 = result}) + + for _, v in ipairs(globalCsv.cheat_check) do + if cheatCount == v[1] then + self:setBan(v[2] / 86400, 5) + break + end + end + end + return status +end function Role:checkBattle(battleType, params) local clientInfo = params.info or {} diff --git a/src/models/RoleLog.lua b/src/models/RoleLog.lua index 7ff9e68..3437652 100644 --- a/src/models/RoleLog.lua +++ b/src/models/RoleLog.lua @@ -592,6 +592,7 @@ local LogType = { guide = "common", newdevice = "common", cbback = "common", + cheat = "common", in_item = "common", out_item = "common", diff --git a/src/models/RolePlugin.lua b/src/models/RolePlugin.lua index f929040..f86d02d 100644 --- a/src/models/RolePlugin.lua +++ b/src/models/RolePlugin.lua @@ -830,7 +830,6 @@ function RolePlugin.bind(Role) self:setProperty("heartWarning", heartWarning) if heartWarning == 50 then self:setBan(30, 1) --封禁 30天 - self:sendGmMsg("server_accountBanned_inGame_1") return end if heartWarning < 50 and heartWarning % 5 == 0 then @@ -843,21 +842,53 @@ function RolePlugin.bind(Role) time = time or 0 banType = banType or 0 local now = skynet.timex() - if time == 0 then + if time <= 0 then self:setProperty("banTime", 0) self:setProperty("banType", 0) self:setProperty("heartWarning", 0) - self:mylog("role_action", {desc = "ban_rm"}) else - self:setProperty("banTime", now + 86400 * time) + self:sendGmMsg(globalCsv.ban_tips[banType] or globalCsv.ban_tips[0]) + print(86400 * time) + self:setProperty("banTime", math.ceil(now + 86400 * time)) self:setProperty("banType", banType) - self:mylog("role_action", {desc = "ban", int1 = time, int2 = banType}) + self:resetRank() + self:mylog("role_action", {desc = "ban", int1 = math.ceil(time), int2 = banType}) end end + -- 清掉所有排行榜 + function Role:resetRank() + local roleId = self:getProperty("id") + redisproxy:pipelining(function (red) + red:zrem(RANK_TOWER, roleId) + for _, rk in pairs(RANK_ADV) do + red:zrem(rk, roleId) + end + for _, rk in pairs(RANK_DINER) do + red:zrem(rk, roleId) + end + for _, rk in pairs(RANK_PVP_COMMON_KEY) do + red:zrem(rk, roleId) + end + for _, rk in pairs(RANK_PVP_HIGHT_KEY) do + red:zrem(rk, roleId) + end + for _, ct in pairs(RANK_TYPE) do + red:zrem(RANK_COMMON .. ct, roleId) + end + end) + end + function Role:sendGmMsg(text, isNotKey) SendPacket(actionCodes.Sys_maintainNotice, MsgPack.pack({ body = text, iskey = not isNotKey})) + + local agent = datacenter.get("agent", self:getProperty("id")) + if agent then + skynet.timeout(50, function () + skynet.call(agent.gate_serv, "lua", "forcekick", agent.fd) + end) + end end -- function Role:getHeroActiveRelationData(heros) -- libgit2 0.21.2