Commit d2249a6f7628c7748cb9e412a3b2a42be4b3df99

Authored by jiyue
2 parents 0f811b9b 49810b00

Merge branch 'cn/develop' into cn/publish/release

src/ProtocolCode.lua
... ... @@ -59,7 +59,7 @@ actionCodes = {
59 59 Role_runeBuyRpc = 142, -- 铭文购买
60 60 Role_setFriendTeamRpc = 143, -- 设置好友切磋队伍
61 61 Role_setBgRpc = 144, -- 设置看板娘
62   - Role_itemExchangeRpc = 145, -- 道具兑换
  62 + Role_itemConvertMonthCardRpc = 145, -- 兑换月卡道具
63 63  
64 64 Adv_startAdvRpc = 151,
65 65 Adv_startHangRpc = 152,
... ... @@ -274,6 +274,17 @@ actionCodes = {
274 274 Seaport_taskRpc = 753,
275 275 Seaport_shopRpc = 754,
276 276 Seaport_resetRpc = 755,
  277 +
  278 + Capsule_listRpc = 850, --扭蛋机列表
  279 + Capsule_joinRpc = 851, --扭蛋机详情
  280 + Capsule_registerRpc = 853, --报名扭蛋机 "报名"后,抽取按钮才会开放,未报名的玩家分在围观玩家中
  281 + Capsule_drawRpc = 854, --抽扭蛋机
  282 + --Capsule_switchRoomRpc = 855, --切换扭蛋机房间
  283 + Capsule_notifyChange = 856, -- 通知信息变动
  284 + Capsule_payReward = 857, -- 特殊赏 奖励通知
  285 + Capsule_exitRpc = 858, -- 退出
  286 + Capsule_getDataRpc = 859, --获取扭蛋机信息
  287 + Capsule_convertCapsuleRpc = 890, --兑换消耗票
277 288 }
278 289  
279 290 rpcResponseBegin = 10000
... ...
src/RedisKeys.lua
... ... @@ -63,6 +63,15 @@ FRIEND_RECOMMEND = "friend:recommend" -- sort set ç™»å½•æŽ’åº èŽ·å–æŽ¨è好å
63 63 CHAT_OFFLINE = "chat:offline:%d" --消æ¯ç¦»çº¿ç¼“å­˜
64 64  
65 65 WORK_BATTLE_COUNT = "global:workbattle" -- 世界次数统计
  66 +
  67 +--Capsule 扭蛋机
  68 +CAPSULE_INFO= "capsule:info" --set
  69 +CAPSULE_PUBLIC = "capsule:%d:info" --hash
  70 +
  71 +CAPSULE_ID_ROLE = "role:%s:capsule:id" -- set
  72 +CAPSULE_ROLE = "role:%s:capsule:%d" --hash 独享
  73 +
  74 +
66 75 -- FRIEND_DINER_LIKE_KEY = "role:%d:diner:like" -- list
67 76  
68 77 -- UNION_SET = "global:union"
... ...
src/actions/CapsuleAction.lua 0 → 100644
... ... @@ -0,0 +1,198 @@
  1 +local ipairs = ipairs
  2 +local table = table
  3 +local math = math
  4 +local next = next
  5 +local string = string
  6 +local redisproxy = redisproxy
  7 +local MsgPack = MsgPack
  8 +local getRandomName = getRandomName
  9 +local mcast_util = mcast_util
  10 +local string_format = string.format
  11 +local tonumber = tonumber
  12 +local require = require
  13 +
  14 +local _M = {}
  15 +
  16 +function _M.listRpc(agent, data)
  17 + local role = agent.role
  18 + local msg = MsgPack.unpack(data)
  19 + local typ = msg.typ
  20 + local coin = msg.coin
  21 +
  22 + local capsules = {}
  23 + if typ == 1 then
  24 + local ret = skynet.call(agent.capsule_serv, "lua", "list", coin)
  25 + if next(ret) then
  26 + for k, v in pairs(ret) do
  27 + capsules[k] = v
  28 + end
  29 + end
  30 + elseif typ == 0 then
  31 + local ret = role:getCapsuleList(coin)
  32 + if next(ret) then
  33 + for k, v in pairs(ret) do
  34 + capsules[k] = v
  35 + end
  36 + end
  37 + end
  38 +
  39 + SendPacket(actionCodes.Capsule_listRpc, MsgPack.pack(capsules))
  40 + return true
  41 +end
  42 +
  43 +function _M.joinRpc(agent, data)
  44 + local role = agent.role
  45 + local msg = MsgPack.unpack(data)
  46 + local roleId = role:getProperty("id")
  47 + local capsuleId = msg.capsule_id --如果刷新则需要传递当前扭蛋机id
  48 + local typ = msg.typ or 1
  49 +
  50 + local ret = {}
  51 + if typ == 1 then
  52 + ret = skynet.call(agent.capsule_serv, "lua", "join", roleId, capsuleId)
  53 + elseif typ == 0 then
  54 + ret = role:joinCapsule()
  55 + end
  56 + SendPacket(actionCodes.Capsule_joinRpc, MsgPack.pack(ret))
  57 + return true
  58 +end
  59 +
  60 +function _M.exitRpc(agent, data)
  61 + local role = agent.role
  62 + local msg = MsgPack.unpack(data)
  63 + local roleId = role:getProperty("id")
  64 + local capsuleId = msg.capsule_id --如果刷新则需要传递当前扭蛋机id
  65 + local typ = msg.typ or 1
  66 +
  67 + local ret = {}
  68 + if typ == 1 then
  69 + ret = skynet.call(agent.capsule_serv, "lua", "exit", roleId, capsuleId)
  70 + elseif typ == 0 then
  71 + ret = role:exitCapsule()
  72 + end
  73 +
  74 + SendPacket(actionCodes.Capsule_exitRpc, MsgPack.pack(ret))
  75 + return true
  76 +end
  77 +
  78 +function _M.registerRpc(agent, data)
  79 + local role = agent.role
  80 + local msg = MsgPack.unpack(data)
  81 + local roleId = role:getProperty("id")
  82 + local capsuleId = msg.capsule_id
  83 +
  84 + local ret = skynet.call(agent.capsule_serv, "lua", "register", roleId, capsuleId)
  85 + if not ret then return 1 end
  86 + SendPacket(actionCodes.Capsule_registerRpc, MsgPack.pack(ret))
  87 + return true
  88 +end
  89 +
  90 +function _M.drawRpc(agent, data)
  91 + local role = agent.role
  92 + local msg = MsgPack.unpack(data)
  93 + local roleId = role:getProperty("id")
  94 + local capsuleId = msg.capsule_id
  95 + local typ = msg.typ --0=独享,1= 公开
  96 + local full = msg.full or 0-- 0=单次,1=十连抽 2=全收
  97 + local cares = msg.cares
  98 +
  99 + local ret, token, reward, change, rewardByGoods, capsule
  100 +
  101 + --检查库存
  102 + if typ == 1 then
  103 + ret, token = skynet.call(agent.capsule_serv, "lua", "goods_stock", capsuleId)
  104 + else
  105 + ret, token = role:goodStock(capsuleId)
  106 + end
  107 + if ret == 0 then skynet.error("零库存 " .. capsuleId) return 0 end
  108 +
  109 + --检查余额
  110 + if not next(token) then skynet.error("代币未配置 " .. capsuleId) return 1 end
  111 + local cost, drawsNum = {}, 0
  112 + if full == 0 then
  113 + drawsNum = 1
  114 + elseif full == 1 then
  115 + if ret < 10 then
  116 + drawsNum = ret
  117 + else
  118 + drawsNum = 10
  119 + end
  120 + elseif full == 2 then
  121 + drawsNum = ret
  122 + end
  123 + cost[token[1]] = drawsNum * token[2]
  124 +
  125 + if not role:checkItemEnough(cost) then return 2 end
  126 + role:costItems(cost, {log = {desc = "CapsuleCoinCost", int1 = token[1], int2 = cost[token[1]]}})
  127 +
  128 + --开始抽奖
  129 + if typ == 1 then
  130 + ret, reward, rewardByGoods, capsule = skynet.call(agent.capsule_serv, "lua", "draw_capsule", roleId, capsuleId, full, cares)
  131 + else
  132 + ret, reward, rewardByGoods, capsule= role:drawCapsule(capsuleId, full, cares)
  133 + end
  134 + if ret < 5 then
  135 + return ret
  136 + end
  137 +
  138 + --dump(rewardByGoods)
  139 + --dump(capsule)
  140 +
  141 + if ret == 5 then
  142 + SendPacket(actionCodes.Capsule_drawRpc, MsgPack.pack({change = reward, capsule = capsule}))
  143 + return true
  144 + end
  145 +
  146 + -- rewardByGoods是抽到的扭蛋信息,reward是抽扭蛋后获得的所有奖励信息。
  147 + if rewardByGoods and next(rewardByGoods) then
  148 + reward, change = role:award(reward, {log = {desc = "CapsuleReward", int1 = tonumber(capsuleId), int2 = roleId}})
  149 + SendPacket(actionCodes.Capsule_drawRpc, MsgPack.pack({reward = rewardByGoods, capsule = capsule}))
  150 + else
  151 + return ret
  152 + end
  153 + return true
  154 +end
  155 +
  156 +function _M.getDataRpc(agent, data)
  157 + local role = agent.role
  158 + local msg = MsgPack.unpack(data)
  159 + local capsuleId = msg.capsule_id
  160 + local typ = msg.typ --0=独享,1= 公开
  161 + local roleId = role:getProperty("id")
  162 +
  163 + local capsule
  164 + if typ == 1 then
  165 + capsule = skynet.call(agent.capsule_serv, "lua", "capsule_data", roleId, capsuleId)
  166 + else
  167 + capsule = role:getCapsuleData(capsuleId)
  168 + end
  169 + if not capsule then return 1 end
  170 +
  171 + SendPacket(actionCodes.Capsule_getDataRpc, MsgPack.pack({capsule = capsule}))
  172 + return true
  173 +
  174 +end
  175 +
  176 +function _M.convertCapsuleRpc(agent, data)
  177 + local role = agent.role
  178 + local msg = MsgPack.unpack(data)
  179 + local coin = msg.coin
  180 + local count = msg.count or 1
  181 +
  182 + local cost, convert = {}
  183 + for k, v in pairs(globalCsv.ichibankuji_buy_cost)do
  184 + if k == coin then
  185 + convert = v:toArray(true, "=")
  186 + break
  187 + end
  188 + end
  189 + cost[convert[1]] = convert[2] * count
  190 + if not role:checkItemEnough(cost) then return 1 end
  191 + role:costItems(cost, {log = {desc = "CapsuleConvert", int1 = convert[1], int2 = cost[convert[1]]}})
  192 +
  193 + local reward, change = role:award({coin = count}, {log = {desc = "CapsuleConvert"}})
  194 + SendPacket(actionCodes.Capsule_convertCapsuleRpc, MsgPack.pack(role:packReward(reward, change)))
  195 + return true
  196 +end
  197 +
  198 +return _M
0 199 \ No newline at end of file
... ...
src/actions/GmAction.lua
... ... @@ -9,7 +9,7 @@ function _M.clientRequest(agent, data)
9 9 SendPacket(actionCodes.Gm_receiveResponse, bin)
10 10 return true
11 11 end
12   - local ret = action(role, msg)
  12 + local ret = action(role, msg, agent.capsule_serv)
13 13 bin = MsgPack.pack({ cmd = ret })
14 14 SendPacket(actionCodes.Gm_receiveResponse, bin)
15 15 return true
... ... @@ -1075,4 +1075,15 @@ function _M.clear_sea(role, pms)
1075 1075 return "成功"
1076 1076 end
1077 1077  
  1078 +table.insert(helpDes, {"重置扭蛋机", "reset_capsule", "typ"})
  1079 +function _M.reset_capsule(role, pms, capsule_serv)
  1080 + local typ = tonumber(pms.pm1)
  1081 + if typ == 1 then
  1082 + skynet.call(capsule_serv, "lua", "reset")
  1083 + else
  1084 + role:resetCapsule()
  1085 + end
  1086 + return "成功"
  1087 +end
  1088 +
1078 1089 return _M
1079 1090 \ No newline at end of file
... ...
src/actions/RoleAction.lua
... ... @@ -1710,7 +1710,7 @@ function _M.setBgRpc(agent, data)
1710 1710 return true
1711 1711 end
1712 1712  
1713   -function _M.itemExchangeRpc(agent, data)
  1713 +function _M.itemConvertMonthCardRpc(agent, data)
1714 1714 local role = agent.role
1715 1715 local msg = MsgPack.unpack(data)
1716 1716 local itemId = msg.item_id
... ... @@ -1738,7 +1738,7 @@ function _M.itemExchangeRpc(agent, data)
1738 1738 end
1739 1739 end
1740 1740  
1741   - SendPacket(actionCodes.Role_itemExchangeRpc, MsgPack.pack(role:packReward(reward)))
  1741 + SendPacket(actionCodes.Role_itemConvertMonthCardRpc, MsgPack.pack(role:packReward(reward)))
1742 1742 return status
1743 1743 end
1744 1744  
... ...
src/actions/StoreAction.lua
... ... @@ -291,8 +291,12 @@ function _M.shopBuyRpc(agent , data)
291 291 return 1
292 292 end
293 293  
294   - if dataSet.disount == 0 then dataSet.disount = 10 end
295   - local cost = {[dataSet.icon] = math.ceil(dataSet.cost * count * ((dataSet.disount or 10) / 10))}
  294 + local cost
  295 + if dataSet.disount == 0 then
  296 + cost = {[dataSet.icon] = math.ceil(dataSet.cost * count)}
  297 + else
  298 + cost = {[dataSet.icon] = math.ceil(dataSet.cost * count * ((dataSet.disount or 10) / 10))}
  299 + end
296 300  
297 301  
298 302 local desc = "unknowShop"
... ...
src/agent.lua
... ... @@ -254,11 +254,12 @@ skynet.register_protocol {
254 254 }
255 255  
256 256 -- function CMD.start(gate, fd, ip)
257   -function CMD.start(session, source, gate, fd, ip, hotfixs)
  257 +function CMD.start(session, source, gate, capsuled, fd, ip, hotfixs)
258 258 ignoreHeartbeat = false
259 259  
260 260 agentInfo.client_fd = fd
261 261 agentInfo.gate_serv = gate
  262 + agentInfo.capsule_serv = capsuled
262 263 agentInfo.ip = ip
263 264  
264 265 agent_util:reset()
... ... @@ -282,6 +283,8 @@ function CMD.close()
282 283 mcast_util.usub_union()
283 284 local role = agentInfo.role
284 285 if not role then return end
  286 +
  287 + skynet.call(agentInfo.capsule_serv, "lua", "exit", role:getProperty("id"))
285 288 role:log("onLogout", {logtime = skynet.timex()-role:getProperty("ltime")})
286 289 role:mylog("logout", {int1 = skynet.timex()-role:getProperty("ltime")})
287 290 role:onOfflineEvent()
... ...
src/models/Capsule.lua 0 → 100644
... ... @@ -0,0 +1,812 @@
  1 +--扭蛋机
  2 +local MsgPack = MsgPack
  3 +local Capsule = class("Capsule", require("shared.ModelBase"))
  4 +
  5 +function Capsule:ctor(properties)
  6 + Capsule.super.ctor(self, properties)
  7 +end
  8 +
  9 +RewardType = {
  10 + GOODS = 1,
  11 + SPECIAL = 2,
  12 + INCENTIVE = 3,
  13 +}
  14 +
  15 +SpecialType = {
  16 + TOP = 1,
  17 + CORE = 2,
  18 + LAST = 3,
  19 + JOKER = 4,
  20 + KING = 5,
  21 +}
  22 +
  23 +CapsuleType = {
  24 + PRIVATE = 0,
  25 + PUBLIC = 1,
  26 +}
  27 +
  28 +--[[
  29 +--通知数据结构
  30 +{ [roleId] = { [good_id1] = { }, [good_id2] = { }, } }
  31 +]]--
  32 +
  33 +Capsule.schema = {
  34 + id = {"number", 0}, --扭蛋机key,配置读取
  35 + room = {"number", 0}, --房间号, 配置读取
  36 + name = {"string"},
  37 + typ = {"number", 1}, -- 1=共享,2=独享
  38 + coin = {"number", 0}, --货币代号
  39 + token = {"table", {}}, --抽一次,货币=消耗
  40 + register = {"table", {}}, --人数 {["id"]=0}, 0 围观, 1 已报名
  41 + record = {"table", {}}, --抽取记录 列表
  42 + recordByRole = {"table", {}}, -- 抽取记录,hash, {roleid=record}
  43 + rank = {"table", {}}, --排行
  44 + goods = {"table", {}}, --奖励池
  45 + specials = {"table", {}}, --特殊赏
  46 + incentive = {"table", {}}, --激励奖
  47 + incentiveRecord = {"table", {}}, --激励奖记录
  48 + specialsRecord= {"table", {}}, --特殊赏领取记录
  49 + resetTimes = {"number", 0}, --每日一次手动重置的机会
  50 + hideTime = {"number", 0} , --隐藏时间
  51 + drawEndTime = {"number", 0}, --抽完时间
  52 +}
  53 +
  54 +function Capsule:getResetFields()
  55 + return {
  56 + id = self:getProperty("id"),
  57 + room = self:getProperty("room"),
  58 + typ = self:getProperty("typ"),
  59 + coin = 0,
  60 + token = {},
  61 + register = {},
  62 + record = {},
  63 + recordByRole = {},
  64 + rank = {},
  65 + goods = {},
  66 + specials = {},
  67 + incentive = {},
  68 + incentiveRecord = {},
  69 + specialsRecord= {},
  70 + resetTimes = 0,
  71 + hideTime = 0,
  72 + drawEndTime = 0,
  73 + }
  74 +end
  75 +
  76 +function Capsule:init()
  77 + local id = self:getProperty("id")
  78 + local room = self:getProperty("room")
  79 + self:setProperties(self:getResetFields())
  80 +
  81 + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room]
  82 +
  83 + --奖励池
  84 + local goods_id = ichibankuji["goods_id"]
  85 + local goods, specials, incentive = {}, {}, {}
  86 + for _, data in pairs(csvdb["ichibankuji_goodsCsv"]) do
  87 + for _, val in pairs(data) do
  88 + if val.key == goods_id then
  89 + goods[goods_id..val.id] = clone(val)
  90 + end
  91 + end
  92 + end
  93 + for _, v in pairs(goods) do
  94 + v.weight = (v.weight or 0) * v.amount
  95 + end
  96 +
  97 + --特殊赏
  98 + local special_ids = ichibankuji["special_id"]
  99 + if special_ids ~= "" then
  100 + for _, special_id in ipairs(special_ids:toArray(true, "=")) do
  101 + local val = csvdb["ichibankuji_specialCsv"][special_id]
  102 + if type(val.type) == "number" then
  103 + specials[special_id] = {np= 1, amount = val.amount, award = val.award, quality = tonumber(val.type), showIndex = val.showIndex}
  104 + elseif type(val.type) == "string" then
  105 + local pos = val.type:find("=")
  106 + if pos then
  107 + for k, v in pairs(val.type:toNumMap()) do
  108 + specials[special_id] = {np= v, amount = val.amount, award = val.award, quality = k, showIndex = val.showIndex}
  109 + end
  110 + else
  111 + specials[special_id] = {np= 1, amount = val.amount, award = val.award, quality = tonumber(val.type), showIndex = val.showIndex}
  112 + end
  113 + end
  114 + end
  115 + end
  116 +
  117 + --激励奖
  118 + local incentive_ids = ichibankuji["incentive_id"]
  119 + if incentive_ids ~= "" then
  120 + for _, incentive_id in ipairs(incentive_ids:toArray(true, "=")) do
  121 + local val = csvdb["ichibankuji_incentiveCsv"][incentive_id]
  122 + if type(val.type) == "number" then
  123 + incentive["last"] = {np=val.type, award = val.award}
  124 + elseif type(val.type) == "string" then
  125 + for k, v in pairs(val.type:toNumMap()) do
  126 + if k == 2 then
  127 + incentive["amount"] = {np= v, award = val.award}
  128 + elseif k==3 then
  129 + incentive["probabilities"] = {np= v, award = val.award}
  130 + end
  131 + end
  132 + end
  133 + end
  134 + end
  135 + --货币类型
  136 + local coin = ichibankuji["token"]:toArray(true, "=")
  137 + self:setProperties({coin = coin[1] or 0, token = coin, hideTime = ichibankuji.hide_time, goods = goods, specials = specials, incentive = incentive})
  138 +
  139 + skynet.error("初始化完成")
  140 + dump(self:data())
  141 +end
  142 +
  143 +function Capsule:isShow()
  144 + if skynet.timex() >= self:getProperty("hideTime") then
  145 + return false
  146 + end
  147 + return true
  148 +end
  149 +
  150 +function Capsule:refreshing(now)
  151 + local id = self:getProperty("id")
  152 + local room = self:getProperty("room")
  153 + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room]
  154 + local reset = tostring(ichibankuji.reset)
  155 +
  156 + if reset == "0" then
  157 + return false
  158 + elseif reset == "1" then
  159 + if self:getProperty("resetTimes") == 1 then
  160 + return true
  161 + end
  162 + return false
  163 + else
  164 + local resetArr = reset:toArray(true, "=")
  165 + if not next(resetArr) then return false end
  166 +
  167 + if resetArr[1] == "2" then
  168 + if self:getGoodsAmount() > 0 then return false end
  169 +
  170 + local drawEndTime = self:getProperty("drawEndTime") or 0
  171 + if drawEndTime == 0 then return false end
  172 +
  173 + if now - drawEndTime >= resetArr[2] then
  174 + return true
  175 + end
  176 + return false
  177 +
  178 + elseif resetArr[1] == "3" then
  179 +
  180 + elseif resetArr[1] == "4" then
  181 + if now >= resetArr[2] then return true end
  182 + end
  183 + end
  184 +
  185 + return false
  186 +end
  187 +
  188 +function Capsule:getOnlineCount()
  189 + local register = self:getProperty("register") or {}
  190 + local reg, onlookers = 0, 0
  191 + for _, v in pairs(register) do
  192 + if v == 1 then
  193 + reg = reg + 1
  194 + else
  195 + onlookers = onlookers + 1
  196 + end
  197 + end
  198 + return {[0]=onlookers, [1]=reg, [2] = reg+onlookers}
  199 +end
  200 +
  201 +function Capsule:join(roleId)
  202 + --一个房间最多人数 TODO
  203 + local register = self:getProperty("register") or {}
  204 + register[roleId] = 0
  205 + self:setProperty("register", register)
  206 + return self:data(roleId)
  207 +end
  208 +
  209 +function Capsule:getRegisterByRoleId(roleId)
  210 + local register = self:getProperty("register") or {}
  211 + return register[roleId] or 0
  212 +end
  213 +
  214 +function Capsule:isRegister(roleId)
  215 + return self:getRegisterByRoleId(roleId) == 1
  216 +end
  217 +
  218 +function Capsule:register(roleId)
  219 + local register = self:getProperty("register") or {}
  220 + register[roleId] = 1
  221 + self:setProperty("register", register)
  222 + return self:data(roleId)
  223 +end
  224 +
  225 +function Capsule:exit(roleId)
  226 + local register = self:getProperty("register") or {}
  227 + if next(register) then
  228 + register[roleId] = nil
  229 + return true
  230 + end
  231 + return false
  232 +end
  233 +
  234 +function Capsule:confirmed(cares)
  235 + local goods = self:getProperty("goods") or {}
  236 + local specials = self:getProperty("specials") or {}
  237 + local change = {}
  238 + for k, v in pairs(cares) do
  239 + if v.typ == 1 then
  240 + if goods[k] and goods[k].amount ~= v.count then
  241 + change[k] = {typ=1, count = goods[k].amount}
  242 + end
  243 + else
  244 + if specials[k] and specials[k].amount ~= v.count then
  245 + change[k] = {typ=1, count = specials[k].amount}
  246 + end
  247 + end
  248 + end
  249 + return change
  250 +end
  251 +
  252 +function Capsule:getGoodsAmount()
  253 + local goods = self:getProperty("goods") or {}
  254 + local amount = 0
  255 + for _, v in pairs(goods) do
  256 + amount = amount + v.amount
  257 + end
  258 + return amount
  259 +end
  260 +
  261 +function Capsule:getSpecialByType(typ)
  262 + local specials = self:getProperty("specials") or {}
  263 + for k, v in pairs(specials) do
  264 + if v.quality == typ then
  265 + return k, v
  266 + end
  267 + end
  268 + return nil
  269 +end
  270 +
  271 +function Capsule:checkSpecialFlag(typ)
  272 + local spKey, special = self:getSpecialByType(typ)
  273 + if not special then return nil end
  274 +
  275 + if special["amount"] <= 0 then return nil end
  276 + return spKey, special
  277 +end
  278 +
  279 +local function getSpecialRoleNotify(rewardRecord, count, award, spKey, typ, now)
  280 + local rewardByRole = {}
  281 + while(count > 0 and next(rewardRecord)) do
  282 + local roleId = math.randWeight(rewardRecord, "amount")
  283 + if roleId then
  284 +
  285 + local tmp = rewardRecord[roleId]
  286 + tmp["amount"] = tmp["amount"] - 1
  287 +
  288 + if tmp["amount"] <= 0 then rewardRecord[roleId] = nil end
  289 +
  290 + tmp = rewardByRole[roleId] or {}
  291 + if not next(tmp) then
  292 + local name = getNameByRoleId(roleId)
  293 + tmp[spKey] = {name = name, good_id = spKey, typ = RewardType.SPECIAL, award = award, amount = 1, quality = typ, create_time= now}
  294 + else
  295 + if not tmp[spKey] then
  296 + local name = getNameByRoleId(roleId)
  297 + tmp[spKey] = {name = name, good_id = spKey, typ = RewardType.SPECIAL, award = award, amount = 1, quality = typ, create_time= now}
  298 + else
  299 + tmp[spKey].amount = tmp[spKey].amount + 1
  300 + end
  301 + end
  302 + rewardByRole[roleId] = tmp
  303 +
  304 + count = count - 1
  305 + end
  306 + end
  307 + return rewardByRole, count
  308 +end
  309 +
  310 +
  311 +local rewardToNtyFunc = function(notify, tmpReward)
  312 + for key, val in pairs(tmpReward or {}) do
  313 + if not notify[key] then
  314 + notify[key] = clone(val)
  315 + else
  316 + for k, v in pairs(val) do
  317 + if not notify[key][k] then
  318 + notify[key][k] = v
  319 + else
  320 + notify[key][k] = notify[key][k].amount + v.amount
  321 + end
  322 + end
  323 +
  324 + end
  325 + end
  326 +end
  327 +
  328 +local function getRecordAmount(record)
  329 + return #record
  330 +end
  331 +
  332 +
  333 +function Capsule:getTop(record, recordAmount,now)
  334 + local spKey, special = self:checkSpecialFlag(SpecialType.TOP)
  335 + if not special then return nil end
  336 + local specials = self:getProperty("specials") or {}
  337 + local specialsRecord = self:getProperty("specialsRecord") or {}
  338 +
  339 + if recordAmount < special["np"] then return nil end
  340 +
  341 + local topRecord = {}
  342 + local count = special["np"]
  343 + for _, v in ipairs(record) do
  344 + if count <= 0 then break end
  345 +
  346 + local tmpCount = 0
  347 + if count >= v.amount then
  348 + count = count - v.amount
  349 + tmpCount = v.amount
  350 + else
  351 + tmpCount = count
  352 + count = 0
  353 + end
  354 +
  355 + if not topRecord[v.roleId]then
  356 + topRecord[v.roleId] = {amount = v.amount }
  357 + else
  358 + topRecord[v.roleId] = {amount = (topRecord[v.roleId]["amount"] or 0) + tmpCount}
  359 + end
  360 + end
  361 +
  362 + local rewardByRole, count = getSpecialRoleNotify(topRecord, special["amount"], special["award"], spKey, SpecialType.TOP,now)
  363 +
  364 + special["amount"] = count
  365 + specials[spKey] = special
  366 +
  367 + rewardToNtyFunc(specialsRecord, rewardByRole)
  368 +
  369 + self:setProperties({specialsRecord = specialsRecord, specials = specials})
  370 + return rewardByRole
  371 +
  372 +end
  373 +
  374 +--TODO
  375 +function Capsule:getCore(record, recordAmount,now)
  376 + local spKey, special = self:checkSpecialFlag(SpecialType.CORE)
  377 + if not special then return nil end
  378 +
  379 + local specials = self:getProperty("specials") or {}
  380 + local specialsRecord = self:getProperty("specialsRecord") or {}
  381 +
  382 + if self:getGoodsAmount() > 0 then return nil end
  383 +
  384 + local np = special["np"]
  385 + if np > recordAmount then return nil end
  386 +
  387 +
  388 + local left = math.ceil((np - recordAmount)/2) or 0
  389 + local count = np
  390 + local roleRecord = {}
  391 + for i, v in ipairs(record) do
  392 + if count <= 0 then break end
  393 + if i > left then
  394 + local tmpCount = 0
  395 + if count >= v.amount then
  396 + count = count - v.amount
  397 + tmpCount = v.amount
  398 + else
  399 + tmpCount = count
  400 + count = 0
  401 + end
  402 +
  403 + if not roleRecord[v.roleId]then
  404 + roleRecord[v.roleId] = {amount = v.amount }
  405 + else
  406 + roleRecord[v.roleId] = {amount = (roleRecord[v.roleId]["amount"] or 0) + tmpCount}
  407 + end
  408 + end
  409 +
  410 + end
  411 +
  412 + local rewardByRole, count = getSpecialRoleNotify(roleRecord, special["amount"], special["award"], spKey, SpecialType.CORE,now)
  413 +
  414 + special["amount"] = count
  415 + specials[spKey] = special
  416 +
  417 + rewardToNtyFunc(specialsRecord, rewardByRole)
  418 + self:setProperties({specialsRecord = specialsRecord, specials = specials})
  419 + return rewardByRole
  420 +end
  421 +
  422 +function Capsule:getLast(record,now)
  423 + local spKey, special = self:checkSpecialFlag(SpecialType.LAST)
  424 + if not special then return nil end
  425 +
  426 + local specials = self:getProperty("specials") or {}
  427 + local specialsRecord = self:getProperty("specialsRecord") or {}
  428 +
  429 + if self:getGoodsAmount() > 0 then return nil end
  430 +
  431 + table.sort(record, function(a, b) return a.create_time > b.create_time end)
  432 +
  433 + local np = special["np"]
  434 + local count = np
  435 + local roleRecord = {}
  436 + for _, v in ipairs(record) do
  437 + if count <= 0 then break end
  438 +
  439 + local tmpCount = 0
  440 + if count >= v.amount then
  441 + count = count - v.amount
  442 + tmpCount = v.amount
  443 + else
  444 + tmpCount = count
  445 + count = 0
  446 + end
  447 +
  448 + if not roleRecord[v.roleId]then
  449 + roleRecord[v.roleId] = {amount = v.amount }
  450 + else
  451 + roleRecord[v.roleId] = {amount = (roleRecord[v.roleId]["amount"] or 0) + tmpCount}
  452 + end
  453 + end
  454 +
  455 + local rewardByRole, count = getSpecialRoleNotify(roleRecord, special["amount"], special["award"], spKey, SpecialType.LAST,now)
  456 +
  457 + special["amount"] = count
  458 + specials[spKey] = special
  459 +
  460 + rewardToNtyFunc(specialsRecord, rewardByRole)
  461 + self:setProperties({specialsRecord = specialsRecord, specials = specials})
  462 + return rewardByRole
  463 +end
  464 +
  465 +function Capsule:getJoker(record,now)
  466 + local spKey, special = self:checkSpecialFlag(SpecialType.JOKER)
  467 + if not special then return nil end
  468 +
  469 + local specials = self:getProperty("specials") or {}
  470 + local specialsRecord = self:getProperty("specialsRecord") or {}
  471 +
  472 + if self:getGoodsAmount() > 0 then return nil end
  473 +
  474 + local roleRecord = {}
  475 + for _, v in ipairs(record) do
  476 + if not roleRecord[v.roleId]then
  477 + roleRecord[v.roleId] = {amount = v.amount }
  478 + else
  479 + roleRecord[v.roleId] = {amount = (roleRecord[v.roleId]["amount"] or 0) + v.amount}
  480 + end
  481 + end
  482 +
  483 + local rewardByRole, count = getSpecialRoleNotify(roleRecord, special["amount"], special["award"], spKey, SpecialType.JOKER,now)
  484 +
  485 + special["amount"] = count
  486 + specials[spKey] = special
  487 +
  488 + rewardToNtyFunc(specialsRecord, rewardByRole)
  489 + self:setProperties({specialsRecord = specialsRecord, specials = specials})
  490 + return rewardByRole
  491 +end
  492 +
  493 +function Capsule:getKing(record,now)
  494 + local spKey, special = self:checkSpecialFlag(SpecialType.KING)
  495 + if not special then return nil end
  496 +
  497 + local specials = self:getProperty("specials") or {}
  498 + local specialsRecord = self:getProperty("specialsRecord") or {}
  499 +
  500 + if self:getGoodsAmount() > 0 then return nil end
  501 +
  502 + local roleRecord = {}
  503 + for _, v in ipairs(record) do
  504 + if not roleRecord[v.roleId]then
  505 + roleRecord[v.roleId] = {amount = v.amount }
  506 + else
  507 + roleRecord[v.roleId] = {amount = (roleRecord[v.roleId]["amount"] or 0) + v.amount}
  508 + end
  509 + end
  510 +
  511 + local rewardByRole, count = getSpecialRoleNotify(roleRecord, special["amount"], special["award"], spKey, SpecialType.KING,now)
  512 + special["amount"] = count
  513 + specials[spKey] = special
  514 +
  515 + rewardToNtyFunc(specialsRecord, rewardByRole)
  516 + self:setProperties({specialsRecord = specialsRecord, specials = specials})
  517 + return rewardByRole
  518 +end
  519 +
  520 +function Capsule:checkSpecialReward( now)
  521 + local specials = self:getProperty("specials") or {}
  522 + if not next(specials) then return nil end
  523 + local record = self:getProperty("record") or {}
  524 +
  525 + if not next(record) then return nil end
  526 + table.sort(record, function(a, b) return a.create_time < b.create_time end )
  527 +
  528 + local recordAmount = getRecordAmount(record)
  529 +
  530 + local notify = self:getTop(record, recordAmount,now) or {}
  531 +
  532 + local coreReward = self:getCore(record, recordAmount, now)
  533 + rewardToNtyFunc(notify, coreReward)
  534 +
  535 + local lastReward = self:getLast(record, now)
  536 + rewardToNtyFunc(notify, lastReward)
  537 +
  538 + local jokerReward = self:getJoker(record, now)
  539 + rewardToNtyFunc(notify, jokerReward)
  540 +
  541 + local kingReward = self:getKing(record, now)
  542 + rewardToNtyFunc(notify, kingReward)
  543 +
  544 +
  545 + return notify
  546 +end
  547 +
  548 +function Capsule:checkIncentive(roleId, name, now)
  549 + local goods = self:getProperty("goods") or {}
  550 + local recordByRole = self:getProperty("recordByRole") or {}
  551 + local roleRecord = recordByRole[roleId] or {}
  552 + local incentiveRecord = self:getProperty("incentiveRecord") or {}
  553 + local incentiveByRole = incentiveRecord[roleId] or {}
  554 + local incentive = self:getProperty("incentive")
  555 +
  556 +
  557 + local notify = {}
  558 + -- 最后一抽 TODO
  559 + if incentive["last"] then
  560 + local last = true
  561 + for k, v in pairs(goods) do
  562 + if v and v.amount then
  563 + last = false
  564 + break
  565 + end
  566 + end
  567 + if last then
  568 + notify["last"] = {name = name, good_id = "last", typ = RewardType.INCENTIVE, award = incentive["last"]["award"], amount = 1, quality = 1, create_time= now}
  569 + end
  570 + end
  571 +
  572 + --次数
  573 + if incentive["amount"] then
  574 + local amount = 0
  575 + for _, v in pairs(roleRecord) do
  576 + if (v.calculated or 0) == 0 then
  577 + amount = amount + v.amount
  578 + end
  579 + end
  580 +
  581 + local count = math.floor(amount / incentive["amount"]["np"])
  582 + local tmpCount = count * incentive["amount"]["np"]
  583 + notify["amount"] = {name = name, roleId= roleId, good_id = "amount", typ = RewardType.INCENTIVE, award = incentive["amount"]["award"], amount = count, quality = 2, create_time= now}
  584 +
  585 + --填充v.calculated 字段,标识已经用于每x抽的计算中。
  586 + for _, v in pairs(roleRecord) do
  587 + if tmpCount <= 0 then break end
  588 +
  589 + v.calculated = v.calculated or 0
  590 + if v.calculated ~= v.amount then
  591 + if tmpCount <= v.amount then
  592 + v.calculated = tmpCount
  593 + tmpCount = 0
  594 + else
  595 + v.calculated = v.amount
  596 + tmpCount = tmpCount - v.amount
  597 + end
  598 + end
  599 +
  600 + end
  601 + end
  602 +
  603 + --概率
  604 + if incentive["probabilities"] then
  605 + local probabilities = math.randomInt(1, 100)
  606 + if probabilities <= incentive["probabilities"]["np"] then
  607 + notify["probabilities"] = {name = name, good_id = "probabilities", typ = RewardType.INCENTIVE, award = incentive["probabilities"]["award"], amount = 1, quality = 3, create_time= now}
  608 +
  609 + end
  610 + end
  611 + table.insert(incentiveByRole, notify)
  612 + incentiveRecord[roleId] = incentiveByRole
  613 + self:setProperty("incentiveRecord", incentiveRecord)
  614 +
  615 + --TODO 先屏蔽
  616 + return {}
  617 +end
  618 +
  619 +function Capsule:drawByCount(roleId, count)
  620 + if count <= 0 then return nil end
  621 +
  622 + local goods = self:getProperty("goods") or {}
  623 + local record = self:getProperty("record") or {}
  624 + local recordByRole = self:getProperty("recordByRole") or {}
  625 + local roleRecord = recordByRole[roleId] or {}
  626 +
  627 + local id = self:getProperty("id")
  628 + local room = self:getProperty("room")
  629 + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room]
  630 + local goods_id = ichibankuji["goods_id"]
  631 + local now = skynet.timex()
  632 +
  633 + --奖励, 通知信息
  634 + local notify= {}
  635 + notify[roleId] = {}
  636 +
  637 + local name = getNameByRoleId(roleId)
  638 + while (goods and next(goods) and count > 0) do
  639 + local good_id = math.randWeight(goods, "weight")
  640 + if not good_id then break end
  641 +
  642 + local good = goods[good_id] or {}
  643 + if good and good.amount > 0 then
  644 + good.amount = good.amount - 1
  645 +
  646 + --插入记录
  647 + local tmpNotify = {roleId = roleId, name= name, good_id = good_id, typ = RewardType.GOODS, award = good.award, amount = 1, quality = good.quality, create_time= now}
  648 + table.insert(record, tmpNotify)
  649 +
  650 + --作为奖励记录+通知
  651 + if not notify[roleId][good_id] then
  652 + notify[roleId][good_id] = tmpNotify
  653 + else
  654 + notify[roleId][good_id].amount = notify[roleId][good_id].amount + 1
  655 + end
  656 +
  657 + --记录角色的抽奖记录 计算激励奖需要用到
  658 + if not roleRecord[good_id] then
  659 + roleRecord[good_id] = tmpNotify
  660 + else
  661 + roleRecord[good_id].amount = roleRecord[good_id].amount + 1
  662 + end
  663 +
  664 + good.weight = good.weight - csvdb["ichibankuji_goodsCsv"][goods_id][good.id].weight
  665 + count = count - 1
  666 + end
  667 +
  668 + end
  669 + recordByRole[roleId] = roleRecord
  670 + self:setProperties({recordByRole = recordByRole, record = record, goods = goods})
  671 +
  672 + local tmpNotify = self:checkIncentive(roleId, name, now)
  673 + for k, v in pairs(tmpNotify) do
  674 + if not notify[roleId][k] then
  675 + notify[roleId][k] = v
  676 + else
  677 + notify[roleId][k].amount = notify[roleId][k].amount + v.amount
  678 + end
  679 + end
  680 +
  681 + local speciNotify = self:checkSpecialReward(now)
  682 + rewardToNtyFunc(notify, speciNotify)
  683 +
  684 + local reward, rewardByGoods = {}, {}
  685 + for key, val in pairs(notify) do
  686 + if key == roleId then
  687 + for k, v in pairs(val) do
  688 + for id, count in pairs(v.award:toNumMap()) do
  689 + reward[id] = (reward[id] or 0) + count
  690 + end
  691 + rewardByGoods[k] = v
  692 + end
  693 + end
  694 +
  695 + end
  696 + return reward, rewardByGoods, notify
  697 +end
  698 +
  699 +function Capsule:drawAll(roleId)
  700 + local goods = self:getProperty("goods") or {}
  701 + local record = self:getProperty("record") or {}
  702 + local recordByRole = self:getProperty("recordByRole") or {}
  703 + local roleRecord = recordByRole[roleId] or {}
  704 + local now = skynet.timex()
  705 +
  706 + local name = getNameByRoleId(roleId)
  707 + local notify = {}
  708 + notify[roleId] = {}
  709 + for good_id, good in pairs(goods) do
  710 + if good.amount > 0 then
  711 + --插入记录
  712 + local tmpNotify = {roleId = roleId, name= name, good_id = good_id, typ = RewardType.GOODS, award = good.award, amount = good.amount, quality = good.quality, create_time = now}
  713 + for i = 1, good.amount do
  714 + table.insert(record, {roleId = roleId, name= name, good_id = good_id, typ = RewardType.GOODS, award = good.award, amount = 1, quality = good.quality, create_time = now})
  715 + end
  716 +
  717 + --作为奖励记录+通知
  718 + if not notify[roleId][good_id] then
  719 + notify[roleId][good_id] = tmpNotify
  720 + else
  721 + notify[roleId][good_id].amount = notify[roleId][good_id].amount + good.award
  722 + end
  723 +
  724 + --记录角色的抽奖记录
  725 + if not roleRecord[good_id] then
  726 + roleRecord[good_id] = tmpNotify
  727 + else
  728 + roleRecord[good_id].amount = roleRecord[good_id].amount + good.amount
  729 + end
  730 +
  731 + good.amount = 0
  732 + end
  733 +
  734 + end
  735 + recordByRole[roleId] = roleRecord
  736 + self:setProperties({recordByRole = recordByRole, record = record, goods = goods})
  737 +
  738 + local tmpNotify = self:checkIncentive(roleId, name, now)
  739 + for k, v in pairs(tmpNotify) do
  740 + if not notify[roleId][k] then
  741 + notify[roleId][k] = v
  742 + else
  743 + notify[roleId][k].amount = notify[roleId][k].amount + v.amount
  744 + end
  745 + end
  746 +
  747 + local speciNotify = self:checkSpecialReward(now)
  748 + rewardToNtyFunc(notify, speciNotify)
  749 +
  750 + local reward, rewardByGoods = {}, {}
  751 + for key, val in pairs(notify) do
  752 + if key == roleId then
  753 + for k, v in pairs(val) do
  754 + for id, count in pairs(v.award:toNumMap()) do
  755 + reward[id] = (reward[id] or 0) + count
  756 + end
  757 + rewardByGoods[k] = v
  758 + end
  759 + end
  760 +
  761 + end
  762 + return reward, rewardByGoods, notify
  763 +end
  764 +
  765 +--@param
  766 +--[[
  767 +@roleId
  768 +@typ 0=独享,1=公开
  769 +@cares 关注{k=v}
  770 +]]--
  771 +
  772 +function Capsule:draw(roleId, full, cares)
  773 + if self:getProperty("typ") == 1 then
  774 + --是否报名
  775 + if self:isRegister(roleId) == false then return 4 end
  776 +
  777 + --关注的奖品的数量发生了变化
  778 + if cares then
  779 + local change = self:confirmed(cares)
  780 + if next(change) then return 5, change end
  781 + end
  782 + end
  783 +
  784 + if full == 0 then
  785 + return 6, self:drawByCount(roleId, 1)
  786 + elseif full == 1 then
  787 + return 6, self:drawByCount(roleId, 10)
  788 + elseif full == 2 then
  789 + return 6, self:drawAll(roleId)
  790 + end
  791 +end
  792 +
  793 +
  794 +function Capsule:data(roleId)
  795 + return {
  796 + id = self:getProperty("id"),
  797 + room = self:getProperty("room"),
  798 + typ = self:getProperty("typ"),
  799 + name = self:getProperty("name"),
  800 + coin = self:getProperty("coin"),
  801 + onlineCount = self:getOnlineCount(),
  802 + playerStatus = self:getRegisterByRoleId(roleId),
  803 + record = self:getProperty("record"),
  804 + rank = self:getProperty("rank"),
  805 + goods = self:getProperty("goods"),
  806 + specials = self:getProperty("specials"),
  807 + incentive = self:getProperty("incentive"),
  808 + specialsRecord= self:getProperty("specialsRecord"),
  809 + }
  810 +end
  811 +
  812 +return Capsule
0 813 \ No newline at end of file
... ...
src/models/Role.lua
... ... @@ -28,6 +28,7 @@ function Role:ctor( properties )
28 28 self.runeBag = {}
29 29 self.friends = {}
30 30 self.sparkBag = {}
  31 + self.capsules = {}
31 32 self.advData = nil
32 33 self.activity = nil
33 34 self._pushToken = nil
... ...
src/models/RoleCross.lua
... ... @@ -210,6 +210,20 @@ RoleCross.bind = function (Role)
210 210 return "成功"
211 211 end
212 212  
  213 + function Role:paySpecialReward(roleId, notify)
  214 + dump(notify)
  215 + if notify and next(notify) then
  216 + local reward = {}
  217 + for key, val in pairs(notify) do
  218 + for id, count in pairs(val.award:toNumMap()) do
  219 + reward[id] = (reward[id] or 0) + count
  220 + end
  221 +
  222 + end
  223 + self:award(reward, {log = {desc = "CapsuleReward", int1=roleId}})
  224 + end
  225 + end
  226 +
213 227 end
214 228  
215 229  
... ... @@ -370,6 +384,22 @@ function CMD.redPTag(roleId, tag, pms)
370 384 end
371 385 end
372 386  
  387 +function CMD.paySpecialReward(roleId, notify)
  388 + dump(notify)
  389 + if notify and next(notify) then
  390 + local reward = {}
  391 + for key, val in pairs(notify) do
  392 + for id, count in pairs(val.award:toNumMap()) do
  393 + reward[id] = (reward[id] or 0) + count
  394 + end
  395 +
  396 + end
  397 + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId})
  398 + role:award(reward, {log = {desc = "CapsuleReward", int1=roleId}})
  399 + end
  400 +
  401 +end
  402 +
373 403 RoleCross.handle = function(cmd, roleId, ...)
374 404 SRole = SRole or require("models.Role")
375 405 if CMD[cmd] then
... ...
src/models/RoleLog.lua
... ... @@ -159,6 +159,10 @@ local ItemReason = {
159 159 seaportTask = 1403, -- 贸易港任务奖励
160 160  
161 161 returner = 1410, -- 回归者奖励
  162 +
  163 + CapsuleReward = 1411, --扭蛋机奖励
  164 + CapsuleConvert = 1412, --扭蛋机 消耗票 兑换
  165 + CapsuleCoinCost = 1413, --抽扭蛋机消耗
162 166 }
163 167  
164 168  
... ...
src/models/RolePlugin.lua
... ... @@ -19,6 +19,7 @@ function RolePlugin.bind(Role)
19 19 --self:loadRoleIncre()
20 20 self:loadFriends()
21 21 self:loadSparks()
  22 + self:loadCapsules()
22 23 end
23 24  
24 25 function Role:reloadWhenLogin()
... ... @@ -821,6 +822,41 @@ function RolePlugin.bind(Role)
821 822 end
822 823 end
823 824  
  825 + function Role:loadCapsules()
  826 + local now = skynet.timex()
  827 + local roleId = self:getProperty("id")
  828 + local res = redisproxy:smembers(CAPSULE_ID_ROLE:format(roleId)) or {}
  829 + for _, key in pairs(res) do
  830 + local capsule = require("models.Capsule").new({ key = CAPSULE_ROLE:format(roleId,tonumber(key))})
  831 + capsule:load()
  832 + if capsule:isShow() then
  833 + if capsule:refreshing(now) then
  834 + capsule:init()
  835 + capsule:create()
  836 + end
  837 + self.capsules[key] = capsule
  838 + else
  839 + redisproxy:del(CAPSULE_ROLE:format(roleId, tonumber(key)))
  840 + redisproxy:srem(CAPSULE_ID_ROLE, key)
  841 + end
  842 + end
  843 +
  844 + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
  845 + for _, val in pairs(data) do
  846 + if val.typ == 0 then
  847 + local key = val.id..val.room
  848 + if not self.capsules[key] then
  849 + local capsule = require("models.Capsule").new({ key = CAPSULE_ROLE:format(roleId, tonumber(key)), id= val.id, room = val.room, typ = 0, name=val.name})
  850 + capsule:init()
  851 + capsule:create()
  852 + self.capsules[key] = capsule
  853 + redisproxy.sadd(CAPSULE_ID_ROLE:format(roleId), key)
  854 + end
  855 + end
  856 + end
  857 + end
  858 + end
  859 +
824 860 -- 0 为操作成功
825 861 function Role:addRune(params)
826 862 if params.type and params.id then
... ... @@ -1995,6 +2031,7 @@ function RolePlugin.bind(Role)
1995 2031 function Role:onRecoverTimer(now)
1996 2032 self:updateTimeReset(now, true)
1997 2033 self:checkNewEvent(now)
  2034 + self:checkCapsule(now)
1998 2035 self:saveRoleData(now)
1999 2036 end
2000 2037  
... ... @@ -3116,7 +3153,73 @@ function RolePlugin.bind(Role)
3116 3153 return itemRandomOccupy
3117 3154 end
3118 3155  
  3156 + function Role:getCapsuleList(coin)
  3157 + local capsules = {}
  3158 + for k, v in pairs(self.capsules) do
  3159 + if v:getProperty("coin") == coin then
  3160 + local onlineCount= v:getOnlineCount()
  3161 + capsules[k] = {id=v:getProperty("id"), room=v:getProperty("room"), typ=v:getProperty("typ"), people=onlineCount[2], coin= v:getProperty("coin")}
  3162 + end
  3163 + end
  3164 + return capsules
  3165 + end
3119 3166  
  3167 + function Role:drawCapsule(capsuleId, full, cares)
  3168 + local capsule = self.capsules[capsuleId] or {}
  3169 + if next(capsule) then
  3170 + local roleId = self:getProperty("id")
  3171 + return capsule:draw(roleId, full, cares)
  3172 + end
  3173 + return 3
  3174 + end
  3175 +
  3176 + function Role:joinCapsule(capsuleId)
  3177 + local capsule = self.capsules[capsuleId] or {}
  3178 + return capsule:data()
  3179 + end
  3180 +
  3181 + function Role:checkCapsule(now)
  3182 + for _, v in pairs(self.capsules) do
  3183 + if v:refreshing(now) then
  3184 + v:init()
  3185 + v:create()
  3186 + end
  3187 + end
  3188 + end
  3189 +
  3190 + function Role:goodStock(capsuleId)
  3191 + local capsule = self.capsules[capsuleId] or {}
  3192 + return capsule:getGoodsAmount(), capsule:getProperty("token")
  3193 + end
  3194 +
  3195 + function Role:getCapsuleData(capsuleId)
  3196 + local capsule = self.capsules[capsuleId] or {}
  3197 + return capsule:data()
  3198 + end
  3199 +
  3200 + function Role:resetCapsule()
  3201 + local roleId = self:getProperty("id")
  3202 + local res = redisproxy:smembers(CAPSULE_ID_ROLE:format(roleId)) or {}
  3203 + for _, key in pairs(res) do
  3204 + redisproxy:del(CAPSULE_ROLE:format(roleId, tonumber(key)))
  3205 + redisproxy:srem(CAPSULE_ID_ROLE, key)
  3206 + end
  3207 +
  3208 + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
  3209 + for _, val in pairs(data) do
  3210 + if val.typ == 0 then
  3211 + local key = val.id..val.room
  3212 + if not self.capsules[key] then
  3213 + local capsule = require("models.Capsule").new({ key = CAPSULE_ROLE:format(roleId, tonumber(key)), id= val.id, room = val.room, typ = 0, name=val.name})
  3214 + capsule:init()
  3215 + capsule:create()
  3216 + self.capsules[key] = capsule
  3217 + redisproxy.sadd(CAPSULE_ID_ROLE:format(roleId), key)
  3218 + end
  3219 + end
  3220 + end
  3221 + end
  3222 + end
3120 3223 end
3121 3224  
3122 3225 return RolePlugin
3123 3226 \ No newline at end of file
... ...
src/services/agent_ctrl.lua
... ... @@ -188,7 +188,7 @@ function _M:query_agent(fd, uid, isQueue)
188 188 end
189 189  
190 190 local agent = get_a(pack)
191   - local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd])
  191 + local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, capsuled, fd, self.f2i[fd])
192 192 if not ok then
193 193 query_agent_response(fd, {ret = "INNER_ERROR"})
194 194 return
... ... @@ -223,7 +223,7 @@ function _M:query_agent(fd, uid, isQueue)
223 223 end
224 224 end
225 225  
226   - local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd], hotfixList)
  226 + local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, capsuled, fd, self.f2i[fd], hotfixList)
227 227 if not ok then
228 228 self.factory:push(agent)
229 229 query_agent_response(fd, {ret = "INNER_ERROR"})
... ...
src/services/capsuled.lua 0 → 100644
... ... @@ -0,0 +1,237 @@
  1 +require "ProtocolCode"
  2 +require "shared.init"
  3 +require "GlobalVar"
  4 +require "RedisKeys"
  5 +require "skynet.manager"
  6 +skynet = require "skynet"
  7 +csvdb = require "shared.csvdata"
  8 +redisproxy = require "shared.redisproxy"
  9 +datacenter = require "skynet.datacenter"
  10 +
  11 +local capsules = {}
  12 +local CMD = {}
  13 +
  14 +NotifyChangeType = {
  15 + JOIN = 1,
  16 + EXIT = 2,
  17 + DRAW = 3,
  18 + SPECIAL = 4,
  19 +}
  20 +
  21 +skynet.register_protocol {
  22 + name = "role",
  23 + id = 101,
  24 + pack = skynet.pack,
  25 + unpack = skynet.unpack,
  26 +}
  27 +
  28 +local function rpcRole(roleId, funcName, ...)
  29 + local fields = ...
  30 + local agent = datacenter.get("agent", roleId)
  31 + if agent and agent.serv then
  32 + if funcName == "getProperties" then
  33 + return true, skynet.call(agent.serv, "role", funcName, fields)
  34 + else
  35 + return true, skynet.call(agent.serv, "role", funcName, ...)
  36 + end
  37 + else
  38 + local roleCross = require("models.RoleCross")
  39 + if funcName == "getProperties" then
  40 + return false, roleCross.handle(funcName, roleId, fields)
  41 + else
  42 + return false, roleCross.handle(funcName, roleId, ...)
  43 + end
  44 + end
  45 +end
  46 +
  47 +function getNameByRoleId(roleId)
  48 + local status, name = rpcRole(roleId, "getProperty", "name")
  49 + return name
  50 +
  51 +end
  52 +
  53 +function broadCastCapsule(roleId, capsuleId, broadInfo)
  54 + local capsule = capsules[capsuleId] or {}
  55 + local register = capsule:getProperty("register") or {}
  56 + if next(capsule) then
  57 + for id, _ in pairs(register) do
  58 + if id ~= roleId then
  59 + rpcRole(id, "SendPacket", actionCodes.Capsule_notifyChange, MsgPack.pack(broadInfo)) -- 通知对方
  60 + end
  61 + end
  62 + end
  63 +end
  64 +
  65 +function broadCastSpecial(roleId, capsuleId, broadInfo)
  66 + local capsule = capsules[capsuleId] or {}
  67 + local register = capsule:getProperty("register") or {}
  68 + if next(capsule) then
  69 + for id, _ in pairs(register) do
  70 + if id ~= roleId then
  71 + if broadInfo[id] then
  72 + rpcRole(id, "paySpecialReward", id, broadInfo[id])
  73 + end
  74 + end
  75 + end
  76 + end
  77 +end
  78 +
  79 +local function add(roleId, capsuleId)
  80 + local capsule = capsules[capsuleId] or {}
  81 + if next(capsule) then
  82 + capsule:join(roleId)
  83 + broadCastCapsule(roleId, capsuleId, {notifyType= NotifyChangeType.JOIN, roleId = roleId})
  84 + return capsule:data(roleId)
  85 + end
  86 + print("id 不存在: ".. capsuleId)
  87 + return nil
  88 +end
  89 +
  90 +local function capsuleRefreshing()
  91 + for _, v in pairs(capsules) do
  92 + if v:refreshing() then
  93 + v:init()
  94 + v:create()
  95 + end
  96 + end
  97 +end
  98 +
  99 +--扭蛋机刷新
  100 +local function check_capsules()
  101 + pcall(capsuleRefreshing)
  102 + skynet.timeout(60, check_capsules)
  103 +end
  104 +
  105 +function CMD.reset()
  106 + local now = skynet.timex()
  107 + local res = redisproxy:smembers(CAPSULE_INFO) or {}
  108 + for _, key in pairs(res) do
  109 + redisproxy:del(CAPSULE_PUBLIC:format(key))
  110 + redisproxy:srem(CAPSULE_INFO, key)
  111 + end
  112 +
  113 + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
  114 + for _, val in ipairs(data) do
  115 + if val.type == 1 then
  116 + local key = val.id..val.room
  117 + if not capsules[key] then
  118 + local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key), id= val.id, room = val.room, typ = 1, name=val.name})
  119 + capsule:init()
  120 + capsule:create()
  121 + capsules[key] = capsule
  122 + redisproxy:sadd(CAPSULE_INFO, key)
  123 + end
  124 + end
  125 + end
  126 + end
  127 +end
  128 +
  129 +function CMD.start()
  130 + local now = skynet.timex()
  131 + local res = redisproxy:smembers(CAPSULE_INFO) or {}
  132 + for _, key in pairs(res) do
  133 + local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key)})
  134 + capsule:load()
  135 + if capsule:isShow() then
  136 + if capsule:refreshing(now) then
  137 + capsule:init()
  138 + capsule:create()
  139 + end
  140 + capsules[key] = capsule
  141 + else
  142 + redisproxy:del(CAPSULE_PUBLIC:format(key))
  143 + redisproxy:srem(CAPSULE_INFO, key)
  144 + end
  145 + end
  146 +
  147 + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
  148 + for _, val in ipairs(data) do
  149 + if val.type == 1 then
  150 + local key = val.id..val.room
  151 + if not capsules[key] then
  152 + local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key), id= val.id, room = val.room, typ = 1, name=val.name})
  153 + capsule:init()
  154 + capsule:create()
  155 + capsules[key] = capsule
  156 + redisproxy:sadd(CAPSULE_INFO, key)
  157 + end
  158 + end
  159 + end
  160 + end
  161 +
  162 + check_capsules()
  163 +end
  164 +
  165 +function CMD.list(coin)
  166 + local tmpCapsules = {}
  167 + for k, v in pairs(capsules) do
  168 + if v:getProperty("coin") == coin then
  169 + local onlineCount= v:getOnlineCount()
  170 + tmpCapsules[k] = {id=v:getProperty("id"), room=v:getProperty("room"), typ=v:getProperty("typ"), people=onlineCount[2], coin= v:getProperty("coin")}
  171 + end
  172 + end
  173 + return tmpCapsules
  174 +end
  175 +
  176 +function CMD.join(roleId, capsuleId)
  177 + if capsuleId then
  178 + return add(roleId, capsuleId)
  179 + end
  180 + return nil
  181 +end
  182 +
  183 +
  184 +function CMD.exit(roleId, capsuleId)
  185 + if capsuleId then
  186 + local capsule = capsules[capsuleId] or {}
  187 + if next(capsule) then
  188 + capsule:exit(roleId)
  189 + broadCastCapsule(roleId, capsuleId, {notifyType = NotifyChangeType.EXIT, roleId = roleId})
  190 + end
  191 + else
  192 + for _, capsule in pairs(capsules) do
  193 + if next(capsule) then
  194 + capsule:exit(roleId)
  195 + broadCastCapsule(roleId, capsuleId, {notifyType = NotifyChangeType.EXIT, roleId = roleId})
  196 + end
  197 + end
  198 + end
  199 +end
  200 +
  201 +function CMD.draw_capsule(roleId, capsuleId, full, drawsNum, cares)
  202 + local capsule = capsules[capsuleId] or {}
  203 + if next(capsule) then
  204 + local ret, reward, rewardByGoods, notify = capsule:draw(roleId, full, drawsNum, cares)
  205 + if ret > 5 then
  206 + --broadCastCapsule(roleId, capsuleId, {notifyType = NotifyChangeType.DRAW, notify = notify})
  207 + broadCastSpecial(roleId, capsuleId, notify)
  208 + end
  209 + return ret, reward, rewardByGoods, capsule:data(roleId)
  210 + end
  211 + return 2
  212 +end
  213 +
  214 +function CMD.register(roleId, capsuleId)
  215 + local capsule = capsules[capsuleId] or {}
  216 + return capsule:register(roleId)
  217 +end
  218 +
  219 +function CMD.goods_stock(capsuleId)
  220 + local capsule = capsules[capsuleId] or {}
  221 + return capsule:getGoodsAmount(), capsule:getProperty("token")
  222 +end
  223 +
  224 +function CMD.capsule_data(roleId, capsuleId)
  225 + local capsule = capsules[capsuleId] or {}
  226 + return capsule:data(roleId)
  227 +end
  228 +
  229 +skynet.start(function()
  230 + skynet.dispatch("lua", function(session, address, cmd, ...)
  231 + local f = CMD[string.lower(cmd)]
  232 + skynet.ret(skynet.pack(f(...)))
  233 + end)
  234 +
  235 + skynet.register("capsuled")
  236 + globalCsv = csvdb["GlobalDefineCsv"]
  237 +end)
0 238 \ No newline at end of file
... ...
src/services/watchdog.lua
... ... @@ -66,6 +66,8 @@ function CMD.start(conf)
66 66 skynet.call(gate_serv, "lua", "open" , conf)
67 67  
68 68 skynet.call(pvpd, "lua", "start")
  69 +
  70 + skynet.call(capsuled, "lua", "start")
69 71 -- 开启agent状态检测定时器
70 72 check_agent_status()
71 73 -- 创建广播服务
... ... @@ -126,4 +128,5 @@ skynet.start(function()
126 128 skynet.newservice("services/chated")
127 129 -- 网关服务
128 130 gate_serv = skynet.newservice("gate")
  131 + capsuled = skynet.newservice("services/capsuled")
129 132 end)
... ...