Commit fa565e0c47dfd1d9d94b27263f27b2377ecba312

Authored by zhouhaihai
1 parent 6bccc3a9

优化结构

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(&quot;.RolePlugin&quot;)
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"),
... ...
src/models/RoleCross.lua 0 → 100644
... ... @@ -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  
... ...
src/models/RolePvp.lua 0 → 100644
... ... @@ -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
... ... @@ -24,6 +24,10 @@ function _M.sub_world(w_channel)
24 24 chan_w:subscribe()
25 25 end
26 26  
  27 +function _M.channel_world()
  28 + return chan_w
  29 +end
  30 +
27 31 function _M.usub_world()
28 32 if chan_w then
29 33 chan_w:unsubscribe()
... ...
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",
... ...