diff --git a/src/ProtocolCode.lua b/src/ProtocolCode.lua index 8021b83..b4f10ac 100644 --- a/src/ProtocolCode.lua +++ b/src/ProtocolCode.lua @@ -230,6 +230,7 @@ actionCodes = { Activity_bossRewardRpc = 664, Activity_crisisMilestoneRpc = 665, Activity_commonSignRpc = 666, + Activity_friendHelpRpc = 667, Radio_startQuestRpc = 700, Radio_finishQuestRpc = 701, diff --git a/src/RedisKeys.lua b/src/RedisKeys.lua index 94f5164..cee5c40 100644 --- a/src/RedisKeys.lua +++ b/src/RedisKeys.lua @@ -47,6 +47,7 @@ FRIEND_KEY = "role:%d:friend" --哈希表 好友 FRIEND_APPLY_KEY = "role:%d:apply" -- sort set 申请列表 FRIEND_BLACK_KEY = "role:%d:black" -- set 黑名单 FRIEND_POINT = "role:%d:point" -- set 当天送给我心的人 +FRIEND_ENERGY = "role:%d:energy" -- set 送给我活动能量的好友 FRIEND_RECOMMEND = "friend:recommend" -- sort set 登录排序 获取推荐好友 CHAT_OFFLINE = "chat:offline:%d" --消息离线缓存 diff --git a/src/actions/ActivityAction.lua b/src/actions/ActivityAction.lua index 89566e1..f30be68 100644 --- a/src/actions/ActivityAction.lua +++ b/src/actions/ActivityAction.lua @@ -888,4 +888,173 @@ function _M.commonSignRpc(agent, data) return true end +function _M.friendHelpRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local oper = tonumber(msg.oper) or -1 + local actid = msg.actid + local result, award + + if not role.activity:isOpenById(actid, "FriendEnergy") then return 1 end + if oper < 0 or oper > 3 then return 2 end + + local actCsv = csvdb["activity_ctrlCsv"][actid] + local getLimit = actCsv.condition + local gifts = actCsv.condition2:toTableArray(true) + + local actData = role.activity:getActData("FriendEnergy") or {} + + local function getIds() + local ids = {} + local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) + for i = 1, #friends , 2 do + local objId = tonumber(friends[i]) + ids[objId] = 1 + end + return ids + end + + if oper == 0 then + local ids = {} + local friendIds = getIds() + for id, _ in pairs(friendIds) do + if redisproxy:sismember(FRIEND_ENERGY:format(roleId), id) then + ids[id] = 1 + end + end + SendPacket(actionCodes.Activity_friendHelpRpc, MsgPack.pack({result = 1, ids = ids})) + return true + elseif oper == 1 then -- 赠送好友能量 + local objId = msg.roleId + local gift = gifts[1] + local ids = {} + + if not objId then + if not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then + return 3 + end + ids[objId] = 1 + else + ids = getIds() + end + + local giveFE = actData.giveFE or {} + redisproxy:pipelining(function(red) + for friendId, _ in pairs(ids) do + if not giveFE[friendId] then + result = 1 + giveFE[friendId] = 1 + award[gift[1]] = (award[gift[1]] or 0) + gift[2] + red:sadd(FRIEND_ENERGY:format(friendId), roleId) + end + end + end) + + actData.giveFE = giveFE + elseif oper == 2 then -- 收取能量 + local objId = msg.roleId + local gift = gifts[2] + local getFE = actData.getFE or {} + local limit = actData.limit or 0 + + if limit >= getLimit then return 4 end + + local ids = {} + if not objId then + if not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then + return 5 + end + if not redisproxy:sismember(FRIEND_ENERGY:format(roleId), objId) then + return 6 + end + ids[objId] = 1 + else + ids = getIds() + end + + local getFE = actData.getFE or {} + redisproxy:pipelining(function(red) + for friendId, _ in pairs(ids) do + if not getFE[friendId] and limit <= getLimit then + result = 1 + limit = limit + 1 + getFE[friendId] = 1 + award[gift[1]] = (award[gift[1]] or 0) + gift[2] + red:srem(FRIEND_ENERGY:format(roleId), friendId) + end + end + end) + + actData.limit = limit + actData.getFE = getFE + elseif oper == 3 then -- 一键送领全部 + local giveFE = actData.giveFE or {} + local getFE = actData.getFE or {} + local gift1 = gifts[1] + local gift2 = gifts[2] + local limit = actData.limit or 0 + local ids = getIds() + redisproxy:pipelining(function(red) + for friendId, _ in pairs(ids) do + if not giveFE[friendId] then + result = 1 + giveFE[friendId] = 1 + award[gift1[1]] = (award[gift1[1]] or 0) + gift1[2] + red:sadd(FRIEND_ENERGY:format(friendId), roleId) + end + + if not getFE[friendId] and limit <= getLimit then + result = 1 + limit = limit + 1 + getFE[friendId] = 1 + award[gift2[1]] = (award[gift2[1]] or 0) + gift2[2] + red:srem(FRIEND_ENERGY:format(roleId), friendId) + end + end + end) + + actData.limit = limit + actData.giveFE = giveFE + actData.getFE = getFE + elseif oper == 4 then -- 抽大奖 + local magic = actData.magic or 0 + local rewards = actData.reward or {} + local rewardCsv = csvdb["activity_orderRewardsCsv"][actid] + local itemId1 = gifts[1][1] + local itemId2 = gifts[2][1] + + local level = math.min(magic + 1,#rewardCsv) + local rewardData = rewardCsv[level] + + local cost = {[itemId1] = rewardData.condition1, [itemId2] = rewardData.condition2} + + if not role:checkItemEnough(cost) then return 7 end + role:costItems(cost, {log = {desc = "actFriendHelp", int1 = actid, int2 = level}}) + + award = {} + if rewardCsv.reward ~= "" then + result = 1 + award = rewardCsv.reward:toNumMap() + end + if rewardCsv.reward_random ~= "" then + result = 1 + local pool = {} + for _, temp in pairs(rewardCsv.reward_random:toArray()) do + table.insert(pool, temp:toArray(true, "=")) + end + local gift = pool(math.randWeight(pool, 3)) + award[gift[1]] = (award[gift[1]] or 0) + gift[2] + end + rewards[level] = 1 + actData.reward = rewards + actData.magic = level + end + + local reward, change = role:award(award, {log = {desc = "actFriendHelp", int1 = actid, int2 = level}}) + role.activity:updateActData("FriendEnergy", actData) + SendPacket(actionCodes.Activity_friendHelpRpc, MsgPack.pack({result = result, reward = reward})) + return true +end + return _M \ No newline at end of file diff --git a/src/models/Activity.lua b/src/models/Activity.lua index 2717f48..a368e55 100644 --- a/src/models/Activity.lua +++ b/src/models/Activity.lua @@ -32,6 +32,7 @@ Activity.ActivityType = { Crisis = 26, -- 宝藏怪活动 CommonSignIn = 28, --通用签到 + FriendEnergy = 29, -- 好友互赠能量活动 } local function checkActivityType(activityType) @@ -77,6 +78,7 @@ Activity.schema = { act26 = {"table", {}}, -- {task = {id = count}, socre = {id = status}} act28 = {"table", {}}, -- 每日活跃签到 {0=day, 1=1,2=1,3=1} + act29 = {"table", {}}, -- {magic = 0, limit = 0, reward = {id = 1, id = 1}, giveAE = {}, getAE = {}} 奖励字段1表示领取过奖励 } function Activity:data() @@ -99,6 +101,7 @@ function Activity:data() act26 = self:getProperty("act26"), act28 = self:getProperty("act28"), + act29 = self:getProperty("act29"), } end @@ -746,7 +749,22 @@ activityFunc[Activity.ActivityType.ActShopGoods] = { end, } - +activityFunc[Activity.ActivityType.FriendEnergy] = { + ["init"] = function (self, actType, isCrossDay, notify, actId) + local data = {magic = 0, limit = 0, reward = {}, giveAE = {}, getAE = {}} + self:updateActData(actType, data, not notify) + end, + ["crossDay"] = function(self, actType, notify) + local actData = self:getActData(actType) + actData.limit = 0 + actData.giveAE = {} + actData.getAE = {} + self:updateActData(actType, actData, not notify) + end, + ["close"] = function (self, actType, notify, actId) + redisproxy:del(FRIEND_ENERGY:format(self.owner:getProperty("id"))) + end +} activityFunc[Activity.ActivityType.Crisis] = { ["check"] = function(self, actType, notify, atype, count) -- 检查 diff --git a/src/models/RoleLog.lua b/src/models/RoleLog.lua index 85b4042..051d0f0 100644 --- a/src/models/RoleLog.lua +++ b/src/models/RoleLog.lua @@ -52,6 +52,7 @@ local ItemReason = { actMilestone = 136, -- 活动关卡boss伤害里程碑 worldBossReward = 137, -- 世界boss翻牌奖励 commonSign = 138, -- 每日活跃签到 + actFriendHelp = 139,-- 好友能量互助活动 advHang = 301, -- 拾荒挂机 diff --git a/src/models/RolePlugin.lua b/src/models/RolePlugin.lua index f8cbbf1..cc5e69b 100644 --- a/src/models/RolePlugin.lua +++ b/src/models/RolePlugin.lua @@ -1515,6 +1515,7 @@ function RolePlugin.bind(Role) local breathes = { ["email"] = breath(120, "email"), -- email ["pvphg"] = breath(300, "pvphg"), -- 高级竞技场 奖励满的红点 + ["actfriend"] = breath(180, "actfriend"), -- 好友能量助力活动 } function Role:checkNewEvent(now) if now - self:getProperty("ltime") < 5 then @@ -1576,7 +1577,21 @@ function RolePlugin.bind(Role) if table.pack(next(newReward))[2] >= divisionData.limit then return true end - + end + + checks["actfriend"] = function () + local ids = {} + local roleId = self:getProperty("id") + local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) + for i = 1, #friends , 2 do + local objId = tonumber(friends[i]) + ids[objId] = 1 + end + for friendId, _ in pairs(ids) do + if redisproxy:sismember(FRIEND_ENERGY:format(roleId), friendId) then + return true + end + end end local events = {} -- libgit2 0.21.2