local ipairs = ipairs local table = table local math = math local next = next local string = string local redisproxy = redisproxy local MsgPack = MsgPack local getRandomName = getRandomName local mcast_util = mcast_util local string_format = string.format local tonumber = tonumber local require = require local table_insert = table.insert local tconcat = table.concat local table_unpack = table.unpack local _M = {} function _M.levelUpRpc( agent, data ) local role = agent.role local msg = MsgPack.unpack(data) print("msg.id "..msg.id) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("level") >= hero:getMaxLevel() then return 2 end local curData = csvdb["unit_expCsv"][hero:getProperty("level")] local cost = {[ItemId.Exp] = curData.exp, [ItemId.Gold] = curData.gold} if not role:checkItemEnough(cost) then return 3 end role:costItems(cost) hero:updateProperty({field = "level", delta = 1}) SendPacket(actionCodes.Hero_levelUpRpc, '') return true end function _M.breakRpc( agent, data ) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("level") < hero:getMaxLevel() then return 2 end if hero:getProperty("breakL") >= #csvdb["unit_breakCsv"] then return 3 end local curData = csvdb["unit_breakCsv"][hero:getProperty("breakL")] local cost = {[ItemId.BreakCost] = curData.cost, [ItemId.Gold] = curData.gold} if not role:checkItemEnough(cost) then return 4 end role:costItems(cost) hero:updateProperty({field = "breakL", delta = 1}) SendPacket(actionCodes.Hero_breakRpc, '') return true end function _M.wakeRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("wakeL") >= #csvdb["unit_wakeCsv"] then return 2 end local typ = hero:getProperty("type") local wakeData = csvdb["unit_wakeCsv"][hero:getProperty("wakeL")] if not wakeData then return 3 end local costMaterial = wakeData.costMaterial:toArray(true,"=") local cost = {[typ] = wakeData.costFigment,[globalCsv.unit_wake_cost[hero:getCamp()][costMaterial[1]]] = costMaterial[2]} if not role:checkItemEnough(cost) then return 4 end local skills = {} for _,v in pairs(wakeData.skill:toArray(true,"=") ) do local skillSet = hero:getSkillData(v) if skillSet and next(skillSet) then local skillLv = hero:getSkillLevel(v)+1 local skillData = skillSet[skillLv] if skillData and next(skillData) then skills[v] = skillLv else return 5 end end end role:costItems(cost) for k,v in pairs(skills) do hero:updateProperty({field = "skillL", value = hero:getProperty("skillL"):setv(k, v)}) end hero:updateProperty({field = "wakeL", delta = 1}) role:checkTaskEnter(role.TaskType.Wake, {heroType = typ, wakeL = hero:getProperty("wakeL")}) SendPacket(actionCodes.Hero_wakeRpc, '') return true end -- 已取消技能升级功能,觉醒时自动升级技能 function _M.skillUpRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local index = msg.skillIdx -- 第几个技能 -- 1 2 3 local hero = role.heros[msg.id] if not hero then return end local curLevel = hero:getSkillLevel(index) if hero:getLSPoint() <= 0 or curLevel >= #hero:getSkillData(index) then return end hero:updateProperty({field = "skillL", value = hero:getProperty("skillL"):setv(index, curLevel + 1)}) SendPacket(actionCodes.Hero_skillUpRpc, '') return true end function _M.talentRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end local index = msg.index -- 第几个天赋 local need = {[1] = 1, [2] = 1, [3] = 1, [4] = 1} if not need[index] then return 2 end local talent = hero:getProperty("talent") local curStage = talent:getv(0, 1) if curStage > csvdb["unit_breakCsv"][hero:getProperty("breakL")].talent then return 3 end local curData = csvdb["unit_talentCsv"][curStage] if not curData then return 4 end local level = talent:getv(index, 0) if level >= #curData then return 5 end local talentData = curData[level] if not talentData then return end local cost = talentData.money:toNumMap() local cost2 = talentData.cost:toNumMap() for k,v in pairs(cost2) do cost[globalCsv.unit_talent_cost[csvdb["unitCsv"][hero:getProperty("type")].camp][k]] = v end if not role:checkItemEnough(cost) then return 6 end role:costItems(cost) talent = talent:incrv(index, 1) --是否进阶 local max = true for i = 1, 4 do if talent:getv(i, 0) < #curData then max = false break end end if max then talent = talent:setv(0, curStage + 1) for i = 1, 4 do talent = talent:setv(i, 0) end end hero:updateProperty({field = "talent", value = talent}) SendPacket(actionCodes.Hero_talentRpc, '') return true end -- 暂时没有这个功能 function _M.likeHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local result = {status = 0} local isLike = false local hadLike = role:getProperty("likeHero"):toArray(true, "=") for _, v in pairs(hadLike) do if v == heroType then isLike = true break end end if isLike then result.status = 1 else redisproxy:hincrby("hero:like", "hero:"..heroType, 1) table.insert(hadLike, heroType) role:setProperty("likeHero", table.concat(hadLike, "=")) end SendPacket(actionCodes.Hero_likeHeroRpc, MsgPack.pack(result)) return true end local RankLikeNum = 5 --热度显示几个 local TimeLikeNum = 95 -- 时间显示几个 local function getCommentKey(heroType) return { commentListKey = string.format("list:%d:herocomments", heroType), commentRankKey = string.format("rank:%d:herocomments", heroType), commentKey = string.format("hero:%d:comments", heroType), } end local function trimComment(heroType, commentId) -- 剪裁 CommentList local commentKey = getCommentKey(heroType) local redret = redisproxy:pipelining(function (red) red:lpush(commentKey.commentListKey, commentId) red:lrange(commentKey.commentListKey, TimeLikeNum,-1) red:ltrim(commentKey.commentListKey, 0, TimeLikeNum - 1) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) end) local hots = {} for _, hot in pairs(redret[4]) do hots[hot] = 1 end redisproxy:pipelining(function (red) local needDel = {} for _, tempId in pairs(redret[2]) do if not hots[tempId] then table.insert(needDel, tempId) end end if #needDel > 0 then red:zrem(commentKey.commentRankKey, table_unpack(needDel)) red:hdel(commentKey.commentKey, table_unpack(needDel)) end end) end function _M.commentHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local content = msg.content local result = {status = 0} -- status 0 成功 1 已经评论过了 local curStutus = role.dailyData:getProperty("commentHero") if curStutus:getv(heroType, 0) ~= 0 then result.status = 1 else local commentKey = getCommentKey(heroType) local SERV = string.format("NAMED%d", math.random(1, 5)) local legal, mod = skynet.call(SERV, "lua", "check", content) if not legal then content = mod or "" end local commentId = tostring(redisproxy:hincrby("hero:comment:autoincr", "hero:" .. heroType, 1)) local comment = { commentId = commentId, content = content, roleId = role:getProperty("id"), name = role:getProperty("name"), -- time = skynet.timex() } redisproxy:hset(commentKey.commentKey, commentId, json.encode(comment)) trimComment(heroType, commentId) comment.like = 0 result.comment = comment role.dailyData:setProperty("commentHero", curStutus:setv(heroType, 1)) end SendPacket(actionCodes.Hero_commentHeroRpc, MsgPack.pack(result)) return true end function _M.getCommentsRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local list = {} -- 评论列表 local commentKey = getCommentKey(heroType) local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) local redret = redisproxy:pipelining(function (red) red:lrange(commentKey.commentListKey, 0,TimeLikeNum - 1) red:zrevrange(commentKey.commentRankKey, 0, -1, "WITHSCORES") --热门 red:hget("hero:like", "hero:"..heroType) red:lrange(commentRoleKey, 0, 999) end) local likeMap = {} local idList = {} local liked = {} for i = 1, #redret[2], 2 do likeMap[redret[2][i]] = redret[2][i + 1] if i < RankLikeNum * 2 then table.insert(idList, redret[2][i]) end end for i = 1, #redret[1] do table.insert(idList, redret[1][i]) end for i = 1, #redret[4] do liked[redret[4][i]] = 1 end local commentData = redisproxy:pipelining(function (red) for _, commentId in ipairs(idList) do red:hget(commentKey.commentKey, commentId) end end) for _, commentS in ipairs(commentData or {}) do local comment = json.decode(commentS) comment.like = likeMap[tostring(comment.commentId)] or 0 comment.liked = liked[heroType .. ":" .. comment.commentId] or 0 table.insert(list, comment) end SendPacket(actionCodes.Hero_getCommentsRpc, MsgPack.pack({list = list, like = tonumber(redret[3] or 0)})) return true end function _M.likeCommentRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actType = msg.actType -- 1 顶 2 踩 local heroType = msg.type local commentId = msg.commentId --评论id local commentKey = getCommentKey(heroType) local add = 0 if actType == 1 then add = 1 elseif actType == 2 then add = -1 else return end local result = {status = 0} local commentIndex = heroType .. ":" .. commentId local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) local redret = redisproxy:pipelining(function (red) red:hexists(commentKey.commentKey, commentId) red:lrem(commentRoleKey, 1, commentIndex) red:lpush(commentRoleKey, commentIndex) red:ltrim(commentRoleKey, 0, 999) end) if (tonumber(redret[2]) or 0) > 0 then result.status = 1 else if redret[1] == 1 then-- 查不到也返回ture local redret2 = redisproxy:pipelining(function (red) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 red:zincrby(commentKey.commentRankKey, add, commentId) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 end) local out = {} for _, v in pairs(redret2[1]) do out[v] = 1 end local new = {} for _, v in pairs(redret2[3]) do if out[v] then out[v] = nil else new[v] = 1 end end for tempId, _ in pairs(out) do trimComment(heroType, tempId) end redisproxy:pipelining(function (red) for tempId, _ in pairs(new) do red:lrem(commentKey.commentListKey, 0, tempId) end end) end end SendPacket(actionCodes.Hero_likeCommentRpc, MsgPack.pack(result)) return true end function _M.loveItemRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.heroId] if not hero then return end local curL = hero:getProperty("loveL") local curExp = hero:getProperty("loveExp") local curType = hero:getProperty("type") local curPlus = csvdb["unit_love_plusCsv"][curType] if not curPlus then return end if curL >= curPlus.limit then SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 1})) --已满级 return true end local curEffect = csvdb["unit_love_effectCsv"][curL] if not curEffect then return end if curExp >= curEffect.loveValue and not msg.bBreak then SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 2})) --当前等级经验已满 return true end if msg.bBreak then local cost = curEffect.cost:toArray(true, "=") if not role:checkItemEnough({[cost[1]] = cost[2]}) then SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 3, itemId = cost[1]})) --物品不足 return true end role:costItems({[cost[1]] = cost[2]}) local newLevel = curL + 1 hero:updateProperty({field = "loveL", value = newLevel}) hero:updateProperty({field = "loveExp", value = 0}) if role:getProperty("loveStatus"):getv(curType, 0) < newLevel then role:changeUpdates({{type = "loveStatus", field = curType, value = newLevel}}) -- 总的 end role:checkTaskEnter(role.TaskType.LoveBreak, {heroType = curType, loveL = newLevel}) else local delta = globalCsv.unit_love_presentValue[msg.itemId] if not delta then return end if not role:checkItemEnough({[msg.itemId] = 1}) then SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 3, itemId = msg.itemId})) return true end local newExp = curExp + delta if newExp > curEffect.loveValue then newExp = curEffect.loveValue end role:costItems({[msg.itemId] = 1}) hero:updateProperty({field = "loveExp", value = newExp}) end SendPacket(actionCodes.Hero_loveItemRpc, "") return true end function _M.loveTaskRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return end local curL = hero:getProperty("loveL") local curExp = hero:getProperty("loveExp") local curType = hero:getProperty("type") local curPlus = csvdb["unit_love_plusCsv"][curType] if not curPlus or curL >= curPlus.limit then return end local curEffect = csvdb["unit_love_effectCsv"][curL] if not curEffect or curExp < curEffect.loveValue then return end local lastEffect = csvdb["unit_love_effectCsv"][curL + 1] local newExp = curExp - curEffect.loveValue if lastEffect and curL + 1 < curPlus.limit then if newExp >= lastEffect.loveValue then -- todo 发任务 end else newExp = 0 end local newLevel = curL + 1 hero:updateProperty({field = "loveExp", value = newExp}) hero:updateProperty({field = "loveL", value = newLevel}) if role:getProperty("loveStatus"):getv(curType, 0) < newLevel then role:changeUpdates({{type = "loveStatus", field = curType, value = newLevel}}) -- 总的 end role:checkTaskEnter(role.TaskType.LoveBreak, {heroType = curType, loveL = newLevel}) SendPacket(actionCodes.Hero_loveTaskRpc, "") return true end function _M.changeSkinRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return end local skin = msg.skin local skinData = csvdb["unit_skinCsv"][hero:getSkinId(skin)] if not skinData or (skinData.itemId ~= 0 and not role:checkItemEnough({[skinData.itemId] = 1})) then return end hero:updateProperty({field = "skin", value = skin}) SendPacket(actionCodes.Hero_changeSkinRpc, "") return true end function _M.createHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.heroType local unitData = csvdb["unitCsv"][heroType] if not unitData then return end local cost = globalCsv.unit_fragment_cost[unitData["rare"]] if not cost then return end if role:getItemCount(heroType) < cost then return end for _, hero in pairs(role.heros) do if hero:getProperty("type") == heroType then return end end role:costItems({[heroType] = cost}) role:award({[heroType + ItemStartId.Hero] = 1}) SendPacket(actionCodes.Hero_createHeroRpc, "") return true end -- typ 位置,level等级对应唯一装备,level为0时为移除,不为0时无则装备,有则替换 function _M.referEquipsRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 10 end local equips = msg.equips if not equips or not next(equips) then return 11 end for typ = 1, 4 do -- 4件装备 if equips[typ] and equips[typ] ~= 0 then if role:getEquipCount(typ, equips[typ]) <= 0 then return end end end local curEquip = hero:getProperty("equip") for typ = 1, 4 do -- 4件装备 if equips[typ] then local cur = curEquip:getv(typ, 0) if cur ~= equips[typ] then if equips[typ] == 0 then curEquip = curEquip:delk(typ) else role:addEquip(typ, equips[typ], -1) -- 穿上 curEquip = curEquip:setv(typ, equips[typ]) end if cur ~= 0 then role:addEquip(typ, cur, 1) -- 脱掉 end end end end -- 更新角色 hero:updateProperty({field = "equip", value = curEquip}) SendPacket(actionCodes.Hero_referEquipsRpc, "") return true end -- typ 位置,uid对应唯一符文,uid为0时为移除,不为0时无则装备,有则替换 function _M.referRunesRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 10 end local runes = msg.runes if not runes or not next(runes) then return 11 end for typ = 1, 6 do if runes[typ] and runes[typ] ~= 0 then local ownRune = role.runeBag[runes[typ]] if not ownRune then return end if ownRune:getProperty("refer") ~= 0 then return end end end local curRune = hero:getProperty("rune") for typ = 1, 6 do if runes[typ] then local cur = curRune:getv(typ, 0) if cur ~= runes[typ] then if runes[typ] == 0 then curRune = curRune:delk(typ) else local newRune = role.runeBag[runes[typ]] newRune:updateProperty({field = "refer",value = hero:getProperty("id")}) curRune = curRune:setv(typ, runes[typ]) end if cur ~= 0 then local oldR = role.runeBag[cur] if oldR then oldR:updateProperty({field = "refer",value = 0}) end end end end end hero:updateProperty({field = "rune", value = curRune}) SendPacket(actionCodes.Hero_referRunesRpc, "") return true end function _M.createHeroRandomRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local itemId = msg.itemId local itemData = csvdb["itemCsv"][itemId] if not itemData or itemData.type ~= ItemType.HeroFCommon then return end local cost = globalCsv.unit_fragment_cost[itemData.quality] if not cost or role:getItemCount(itemId) < cost then return end local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] if not randomData then return end local temp = randomData.random_gift:randWeight(true) if not temp or not next(temp) then return end local reward = {} if role:isHaveHero(temp[1]) then reward = {[temp[1]] = cost} else reward = {[temp[1] + ItemStartId.Hero] = 1} end role:costItems({[itemId] = cost}) reward = role:award(reward) SendPacket(actionCodes.Hero_createHeroRandomRpc, MsgPack.pack({reward = reward})) return true end return _M