Commit fa565e0c47dfd1d9d94b27263f27b2377ecba312
1 parent
6bccc3a9
优化结构
Showing
12 changed files
with
559 additions
and
232 deletions
Show diff stats
src/RedisKeys.lua
... | ... | @@ -18,10 +18,7 @@ RANK_DINER = {"rank:diner1", "rank:diner2"} -- é¤åŽ…æŽ’è¡Œæ¦œ 两个æ¯å¤©äº’æ |
18 | 18 | RANK_DINER_INFO = "rank:diner:info" |
19 | 19 | |
20 | 20 | RANK_PVP_COMMON = "rank:pvpc" |
21 | -RANK_PVP_INFO_COMMON = "rank:pvpc:info" | |
22 | - | |
23 | 21 | RANK_PVP_HIGHT = "rank:pvph" |
24 | -RANK_PVP_INFO_HIGHT = "rank:pvph:info" | |
25 | 22 | -- -- role |
26 | 23 | -- R_FARM_KEY = "role:%d:farm" |
27 | 24 | -- R_TOWER_KEY = "role:%d:tower" | ... | ... |
src/actions/HangAction.lua
... | ... | @@ -208,8 +208,7 @@ function _M.roleFormatRpc(agent , data) |
208 | 208 | hangTeam.heros[slot] = heroId |
209 | 209 | end |
210 | 210 | hangTeam.leader = msg.leader |
211 | - | |
212 | - role:updateProperty({field = "hangTeam", value = hangTeam}) | |
211 | + role:saveHangTeam(hangTeam) | |
213 | 212 | SendPacket(actionCodes.Hang_roleFormatRpc, '') |
214 | 213 | return true |
215 | 214 | end | ... | ... |
src/actions/PvpAction.lua
... | ... | @@ -10,21 +10,26 @@ local _M = {} |
10 | 10 | |
11 | 11 | function _M.formatCommonRpc(agent , data) |
12 | 12 | local role = agent.role |
13 | + local roleId = role:getProperty("id") | |
13 | 14 | local msg = MsgPack.unpack(data) |
14 | - local pvpFC = role.pvpData:getProperty("pvpFC") | |
15 | + local pvpTC = role:getProperty("pvpTC") | |
15 | 16 | for slot, heroId in pairs(msg.heros) do |
16 | 17 | if not role.heros[heroId] then |
17 | 18 | return |
18 | 19 | end |
19 | 20 | end |
20 | - table.clear(pvpFC) | |
21 | - pvpFC.heros = {} | |
22 | - for slot, heroId in pairs(msg.heros) do | |
23 | - pvpFC.heros[slot] = heroId | |
21 | + if not next(msg.heros) then | |
22 | + return | |
24 | 23 | end |
25 | - pvpFC.leader = msg.leader | |
26 | 24 | |
27 | - role.pvpData:updateProperty({field = "pvpFC", value = pvpFC}) | |
25 | + table.clear(pvpTC) | |
26 | + pvpTC.heros = {} | |
27 | + for slot, heroId in pairs(msg.heros) do | |
28 | + pvpTC.heros[slot] = heroId | |
29 | + end | |
30 | + pvpTC.leader = msg.leader | |
31 | + | |
32 | + role:savePvpCTeam(pvpTC) | |
28 | 33 | SendPacket(actionCodes.Pvp_formatCommonRpc, '') |
29 | 34 | return true |
30 | 35 | end |
... | ... | @@ -32,10 +37,10 @@ end |
32 | 37 | function _M.formatHighRpc(agent , data) |
33 | 38 | local role = agent.role |
34 | 39 | local msg = MsgPack.unpack(data) |
35 | - local pvpFH = role.pvpData:getProperty("pvpFH") | |
40 | + local pvpTH = role.pvpData:getProperty("pvpTH") | |
36 | 41 | |
37 | 42 | |
38 | - role.pvpData:updateProperty({field = "pvpFH", value = pvpFH}) | |
43 | + role.pvpData:updateProperty({field = "pvpTH", value = pvpTH}) | |
39 | 44 | SendPacket(actionCodes.Pvp_formatHighRpc, '') |
40 | 45 | return true |
41 | 46 | end | ... | ... |
src/actions/RoleAction.lua
... | ... | @@ -124,7 +124,7 @@ function _M.loginRpc( agent, data ) |
124 | 124 | role:setProperty("ltime", now) |
125 | 125 | redisproxy:zadd(FRIEND_RECOMMEND, now, roleId) |
126 | 126 | |
127 | - for _, name in ipairs({"dailyData", "dinerData", "pvpData"}) do | |
127 | + for _, name in ipairs({"dailyData", "dinerData"}) do | |
128 | 128 | response[name] = role[name]:data() |
129 | 129 | end |
130 | 130 | |
... | ... | @@ -201,27 +201,23 @@ function _M.loginRpc( agent, data ) |
201 | 201 | end |
202 | 202 | curWave = curWave + heroWave |
203 | 203 | |
204 | - -- role:log("login", { ip = agent.ip, diamond = role:getProperty("diamond"), reDiamond = role:getProperty("reDiamond")}) | |
205 | - | |
206 | - datacenter.set("agent", roleId, { | |
207 | - serv = skynet.self(), | |
208 | - fd = agent.client_fd, | |
209 | - gate_serv = agent.gate_serv, | |
210 | - }) | |
211 | - agent.role = role | |
204 | + | |
212 | 205 | |
213 | - start_agent_timer() | |
214 | 206 | -- 注册全服广播 |
215 | - local channel = math.randomInt(1, 1) | |
216 | - role._channelIdx = channel | |
217 | - local w_channel = datacenter.get( ("MC_W_CHANNEL" .. channel) ) | |
218 | - if w_channel then | |
219 | - mcast_util.sub_world(w_channel) | |
207 | + if not role._channelIdx then | |
208 | + local channel = math.randomInt(1, 1) | |
209 | + role._channelIdx = channel | |
210 | + end | |
211 | + if not mcast_util.channel_world() then | |
212 | + local w_channel = datacenter.get( ("MC_W_CHANNEL" .. role._channelIdx) ) | |
213 | + if w_channel then | |
214 | + mcast_util.sub_world(w_channel) | |
215 | + end | |
220 | 216 | end |
221 | 217 | |
222 | 218 | -- 发下缓存的世界消息 |
223 | 219 | local worldChatResponse = {worldChats = {}} |
224 | - local ok, msgs = pcall(skynet.call, 'GLOBALD', "lua", "getWorldMsg", channel) | |
220 | + local ok, msgs = pcall(skynet.call, 'GLOBALD', "lua", "getWorldMsg", role._channelIdx) | |
225 | 221 | if not ok then |
226 | 222 | msgs = {} |
227 | 223 | end |
... | ... | @@ -232,6 +228,16 @@ function _M.loginRpc( agent, data ) |
232 | 228 | |
233 | 229 | SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(worldChatResponse)) |
234 | 230 | |
231 | + datacenter.set("agent", roleId, { | |
232 | + serv = skynet.self(), | |
233 | + fd = agent.client_fd, | |
234 | + gate_serv = agent.gate_serv, | |
235 | + }) | |
236 | + agent.role = role | |
237 | + | |
238 | + start_agent_timer() | |
239 | + -- role:log("login", { ip = agent.ip, diamond = role:getProperty("diamond"), reDiamond = role:getProperty("reDiamond")}) | |
240 | + | |
235 | 241 | return true |
236 | 242 | end |
237 | 243 | |
... | ... | @@ -616,7 +622,7 @@ function _M.chatRpc(agent, data) |
616 | 622 | |
617 | 623 | if now < role._worldChatLimit.canSayt then |
618 | 624 | result = 2 |
619 | - waitTime = canSayt - now | |
625 | + waitTime = role._worldChatLimit.canSayt - now | |
620 | 626 | return |
621 | 627 | end |
622 | 628 | |
... | ... | @@ -634,14 +640,13 @@ function _M.chatRpc(agent, data) |
634 | 640 | return |
635 | 641 | end |
636 | 642 | end |
637 | - | |
638 | 643 | mcast_util.pub_world(actionCodes.Role_chat, MsgPack.pack(response)) |
639 | - pcall(skynet.call, 'GLOBALD', "lua", "sendWorldMsg", role._channelIdx, response) | |
644 | + pcall(skynet.send, 'GLOBALD', "lua", "sendWorldMsg", role._channelIdx, response) | |
640 | 645 | end, |
641 | 646 | -- 私聊 |
642 | 647 | [2] = function () |
643 | 648 | local objectId = msg.roleId |
644 | - | |
649 | + response.objId = objectId | |
645 | 650 | if 0 == redisproxy:exists(string.format("role:%d", objectId)) then |
646 | 651 | result = 1 |
647 | 652 | return | ... | ... |
src/agent.lua
... | ... | @@ -114,38 +114,8 @@ function rpcRole(roleId, funcName, ...) |
114 | 114 | return true, skynet.call(agent.serv, "role", funcName, ...) |
115 | 115 | end |
116 | 116 | else |
117 | - local rediskey = string_format("role:%d", roleId) | |
118 | - if funcName == "setProperty" then | |
119 | - return false, redisproxy:hset(rediskey, ...) | |
120 | - elseif funcName == "getProperty" then | |
121 | - return false, redisproxy:hget(rediskey, ...) | |
122 | - elseif funcName == "getProperties" then | |
123 | - local sRole = require("models.Role") | |
124 | - local returnValue = redisproxy:hmget(rediskey, table_unpack(...)) | |
125 | - local ret = {} | |
126 | - for index, key in ipairs(fields) do | |
127 | - local typ = sRole.schema[key][1] | |
128 | - local def = sRole.schema[key][2] | |
129 | - if typ == "number" then | |
130 | - ret[key] = tonumber(returnValue[index] or def) | |
131 | - else | |
132 | - ret[key] = returnValue[index] | |
133 | - end | |
134 | - end | |
135 | - return false, ret | |
136 | - elseif funcName == "setProperties" then | |
137 | - local result = {} | |
138 | - for k,v in pairs(fields) do | |
139 | - result[#result+1] = k | |
140 | - result[#result+1] = v | |
141 | - end | |
142 | - return false, redisproxy:hmset(rediskey, table_unpack(result)) | |
143 | - elseif funcName == "friendSInfo" or funcName == "friendInfo" then | |
144 | - local sRole = require("models.Role").new({key = rediskey}) | |
145 | - sRole:load() | |
146 | - sRole:loadAll() | |
147 | - return false, sRole[funcName] and sRole[funcName](sRole, ...) | |
148 | - end | |
117 | + local roleCross = require("models.RoleCross") | |
118 | + return false, roleCross.handle(funcName, roleId, ...) | |
149 | 119 | end |
150 | 120 | end |
151 | 121 | |
... | ... | @@ -264,7 +234,6 @@ function CMD.close() |
264 | 234 | cancel_agent_timer() |
265 | 235 | mcast_util.usub_world() |
266 | 236 | mcast_util.usub_union() |
267 | - | |
268 | 237 | local role = agentInfo.role |
269 | 238 | if not role then return end |
270 | 239 | role:log("logout", {online = skynet.timex()-role:getProperty("ltime")}) | ... | ... |
src/models/Pvp.lua deleted
... | ... | @@ -1,75 +0,0 @@ |
1 | --- 日常数据 | |
2 | - | |
3 | -local Pvp = class("Pvp", require("shared.ModelBase")) | |
4 | - | |
5 | -function Pvp:ctor(properties) | |
6 | - Pvp.super.ctor(self, properties) | |
7 | -end | |
8 | - | |
9 | -Pvp.schema = { | |
10 | - pvpFC = {"table", {}}, -- pvp 编队普通 | |
11 | - pvpFH = {"table", {}}, -- pvp 编队高级 | |
12 | - matchC = {"table", {}}, -- pvp 匹配的对手 普通 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 | |
13 | - matchH = {"table", {}}, -- pvp 匹配的对手 高级 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 | |
14 | -} | |
15 | - | |
16 | -function Pvp:updateProperty(params) | |
17 | - if params.delta then | |
18 | - self:incrProperty(params.field, params.delta) | |
19 | - if not params.notNotify then | |
20 | - self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) | |
21 | - end | |
22 | - return true | |
23 | - end | |
24 | - if params.value then | |
25 | - self:setProperty(params.field, params.value) | |
26 | - if not params.notNotify then | |
27 | - self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) | |
28 | - end | |
29 | - return true | |
30 | - end | |
31 | - return false | |
32 | -end | |
33 | - | |
34 | - | |
35 | - | |
36 | -function Pvp:refreshDailyData(notify) | |
37 | - | |
38 | -end | |
39 | - | |
40 | -function Pvp:rankResetData(notify) | |
41 | - | |
42 | -end | |
43 | - | |
44 | -function Pvp:refreshMatchC(score) | |
45 | - local roleId = self.owner:getProperty("id") | |
46 | - local score = score or redisproxy:zscore(RANK_PVP_COMMON, roleId) | |
47 | - local redret = redisproxy:pipelining(function(red) | |
48 | - | |
49 | - end) | |
50 | -end | |
51 | - | |
52 | - | |
53 | -function Pvp:changeScoreCommon(score) | |
54 | - local roleId = self.owner:getProperty("id") | |
55 | - local newScore = tonumber(redisproxy:ZINCRBY(RANK_PVP_COMMON, score, roleId)) | |
56 | - if newScore < 0 then -- 最低0分 | |
57 | - newScore = 0 | |
58 | - redisproxy:zadd(RANK_PVP_COMMON, 0, roleId) | |
59 | - end | |
60 | - self:refreshMatch(newScore) | |
61 | - return newScore | |
62 | -end | |
63 | - | |
64 | - | |
65 | - | |
66 | - | |
67 | - | |
68 | -function Pvp:data() | |
69 | - return { | |
70 | - pvpFC = self:getProperty("pvpFC"), | |
71 | - pvpFH = self:getProperty("pvpFH"), | |
72 | - } | |
73 | -end | |
74 | - | |
75 | -return Pvp | |
76 | 0 | \ No newline at end of file |
src/models/Role.lua
... | ... | @@ -4,10 +4,15 @@ local RolePlugin = import(".RolePlugin") |
4 | 4 | local RoleTask = import(".RoleTask") |
5 | 5 | local RoleActivity = import(".RoleActivity") |
6 | 6 | local RoleChangeStruct = import(".RoleChangeStruct") |
7 | +local RolePvp = import(".RolePvp") | |
8 | +local RoleCross = import(".RoleCross") | |
9 | + | |
7 | 10 | RolePlugin.bind(Role) |
8 | 11 | RoleTask.bind(Role) |
9 | 12 | RoleActivity.bind(Role) |
10 | 13 | RoleChangeStruct.bind(Role) |
14 | +RolePvp.bind(Role) | |
15 | +RoleCross.bind(Role) | |
11 | 16 | |
12 | 17 | function Role:ctor( properties ) |
13 | 18 | Role.super.ctor(self, properties) |
... | ... | @@ -61,11 +66,28 @@ Role.schema = { |
61 | 66 | --挂机相关 |
62 | 67 | hangPass = {"table", {}}, -- 挂机通过的最大关卡 |
63 | 68 | hangTeam = {"table", {}}, -- 挂机队伍 |
69 | + hangTS = {"table", {}}, -- 挂机队伍他人可读的队伍信息 | |
70 | + hangTB = {"table", {}}, -- 挂机队伍他人可用的战斗信息 | |
71 | + hangTBV = {"number", 0}, -- 挂机队伍他人可用的战斗力 | |
72 | + | |
64 | 73 | hangInfo = {"table", {}}, -- 当前挂机信息 |
65 | 74 | hangBag = {"table", {}}, -- 背包 |
66 | 75 | hangBagLimit = {"number", globalCsv.idle_field_origin}, --背包上限 |
67 | 76 | bTeam = {"table", {}}, -- 奖励副本队伍 |
68 | 77 | |
78 | + pvpTC = {"table", {}}, -- pvp 编队普通 | |
79 | + pvpTSC = {"table", {}}, -- pvp 他人可读的队伍信息 | |
80 | + pvpTBC = {"table", {}}, -- pvp 他人可用的战斗信息 | |
81 | + pvpTBVC = {"number", 0}, -- pvp 他人可用的战斗力 | |
82 | + pvpMC = {"table", {}}, -- pvp 匹配的对手 普通 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 | |
83 | + | |
84 | + pvpTH = {"table", {}}, -- pvp 编队高级 | |
85 | + pvpTSH = {"table", {}}, -- pvp 他人可读的队伍信息 | |
86 | + pvpTBH = {"table", {}}, -- pvp 他人可用的战斗信息 | |
87 | + pvpTBVH = {"table", {}}, -- pvp 他人可用的战斗力 | |
88 | + pvpMH = {"table", {}}, -- pvp 匹配的对手 高级 {{t = 1, id = roleId}, {t = 2, id = id}, {t = 2, id = id}} -- t 1 玩家 2 机器人 | |
89 | + | |
90 | + | |
69 | 91 | potionBag = {"table", {}}, -- 营养剂背包 |
70 | 92 | |
71 | 93 | storyB = {"table", {}}, -- 剧情记录 |
... | ... | @@ -216,6 +238,9 @@ function Role:data() |
216 | 238 | hangBagLimit = self:getProperty("hangBagLimit"), |
217 | 239 | bTeam = self:getProperty("bTeam"), |
218 | 240 | |
241 | + pvpTC = self:getProperty("pvpTC"), | |
242 | + pvpTH = self:getProperty("pvpTH"), | |
243 | + | |
219 | 244 | potionBag = self:getProperty("potionBag"), |
220 | 245 | storyB = self:getProperty("storyB"), |
221 | 246 | equips = self:getProperty("equips"), | ... | ... |
... | ... | @@ -0,0 +1,174 @@ |
1 | + | |
2 | +-- 跨越 agent 获取数据使用 | |
3 | +local RoleCross = {} | |
4 | + | |
5 | +--*********************************** agent 存在时调用 ****************************************-- | |
6 | +RoleCross.bind = function (Role) | |
7 | + -- 好友列表简约信息 | |
8 | + function Role:friendSInfo() | |
9 | + local info = { | |
10 | + name = self:getProperty("name"), | |
11 | + level = self:getProperty("level"), | |
12 | + headId = self:getProperty("headId"), | |
13 | + ltime = self:getProperty("ltime"), | |
14 | + battleV = self:getProperty("pvpTBVC") ~= 0 and self:getProperty("pvpTBVC") or self:getProperty("hangTBV") | |
15 | + } | |
16 | + return info | |
17 | + end | |
18 | + | |
19 | + -- 好友详细队伍信息 | |
20 | + function Role:friendInfo() | |
21 | + local info = self:friendSInfo() | |
22 | + local heros = self:getProperty("pvpTBVC") ~= 0 and self:getProperty("pvpTSC") or self:getProperty("hangTS") | |
23 | + info.heros = heros | |
24 | + return info | |
25 | + end | |
26 | + | |
27 | + -- 好友队伍战斗信息 | |
28 | + function Role:friendBattleInfo() | |
29 | + return self:getProperty("pvpTBVC") ~= 0 and self:getProperty("pvpTBC") or self:getProperty("hangTB") | |
30 | + end | |
31 | + | |
32 | + -- pvp 战斗数据 | |
33 | + function Role:pvpCBattleInfo() | |
34 | + return self:getProperty("pvpTBC") | |
35 | + end | |
36 | + | |
37 | + -- pvp 简略数据 | |
38 | + function Role:pvpCSInfo() | |
39 | + local info = { | |
40 | + name = self:getProperty("name"), | |
41 | + level = self:getProperty("level"), | |
42 | + headId = self:getProperty("headId"), | |
43 | + ltime = self:getProperty("ltime"), | |
44 | + battleV = self:getProperty("pvpTBVC"), | |
45 | + heros = self:getProperty("pvpTSC"), | |
46 | + } | |
47 | + return info | |
48 | + end | |
49 | + | |
50 | +end | |
51 | + | |
52 | + | |
53 | +--*********************************** agent 不存在时调用 ***************************************-- | |
54 | +local CMD = {} | |
55 | +local SRole | |
56 | +local function unpackRoleField(field, value) | |
57 | + if not SRole.schema[field] then | |
58 | + return nil | |
59 | + end | |
60 | + local typ, def = table.unpack(SRole.schema[field]) | |
61 | + | |
62 | + if typ == "number" then | |
63 | + value = tonumber(value or def) | |
64 | + elseif typ == "table" then | |
65 | + if type(value) == "string" then | |
66 | + value = MsgPack.unpack(value) | |
67 | + else | |
68 | + value = def | |
69 | + end | |
70 | + end | |
71 | + return value | |
72 | +end | |
73 | + | |
74 | +local function packRoleField(field, value) | |
75 | + if not SRole.schema[field] then | |
76 | + return nil | |
77 | + end | |
78 | + local typ, def = table.unpack(SRole.schema[field]) | |
79 | + | |
80 | + if typ == "table" then | |
81 | + if type(value) == "table" then | |
82 | + value = MsgPack.pack(value) | |
83 | + end | |
84 | + end | |
85 | + return value | |
86 | +end | |
87 | + | |
88 | +local function getRoleKey(roleId) | |
89 | + return string.format("role:%d", roleId) | |
90 | +end | |
91 | + | |
92 | +function CMD.setProperty(roleId, field, value) | |
93 | + local value = packRoleField(field, value) | |
94 | + if not value then return end | |
95 | + return redisproxy:hset(getRoleKey(roleId), field, value) | |
96 | +end | |
97 | + | |
98 | + | |
99 | +function CMD.setProperties(roleId, fields) | |
100 | + local result = {} | |
101 | + for k,v in pairs(fields) do | |
102 | + local value = packRoleField(k, v) | |
103 | + if value then | |
104 | + result[#result + 1] = k | |
105 | + result[#result + 1] = value | |
106 | + end | |
107 | + end | |
108 | + return redisproxy:hmset(getRoleKey(roleId), table.unpack(result)) | |
109 | +end | |
110 | + | |
111 | +function CMD.getProperty(roleId, field) | |
112 | + return unpackRoleField(field ,redisproxy:hget(getRoleKey(roleId), field)) | |
113 | +end | |
114 | + | |
115 | +function CMD.getProperties(roleId, fields) | |
116 | + local returnValue = redisproxy:hmget(getRoleKey(roleId), table.unpack(fields)) | |
117 | + local ret = {} | |
118 | + for index, key in ipairs(fields) do | |
119 | + ret[key] = unpackRoleField(key, returnValue[index]) | |
120 | + end | |
121 | + return ret | |
122 | +end | |
123 | + | |
124 | +function CMD.friendSInfo(roleId) | |
125 | + local info = CMD.getProperties(roleId, {"name", "level", "headId", "ltime", "pvpTBVC", "hangTBV"}) | |
126 | + return { | |
127 | + name = info.name, | |
128 | + level = info.level, | |
129 | + headId = info.headId, | |
130 | + ltime = info.ltime, | |
131 | + battleV = info.pvpTBVC ~= 0 and info.pvpTBVC or info.hangTBV, | |
132 | + } | |
133 | +end | |
134 | + | |
135 | +function CMD.friendInfo(roleId) | |
136 | + local info = CMD.getProperties(roleId, {"name", "level", "headId", "ltime", "pvpTBVC", "hangTBV", "pvpTSC", "hangTS"}) | |
137 | + return { | |
138 | + name = info.name, | |
139 | + level = info.level, | |
140 | + headId = info.headId, | |
141 | + ltime = info.ltime, | |
142 | + battleV = info.pvpTBVC ~= 0 and info.pvpTBVC or info.hangTBV, | |
143 | + heros = info.pvpTBVC ~= 0 and info.pvpTSC or info.hangTS | |
144 | + } | |
145 | +end | |
146 | + | |
147 | +function CMD.friendBattleInfo(roleId) | |
148 | + local info = CMD.getProperties(roleId, {"pvpTBC", "hangTB"}) | |
149 | + return next(info.pvpTBC) and info.pvpTBC or info.hangTB | |
150 | +end | |
151 | + | |
152 | +function CMD.pvpCBattleInfo(roleId) | |
153 | + return CMD.getProperty(roleId, "pvpTBC") | |
154 | +end | |
155 | + | |
156 | +function CMD.pvpCSInfo(roleId) | |
157 | + local info = CMD.getProperties(roleId, {"name", "level", "headId", "pvpTBVC", "pvpTSC"}) | |
158 | + return { | |
159 | + name = info.name, | |
160 | + level = info.level, | |
161 | + headId = info.headId, | |
162 | + battleV = info.pvpTBVC, | |
163 | + heros = info.pvpTSC, | |
164 | + } | |
165 | +end | |
166 | + | |
167 | +RoleCross.handle = function(cmd, roleId, ...) | |
168 | + SRole = SRole or require("models.Role") | |
169 | + if CMD[cmd] then | |
170 | + return CMD[cmd](roleId, ...) | |
171 | + end | |
172 | +end | |
173 | + | |
174 | +return RoleCross | |
0 | 175 | \ No newline at end of file | ... | ... |
src/models/RolePlugin.lua
... | ... | @@ -14,7 +14,6 @@ function RolePlugin.bind(Role) |
14 | 14 | self:loadRunes() |
15 | 15 | self:loadHeros() |
16 | 16 | self:loadDiner() |
17 | - self:loadPvp() | |
18 | 17 | end |
19 | 18 | |
20 | 19 | function Role:reloadWhenLogin() |
... | ... | @@ -32,7 +31,6 @@ function RolePlugin.bind(Role) |
32 | 31 | |
33 | 32 | self.dailyData:refreshDailyData(notify) |
34 | 33 | self.dinerData:refreshDailyData(notify) |
35 | - self.pvpData:refreshDailyData(notify) | |
36 | 34 | self:setProperty("dTask", {}) |
37 | 35 | response.dTask = {} |
38 | 36 | |
... | ... | @@ -73,7 +71,6 @@ function RolePlugin.bind(Role) |
73 | 71 | local response = {} |
74 | 72 | |
75 | 73 | self.dinerData:rankResetData(notify) |
76 | - self.pvpData:rankResetData(notify) | |
77 | 74 | |
78 | 75 | return response |
79 | 76 | end |
... | ... | @@ -433,17 +430,6 @@ function RolePlugin.bind(Role) |
433 | 430 | end |
434 | 431 | end |
435 | 432 | |
436 | - function Role:loadPvp() | |
437 | - local roleId = self:getProperty("id") | |
438 | - local dataKey = string.format(R_PVP, roleId) | |
439 | - self.pvpData = require("models.Pvp").new({key = dataKey}) | |
440 | - self.pvpData.owner = self | |
441 | - if not redisproxy:exists(dataKey) then | |
442 | - self.pvpData:create() | |
443 | - else | |
444 | - self.pvpData:load() | |
445 | - end | |
446 | - end | |
447 | 433 | |
448 | 434 | function Role:loadEquips() |
449 | 435 | -- 放role 里面了 |
... | ... | @@ -723,27 +709,6 @@ function RolePlugin.bind(Role) |
723 | 709 | end |
724 | 710 | end |
725 | 711 | |
726 | - function Role:getTeamBattleValue(heros) | |
727 | - local battleV = 0 | |
728 | - for _, heroId in pairs(heros) do | |
729 | - local hero = self.heros[heroId] | |
730 | - battleV = battleV + hero:getProperty("battleV") | |
731 | - end | |
732 | - return battleV | |
733 | - end | |
734 | - | |
735 | - function Role:recordRankTeam(heroIds) | |
736 | - local heros = {} | |
737 | - for slot, heroId in pairs(heroIds) do | |
738 | - local hero = self.heros[heroId] | |
739 | - heros[slot] = { | |
740 | - htype = hero:getProperty("type"), | |
741 | - lv = hero:getProperty("level"), | |
742 | - wakeL = hero:getProperty("wakeL"), | |
743 | - } | |
744 | - end | |
745 | - return heros | |
746 | - end | |
747 | 712 | |
748 | 713 | local StdDinerRankTime = toUnixtime("20190101"..string.format("%02x", RESET_RANK_TIME)) --跨天时间 |
749 | 714 | function Role:getCurDinerRankKey() |
... | ... | @@ -770,7 +735,7 @@ function RolePlugin.bind(Role) |
770 | 735 | lv = self:getProperty("level"), |
771 | 736 | batteV = battleV, |
772 | 737 | level = level, |
773 | - format = self:recordRankTeam(towerTeam.heros), | |
738 | + format = self:getTeamHerosInfo(towerTeam.heros), | |
774 | 739 | } |
775 | 740 | local roleId = self:getProperty("id") |
776 | 741 | redisproxy:pipelining(function (red) |
... | ... | @@ -831,56 +796,69 @@ function RolePlugin.bind(Role) |
831 | 796 | end |
832 | 797 | self:updateProperty({field = "advL", value = advL}) |
833 | 798 | end |
834 | - -- 好友列表简约信息 | |
835 | - function Role:friendSInfo() | |
836 | - local info = { | |
837 | - name = self:getProperty("name"), | |
838 | - level = self:getProperty("level"), | |
839 | - headId = self:getProperty("headId"), | |
840 | - ltime = self:getProperty("ltime"), | |
841 | - battleV = self:getTeamBattleValue(self:getProperty("hangTeam").heros or {}), -- Todo | |
842 | - } | |
843 | - return info | |
844 | - end | |
845 | 799 | |
846 | - local slotToPos = { | |
847 | - [1] = 6, | |
848 | - [2] = 2, | |
849 | - [3] = 35, | |
850 | - [4] = 32, | |
851 | - [5] = 29, | |
852 | - } | |
853 | 800 | function Role:getTeamBattleInfo(team) |
854 | - local heros = {} | |
855 | - -- local activeRelation = self:getHeroActiveRelation(team.heros) | |
801 | + local teamInfo = {heros = {}} | |
802 | + local activeRelation = self:getHeroActiveRelation(team.heros) | |
856 | 803 | |
857 | 804 | for slot, id in pairs(team.heros or {}) do |
858 | - local info = {id = id} | |
859 | - local hero = self.heros[info.id] | |
805 | + local info = {} | |
806 | + local hero = self.heros[id] | |
860 | 807 | if not hero then |
861 | - print("error heroid " .. info.id) | |
808 | + print("error heroid " .. id) | |
809 | + end | |
810 | + local attrs = hero:getTotalAttrs({activeRelation = activeRelation}) | |
811 | + for k, v in pairs(AttsEnumEx) do | |
812 | + info[v] = (attrs[v] or 0) | |
862 | 813 | end |
863 | - -- local attrs = hero:getTotalAttrs({activeRelation = activeRelation}) | |
864 | - -- for k, v in pairs(AttsEnumEx) do | |
865 | - -- info[v] = (attrs[v] or 0) | |
866 | - -- end | |
867 | - -- info.blockLevel = hero:getSkillLevel(4) | |
868 | - -- info.specialLevel = hero:getSkillLevel(1) | |
869 | - | |
870 | 814 | info.type = hero:getProperty("type") |
871 | 815 | info.level = hero:getProperty("level") |
872 | - info.wakeL = hero:getProperty("wakeL") | |
873 | - heros[slot] = info | |
816 | + info.blockLevel = hero:getSkillLevel(4) | |
817 | + info.specialLevel = hero:getSkillLevel(1) | |
818 | + teamInfo.heros[slot] = info | |
819 | + end | |
820 | + -- todo 支援技能 | |
821 | + return teamInfo | |
822 | + end | |
823 | + | |
824 | + function Role:getTeamHerosInfo(heroIds) | |
825 | + local heros = {} | |
826 | + for slot, heroId in pairs(heroIds or {}) do | |
827 | + local hero = self.heros[heroId] | |
828 | + heros[slot] = { | |
829 | + type = hero:getProperty("type"), | |
830 | + level = hero:getProperty("level"), | |
831 | + wakeL = hero:getProperty("wakeL"), | |
832 | + } | |
874 | 833 | end |
875 | 834 | return heros |
876 | 835 | end |
877 | 836 | |
878 | - -- 角色详细信息 | |
879 | - function Role:friendInfo() | |
880 | - local info = self:friendSInfo() | |
881 | - local heros = self:getTeamBattleInfo(self:getProperty("hangTeam")) | |
882 | - info.heros = heros | |
883 | - return info | |
837 | + function Role:getTeamBattleValue(heros) | |
838 | + local battleV = 0 | |
839 | + for _, heroId in pairs(heros or {}) do | |
840 | + local hero = self.heros[heroId] | |
841 | + battleV = battleV + hero:getProperty("battleV") | |
842 | + end | |
843 | + return battleV | |
844 | + end | |
845 | + | |
846 | + function Role:saveHangTeam(team) | |
847 | + self:updateProperty({field = "hangTeam", value = team}) | |
848 | + self:setProperties({ | |
849 | + hangTS = self:getTeamHerosInfo(team.heros), | |
850 | + hangTB = self:getTeamBattleInfo(team), | |
851 | + hangTBV = self:getTeamBattleValue(team.heros), | |
852 | + }) | |
853 | + end | |
854 | + | |
855 | + function Role:savePvpCTeam(team) | |
856 | + self:updateProperty({field = "pvpTSC", value = team}) | |
857 | + self:setProperties({ | |
858 | + pvpTSC = self:getTeamHerosInfo(team.heros), | |
859 | + pvpTBC = self:getTeamBattleInfo(team), | |
860 | + pvpTBVC = self:getTeamBattleValue(team.heros), | |
861 | + }) | |
884 | 862 | end |
885 | 863 | end |
886 | 864 | ... | ... |
... | ... | @@ -0,0 +1,224 @@ |
1 | + | |
2 | +local RolePvp = {} | |
3 | + | |
4 | +RolePvp.bind = function (Role) | |
5 | + | |
6 | +local PVP_RANK_TIME_SORT_STD = 1924876800 -- 2030-12-31 00:00:00 | |
7 | +local PVP_RANK_TIME_SORT_PLACE = 1000000 -- 时间戳占据 6位数 | |
8 | +local PVP_RANK_TIME_SORT_PRECISION = 360 -- 时间精度 每6分钟忽略差异 | |
9 | +local PVP_RANK_ROBOT_SCORE = 1000 -- 机器人积分 | |
10 | + | |
11 | +local function unpackScore(score) | |
12 | + score = tonumber(score or 0) | |
13 | + return math.floor(score / PVP_RANK_TIME_SORT_PLACE) | |
14 | +end | |
15 | + | |
16 | +local function packScore(score, now) | |
17 | + now = now or skynet.timex() | |
18 | + return math.floor(score * PVP_RANK_TIME_SORT_PLACE + (PVP_RANK_TIME_SORT_STD - now) / PVP_RANK_TIME_SORT_PRECISION) | |
19 | +end | |
20 | + | |
21 | + | |
22 | +function Role:changePvpScoreCommon(matchId, isWin) | |
23 | + local roleId = self:getProperty("id") | |
24 | + local isPlayer = matchId ~= -1 | |
25 | + local redret = redisproxy:pipelining(function(red) | |
26 | + red:zscore(RANK_PVP_COMMON, roleId) | |
27 | + if isPlayer then | |
28 | + red:zscore(RANK_PVP_COMMON, matchId) | |
29 | + end | |
30 | + end) | |
31 | + local myScore = unpackScore(redret[1]) | |
32 | + local matchScore = PVP_RANK_ROBOT_SCORE | |
33 | + if isPlayer then | |
34 | + matchScore = unpackScore(redret[2]) | |
35 | + end | |
36 | + | |
37 | + if isWin then | |
38 | + local scoreChange = math.ceil(60 / (1 + 10 ^ ((myScore - matchScore) / 400))) | |
39 | + myScore = myScore + scoreChange | |
40 | + matchScore = matchScore - scoreChange | |
41 | + else | |
42 | + local scoreChange = math.ceil(60 / (1 + 10 ^ ((matchScore - myScore) / 400))) | |
43 | + myScore = myScore - scoreChange | |
44 | + matchScore = matchScore + scoreChange | |
45 | + end | |
46 | + | |
47 | + myScore = math.max(myScore, 0) | |
48 | + matchScore = math.max(matchScore, 0) | |
49 | + | |
50 | + local now = skynet.timex() | |
51 | + redisproxy:pipelining(function(red) | |
52 | + red:zadd(RANK_PVP_COMMON, packScore(myScore, now), roleId) | |
53 | + if isPlayer then | |
54 | + red:zadd(RANK_PVP_COMMON, packScore(matchScore, now), matchId) | |
55 | + end | |
56 | + end) | |
57 | + self:refreshMatchC(myScore) | |
58 | + return myScore | |
59 | +end | |
60 | + | |
61 | +function Role:refreshPvpMatchC(score) | |
62 | + local roleId = self:getProperty("id") | |
63 | + local score = score or redisproxy:zscore(RANK_PVP_COMMON, roleId) | |
64 | + | |
65 | + local function getPlayers(levels) | |
66 | + local redret = redisproxy:pipelining(function(red) | |
67 | + for _, level in ipairs(levels) do | |
68 | + local low, high = table.unpack(level) | |
69 | + red:zadd(RANK_PVP_COMMON, low * PVP_RANK_TIME_SORT_PLACE, "std_temp1") | |
70 | + red:zadd(RANK_PVP_COMMON, high * PVP_RANK_TIME_SORT_PLACE + PVP_RANK_TIME_SORT_PLACE - 1, "std_temp2") | |
71 | + red:ZREVRANK(RANK_PVP_COMMON, "std_temp1") | |
72 | + red:ZREVRANK(RANK_PVP_COMMON, "std_temp2") | |
73 | + end | |
74 | + red:zrem(RANK_PVP_COMMON, "std_temp1", "std_temp2") | |
75 | + end) | |
76 | + | |
77 | + local PreGetCount = 7 | |
78 | + local redret = redisproxy:pipelining(function(red) | |
79 | + for idx, level in ipairs(levels) do | |
80 | + local rank1 = tonumber(redret[(idx - 1) * 4 + 3]) | |
81 | + local rank2 = tonumber(redret[(idx - 1) * 4 + 4]) | |
82 | + if rank1 - rank2 > PreGetCount then | |
83 | + rank2 = math.randomInt(rank2, rank1 - PreGetCount + 1) | |
84 | + rank1 = rank2 + PreGetCount - 1 | |
85 | + end | |
86 | + red:ZREVRANGE(RANK_PVP_COMMON, rank2, rank1) | |
87 | + end | |
88 | + end) | |
89 | + return redret | |
90 | + end | |
91 | + | |
92 | + local findIdx = #globalCsv.pvp_division | |
93 | + for idx, limit in ipairs(globalCsv.pvp_division) do | |
94 | + if score < limit then | |
95 | + findIdx = idx - 1 | |
96 | + break | |
97 | + end | |
98 | + end | |
99 | + local levels = { | |
100 | + {}, {}, {} | |
101 | + } | |
102 | + if globalCsv.pvp_division[findIdx + 1] then | |
103 | + levels[1] = {globalCsv.pvp_division[findIdx + 1], (globalCsv.pvp_division[findIdx + 2] or 100000000) - 1} | |
104 | + end | |
105 | + levels[2] = {globalCsv.pvp_division[findIdx], (globalCsv.pvp_division[findIdx + 1] or 100000000) - 1} | |
106 | + if globalCsv.pvp_division[findIdx - 1] then | |
107 | + levels[3] = {globalCsv.pvp_division[findIdx - 1], globalCsv.pvp_division[findIdx] - 1} | |
108 | + end | |
109 | + local redirect = {} | |
110 | + for i = #levels , 1, -1 do | |
111 | + if not next(levels[i]) then | |
112 | + table.remove(levels, i) | |
113 | + redirect[i] = -1 | |
114 | + for _, v in pairs(redirect) do | |
115 | + redirect[_] = v - 1 | |
116 | + end | |
117 | + else | |
118 | + redirect[i] = i | |
119 | + end | |
120 | + end | |
121 | + | |
122 | + local result = getPlayers(levels) | |
123 | + local matchC = self:getProperty("pvpMC") | |
124 | + local hadPlayer = {[roleId] = 1} | |
125 | + local hadRobot = {} | |
126 | + for _, one in pairs(matchC) do | |
127 | + if one.t == 1 then | |
128 | + hadPlayer[one.id] = 1 | |
129 | + elseif one.t == 2 then | |
130 | + hadRobot[one.id] = 1 | |
131 | + end | |
132 | + end | |
133 | + | |
134 | + for _, temp in pairs(result) do | |
135 | + for i = #temp, 1, -1 do | |
136 | + local id = tonumber(temp[i]) | |
137 | + if hadPlayer[id] then | |
138 | + table.remove(temp, i) | |
139 | + else | |
140 | + temp[i] = id | |
141 | + hadPlayer[id] = 1 | |
142 | + end | |
143 | + end | |
144 | + end | |
145 | + -- 增加第几个 | |
146 | + local function getPlayer(idx) | |
147 | + for i = idx, 3 do | |
148 | + if redirect[i] ~= -1 then | |
149 | + local curR = result[redirect[i]] or {} | |
150 | + if next(curR) then | |
151 | + local curIdx = math.randomInt(1, #curR) | |
152 | + local objId = curR[curIdx] | |
153 | + table.remove(curR, curIdx) | |
154 | + return objId | |
155 | + end | |
156 | + end | |
157 | + end | |
158 | + end | |
159 | + | |
160 | + local tempMatchC = {} | |
161 | + local curCount = 0 | |
162 | + for i = 1, 3 do | |
163 | + local objId = getPlayer(i) | |
164 | + if objId then | |
165 | + tempMatchC[i] = {t = 1, id = objId} | |
166 | + curCount = curCount + 1 | |
167 | + end | |
168 | + end | |
169 | + | |
170 | + -- 正常的玩家不够了 低一档继续 | |
171 | + if curCount < 3 then | |
172 | + local level = nil | |
173 | + if globalCsv.pvp_division[findIdx - 2] then | |
174 | + level = {globalCsv.pvp_division[findIdx - 2], globalCsv.pvp_division[findIdx - 1] - 1} | |
175 | + end | |
176 | + if level then | |
177 | + local result = getPlayers({level})[1] or {} | |
178 | + for i = #result, 1, -1 do | |
179 | + local id = tonumber(result[i]) | |
180 | + if hadPlayer[id] then | |
181 | + table.remove(result, i) | |
182 | + else | |
183 | + result[i] = id | |
184 | + hadPlayer[id] = 1 | |
185 | + end | |
186 | + end | |
187 | + | |
188 | + if next(result) then | |
189 | + for i = curCount + 1, 3 do | |
190 | + local curIdx = math.randomInt(1, #result) | |
191 | + local objId = result[curIdx] | |
192 | + table.remove(result, curIdx) | |
193 | + tempMatchC[i] = {t = 1, id = objId} | |
194 | + curCount = curCount + 1 | |
195 | + if not next(result) then | |
196 | + break | |
197 | + end | |
198 | + end | |
199 | + end | |
200 | + end | |
201 | + end | |
202 | + | |
203 | + -- 增加机器人 | |
204 | + if curCount < 3 then | |
205 | + for i = curCount + 1, 3 do | |
206 | + while true do | |
207 | + local id = math.randomInt(1, #csvdb["pvp_robotCsv"]) | |
208 | + if not hadRobot[id] then | |
209 | + hadRobot[id] = 1 | |
210 | + tempMatchC[i] = {t = 2, id = id} | |
211 | + break | |
212 | + end | |
213 | + end | |
214 | + end | |
215 | + end | |
216 | + | |
217 | + self:setProperty("pvpMC", tempMatchC) | |
218 | +end | |
219 | + | |
220 | + | |
221 | +end | |
222 | + | |
223 | + | |
224 | +return RolePvp | |
0 | 225 | \ No newline at end of file | ... | ... |
src/services/mcast_util.lua
src/shared/ModelBase.lua
... | ... | @@ -32,7 +32,7 @@ function ModelBase:ctor(properties) |
32 | 32 | end |
33 | 33 | |
34 | 34 | if type(properties) ~= "table" then properties = {} end |
35 | - self:setProperties(properties, true) --缺少的域将设置默认值 | |
35 | + self:loadProperties(properties) --缺少的域将设置默认值 | |
36 | 36 | end |
37 | 37 | |
38 | 38 | -- startCache 和 endCache 在恰当的时候*配对使用* 嵌套使用多次增加引用计数 直到引用计数为0 写入 |
... | ... | @@ -107,7 +107,7 @@ function ModelBase:load(properties) |
107 | 107 | end |
108 | 108 | if not next(properties) then return false end |
109 | 109 | |
110 | - self:setProperties(properties, true) | |
110 | + self:loadProperties(properties) | |
111 | 111 | |
112 | 112 | self:onLoad() |
113 | 113 | |
... | ... | @@ -126,6 +126,7 @@ function ModelBase:create() |
126 | 126 | |
127 | 127 | return self |
128 | 128 | end |
129 | + | |
129 | 130 | -- save 忽略 缓存配置 |
130 | 131 | function ModelBase:save() |
131 | 132 | local redisProperties = self:getProperties() |
... | ... | @@ -158,7 +159,7 @@ end |
158 | 159 | |
159 | 160 | --[[-- |
160 | 161 | |
161 | -修改对象的属性。 | |
162 | +加载对象的属性进内存。 | |
162 | 163 | NOTE: 如果properties缺少schema中的域, 将用默认值来填充 |
163 | 164 | |
164 | 165 | **Parameters:** |
... | ... | @@ -166,11 +167,9 @@ NOTE: 如果properties缺少schema中的域, 将用默认值来填充 |
166 | 167 | - properties: 包含属性值的数组 |
167 | 168 | |
168 | 169 | ]] |
169 | -function ModelBase:setProperties(properties, notWrite) | |
170 | +function ModelBase:loadProperties(properties) | |
170 | 171 | assert(type(properties) == "table", "Invalid properties") |
171 | - -- string_format("%s [%s:setProperties()] Invalid properties", tostring(self), self.class.__cname)) | |
172 | 172 | |
173 | - local params = {} | |
174 | 173 | for field, schema in pairs(self.class.schema) do |
175 | 174 | local typ, def = table_unpack(schema) |
176 | 175 | local propname = field .. "_" |
... | ... | @@ -186,18 +185,8 @@ function ModelBase:setProperties(properties, notWrite) |
186 | 185 | string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", |
187 | 186 | tostring(self), self.class.__cname, field, typ, type(val))) |
188 | 187 | self[propname] = val |
189 | - if not self.cacheFields[field] then | |
190 | - table_insert(params, field) | |
191 | - if typ == "table" then | |
192 | - val = MsgPack.pack(val) | |
193 | - end | |
194 | - table_insert(params, val) | |
195 | - end | |
196 | 188 | end |
197 | 189 | end |
198 | - if not notWrite and next(params) then | |
199 | - redisproxy:hmset(self:getKey(), table_unpack(params)) | |
200 | - end | |
201 | 190 | end |
202 | 191 | |
203 | 192 | --[[-- |
... | ... | @@ -270,6 +259,39 @@ function ModelBase:setProperty(property, value) |
270 | 259 | end |
271 | 260 | end |
272 | 261 | |
262 | +function ModelBase:setProperties(fields) | |
263 | + local result = {} | |
264 | + for property, value in pairs(fields) do | |
265 | + if not self.class.schema[property] then | |
266 | + print(string_format("%s [%s:setProperty()] Invalid property : %s", | |
267 | + tostring(self), self.class.__cname, property)) | |
268 | + else | |
269 | + local typ, def = table_unpack(self.class.schema[property]) | |
270 | + local propname = property .. "_" | |
271 | + if typ == "number" then value = tonumber(value) end | |
272 | + if typ == "table" and not value then | |
273 | + value = self[propname] -- table 可以用自己的缓冲 | |
274 | + end | |
275 | + assert(type(value) == typ, | |
276 | + string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", | |
277 | + tostring(self), self.class.__cname, property, typ, type(value))) | |
278 | + self[propname] = value | |
279 | + | |
280 | + if not self.cacheFields[property] then | |
281 | + table_insert(result, property) | |
282 | + if typ == "table" then | |
283 | + table_insert(result, MsgPack.pack(self[propname])) | |
284 | + else | |
285 | + table_insert(result, self[propname]) | |
286 | + end | |
287 | + end | |
288 | + end | |
289 | + end | |
290 | + if next(result) then | |
291 | + redisproxy:hmset(self:getKey(), table_unpack(result)) | |
292 | + end | |
293 | +end | |
294 | + | |
273 | 295 | function ModelBase:incrProperty(property, value) |
274 | 296 | if not self.class.schema[property] then |
275 | 297 | print(string_format("%s [%s:setProperty()] Invalid property : %s", | ... | ... |