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 |