Commit fa565e0c47dfd1d9d94b27263f27b2377ecba312

Authored by zhouhaihai
1 parent 6bccc3a9

优化结构

@@ -18,10 +18,7 @@ RANK_DINER = {"rank:diner1", "rank:diner2"} -- é¤åŽ…æŽ’è¡Œæ¦œ 两个æ¯å¤©äº’æ @@ -18,10 +18,7 @@ RANK_DINER = {"rank:diner1", "rank:diner2"} -- é¤åŽ…æŽ’è¡Œæ¦œ 两个æ¯å¤©äº’æ
18 RANK_DINER_INFO = "rank:diner:info" 18 RANK_DINER_INFO = "rank:diner:info"
19 19
20 RANK_PVP_COMMON = "rank:pvpc" 20 RANK_PVP_COMMON = "rank:pvpc"
21 -RANK_PVP_INFO_COMMON = "rank:pvpc:info"  
22 -  
23 RANK_PVP_HIGHT = "rank:pvph" 21 RANK_PVP_HIGHT = "rank:pvph"
24 -RANK_PVP_INFO_HIGHT = "rank:pvph:info"  
25 -- -- role 22 -- -- role
26 -- R_FARM_KEY = "role:%d:farm" 23 -- R_FARM_KEY = "role:%d:farm"
27 -- R_TOWER_KEY = "role:%d:tower" 24 -- R_TOWER_KEY = "role:%d:tower"
src/actions/HangAction.lua
@@ -208,8 +208,7 @@ function _M.roleFormatRpc(agent , data) @@ -208,8 +208,7 @@ function _M.roleFormatRpc(agent , data)
208 hangTeam.heros[slot] = heroId 208 hangTeam.heros[slot] = heroId
209 end 209 end
210 hangTeam.leader = msg.leader 210 hangTeam.leader = msg.leader
211 -  
212 - role:updateProperty({field = "hangTeam", value = hangTeam}) 211 + role:saveHangTeam(hangTeam)
213 SendPacket(actionCodes.Hang_roleFormatRpc, '') 212 SendPacket(actionCodes.Hang_roleFormatRpc, '')
214 return true 213 return true
215 end 214 end
src/actions/PvpAction.lua
@@ -10,21 +10,26 @@ local _M = {} @@ -10,21 +10,26 @@ local _M = {}
10 10
11 function _M.formatCommonRpc(agent , data) 11 function _M.formatCommonRpc(agent , data)
12 local role = agent.role 12 local role = agent.role
  13 + local roleId = role:getProperty("id")
13 local msg = MsgPack.unpack(data) 14 local msg = MsgPack.unpack(data)
14 - local pvpFC = role.pvpData:getProperty("pvpFC") 15 + local pvpTC = role:getProperty("pvpTC")
15 for slot, heroId in pairs(msg.heros) do 16 for slot, heroId in pairs(msg.heros) do
16 if not role.heros[heroId] then 17 if not role.heros[heroId] then
17 return 18 return
18 end 19 end
19 end 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 end 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 SendPacket(actionCodes.Pvp_formatCommonRpc, '') 33 SendPacket(actionCodes.Pvp_formatCommonRpc, '')
29 return true 34 return true
30 end 35 end
@@ -32,10 +37,10 @@ end @@ -32,10 +37,10 @@ end
32 function _M.formatHighRpc(agent , data) 37 function _M.formatHighRpc(agent , data)
33 local role = agent.role 38 local role = agent.role
34 local msg = MsgPack.unpack(data) 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 SendPacket(actionCodes.Pvp_formatHighRpc, '') 44 SendPacket(actionCodes.Pvp_formatHighRpc, '')
40 return true 45 return true
41 end 46 end
src/actions/RoleAction.lua
@@ -124,7 +124,7 @@ function _M.loginRpc( agent, data ) @@ -124,7 +124,7 @@ function _M.loginRpc( agent, data )
124 role:setProperty("ltime", now) 124 role:setProperty("ltime", now)
125 redisproxy:zadd(FRIEND_RECOMMEND, now, roleId) 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 response[name] = role[name]:data() 128 response[name] = role[name]:data()
129 end 129 end
130 130
@@ -201,27 +201,23 @@ function _M.loginRpc( agent, data ) @@ -201,27 +201,23 @@ function _M.loginRpc( agent, data )
201 end 201 end
202 curWave = curWave + heroWave 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 end 216 end
221 217
222 -- 发下缓存的世界消息 218 -- 发下缓存的世界消息
223 local worldChatResponse = {worldChats = {}} 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 if not ok then 221 if not ok then
226 msgs = {} 222 msgs = {}
227 end 223 end
@@ -232,6 +228,16 @@ function _M.loginRpc( agent, data ) @@ -232,6 +228,16 @@ function _M.loginRpc( agent, data )
232 228
233 SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(worldChatResponse)) 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 return true 241 return true
236 end 242 end
237 243
@@ -616,7 +622,7 @@ function _M.chatRpc(agent, data) @@ -616,7 +622,7 @@ function _M.chatRpc(agent, data)
616 622
617 if now < role._worldChatLimit.canSayt then 623 if now < role._worldChatLimit.canSayt then
618 result = 2 624 result = 2
619 - waitTime = canSayt - now 625 + waitTime = role._worldChatLimit.canSayt - now
620 return 626 return
621 end 627 end
622 628
@@ -634,14 +640,13 @@ function _M.chatRpc(agent, data) @@ -634,14 +640,13 @@ function _M.chatRpc(agent, data)
634 return 640 return
635 end 641 end
636 end 642 end
637 -  
638 mcast_util.pub_world(actionCodes.Role_chat, MsgPack.pack(response)) 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 end, 645 end,
641 -- 私聊 646 -- 私聊
642 [2] = function () 647 [2] = function ()
643 local objectId = msg.roleId 648 local objectId = msg.roleId
644 - 649 + response.objId = objectId
645 if 0 == redisproxy:exists(string.format("role:%d", objectId)) then 650 if 0 == redisproxy:exists(string.format("role:%d", objectId)) then
646 result = 1 651 result = 1
647 return 652 return
@@ -114,38 +114,8 @@ function rpcRole(roleId, funcName, ...) @@ -114,38 +114,8 @@ function rpcRole(roleId, funcName, ...)
114 return true, skynet.call(agent.serv, "role", funcName, ...) 114 return true, skynet.call(agent.serv, "role", funcName, ...)
115 end 115 end
116 else 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 end 119 end
150 end 120 end
151 121
@@ -264,7 +234,6 @@ function CMD.close() @@ -264,7 +234,6 @@ function CMD.close()
264 cancel_agent_timer() 234 cancel_agent_timer()
265 mcast_util.usub_world() 235 mcast_util.usub_world()
266 mcast_util.usub_union() 236 mcast_util.usub_union()
267 -  
268 local role = agentInfo.role 237 local role = agentInfo.role
269 if not role then return end 238 if not role then return end
270 role:log("logout", {online = skynet.timex()-role:getProperty("ltime")}) 239 role:log("logout", {online = skynet.timex()-role:getProperty("ltime")})
src/models/Pvp.lua deleted
@@ -1,75 +0,0 @@ @@ -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 \ No newline at end of file 0 \ No newline at end of file
src/models/Role.lua
@@ -4,10 +4,15 @@ local RolePlugin = import(&quot;.RolePlugin&quot;) @@ -4,10 +4,15 @@ local RolePlugin = import(&quot;.RolePlugin&quot;)
4 local RoleTask = import(".RoleTask") 4 local RoleTask = import(".RoleTask")
5 local RoleActivity = import(".RoleActivity") 5 local RoleActivity = import(".RoleActivity")
6 local RoleChangeStruct = import(".RoleChangeStruct") 6 local RoleChangeStruct = import(".RoleChangeStruct")
  7 +local RolePvp = import(".RolePvp")
  8 +local RoleCross = import(".RoleCross")
  9 +
7 RolePlugin.bind(Role) 10 RolePlugin.bind(Role)
8 RoleTask.bind(Role) 11 RoleTask.bind(Role)
9 RoleActivity.bind(Role) 12 RoleActivity.bind(Role)
10 RoleChangeStruct.bind(Role) 13 RoleChangeStruct.bind(Role)
  14 +RolePvp.bind(Role)
  15 +RoleCross.bind(Role)
11 16
12 function Role:ctor( properties ) 17 function Role:ctor( properties )
13 Role.super.ctor(self, properties) 18 Role.super.ctor(self, properties)
@@ -61,11 +66,28 @@ Role.schema = { @@ -61,11 +66,28 @@ Role.schema = {
61 --挂机相关 66 --挂机相关
62 hangPass = {"table", {}}, -- 挂机通过的最大关卡 67 hangPass = {"table", {}}, -- 挂机通过的最大关卡
63 hangTeam = {"table", {}}, -- 挂机队伍 68 hangTeam = {"table", {}}, -- 挂机队伍
  69 + hangTS = {"table", {}}, -- 挂机队伍他人可读的队伍信息
  70 + hangTB = {"table", {}}, -- 挂机队伍他人可用的战斗信息
  71 + hangTBV = {"number", 0}, -- 挂机队伍他人可用的战斗力
  72 +
64 hangInfo = {"table", {}}, -- 当前挂机信息 73 hangInfo = {"table", {}}, -- 当前挂机信息
65 hangBag = {"table", {}}, -- 背包 74 hangBag = {"table", {}}, -- 背包
66 hangBagLimit = {"number", globalCsv.idle_field_origin}, --背包上限 75 hangBagLimit = {"number", globalCsv.idle_field_origin}, --背包上限
67 bTeam = {"table", {}}, -- 奖励副本队伍 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 potionBag = {"table", {}}, -- 营养剂背包 91 potionBag = {"table", {}}, -- 营养剂背包
70 92
71 storyB = {"table", {}}, -- 剧情记录 93 storyB = {"table", {}}, -- 剧情记录
@@ -216,6 +238,9 @@ function Role:data() @@ -216,6 +238,9 @@ function Role:data()
216 hangBagLimit = self:getProperty("hangBagLimit"), 238 hangBagLimit = self:getProperty("hangBagLimit"),
217 bTeam = self:getProperty("bTeam"), 239 bTeam = self:getProperty("bTeam"),
218 240
  241 + pvpTC = self:getProperty("pvpTC"),
  242 + pvpTH = self:getProperty("pvpTH"),
  243 +
219 potionBag = self:getProperty("potionBag"), 244 potionBag = self:getProperty("potionBag"),
220 storyB = self:getProperty("storyB"), 245 storyB = self:getProperty("storyB"),
221 equips = self:getProperty("equips"), 246 equips = self:getProperty("equips"),
src/models/RoleCross.lua 0 → 100644
@@ -0,0 +1,174 @@ @@ -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 \ No newline at end of file 175 \ No newline at end of file
src/models/RolePlugin.lua
@@ -14,7 +14,6 @@ function RolePlugin.bind(Role) @@ -14,7 +14,6 @@ function RolePlugin.bind(Role)
14 self:loadRunes() 14 self:loadRunes()
15 self:loadHeros() 15 self:loadHeros()
16 self:loadDiner() 16 self:loadDiner()
17 - self:loadPvp()  
18 end 17 end
19 18
20 function Role:reloadWhenLogin() 19 function Role:reloadWhenLogin()
@@ -32,7 +31,6 @@ function RolePlugin.bind(Role) @@ -32,7 +31,6 @@ function RolePlugin.bind(Role)
32 31
33 self.dailyData:refreshDailyData(notify) 32 self.dailyData:refreshDailyData(notify)
34 self.dinerData:refreshDailyData(notify) 33 self.dinerData:refreshDailyData(notify)
35 - self.pvpData:refreshDailyData(notify)  
36 self:setProperty("dTask", {}) 34 self:setProperty("dTask", {})
37 response.dTask = {} 35 response.dTask = {}
38 36
@@ -73,7 +71,6 @@ function RolePlugin.bind(Role) @@ -73,7 +71,6 @@ function RolePlugin.bind(Role)
73 local response = {} 71 local response = {}
74 72
75 self.dinerData:rankResetData(notify) 73 self.dinerData:rankResetData(notify)
76 - self.pvpData:rankResetData(notify)  
77 74
78 return response 75 return response
79 end 76 end
@@ -433,17 +430,6 @@ function RolePlugin.bind(Role) @@ -433,17 +430,6 @@ function RolePlugin.bind(Role)
433 end 430 end
434 end 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 function Role:loadEquips() 434 function Role:loadEquips()
449 -- 放role 里面了 435 -- 放role 里面了
@@ -723,27 +709,6 @@ function RolePlugin.bind(Role) @@ -723,27 +709,6 @@ function RolePlugin.bind(Role)
723 end 709 end
724 end 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 local StdDinerRankTime = toUnixtime("20190101"..string.format("%02x", RESET_RANK_TIME)) --跨天时间 713 local StdDinerRankTime = toUnixtime("20190101"..string.format("%02x", RESET_RANK_TIME)) --跨天时间
749 function Role:getCurDinerRankKey() 714 function Role:getCurDinerRankKey()
@@ -770,7 +735,7 @@ function RolePlugin.bind(Role) @@ -770,7 +735,7 @@ function RolePlugin.bind(Role)
770 lv = self:getProperty("level"), 735 lv = self:getProperty("level"),
771 batteV = battleV, 736 batteV = battleV,
772 level = level, 737 level = level,
773 - format = self:recordRankTeam(towerTeam.heros), 738 + format = self:getTeamHerosInfo(towerTeam.heros),
774 } 739 }
775 local roleId = self:getProperty("id") 740 local roleId = self:getProperty("id")
776 redisproxy:pipelining(function (red) 741 redisproxy:pipelining(function (red)
@@ -831,56 +796,69 @@ function RolePlugin.bind(Role) @@ -831,56 +796,69 @@ function RolePlugin.bind(Role)
831 end 796 end
832 self:updateProperty({field = "advL", value = advL}) 797 self:updateProperty({field = "advL", value = advL})
833 end 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 function Role:getTeamBattleInfo(team) 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 for slot, id in pairs(team.heros or {}) do 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 if not hero then 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 end 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 info.type = hero:getProperty("type") 814 info.type = hero:getProperty("type")
871 info.level = hero:getProperty("level") 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 end 833 end
875 return heros 834 return heros
876 end 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 end 862 end
885 end 863 end
886 864
src/models/RolePvp.lua 0 → 100644
@@ -0,0 +1,224 @@ @@ -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 \ No newline at end of file 225 \ No newline at end of file
src/services/mcast_util.lua
@@ -24,6 +24,10 @@ function _M.sub_world(w_channel) @@ -24,6 +24,10 @@ function _M.sub_world(w_channel)
24 chan_w:subscribe() 24 chan_w:subscribe()
25 end 25 end
26 26
  27 +function _M.channel_world()
  28 + return chan_w
  29 +end
  30 +
27 function _M.usub_world() 31 function _M.usub_world()
28 if chan_w then 32 if chan_w then
29 chan_w:unsubscribe() 33 chan_w:unsubscribe()
src/shared/ModelBase.lua
@@ -32,7 +32,7 @@ function ModelBase:ctor(properties) @@ -32,7 +32,7 @@ function ModelBase:ctor(properties)
32 end 32 end
33 33
34 if type(properties) ~= "table" then properties = {} end 34 if type(properties) ~= "table" then properties = {} end
35 - self:setProperties(properties, true) --缺少的域将设置默认值 35 + self:loadProperties(properties) --缺少的域将设置默认值
36 end 36 end
37 37
38 -- startCache 和 endCache 在恰当的时候*配对使用* 嵌套使用多次增加引用计数 直到引用计数为0 写入 38 -- startCache 和 endCache 在恰当的时候*配对使用* 嵌套使用多次增加引用计数 直到引用计数为0 写入
@@ -107,7 +107,7 @@ function ModelBase:load(properties) @@ -107,7 +107,7 @@ function ModelBase:load(properties)
107 end 107 end
108 if not next(properties) then return false end 108 if not next(properties) then return false end
109 109
110 - self:setProperties(properties, true) 110 + self:loadProperties(properties)
111 111
112 self:onLoad() 112 self:onLoad()
113 113
@@ -126,6 +126,7 @@ function ModelBase:create() @@ -126,6 +126,7 @@ function ModelBase:create()
126 126
127 return self 127 return self
128 end 128 end
  129 +
129 -- save 忽略 缓存配置 130 -- save 忽略 缓存配置
130 function ModelBase:save() 131 function ModelBase:save()
131 local redisProperties = self:getProperties() 132 local redisProperties = self:getProperties()
@@ -158,7 +159,7 @@ end @@ -158,7 +159,7 @@ end
158 159
159 --[[-- 160 --[[--
160 161
161 -修改对象的属性 162 +加载对象的属性进内存
162 NOTE: 如果properties缺少schema中的域, 将用默认值来填充 163 NOTE: 如果properties缺少schema中的域, 将用默认值来填充
163 164
164 **Parameters:** 165 **Parameters:**
@@ -166,11 +167,9 @@ NOTE: 如果properties缺少schema中的域, 将用默认值来填充 @@ -166,11 +167,9 @@ NOTE: 如果properties缺少schema中的域, 将用默认值来填充
166 - properties: 包含属性值的数组 167 - properties: 包含属性值的数组
167 168
168 ]] 169 ]]
169 -function ModelBase:setProperties(properties, notWrite) 170 +function ModelBase:loadProperties(properties)
170 assert(type(properties) == "table", "Invalid properties") 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 for field, schema in pairs(self.class.schema) do 173 for field, schema in pairs(self.class.schema) do
175 local typ, def = table_unpack(schema) 174 local typ, def = table_unpack(schema)
176 local propname = field .. "_" 175 local propname = field .. "_"
@@ -186,18 +185,8 @@ function ModelBase:setProperties(properties, notWrite) @@ -186,18 +185,8 @@ function ModelBase:setProperties(properties, notWrite)
186 string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", 185 string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s",
187 tostring(self), self.class.__cname, field, typ, type(val))) 186 tostring(self), self.class.__cname, field, typ, type(val)))
188 self[propname] = val 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 end 188 end
197 end 189 end
198 - if not notWrite and next(params) then  
199 - redisproxy:hmset(self:getKey(), table_unpack(params))  
200 - end  
201 end 190 end
202 191
203 --[[-- 192 --[[--
@@ -270,6 +259,39 @@ function ModelBase:setProperty(property, value) @@ -270,6 +259,39 @@ function ModelBase:setProperty(property, value)
270 end 259 end
271 end 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 function ModelBase:incrProperty(property, value) 295 function ModelBase:incrProperty(property, value)
274 if not self.class.schema[property] then 296 if not self.class.schema[property] then
275 print(string_format("%s [%s:setProperty()] Invalid property : %s", 297 print(string_format("%s [%s:setProperty()] Invalid property : %s",