diff --git a/src/GlobalVar.lua b/src/GlobalVar.lua index 07534bd..3c078aa 100644 --- a/src/GlobalVar.lua +++ b/src/GlobalVar.lua @@ -72,6 +72,7 @@ ItemId = { Exp = 2, -- 经验 Diamond = 3, -- 钻石 PlayerExp = 4, -- 突破材料 + FriendPoint = 5, -- 友情点 BreakCost = 10, -- 突破材料 EquipUp = 11, -- 装备升级材料 DinerCoin = 12, --后勤物资 diff --git a/src/ProtocolCode.lua b/src/ProtocolCode.lua index 7c993c6..fea8560 100644 --- a/src/ProtocolCode.lua +++ b/src/ProtocolCode.lua @@ -32,6 +32,8 @@ actionCodes = { Role_taskRpc = 117, Role_taskActiveRpc = 118, Role_achiveRpc = 119, + Role_chatRpc = 120, + Role_chat = 121, Adv_startAdvRpc = 151, Adv_startHangRpc = 152, @@ -110,6 +112,20 @@ actionCodes = { Car_runeUpRpc = 402, Car_saleEquipRpc = 403, Car_saleRuneRpc = 404, + + + Friend_searchRpc = 450, + Friend_applyRpc = 451, + Friend_applyListRpc = 452, + Friend_handleApplyRpc = 453, + Friend_listRpc = 454, + Friend_deleteRpc = 455, + Friend_blockRpc = 456, + Friend_blockListRpc = 457, + Friend_infoRpc = 458, + Friend_pointRpc = 459, + Friend_updateProperty = 460, + Friend_randomRpc = 461, } rpcResponseBegin = 10000 diff --git a/src/RedisKeys.lua b/src/RedisKeys.lua index 4e2c933..8d4e459 100644 --- a/src/RedisKeys.lua +++ b/src/RedisKeys.lua @@ -42,8 +42,13 @@ RANK_DINER_INFO = "rank:diner:info" -- BOSS_SET = "boss:%d:%d" -- BOSS_INFO = "boss:battle" --- FRIEND_KEY = "role:%d:friend" --哈希表 --- FRIEND_APPLY_KEY = "role:%d:apply" -- set +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_RECOMMEND = "friend:recommend" -- sort set 登录排序 获取推荐好友 + + -- FRIEND_DINER_LIKE_KEY = "role:%d:diner:like" -- list -- UNION_SET = "global:union" diff --git a/src/actions/FriendAction.lua b/src/actions/FriendAction.lua new file mode 100644 index 0000000..4d32197 --- /dev/null +++ b/src/actions/FriendAction.lua @@ -0,0 +1,630 @@ +local ipairs = ipairs +local table = table +local math = math +local string = string +local redisproxy = redisproxy +local MsgPack = MsgPack +local string_format = string.format +local tonumber = tonumber +local table_insert = table.insert +local table_unpack = table.unpack +local table_find = table.find +local table_nums = table.nums +local math_random = math.randomInt + +local _M = {} + +local function formatArray(tb) + tb = tb or {} + local t = {} + for _, objectId in ipairs(tb) do + t[tonumber(objectId)] = 1 + end + return t +end + +local function checkFriendLimit(roleId) + roleId = tonumber(roleId) + local count = redisproxy:hlen(FRIEND_KEY:format(roleId)) + return count < globalCsv.friendListLimit +end + + +local function addAndCheckApplyLimit(roleId, objId) + roleId = tonumber(roleId) + local dbKey = FRIEND_APPLY_KEY:format(roleId) + local redret = redisproxy:pipelining(function (red) + red:zadd(dbKey, skynet.timex(), objId) + red:zremrangebyrank(dbKey, 0, -(globalCsv.friendApplyLimit + 1)) + end) +end + +local function checkBlackLimit(roleId) + roleId = tonumber(roleId) + local count = redisproxy:scard(FRIEND_BLACK_KEY:format(roleId)) + return count < globalCsv.friendListLimit +end + +local function getRoleInfo(roleId) + local online, info = rpcRole(roleId, "friendSInfo") + return online, info +end + +local function getRoleAllInfo(roleId) + local online, info = rpcRole(roleId, "friendInfo") + return online, info +end + +local function table_merge(tab1, tab2, filter) + tab1 = tab1 or {} + tab2 = tab2 or {} + filter = filter or {} + for k_, v_ in pairs(tab2) do + if not filter[k_] then + tab1[k_] = v_ + end + end + return tab1 +end + +function _M.searchRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local key = msg.key + + if not key then return end + + local objIds = {} + local tempId = tonumber(key) + if tempId then + if redisproxy:exists(string_format("role:%d", tempId)) then + objIds[tempId] = 1 + end + end + local tempId = redisproxy:get(string_format("user:%s", string.upper(key))) + if tempId then + objIds[tonumber(tempId)] = 1 + end + objIds[roleId] = nil --不能有自己 + + local searchList = {} + for objId, _ in pairs(objIds) do + local online, info = getRoleInfo(objId) + local redret = redisproxy:pipelining(function (red) + red:hexists(FRIEND_KEY:format(roleId), objId) + red:zscore(FRIEND_APPLY_KEY:format(objId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(roleId), objId) + end) + local isFriend = redret[1] == 1 and 1 or nil + local hadApply = redret[2] and 1 or nil + local inBlack = redret[3] == 1 and 1 or nil + + table.insert(searchList, table_merge({ + roleId = objId, + online = online, + isFriend = isFriend, + hadApply = hadApply, + inBlack = inBlack, + }, info, { + + })) + end + SendPacket(actionCodes.Friend_searchRpc, MsgPack.pack({searchList = searchList})) + return true +end + + +function _M.applyRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local msg = MsgPack.unpack(data) + local objectId = msg.roleId + + if objectId == roleId then + return + end + + local result = nil + local redret = redisproxy:pipelining(function (red) + red:exists(string_format("role:%d", objectId)) + red:hexists(FRIEND_KEY:format(roleId), objectId) + red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) + red:hlen(FRIEND_KEY:format(roleId)) + red:hlen(FRIEND_KEY:format(objectId)) + end) + -- 玩家id不存在 + if not result and redret[1] ~= 1 then + result = 1 + end + + -- 已经有这个好友 + if not result and redret[2] == 1 then + result = 2 + end + -- 已经申请 + if not result and redret[3] then + result = 3 + end + -- 对方把你拉黑 + if not result and redret[4] == 1 then + result = 4 + end + + -- 你把对方拉黑了 + if not result and redret[4] == 1 then + result = 5 + end + + -- 自己好友已经满 + if not result and redret[6] >= globalCsv.friendListLimit then + result = 6 + end + -- 对方的好友已满 + if not result and redret[7] >= globalCsv.friendListLimit then + result = 7 + end + + if not result then + addAndCheckApplyLimit(objectId, roleId) + local myInfo = role:friendSInfo() + myInfo.roleId = roleId + myInfo.online = true + myInfo.hadApply = true + rpcRole(objectId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({newApply = 1, info = {myInfo}})) -- 通知对方 + end + SendPacket(actionCodes.Friend_applyRpc, MsgPack.pack({result = result})) + return true +end + +function _M.applyListRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local applyList = {} + + local friends = redisproxy:zrange(FRIEND_APPLY_KEY:format(roleId), 0, -1) + for _ , id in pairs(friends) do + id = tonumber(id) + local online, info = getRoleInfo(id) + table.insert(applyList, table_merge({ + roleId = id, online = online + }, info, { + + })) + end + SendPacket(actionCodes.Friend_applyListRpc, MsgPack.pack({list = applyList})) + return true +end + +local function checkHandleApply(roleId, objectId) + local result = nil + local redret = redisproxy:pipelining(function (red) + red:hlen(FRIEND_KEY:format(roleId)) + red:hlen(FRIEND_KEY:format(objectId)) + red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) + end) + --自己好友满了 + if not result and redret[1] >= globalCsv.friendListLimit then + result = 1 + end + -- 对方好友满了 + if not result and redret[2] >= globalCsv.friendListLimit then + result = 2 + end + -- 对方把你拉黑 + if not result and redret[3] == 1 then + result = 3 + end + -- 你把对方拉黑了 + if not result and redret[4] == 1 then + result = 4 + end + return result +end + +function _M.handleApplyRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local msg = MsgPack.unpack(data) + local cmd = msg.cmd + + local newTag = MsgPack.pack({ skynet.timex(), 1}) + local result = nil + if cmd == 1 then --同意 + + local objectId = msg.roleId + + if not redisproxy:zscore(FRIEND_APPLY_KEY:format(roleId), objectId) then + return + end + result = checkHandleApply(roleId, objectId) + + if not result then + redisproxy:pipelining(function (red) + red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) + red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) + red:hsetnx(FRIEND_KEY:format(roleId), objectId, newTag) + red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 + end) + local myInfo = role:friendSInfo() + myInfo.online = true + myInfo.roleId = roleId + myInfo.isFriend = 1 + local redret = redisproxy:pipelining(function (red) + red:sismember(FRIEND_POINT:format(objectId), roleId) + red:sismember(FRIEND_POINT:format(roleId), objectId) + end) + myInfo.pGet = redret[1] == 1 and 1 or nil + rpcRole(objectId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({newFriend = 1, info = {myInfo}})) -- 通知对方 + local online , otherInfo = getRoleInfo(objectId) + otherInfo.roleId = objectId + otherInfo.online = online + otherInfo.isFriend = true + otherInfo.pGet = redret[2] == 1 and 1 or nil + SendPacket(actionCodes.Friend_updateProperty, MsgPack.pack({newFriend = 1, info = {otherInfo}})) + end + + elseif cmd == 0 then -- 不同意 + local objectId = msg.roleId + if not redisproxy:zscore(FRIEND_APPLY_KEY:format(roleId), objectId) then + return + end + redisproxy:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) + elseif cmd == 2 then -- 一键拒绝 + redisproxy:del(FRIEND_APPLY_KEY:format(roleId)) + elseif cmd == 3 then -- 一键同意 + local redret = redisproxy:pipelining(function(red) + red:zrange(FRIEND_APPLY_KEY:format(roleId)) + red:SMEMBERS(FRIEND_POINT:format(roleId)) + end) + local allIds = redret[1] + local fpoint = formatArray(redret[2]) + local needAdd = {} + local needAddMy = {} + local needAddInfo = {} + for _, objId in ipairs(allIds) do + objId = tonumber(objId) + local cr = checkHandleApply(roleId, objId) + if not cr then + table.insert(needAdd, objId) + table.insert(needAddMy, objId) + table.insert(needAddMy, newTag) + local online, otherInfo = getRoleInfo(objId) + otherInfo.online = true + otherInfo.roleId = objId + otherInfo.isFriend = true + otherInfo.pGet = fpoint[objId] and 1 or nil + table.insert(needAddInfo, otherInfo) + end + end + + redisproxy:pipelining(function (red) + red:ZREM(FRIEND_APPLY_KEY:format(roleId), table_unpack(needAdd)) + red:hsetnx(FRIEND_KEY:format(roleId), table_unpack(needAddMy)) + for _, objectId in pairs(needAdd) do + red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) + red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 + end + end) + local myInfo = role:friendSInfo() + myInfo.roleId = roleId + myInfo.online = true + myInfo.isFriend = 1 + local giveFP = role.dailyData:getProperty("giveFP") + for _, objectId in pairs(needAdd) do + myInfo.pGet = giveFP[objectId] + rpcRole(objectId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({newFriend = 1, info = {myInfo}})) -- 通知对方 + end + if next(needAdd) then + SendPacket(actionCodes.Friend_updateProperty, MsgPack.pack({newFriend = 1, info = needAddInfo})) + else + result = 1 + end + + else --不存在 + return + end + + SendPacket(actionCodes.Friend_handleApplyRpc, MsgPack.pack({result = result})) + return true +end + +function _M.listRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local friendList = {} + local redret = redisproxy:pipelining(function (red) + red:hgetall(FRIEND_KEY:format(roleId)) + red:SMEMBERS(FRIEND_POINT:format(roleId)) + end) + + local friends = redret[1] + local fpoint = formatArray(redret[2]) + local hadGet = role.dailyData:getProperty("getFP") + local hadGive = role.dailyData:getProperty("giveFP") + + local clearRed = {} + for i = 1, #friends, 2 do + local id = friends[i] + local data = friends[i + 1] + local friendInfo = MsgPack.unpack(data) + id = tonumber(id) + local online, info = getRoleInfo(id) + local roleInfo = { + roleId = id, + online = online, + addTime = friendInfo[1], + isNew = friendInfo[2], + pGive = hadGive[id], + pGet = hadGet[id] and -1 or (fpoint[id] and 1 or nil) + } + roleInfo = table_merge(roleInfo, info, {}) + + friendList[#friendList + 1] = roleInfo + + if friendInfo[2] then + friendInfo[2] = nil --清除新好友标记 + clearRed[#clearRed + 1] = id + clearRed[#clearRed + 1] = MsgPack.pack(friendInfo) + end + end + if next(clearRed) then + redisproxy:hmset(FRIEND_KEY:format(roleId), table_unpack(clearRed)) --清除新好友标记 + end + + SendPacket(actionCodes.Friend_listRpc, MsgPack.pack({list = friendList})) + return true +end + +function _M.deleteRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local objectId = msg.roleId + if not redisproxy:exists(string_format("role:%d", objectId)) then + return + end + -- 是否在好友列表中 + if redisproxy:hexists(FRIEND_KEY:format(roleId), objectId) then + redisproxy:pipelining(function (red) + red:hdel(FRIEND_KEY:format(roleId), objectId) + red:hdel(FRIEND_KEY:format(objectId), roleId) + red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) + red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) + end) + end + rpcRole(objectId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({deleteFriend = 1, roleId = roleId})) + + SendPacket(actionCodes.Friend_deleteRpc, MsgPack.pack("")) + return true +end + +function _M.blockRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local cmd = msg.cmd + local objectId = msg.roleId + if not redisproxy:exists(string_format("role:%d", objectId)) then + return + end + + local result = nil + if cmd == 1 then + -- 黑名单满了 + if not result and not checkBlackLimit(roleId) then + result = 1 + end + -- 删除好友 + if not result then + redisproxy:pipelining(function (red) + red:hdel(FRIEND_KEY:format(roleId), objectId) + red:hdel(FRIEND_KEY:format(objectId), roleId) + red:sadd(FRIEND_BLACK_KEY:format(roleId), objectId) + end) + end + elseif cmd == 2 then + redisproxy:SREM(FRIEND_BLACK_KEY:format(roleId), objectId) + else + return + end + + SendPacket(actionCodes.Friend_blockRpc, MsgPack.pack({result = result})) + return true +end + +function _M.blockListRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local blockList = {} + + local friends = redisproxy:SMEMBERS(FRIEND_BLACK_KEY:format(roleId)) + for _ , id in pairs(friends) do + id = tonumber(id) + local online, info = getRoleInfo(id) + table.insert(blockList, table_merge({ + roleId = id, online = online + }, info, { + + })) + end + SendPacket(actionCodes.Friend_blockListRpc, MsgPack.pack({list = blockList})) + return true +end + +function _M.infoRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local objectId = msg.roleId + if not redisproxy:exists(string_format("role:%d", objectId)) then + return + end + + local online, info = getRoleAllInfo(objectId) + local redret = redisproxy:pipelining(function (red) + red:hexists(FRIEND_KEY:format(roleId), objectId) + red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) + end) + local isFriend = redret[1] == 1 and 1 or nil + local hadApply = redret[2] == 1 and 1 or nil + local inBlack = redret[3] == 1 and 1 or nil + + local objInfo = table_merge({ + roleId = objectId, + online = online, + isFriend = isFriend, + hadApply = hadApply, + inBlack = inBlack, + }, info, { + + }) + SendPacket(actionCodes.Friend_infoRpc, MsgPack.pack({info = objInfo})) + return true +end + +function _M.pointRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + local cmd = msg.cmd + local result = nil + local reward = {} + if cmd == 1 then -- 赠送 + local objId = msg.roleId + local giveP = role.dailyData:getProperty("giveFP") + if not result and giveP[objId] then + result = 1 + end + if not result and not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then + result = 2 + end + if not result then + redisproxy:sadd(FRIEND_POINT:format(objId), roleId) + giveP[objId] = 1 + role.dailyData:updateProperty({field = "giveFP", value = giveP}) + rpcRole(objId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({newPoint = 1, roleId = roleId})) + end + elseif cmd == 2 then -- 领取 + local objId = msg.roleId + local getP = role.dailyData:getProperty("getFP") + if not result and table.numbers(getP) >= globalCsv.friendPointLimit then + result = 1 + end + if not result and getP[objId] then + result = 2 + end + if not redisproxy:sismember(FRIEND_POINT:format(roleId), objId) then + result = 3 + end + if not result then + getP[objId] = 1 + reward = role:award({[ItemId.FriendPoint] = 1}) + role.dailyData:updateProperty({field = "getFP", value = getP}) + end + elseif cmd == 3 then -- 一键赠送领取 + -- 赠送 + local giveP = role.dailyData:getProperty("giveFP") + local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) + local change = false + redisproxy:pipelining(function(red) + for i = 1, #friends , 2 do + local objId = tonumber(friends[i]) + if not giveP[objId] then + giveP[objId] = 1 + change = true + red:sadd(FRIEND_POINT:format(objId), roleId) + rpcRole(objId, "SendPacket", actionCodes.Friend_updateProperty, MsgPack.pack({newPoint = 1, roleId = roleId})) + end + end + end) + if change then + role.dailyData:updateProperty({field = "giveFP", value = giveP}) + else + result = 1 + end + + --领取 + local getP = role.dailyData:getProperty("getFP") + local curCount = table.numbers(getP) + local getCount = 0 + if curCount < globalCsv.friendPointLimit then + for _, objId in pairs(redisproxy:SMEMBERS(FRIEND_POINT:format(roleId))) do + local objId = tonumber(objId) + if not getP[objId] then + getCount = getCount + 1 + curCount = curCount + 1 + getP[objId] = 1 + if curCount >= globalCsv.friendPointLimit then + break + end + end + end + if getCount > 0 then + reward = role:award({[ItemId.FriendPoint] = getCount}) + role.dailyData:updateProperty({field = "getFP", value = getP}) + else + result = result + 2 + end + end + else + return + end + SendPacket(actionCodes.Friend_pointRpc, MsgPack.pack({result = result, reward = reward})) + return true +end +function _M.randomRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + + local redret = redisproxy:pipelining(function (red) + red:hgetall(FRIEND_KEY:format(roleId)) + red:zrevrange(FRIEND_RECOMMEND, 0, globalCsv.friendRecommendLimit + globalCsv.friendListLimit) + end) + + local friends = redret[1] + local newList = redret[2] + local needRoleIds = {} + for _, newId in pairs(newList) do + local numNewId = tonumber(newId) + if numNewId ~= roleId and not friends[newId] then + table.insert(needRoleIds, numNewId) + end + end + + local randomRoles = {} + for _, objId in ipairs(needRoleIds) do + local online, info = getRoleInfo(objId) + local redret = redisproxy:pipelining(function (red) + red:zscore(FRIEND_APPLY_KEY:format(objId), roleId) + red:sismember(FRIEND_BLACK_KEY:format(roleId), objId) + end) + local hadApply = redret[1] and 1 or nil + local inBlack = redret[2] == 1 and 1 or nil + + table.insert(randomRoles, table_merge({ + roleId = objId, + online = online, + hadApply = hadApply, + inBlack = inBlack, + }, info, { + + })) + if #randomRoles >= globalCsv.friendRecommendLimit then break end + end + + SendPacket(actionCodes.Friend_randomRpc, MsgPack.pack({list = randomRoles})) + return true +end + + +return _M \ No newline at end of file diff --git a/src/actions/RoleAction.lua b/src/actions/RoleAction.lua index 94bd84d..bcb0ffc 100644 --- a/src/actions/RoleAction.lua +++ b/src/actions/RoleAction.lua @@ -122,7 +122,7 @@ function _M.loginRpc( agent, data ) role:onCrossDay(now) role:onResetRank(now) role:setProperty("ltime", now) - + redisproxy:zadd(FRIEND_RECOMMEND, now, roleId) for _, name in ipairs({"dailyData", "dinerData"}) do response[name] = role[name]:data() @@ -161,7 +161,7 @@ function _M.loginRpc( agent, data ) end end - response.wave = 1 + heroWave + runeWave + response.wave = 1 + heroWave + runeWave + 1 SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) @@ -213,10 +213,24 @@ function _M.loginRpc( agent, data ) start_agent_timer() -- 注册全服广播 local channel = math.randomInt(1, 1) + role._channelIdx = channel local w_channel = datacenter.get( ("MC_W_CHANNEL" .. channel) ) if w_channel then mcast_util.sub_world(w_channel) end + + -- 发下缓存的世界消息 + local worldChatResponse = {worldChats = {}} + local ok, msgs = pcall(skynet.call, 'GLOBALD', "lua", "getWorldMsg", channel) + if not ok then + msgs = {} + end + worldChatResponse.worldChats = msgs + worldChatResponse.chatWave = curWave + 1 + curWave = curWave + 1 + + SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(worldChatResponse)) + return true end @@ -352,7 +366,7 @@ function _M.openTimeBoxRpc(agent, data) local itemId = msg.itemId if role:getItemCount(itemId) < 1 then return end local itemData = csvdb["itemCsv"][itemId] - local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] + local randomData = csvdb["item_randomCsv"][itemId] if not randomData or randomData.openTime <= 0 then return end if boxL[slot] then return end @@ -364,7 +378,7 @@ function _M.openTimeBoxRpc(agent, data) if not boxL[slot] then return end if boxL[slot].gem or boxL[slot].time <= skynet.timex() then return end local itemData = csvdb["itemCsv"][boxL[slot].id] - local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] + local randomData = csvdb["item_randomCsv"][itemId] local num = randomData[gemId .. "_gem_num"] if not num then return end @@ -383,7 +397,7 @@ function _M.openTimeBoxRpc(agent, data) end local itemData = csvdb["itemCsv"][boxL[slot].id] - local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] + local randomData = csvdb["item_randomCsv"][itemId] reward = randomData.gift:toNumMap() -- 固定奖励 -- 随机奖励 local randomGift = randomData.random_gift @@ -551,5 +565,73 @@ function _M.achiveRpc(agent, data) return true end +function _M.chatRpc(agent, data) + local role = agent.role + local roleId = role:getProperty("id") + local msg = MsgPack.unpack(data) + + local cmd = msg.cmd + local content = msg.content + + if not content then return end + + local now = skynet.timex() + -- 判断禁言 + local result = nil + + local SERV = string_format("CHATED%d", math.random(1, 5)) + local legal, mod = skynet.call(SERV, "lua", "check", content) + if not legal then + content = mod or "" + end + + if content == "" then + result = -1 + end + + local response = { + chatType = cmd, + player = { + roleId = role:getProperty("id"), + name = role:getProperty("name"), + level = role:getProperty("level"), + headId = role:getProperty("headId"), + }, + content = content, + time = now, + } + + local check = { + ["world"] = function () + if role:getProperty("silent") > now then --禁言 + result = 1 + return + end + mcast_util.pub_world(actionCodes.Role_chat, MsgPack.pack(response)) + pcall(skynet.call, 'GLOBALD', "lua", "sendWorldMsg", role._channelIdx, response) + end, + ["p2p"] = function () + -- local result + -- local objectId = msg.objectId + -- if redisproxy:hexists(FRIEND_KEY:format(roleId), objectId) then + -- response.to = objectId + -- result = mcast_util.pub_person(agent.client_fd, objectId, actionCodes.Role_chat, MsgPack.pack(response)) + -- else + -- result = SYS_ERR_CHAT_NOT_FRIEND + -- end + -- if result then + -- role:sendSysErrMsg(result) + -- end + end, + } + if not check[cmd] then return end + + if not result then + check[cmd]() + end + SendPacket(actionCodes.Role_chatRpc, MsgPack.pack({result = result})) + return true +end + return _M \ No newline at end of file diff --git a/src/agent.lua b/src/agent.lua index 25b8401..3584856 100644 --- a/src/agent.lua +++ b/src/agent.lua @@ -140,6 +140,11 @@ function rpcRole(roleId, funcName, ...) result[#result+1] = v end return false, redisproxy:hmset(rediskey, table_unpack(result)) + elseif funcName == "friendSInfo" or funcName == "friendInfo" then + local sRole = require("models.Role").new({key = rediskey}) + sRole:load() + sRole:loadAll() + return false, sRole[funcName] and sRole[funcName](sRole, ...) end end end diff --git a/src/models/Daily.lua b/src/models/Daily.lua index 1d7551d..e3f36f4 100644 --- a/src/models/Daily.lua +++ b/src/models/Daily.lua @@ -15,7 +15,9 @@ Daily.schema = { advBC = {"number", 0}, -- 冒险次数购买次数(冒险体力购买次数) advElBC = {"number", 0}, -- 无尽次数购买次数(冒险体力购买次数) advWs = {"table", {}}, -- 冒险队工坊 - bonusC = {"table", {}} -- 奖励副本 次数 {[type] = {c = 0, b = 0}} + bonusC = {"table", {}}, -- 奖励副本 次数 {[type] = {c = 0, b = 0}} + giveFP = {"table", {}}, -- 给谁送过心心 + getFP = {"table", {}}, -- 领过谁的心心 } function Daily:updateProperty(params) @@ -35,6 +37,7 @@ function Daily:updateProperty(params) end function Daily:refreshDailyData(notify) + redisproxy:del(FRIEND_POINT:format(self.owner:getProperty("id"))) for field, schema in pairs(self.schema) do if field ~= "key" then local typ, def = table.unpack(schema) @@ -56,6 +59,8 @@ function Daily:data() advElBC = self:getProperty("advElBC"), advWs = self:getProperty("advWs"), bonusC = self:getProperty("bonusC"), + giveFP = self:getProperty("giveFP"), + getFP = self:getProperty("getFP"), } end diff --git a/src/models/Role.lua b/src/models/Role.lua index 6f41d96..6b9227d 100644 --- a/src/models/Role.lua +++ b/src/models/Role.lua @@ -41,6 +41,7 @@ Role.schema = { funcLv = {"table", {}}, --功能等级 loveStatus = {"string", ""}, --统计角色的最高 好感度等级 类型相关 -- type=loveL type=loveL crown = {"number", 0}, -- 看伴娘 + silent = {"number", 0}, --禁言解禁时间 bagLimit = {"table", globalCsv.store_limit_max}, diff --git a/src/models/RolePlugin.lua b/src/models/RolePlugin.lua index 9fb9e88..8338f4d 100644 --- a/src/models/RolePlugin.lua +++ b/src/models/RolePlugin.lua @@ -19,6 +19,10 @@ function RolePlugin.bind(Role) function Role:reloadWhenLogin() end + function Role:SendPacket(...) + SendPacket(...) + end + function Role:onCrossDay(now, notify) local ltime = self:getProperty("ltime") @@ -72,7 +76,8 @@ function RolePlugin.bind(Role) end function Role:onOfflineEvent() - + -- 设置最新的登录时间 + self:setProperty("ltime", skynet.timex()) end local function checkItemCount(self, itemId, count) @@ -613,8 +618,8 @@ function RolePlugin.bind(Role) return result end - function Role:getRealBattleValue(heros) -- 获取队伍战斗力 羁绊加成 - local activeRelation = self:getHeroActiveRelation(heros) + function Role:getRealBattleValue(heros, activeRelation) -- 获取队伍战斗力 羁绊加成 + local activeRelation = activeRelation or self:getHeroActiveRelation(heros) local battleValue = 0 for _, id in pairs(heros) do local hero = self.heros[id] @@ -719,7 +724,7 @@ function RolePlugin.bind(Role) heros[slot] = { htype = hero:getProperty("type"), lv = hero:getProperty("level"), - breakL = hero:getProperty("breakL"), + wakeL = hero:getProperty("wakeL"), } end return heros @@ -811,6 +816,57 @@ function RolePlugin.bind(Role) end self:updateProperty({field = "advL", value = advL}) end + -- 好友列表简约信息 + function Role:friendSInfo() + local info = { + name = self:getProperty("name"), + level = self:getProperty("level"), + headId = self:getProperty("headId"), + ltime = self:getProperty("ltime"), + battleV = self:getTeamBattleValue(self:getProperty("hangTeam").heros or {}), -- Todo + } + return info + end + + local slotToPos = { + [1] = 6, + [2] = 2, + [3] = 35, + [4] = 32, + [5] = 29, + } + function Role:getTeamBattleInfo(team) + local heros = {} + -- local activeRelation = self:getHeroActiveRelation(team.heros) + + for slot, id in pairs(team.heros or {}) do + local info = {id = id} + local hero = self.heros[info.id] + if not hero then + print("error heroid " .. info.id) + end + -- local attrs = hero:getTotalAttrs({activeRelation = activeRelation}) + -- for k, v in pairs(AttsEnumEx) do + -- info[v] = (attrs[v] or 0) + -- end + -- info.blockLevel = hero:getSkillLevel(4) + -- info.specialLevel = hero:getSkillLevel(1) + + info.type = hero:getProperty("type") + info.level = hero:getProperty("level") + info.wakeL = hero:getProperty("wakeL") + heros[slot] = info + end + return heros + end + + -- 角色详细信息 + function Role:friendInfo() + local info = self:friendSInfo() + local heros = self:getTeamBattleInfo(self:getProperty("hangTeam")) + info.heros = heros + return info + end end return RolePlugin \ No newline at end of file diff --git a/src/services/globald.lua b/src/services/globald.lua index 6c3c287..08bead6 100644 --- a/src/services/globald.lua +++ b/src/services/globald.lua @@ -17,7 +17,6 @@ local pointDataMark = {} local utils = {} local CHECK_MAIL_STATUS_INTERVAL = 60 - local function mailQuene() local delayEmail = tonum(redisproxy:hget("autoincrement_set", "delay_email")) if delayEmail == 0 then @@ -91,15 +90,40 @@ local function check_mail_queue() skynet.timeout(CHECK_MAIL_STATUS_INTERVAL, check_mail_queue) end + + local CMD = {} + +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() check_mail_queue() end local function __init__() skynet.dispatch("lua", function(_, _, command, ...) - if CMD[command] then - skynet.ret(skynet.pack(CMD[command](...))) + local f = CMD[command] + if f then + if command == "sendWorldMsg" then + skynet.ignoreret() + f(...) + else + skynet.ret(skynet.pack(f(...))) + end end end) redisd = harbor.queryname("REDIS") diff --git a/src/services/named.lua b/src/services/named.lua index a2c5d27..1d771fa 100644 --- a/src/services/named.lua +++ b/src/services/named.lua @@ -39,7 +39,7 @@ if mode == "sub" then end) else skynet.start(function() - local ok, forbidNames = pcall(require, "csvdata.name_forbid") + local ok, forbidNames = pcall(require, "csvdata.forbid_name") if not ok then forbidNames = {} end local words = {} diff --git a/src/utils/TableUtil.lua b/src/utils/TableUtil.lua index b858f7a..9cb7bb4 100644 --- a/src/utils/TableUtil.lua +++ b/src/utils/TableUtil.lua @@ -11,4 +11,12 @@ function table.clear(tab) for k, _ in pairs(tab) do tab[k] = nil end +end + +function table.numbers(tab) + local count = 0 + for k, _ in pairs(tab) do + count = count + 1 + end + return count end \ No newline at end of file -- libgit2 0.21.2