Commit be9c9ca6ce47cadbc80f28f616678e546fec02c4
1 parent
07fd5799
角色评论
Showing
6 changed files
with
303 additions
and
7 deletions
Show diff stats
src/ProtocolCode.lua
| @@ -27,6 +27,10 @@ actionCodes = { | @@ -27,6 +27,10 @@ actionCodes = { | ||
| 27 | Hero_wakeRpc = 205, | 27 | Hero_wakeRpc = 205, |
| 28 | Hero_skillUpRpc = 206, | 28 | Hero_skillUpRpc = 206, |
| 29 | Hero_talentRpc = 207, | 29 | Hero_talentRpc = 207, |
| 30 | + Hero_likeHeroRpc = 208, | ||
| 31 | + Hero_commentHeroRpc = 209, | ||
| 32 | + Hero_getCommentsRpc = 210, | ||
| 33 | + Hero_likeCommentRpc = 211, | ||
| 30 | } | 34 | } |
| 31 | 35 | ||
| 32 | rpcResponseBegin = 10000 | 36 | rpcResponseBegin = 10000 |
src/RedisKeys.lua
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | R_INCR = "role:%d:autoincr" | 3 | R_INCR = "role:%d:autoincr" |
| 4 | R_HEROS = "role:%d:heroIds" | 4 | R_HEROS = "role:%d:heroIds" |
| 5 | R_HERO = "hero:%d:%d" | 5 | R_HERO = "hero:%d:%d" |
| 6 | +R_DAILY = "role:%d:daily" | ||
| 6 | 7 | ||
| 7 | -- -- role | 8 | -- -- role |
| 8 | -- R_FARM_KEY = "role:%d:farm" | 9 | -- R_FARM_KEY = "role:%d:farm" |
src/actions/HeroAction.lua
| @@ -12,6 +12,7 @@ local tonumber = tonumber | @@ -12,6 +12,7 @@ local tonumber = tonumber | ||
| 12 | local require = require | 12 | local require = require |
| 13 | local table_insert = table.insert | 13 | local table_insert = table.insert |
| 14 | local tconcat = table.concat | 14 | local tconcat = table.concat |
| 15 | +local table_unpack = table.unpack | ||
| 15 | 16 | ||
| 16 | local _M = {} | 17 | local _M = {} |
| 17 | function _M.levelUpRpc( agent, data ) | 18 | function _M.levelUpRpc( agent, data ) |
| @@ -128,4 +129,208 @@ function _M.talentRpc(agent, data) | @@ -128,4 +129,208 @@ function _M.talentRpc(agent, data) | ||
| 128 | return true | 129 | return true |
| 129 | end | 130 | end |
| 130 | 131 | ||
| 132 | +-- 暂时没有这个功能 | ||
| 133 | +function _M.likeHeroRpc(agent, data) | ||
| 134 | + local role = agent.role | ||
| 135 | + local msg = MsgPack.unpack(data) | ||
| 136 | + local heroType = msg.type | ||
| 137 | + local result = {status = 0} | ||
| 138 | + local isLike = false | ||
| 139 | + local hadLike = role:getProperty("likeHero"):toArray(true, "=") | ||
| 140 | + for _, v in pairs(hadLike) do | ||
| 141 | + if v == heroType then | ||
| 142 | + isLike = true | ||
| 143 | + break | ||
| 144 | + end | ||
| 145 | + end | ||
| 146 | + if isLike then | ||
| 147 | + result.status = 1 | ||
| 148 | + else | ||
| 149 | + redisproxy:hincrby("hero:like", "hero:"..heroType, 1) | ||
| 150 | + table.insert(hadLike, heroType) | ||
| 151 | + role:setProperty("likeHero", table.concat(hadLike, "=")) | ||
| 152 | + end | ||
| 153 | + | ||
| 154 | + SendPacket(actionCodes.Hero_likeHeroRpc, MsgPack.pack(result)) | ||
| 155 | + return true | ||
| 156 | +end | ||
| 157 | +local RankLikeNum = 5 --热度显示几个 | ||
| 158 | +local TimeLikeNum = 95 -- 时间显示几个 | ||
| 159 | +local function getCommentKey(heroType) | ||
| 160 | + return { | ||
| 161 | + commentListKey = string.format("list:%d:herocomments", heroType), | ||
| 162 | + commentRankKey = string.format("rank:%d:herocomments", heroType), | ||
| 163 | + commentKey = string.format("hero:%d:comments", heroType), | ||
| 164 | + } | ||
| 165 | +end | ||
| 166 | + | ||
| 167 | +local function trimComment(heroType, commentId) -- 剪裁 CommentList | ||
| 168 | + local commentKey = getCommentKey(heroType) | ||
| 169 | + local redret = redisproxy:pipelining(function (red) | ||
| 170 | + red:lpush(commentKey.commentListKey, commentId) | ||
| 171 | + red:lrange(commentKey.commentListKey, TimeLikeNum,-1) | ||
| 172 | + red:ltrim(commentKey.commentListKey, 0, TimeLikeNum - 1) | ||
| 173 | + red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) | ||
| 174 | + end) | ||
| 175 | + local hots = {} | ||
| 176 | + for _, hot in pairs(redret[4]) do | ||
| 177 | + hots[hot] = 1 | ||
| 178 | + end | ||
| 179 | + redisproxy:pipelining(function (red) | ||
| 180 | + local needDel = {} | ||
| 181 | + for _, tempId in pairs(redret[2]) do | ||
| 182 | + if not hots[tempId] then | ||
| 183 | + table.insert(needDel, tempId) | ||
| 184 | + end | ||
| 185 | + end | ||
| 186 | + if #needDel > 0 then | ||
| 187 | + red:zrem(commentKey.commentRankKey, table_unpack(needDel)) | ||
| 188 | + red:hdel(commentKey.commentKey, table_unpack(needDel)) | ||
| 189 | + end | ||
| 190 | + end) | ||
| 191 | +end | ||
| 192 | + | ||
| 193 | + | ||
| 194 | +function _M.commentHeroRpc(agent, data) | ||
| 195 | + local role = agent.role | ||
| 196 | + local msg = MsgPack.unpack(data) | ||
| 197 | + local heroType = msg.type | ||
| 198 | + local content = msg.content | ||
| 199 | + | ||
| 200 | + local result = {status = 0} -- status 0 成功 1 已经评论过了 | ||
| 201 | + local curStutus = role.dailyData:getProperty("commentHero") | ||
| 202 | + if curStutus:getv(heroType, 0) ~= 0 then | ||
| 203 | + result.status = 1 | ||
| 204 | + else | ||
| 205 | + local commentKey = getCommentKey(heroType) | ||
| 206 | + local SERV = string.format("NAMED%d", math.random(1, 5)) | ||
| 207 | + local legal, mod = skynet.call(SERV, "lua", "check", content) | ||
| 208 | + if not legal then | ||
| 209 | + content = mod or "" | ||
| 210 | + end | ||
| 211 | + local commentId = tostring(redisproxy:hincrby("hero:comment:autoincr", "hero:" .. heroType, 1)) | ||
| 212 | + local comment = { | ||
| 213 | + commentId = commentId, | ||
| 214 | + content = content, | ||
| 215 | + roleId = role:getProperty("id"), | ||
| 216 | + name = role:getProperty("name"), | ||
| 217 | + -- time = skynet.timex() | ||
| 218 | + } | ||
| 219 | + redisproxy:hset(commentKey.commentKey, commentId, json.encode(comment)) | ||
| 220 | + trimComment(heroType, commentId) | ||
| 221 | + | ||
| 222 | + comment.like = 0 | ||
| 223 | + result.comment = comment | ||
| 224 | + role.dailyData:setProperty("commentHero", curStutus:setv(heroType, 1)) | ||
| 225 | + end | ||
| 226 | + SendPacket(actionCodes.Hero_commentHeroRpc, MsgPack.pack(result)) | ||
| 227 | + return true | ||
| 228 | +end | ||
| 229 | + | ||
| 230 | +function _M.getCommentsRpc(agent, data) | ||
| 231 | + local role = agent.role | ||
| 232 | + local msg = MsgPack.unpack(data) | ||
| 233 | + local heroType = msg.type | ||
| 234 | + local list = {} -- 评论列表 | ||
| 235 | + local commentKey = getCommentKey(heroType) | ||
| 236 | + local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) | ||
| 237 | + local redret = redisproxy:pipelining(function (red) | ||
| 238 | + red:lrange(commentKey.commentListKey, 0,TimeLikeNum - 1) | ||
| 239 | + red:zrevrange(commentKey.commentRankKey, 0, -1, "WITHSCORES") --热门 | ||
| 240 | + red:hget("hero:like", "hero:"..heroType) | ||
| 241 | + red:lrange(commentRoleKey, 0, 999) | ||
| 242 | + end) | ||
| 243 | + | ||
| 244 | + local likeMap = {} | ||
| 245 | + local idList = {} | ||
| 246 | + local liked = {} | ||
| 247 | + for i = 1, #redret[2], 2 do | ||
| 248 | + likeMap[redret[2][i]] = redret[2][i + 1] | ||
| 249 | + if i < RankLikeNum * 2 then | ||
| 250 | + table.insert(idList, redret[2][i]) | ||
| 251 | + end | ||
| 252 | + end | ||
| 253 | + for i = 1, #redret[1] do | ||
| 254 | + table.insert(idList, redret[1][i]) | ||
| 255 | + end | ||
| 256 | + for i = 1, #redret[4] do | ||
| 257 | + liked[redret[4][i]] = 1 | ||
| 258 | + end | ||
| 259 | + | ||
| 260 | + local commentData = redisproxy:pipelining(function (red) | ||
| 261 | + for _, commentId in ipairs(idList) do | ||
| 262 | + red:hget(commentKey.commentKey, commentId) | ||
| 263 | + end | ||
| 264 | + end) | ||
| 265 | + for _, commentS in ipairs(commentData or {}) do | ||
| 266 | + local comment = json.decode(commentS) | ||
| 267 | + comment.like = likeMap[tostring(comment.commentId)] or 0 | ||
| 268 | + comment.liked = liked[heroType .. ":" .. comment.commentId] or 0 | ||
| 269 | + table.insert(list, comment) | ||
| 270 | + end | ||
| 271 | + SendPacket(actionCodes.Hero_getCommentsRpc, MsgPack.pack({list = list, like = tonumber(redret[3] or 0)})) | ||
| 272 | + return true | ||
| 273 | +end | ||
| 274 | + | ||
| 275 | +function _M.likeCommentRpc(agent, data) | ||
| 276 | + local role = agent.role | ||
| 277 | + local msg = MsgPack.unpack(data) | ||
| 278 | + local actType = msg.actType -- 1 顶 2 踩 | ||
| 279 | + local heroType = msg.type | ||
| 280 | + local commentId = msg.commentId --评论id | ||
| 281 | + local commentKey = getCommentKey(heroType) | ||
| 282 | + local add = 0 | ||
| 283 | + if actType == 1 then | ||
| 284 | + add = 1 | ||
| 285 | + elseif actType == 2 then | ||
| 286 | + add = -1 | ||
| 287 | + else | ||
| 288 | + return | ||
| 289 | + end | ||
| 290 | + | ||
| 291 | + local result = {status = 0} | ||
| 292 | + local commentIndex = heroType .. ":" .. commentId | ||
| 293 | + local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) | ||
| 294 | + local redret = redisproxy:pipelining(function (red) | ||
| 295 | + red:hexists(commentKey.commentKey, commentId) | ||
| 296 | + red:lrem(commentRoleKey, 1, commentIndex) | ||
| 297 | + red:lpush(commentRoleKey, commentIndex) | ||
| 298 | + red:ltrim(commentRoleKey, 0, 999) | ||
| 299 | + end) | ||
| 300 | + if (tonumber(redret[2]) or 0) > 0 then | ||
| 301 | + result.status = 1 | ||
| 302 | + else | ||
| 303 | + if redret[1] == 1 then-- 查不到也返回ture | ||
| 304 | + local redret2 = redisproxy:pipelining(function (red) | ||
| 305 | + red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 | ||
| 306 | + red:zincrby(commentKey.commentRankKey, add, commentId) | ||
| 307 | + red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 | ||
| 308 | + end) | ||
| 309 | + local out = {} | ||
| 310 | + for _, v in pairs(redret2[1]) do | ||
| 311 | + out[v] = 1 | ||
| 312 | + end | ||
| 313 | + local new = {} | ||
| 314 | + for _, v in pairs(redret2[3]) do | ||
| 315 | + if out[v] then | ||
| 316 | + out[v] = nil | ||
| 317 | + else | ||
| 318 | + new[v] = 1 | ||
| 319 | + end | ||
| 320 | + end | ||
| 321 | + for tempId, _ in pairs(out) do | ||
| 322 | + trimComment(heroType, tempId) | ||
| 323 | + end | ||
| 324 | + redisproxy:pipelining(function (red) | ||
| 325 | + for tempId, _ in pairs(new) do | ||
| 326 | + red:lrem(commentKey.commentListKey, 0, tempId) | ||
| 327 | + end | ||
| 328 | + end) | ||
| 329 | + end | ||
| 330 | + end | ||
| 331 | + | ||
| 332 | + SendPacket(actionCodes.Hero_likeCommentRpc, MsgPack.pack(result)) | ||
| 333 | + return true | ||
| 334 | +end | ||
| 335 | + | ||
| 131 | return _M | 336 | return _M |
| 132 | \ No newline at end of file | 337 | \ No newline at end of file |
src/actions/RoleAction.lua
| @@ -121,9 +121,13 @@ function _M.loginRpc( agent, data ) | @@ -121,9 +121,13 @@ function _M.loginRpc( agent, data ) | ||
| 121 | 121 | ||
| 122 | -- 跨天登陆事件 | 122 | -- 跨天登陆事件 |
| 123 | role:onCrossDay(now) | 123 | role:onCrossDay(now) |
| 124 | - | ||
| 125 | role:setProperty("ltime", now) | 124 | role:setProperty("ltime", now) |
| 126 | 125 | ||
| 126 | + | ||
| 127 | + for _, name in ipairs({"dailyData"}) do | ||
| 128 | + response[name] = role[name]:data() | ||
| 129 | + end | ||
| 130 | + | ||
| 127 | response.role = role:data() | 131 | response.role = role:data() |
| 128 | response.result = "SUCCESS" | 132 | response.result = "SUCCESS" |
| 129 | response.serverTime = now | 133 | response.serverTime = now |
| @@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
| 1 | +-- 日常数据 | ||
| 2 | + | ||
| 3 | +local Daily = class("Daily", require("shared.ModelBase")) | ||
| 4 | + | ||
| 5 | +function Daily:ctor(properties) | ||
| 6 | + Daily.super.ctor(self, properties) | ||
| 7 | +end | ||
| 8 | + | ||
| 9 | +Daily.schema = { | ||
| 10 | + key = {"string"}, -- redis key | ||
| 11 | + commentHero = {"string", ""}, --单日评论食灵记录 type=1 | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +Daily.fields = { | ||
| 15 | + commentHero = true, | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +function Daily:updateProperty(params) | ||
| 19 | + local type, default = table.unpack(self.schema[params.field]) | ||
| 20 | + | ||
| 21 | + if params.delta then | ||
| 22 | + self:setProperty(params.field, self:getProperty(paramsfield) + params.delta) | ||
| 23 | + self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) | ||
| 24 | + return true | ||
| 25 | + end | ||
| 26 | + if params.value then | ||
| 27 | + self:setProperty(params.field, params.value) | ||
| 28 | + self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) | ||
| 29 | + return true | ||
| 30 | + end | ||
| 31 | + return false | ||
| 32 | +end | ||
| 33 | + | ||
| 34 | +function Daily:refreshDailyData(notify) | ||
| 35 | + for field, schema in pairs(self.schema) do | ||
| 36 | + if field ~= "key" then | ||
| 37 | + local typ, def = table.unpack(schema) | ||
| 38 | + self:setProperty(field, def) | ||
| 39 | + end | ||
| 40 | + end | ||
| 41 | + if notify then | ||
| 42 | + self.owner:notifyUpdateProperties(self:data()) | ||
| 43 | + end | ||
| 44 | +end | ||
| 45 | + | ||
| 46 | +function Daily:data() | ||
| 47 | + return { | ||
| 48 | + -- dailyTaskStatus = self:getProperty("dailyTaskStatus"), | ||
| 49 | + } | ||
| 50 | +end | ||
| 51 | + | ||
| 52 | +return Daily | ||
| 0 | \ No newline at end of file | 53 | \ No newline at end of file |
src/models/RolePlugin.lua
| @@ -9,14 +9,27 @@ function RolePlugin.bind(Role) | @@ -9,14 +9,27 @@ function RolePlugin.bind(Role) | ||
| 9 | end | 9 | end |
| 10 | 10 | ||
| 11 | function Role:loadAll() | 11 | function Role:loadAll() |
| 12 | + self:loadDaily() | ||
| 12 | self:loadHeros() | 13 | self:loadHeros() |
| 13 | end | 14 | end |
| 14 | 15 | ||
| 15 | function Role:reloadWhenLogin() | 16 | function Role:reloadWhenLogin() |
| 16 | end | 17 | end |
| 17 | 18 | ||
| 18 | - function Role:onCrossDay(now) | 19 | + function Role:onCrossDay(now, notify) |
| 20 | + local roleId = self:getProperty("id") | ||
| 21 | + local ltime = self:getProperty("ltime") | ||
| 22 | + | ||
| 23 | + if isCrossDay(ltime, now) then | ||
| 24 | + local response = {} | ||
| 19 | 25 | ||
| 26 | + self.dailyData:refreshDailyData(notify) | ||
| 27 | + | ||
| 28 | + if notify then | ||
| 29 | + self:notifyUpdateProperties(response) | ||
| 30 | + end | ||
| 31 | + return true | ||
| 32 | + end | ||
| 20 | end | 33 | end |
| 21 | function Role:onOfflineEvent() | 34 | function Role:onOfflineEvent() |
| 22 | 35 | ||
| @@ -28,11 +41,17 @@ function RolePlugin.bind(Role) | @@ -28,11 +41,17 @@ function RolePlugin.bind(Role) | ||
| 28 | local curType = itemData.type | 41 | local curType = itemData.type |
| 29 | local change = {} -- 奖励被转化为了其他奖励 id = count | 42 | local change = {} -- 奖励被转化为了其他奖励 id = count |
| 30 | 43 | ||
| 31 | - if curType == ItemType.Hero then | ||
| 32 | - params.type = itemId - ItemStartId.Hero | ||
| 33 | - for i = 1, count do | ||
| 34 | - self:addHero(params) | ||
| 35 | - end | 44 | + local itemTypeAward = { |
| 45 | + [ItemType.Hero] = function() | ||
| 46 | + params.type = itemId - ItemStartId.Hero | ||
| 47 | + for i = 1, count do | ||
| 48 | + self:addHero(params) | ||
| 49 | + end | ||
| 50 | + end, | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + if itemTypeAward[curType] then | ||
| 54 | + itemTypeAward[curType]() | ||
| 36 | else | 55 | else |
| 37 | params.itemId = itemId | 56 | params.itemId = itemId |
| 38 | params.count = count | 57 | params.count = count |
| @@ -171,6 +190,17 @@ function RolePlugin.bind(Role) | @@ -171,6 +190,17 @@ function RolePlugin.bind(Role) | ||
| 171 | end | 190 | end |
| 172 | end | 191 | end |
| 173 | 192 | ||
| 193 | + function Role:loadDaily() | ||
| 194 | + local roleId = self:getProperty("id") | ||
| 195 | + local dataKey = string.format(R_DAILY, roleId) | ||
| 196 | + self.dailyData = require("models.Daily").new({key = dataKey}) | ||
| 197 | + self.dailyData.owner = self | ||
| 198 | + if not redisproxy:exists(dataKey) then | ||
| 199 | + self.dailyData:create() | ||
| 200 | + else | ||
| 201 | + self.dailyData:load() | ||
| 202 | + end | ||
| 203 | + end | ||
| 174 | end | 204 | end |
| 175 | 205 | ||
| 176 | return RolePlugin | 206 | return RolePlugin |
| 177 | \ No newline at end of file | 207 | \ No newline at end of file |