Commit 555f745e7e302cce57f7fb404727bce3d4f0fe1f
1 parent
34c8cf27
feat: 一番赏
Showing
12 changed files
with
1190 additions
and
3 deletions
Show diff stats
src/ProtocolCode.lua
| ... | ... | @@ -274,6 +274,15 @@ 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, -- 退出 | |
| 277 | 286 | } |
| 278 | 287 | |
| 279 | 288 | 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" | ... | ... |
| ... | ... | @@ -0,0 +1,123 @@ |
| 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 | + SendPacket(actionCodes.Capsule_registerRpc, MsgPack.pack(ret)) | |
| 86 | + return true | |
| 87 | +end | |
| 88 | + | |
| 89 | +function _M.drawRpc(agent, data) | |
| 90 | + local role = agent.role | |
| 91 | + local msg = MsgPack.unpack(data) | |
| 92 | + local roleId = role:getProperty("id") | |
| 93 | + local capsuleId = msg.capsule_id | |
| 94 | + local typ = msg.typ --0=独享,1= 公开 | |
| 95 | + local full = msg.full -- 0=单次,1=十连抽 2=全收 | |
| 96 | + local continue = msg.continue--确认次数。 | |
| 97 | + local cares = msg.cares | |
| 98 | + | |
| 99 | + local ret, reward, change | |
| 100 | + if typ == 1 then | |
| 101 | + ret, reward = skynet.call(agent.capsule_serv, "lua", "draw_capsule", roleId, capsuleId, full, continue, cares) | |
| 102 | + else | |
| 103 | + ret, reward = role:drawCapsule(capsuleId, full, cares) | |
| 104 | + end | |
| 105 | + if ret <= 4 then return ret end | |
| 106 | + | |
| 107 | + reward, change = role:award(reward, {log = {desc = "CapsuleReward", int1 = capsuleId, int2 = roleId}}) | |
| 108 | + dump(reward) | |
| 109 | + SendPacket(actionCodes.Capsule_drawRpc, MsgPack.pack(role:packReward(reward, change))) | |
| 110 | + return true | |
| 111 | +end | |
| 112 | + | |
| 113 | +function _M.switchRoomRpc(agent, data) | |
| 114 | + local role = agent.role | |
| 115 | + local msg = MsgPack.unpack(data) | |
| 116 | + local roleId = role:getProperty("id") | |
| 117 | + | |
| 118 | + local ret = skynet.call(agent.capsule_serv, "lua", "switch_room", roleId) | |
| 119 | + SendPacket(actionCodes.Capsule_switchRoomRpc, MsgPack.pack(ret)) | |
| 120 | + return true | |
| 121 | +end | |
| 122 | + | |
| 123 | +return _M | |
| 0 | 124 | \ No newline at end of file | ... | ... |
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() | ... | ... |
| ... | ... | @@ -0,0 +1,797 @@ |
| 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 = 0, | |
| 11 | + TOP = 1, | |
| 12 | + CORE = 2, | |
| 13 | + LAST = 3, | |
| 14 | + JOKER = 4, | |
| 15 | + KING = 5, | |
| 16 | + GOOD = 6, | |
| 17 | + INCENTIVE = 7, | |
| 18 | +} | |
| 19 | + | |
| 20 | +CapsuleType = { | |
| 21 | + PRIVATE = 0, | |
| 22 | + PUBLIC = 1, | |
| 23 | +} | |
| 24 | + | |
| 25 | +Capsule.schema = { | |
| 26 | + id = {"number", 0}, --扭蛋机key,配置读取 | |
| 27 | + room = {"number", 0}, --房间号, 配置读取 | |
| 28 | + name = {"string", 0}, | |
| 29 | + typ = {"number", 1}, -- 1=共享,2=独享 | |
| 30 | + coin = {"number", 0}, --货币代号 | |
| 31 | + register = {"table", {}}, --人数 {["id"]=0}, 0 围观, 1 已报名 | |
| 32 | + record = {"table", {}}, --抽取记录 列表 | |
| 33 | + recordByRole = {"table", {}}, -- 抽取记录,hash, {roleid=record} | |
| 34 | + rank = {"table", {}}, --排行 | |
| 35 | + goods = {"table", {}}, --奖励池 | |
| 36 | + specials = {"table", {}}, --特殊赏 | |
| 37 | + incentive = {"table", {}}, --激励奖 | |
| 38 | + specialsFlag= {"table", {}}, --特殊赏是否已经领取 | |
| 39 | + resetInfo = {"table", {}}, | |
| 40 | + resetTimes = {"number", 0}, --每日一次手动重置的机会 | |
| 41 | + hideTime = {"number", 0} , --隐藏时间 | |
| 42 | + drawEndTime = {"number", 0}, --抽完时间 | |
| 43 | +} | |
| 44 | + | |
| 45 | +function Capsule:isShow() | |
| 46 | + if skynet.timex() >= self:getProperty("hideTime") then | |
| 47 | + return false | |
| 48 | + end | |
| 49 | + return true | |
| 50 | +end | |
| 51 | + | |
| 52 | +function Capsule:refreshing(now) | |
| 53 | + local id = self:getProperty("id") | |
| 54 | + local room = self:getProperty("room") | |
| 55 | + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room] | |
| 56 | + local reset = tostring(ichibankuji.reset) | |
| 57 | + | |
| 58 | + if reset == "0" then | |
| 59 | + return false | |
| 60 | + elseif reset == "1" then | |
| 61 | + if self:getProperty("resetTimes") == 1 then | |
| 62 | + return true | |
| 63 | + end | |
| 64 | + return false | |
| 65 | + else | |
| 66 | + local resetArr = reset:toArray(true, "=") | |
| 67 | + if not next(resetArr) then return false end | |
| 68 | + | |
| 69 | + if resetArr[1] == "2" then | |
| 70 | + if self:getGoodsAmount() > 0 then return false end | |
| 71 | + | |
| 72 | + local drawEndTime = self:getProperty("drawEndTime") or 0 | |
| 73 | + if drawEndTime == 0 then return false end | |
| 74 | + | |
| 75 | + if now - drawEndTime >= resetArr[2] then | |
| 76 | + return true | |
| 77 | + end | |
| 78 | + return false | |
| 79 | + | |
| 80 | + elseif resetArr[1] == "3" then | |
| 81 | + | |
| 82 | + elseif resetArr[1] == "4" then | |
| 83 | + if now >= resetArr[2] then return true end | |
| 84 | + end | |
| 85 | + end | |
| 86 | + | |
| 87 | + return false | |
| 88 | +end | |
| 89 | + | |
| 90 | +function Capsule:getResetFields() | |
| 91 | + return { | |
| 92 | + id = self:getProperty("id"), | |
| 93 | + room = self:getProperty("room"), | |
| 94 | + typ = self:getProperty("typ"), | |
| 95 | + coin = 0, | |
| 96 | + register = {}, | |
| 97 | + record = {}, | |
| 98 | + recordByRole = {}, | |
| 99 | + rank = {}, | |
| 100 | + goods = {}, | |
| 101 | + specials = {}, | |
| 102 | + incentive = {}, | |
| 103 | + specialsFlag= {}, | |
| 104 | + resetInfo = {}, | |
| 105 | + resetTimes = 0, | |
| 106 | + } | |
| 107 | +end | |
| 108 | + | |
| 109 | +function Capsule:init() | |
| 110 | + local id = self:getProperty("id") | |
| 111 | + local room = self:getProperty("room") | |
| 112 | + self:setProperties(self:getResetFields()) | |
| 113 | + | |
| 114 | + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room] | |
| 115 | + | |
| 116 | + --奖励池 | |
| 117 | + local goods_id = ichibankuji["goods_id"] | |
| 118 | + local goods, specials, incentive = {}, {}, {} | |
| 119 | + for _, data in pairs(csvdb["ichibankuji_goodsCsv"]) do | |
| 120 | + for _, val in pairs(data) do | |
| 121 | + if val.key == goods_id then | |
| 122 | + goods[goods_id..val.id] = clone(val) | |
| 123 | + end | |
| 124 | + end | |
| 125 | + end | |
| 126 | + for _, v in ipairs(goods) do | |
| 127 | + v.weight = (v.weight or 0) * v.amount | |
| 128 | + end | |
| 129 | + | |
| 130 | + --特殊赏 | |
| 131 | + local special_ids = ichibankuji["special_id"] | |
| 132 | + if special_ids ~= "" then | |
| 133 | + for _, special_id in ipairs(special_ids:toArray(true, "=")) do | |
| 134 | + local val = csvdb["ichibankuji_specialCsv"][special_id] | |
| 135 | + if type(val.type) == "number" then | |
| 136 | + specials[special_id] = {np= 1, amount = val.amount, award = val.award, quality = tonumber(val.type), showIndex = val.showIndex} | |
| 137 | + elseif type(val.type) == "string" then | |
| 138 | + local pos = val.type:find("=") | |
| 139 | + if pos then | |
| 140 | + for k, v in pairs(val.type:toNumMap()) do | |
| 141 | + specials[special_id] = {np= v, amount = val.amount, award = val.award, quality = k, showIndex = val.showIndex} | |
| 142 | + end | |
| 143 | + else | |
| 144 | + specials[special_id] = {np= 1, amount = val.amount, award = val.award, quality = tonumber(val.type), showIndex = val.showIndex} | |
| 145 | + end | |
| 146 | + end | |
| 147 | + end | |
| 148 | + end | |
| 149 | + | |
| 150 | + --激励奖 | |
| 151 | + local incentive_ids = ichibankuji["incentive_id"] | |
| 152 | + if incentive_ids ~= "" then | |
| 153 | + for _, incentive_id in ipairs(incentive_ids:toArray(true, "=")) do | |
| 154 | + local val = csvdb["ichibankuji_incentiveCsv"][incentive_id] | |
| 155 | + if type(val.type) == "number" then | |
| 156 | + incentive["last"] = {np=val.type, award = val.award} | |
| 157 | + elseif type(val.type) == "string" then | |
| 158 | + for k, v in pairs(val.type:toNumMap()) do | |
| 159 | + if k == 2 then | |
| 160 | + incentive["amount"] = {np= v, award = val.award} | |
| 161 | + elseif k==3 then | |
| 162 | + incentive["probabilities"] = {np= v, award = val.award} | |
| 163 | + end | |
| 164 | + end | |
| 165 | + end | |
| 166 | + end | |
| 167 | + end | |
| 168 | + --货币类型 | |
| 169 | + local coin = ichibankuji["token"]:toArray(true, "=") | |
| 170 | + self:setProperties({coin = coin[1] or 0, hideTime = ichibankuji.hide_time, goods = goods, specials = specials, incentive = incentive}) | |
| 171 | +end | |
| 172 | + | |
| 173 | +function Capsule:getOnlineCount() | |
| 174 | + local register = self:getProperty("register") or {} | |
| 175 | + local reg, onlookers = 0, 0 | |
| 176 | + for _, v in pairs(register) do | |
| 177 | + if v == 1 then | |
| 178 | + reg = reg + 1 | |
| 179 | + else | |
| 180 | + onlookers = onlookers + 1 | |
| 181 | + end | |
| 182 | + end | |
| 183 | + return {[0]=onlookers, [1]=reg, [2] = reg+onlookers} | |
| 184 | +end | |
| 185 | + | |
| 186 | +function Capsule:join(roleId) | |
| 187 | + --一个房间最多人数 TODO | |
| 188 | + local register = self:getProperty("register") or {} | |
| 189 | + register[roleId] = 0 | |
| 190 | + self:setProperty("register", register) | |
| 191 | + return true | |
| 192 | +end | |
| 193 | + | |
| 194 | +function Capsule:isRegister(roleId) | |
| 195 | + local register = self:getProperty("register") or {} | |
| 196 | + return register[roleId] == 1 | |
| 197 | +end | |
| 198 | + | |
| 199 | +function Capsule:register(roleId) | |
| 200 | + local register = self:getProperty("register") or {} | |
| 201 | + if next(register) then | |
| 202 | + register[roleId] = 1 | |
| 203 | + return true | |
| 204 | + end | |
| 205 | + return false | |
| 206 | +end | |
| 207 | + | |
| 208 | +function Capsule:exit(roleId) | |
| 209 | + local register = self:getProperty("register") or {} | |
| 210 | + if next(register) then | |
| 211 | + register[roleId] = nil | |
| 212 | + return true | |
| 213 | + end | |
| 214 | + return false | |
| 215 | +end | |
| 216 | + | |
| 217 | +function Capsule:confirmed(cares) | |
| 218 | + local goods = self:getProperty("goods") or {} | |
| 219 | + local specials = self:getProperty("specials") or {} | |
| 220 | + local change = {} | |
| 221 | + for k, v in pairs(cares) do | |
| 222 | + if v.typ == 1 then | |
| 223 | + if goods[k] and goods[k].amount ~= v.count then | |
| 224 | + change[k] = goods[k].amount | |
| 225 | + end | |
| 226 | + else | |
| 227 | + if specials[k] and specials[k].amount ~= v.count then | |
| 228 | + change[k] = specials[k].amount | |
| 229 | + end | |
| 230 | + end | |
| 231 | + end | |
| 232 | + return change | |
| 233 | +end | |
| 234 | + | |
| 235 | +function Capsule:getGoodsAmount() | |
| 236 | + local goods = self:getProperty("goods") or {} | |
| 237 | + local amount = 0 | |
| 238 | + for _, v in ipairs(goods) do | |
| 239 | + amount = amount + v.amount | |
| 240 | + end | |
| 241 | + return amount | |
| 242 | +end | |
| 243 | + | |
| 244 | +function Capsule:getSpecialByType(typ) | |
| 245 | + local specials = self:getProperty("specials") or {} | |
| 246 | + for k, v in pairs(specials) do | |
| 247 | + if v.quality == typ then | |
| 248 | + return k, v | |
| 249 | + end | |
| 250 | + end | |
| 251 | + return nil | |
| 252 | +end | |
| 253 | + | |
| 254 | +function Capsule:getTop(record) | |
| 255 | + local specialsFlag = self:getProperty("specialsFlag") or {} | |
| 256 | + if specialsFlag[RewardTYpe.TOP] then return nil end | |
| 257 | + | |
| 258 | + local specials = self:getProperty("specials") or {} | |
| 259 | + local spKey, special = self:getSpecialByType(RewardTYpe.TOP) | |
| 260 | + if not special then return nil end | |
| 261 | + | |
| 262 | + local np = special["np"] | |
| 263 | + if #record >= special["np"] then | |
| 264 | + local topRecord = {} | |
| 265 | + local count = np | |
| 266 | + for _, v in ipairs(record) do | |
| 267 | + if count <= 0 then break end | |
| 268 | + | |
| 269 | + local tmpCount = 0 | |
| 270 | + if count >= v.amount then | |
| 271 | + count = count - v.amount | |
| 272 | + tmpCount = v.amount | |
| 273 | + else | |
| 274 | + tmpCount = count | |
| 275 | + count = 0 | |
| 276 | + end | |
| 277 | + | |
| 278 | + if not topRecord[v.role_id]then | |
| 279 | + topRecord[v.role_id] = {amount = v.amount } | |
| 280 | + else | |
| 281 | + topRecord[v.role_id] = {amount = (topRecord[v.rol_id]["amount"] or 0) + tmpCount} | |
| 282 | + end | |
| 283 | + end | |
| 284 | + | |
| 285 | + count = special["amount"] | |
| 286 | + local topRoleIds = {} | |
| 287 | + while(count > 0 and next(topRecord)) do | |
| 288 | + local roleId = math.randWeight(topRecord, "amount") | |
| 289 | + if roleId then | |
| 290 | + table.insert(topRoleIds, roleId) | |
| 291 | + local tmpTopRecord = topRecord[roleId] | |
| 292 | + tmpTopRecord["amount"] = tmpTopRecord["amount"] - 1 | |
| 293 | + | |
| 294 | + if tmpTopRecord["amount"] <= 0 then topRecord[roleId] = nil end | |
| 295 | + | |
| 296 | + count = count - 1 | |
| 297 | + end | |
| 298 | + | |
| 299 | + end | |
| 300 | + | |
| 301 | + special["amount"] = count | |
| 302 | + specials[spKey] = special | |
| 303 | + specialsFlag[RewardTYpe.TOP] = topRoleIds | |
| 304 | + self:setProperty("specialsFlag", specialsFlag) | |
| 305 | + self:setProperty("specials", specials) | |
| 306 | + return {role_ids = topRoleIds, award = sspecial["award"]} | |
| 307 | + end | |
| 308 | + | |
| 309 | + return nil | |
| 310 | +end | |
| 311 | + | |
| 312 | +--TODO | |
| 313 | +function Capsule:getCore(record) | |
| 314 | + if self:getGoodsAmount() > 0 then return nil end | |
| 315 | + | |
| 316 | + local specialsFlag = self:getProperty("specialsFlag") or {} | |
| 317 | + if specialsFlag[RewardTYpe.CORE] then return nil end | |
| 318 | + | |
| 319 | + local specials = self:getProperty("specials") or {} | |
| 320 | + local spKey, special = self:getSpecialByType(RewardTYpe.CORE) | |
| 321 | + if not special then return nil end | |
| 322 | + | |
| 323 | + local np = special["np"] | |
| 324 | + if np > #record then return nil end | |
| 325 | + | |
| 326 | + | |
| 327 | + local left = math.ceil((np - #record)/2) or 0 | |
| 328 | + local count = np | |
| 329 | + local roleRecord = {} | |
| 330 | + for i, v in ipairs(record) do | |
| 331 | + if count <= 0 then break end | |
| 332 | + if i > left then | |
| 333 | + local tmpCount = 0 | |
| 334 | + if count >= v.amount then | |
| 335 | + count = count - v.amount | |
| 336 | + tmpCount = v.amount | |
| 337 | + else | |
| 338 | + tmpCount = count | |
| 339 | + count = 0 | |
| 340 | + end | |
| 341 | + | |
| 342 | + if not roleRecord[v.role_id]then | |
| 343 | + roleRecord[v.role_id] = {amount = v.amount } | |
| 344 | + else | |
| 345 | + roleRecord[v.role_id] = {amount = (roleRecord[v.rol_id]["amount"] or 0) + tmpCount} | |
| 346 | + end | |
| 347 | + end | |
| 348 | + | |
| 349 | + end | |
| 350 | + | |
| 351 | + count = special["amount"] | |
| 352 | + local roleIds = {} | |
| 353 | + while(count > 0 and next(roleRecord)) do | |
| 354 | + local roleId = math.randWeight(roleRecord, "amount") | |
| 355 | + if roleId then | |
| 356 | + table.insert(roleIds, roleId) | |
| 357 | + local tmpLastRecord = roleRecord[roleId] | |
| 358 | + tmpLastRecord["amount"] = tmpLastRecord["amount"] - 1 | |
| 359 | + | |
| 360 | + if tmpLastRecord["amount"] <= 0 then roleRecord[roleId] = nil end | |
| 361 | + | |
| 362 | + count = count - 1 | |
| 363 | + end | |
| 364 | + end | |
| 365 | + special["amount"] = count | |
| 366 | + specials[spKey] = special | |
| 367 | + specialsFlag[RewardTYpe.CORE] = roleIds | |
| 368 | + self:setProperty("specialsFlag", specialsFlag) | |
| 369 | + self:setProperty("specials", specials) | |
| 370 | + return {role_ids = roleIds, award = special["award"]} | |
| 371 | +end | |
| 372 | + | |
| 373 | +function Capsule:getLast(record) | |
| 374 | + if self:getGoodsAmount() > 0 then return nil end | |
| 375 | + | |
| 376 | + local specialsFlag = self:getProperty("specialsFlag") or {} | |
| 377 | + if specialsFlag[RewardTYpe.LAST] then return nil end | |
| 378 | + | |
| 379 | + local specials = self:getProperty("specials") or {} | |
| 380 | + local spKey, special = self:getSpecialByType(RewardTYpe.LAST) | |
| 381 | + if not special then return nil end | |
| 382 | + | |
| 383 | + if not next(record) then return nil end | |
| 384 | + table.sort(record, function(a, b) return a.create_time > b.create_time end) | |
| 385 | + | |
| 386 | + | |
| 387 | + local np = special["np"] | |
| 388 | + local count = np | |
| 389 | + local lastRecord = {} | |
| 390 | + for _, v in ipairs(record) do | |
| 391 | + if count <= 0 then break end | |
| 392 | + | |
| 393 | + local tmpCount = 0 | |
| 394 | + if count >= v.amount then | |
| 395 | + count = count - v.amount | |
| 396 | + tmpCount = v.amount | |
| 397 | + else | |
| 398 | + tmpCount = count | |
| 399 | + count = 0 | |
| 400 | + end | |
| 401 | + | |
| 402 | + if not lastRecord[v.role_id]then | |
| 403 | + lastRecord[v.role_id] = {amount = v.amount } | |
| 404 | + else | |
| 405 | + lastRecord[v.role_id] = {amount = (lastRecord[v.rol_id]["amount"] or 0) + tmpCount} | |
| 406 | + end | |
| 407 | + end | |
| 408 | + | |
| 409 | + count = special["amount"] | |
| 410 | + local lastRoleIds = {} | |
| 411 | + while(count > 0 and next(lastRecord)) do | |
| 412 | + local roleId = math.randWeight(lastRecord, "amount") | |
| 413 | + if roleId then | |
| 414 | + table.insert(lastRoleIds, roleId) | |
| 415 | + local tmpLastRecord = lastRecord[roleId] | |
| 416 | + tmpLastRecord["amount"] = tmpLastRecord["amount"] - 1 | |
| 417 | + | |
| 418 | + if tmpLastRecord["amount"] <= 0 then lastRecord[roleId] = nil end | |
| 419 | + | |
| 420 | + count = count - 1 | |
| 421 | + end | |
| 422 | + end | |
| 423 | + special["amount"] = count | |
| 424 | + specials[spKey] = special | |
| 425 | + specialsFlag[RewardTYpe.LAST] = lastRoleIds | |
| 426 | + self:setProperty("specialsFlag", specialsFlag) | |
| 427 | + self:setProperty("specials", specials) | |
| 428 | + return {role_ids = lastRoleIds, award = special["award"]} | |
| 429 | +end | |
| 430 | + | |
| 431 | +function Capsule:getJoker(record) | |
| 432 | + if self:getGoodsAmount() > 0 then return nil end | |
| 433 | + local specialsFlag = self:getProperty("specialsFlag") or {} | |
| 434 | + if specialsFlag[RewardTYpe.JOKER] then return nil end | |
| 435 | + | |
| 436 | + local specials = self:getProperty("specials") or {} | |
| 437 | + local spKey, special = self:getSpecialByType(RewardTYpe.JOKER) | |
| 438 | + if not special then return nil end | |
| 439 | + | |
| 440 | + local roleRecord = {} | |
| 441 | + for _, v in ipairs(record) do | |
| 442 | + if not roleRecord[v.role_id]then | |
| 443 | + roleRecord[v.role_id] = {amount = v.amount } | |
| 444 | + else | |
| 445 | + roleRecord[v.role_id] = {amount = (roleRecord[v.rol_id]["amount"] or 0) + v.amount} | |
| 446 | + end | |
| 447 | + end | |
| 448 | + | |
| 449 | + local count = special["amount"] | |
| 450 | + local roleIds = {} | |
| 451 | + while(count > 0 and next(roleRecord)) do | |
| 452 | + local roleId = math.randWeight(roleRecord, "amount") | |
| 453 | + if roleId then | |
| 454 | + table.insert(roleIds, roleId) | |
| 455 | + local tmpRoleRecord = roleRecord[roleId] | |
| 456 | + tmpRoleRecord["amount"] = tmpRoleRecord["amount"] - 1 | |
| 457 | + | |
| 458 | + if tmpRoleRecord["amount"] <= 0 then roleRecord[roleId] = nil end | |
| 459 | + | |
| 460 | + count = count - 1 | |
| 461 | + end | |
| 462 | + end | |
| 463 | + special["amount"] = count | |
| 464 | + specials[spKey] = special | |
| 465 | + specialsFlag[RewardTYpe.JOKER] = roleIds | |
| 466 | + self:setProperty("specialsFlag", specialsFlag) | |
| 467 | + self:setProperty("specials", specials) | |
| 468 | + return {role_ids = roleIds, award = special["award"]} | |
| 469 | +end | |
| 470 | + | |
| 471 | +function Capsule:getKing(record) | |
| 472 | + if self:getGoodsAmount() > 0 then return nil end | |
| 473 | + local specialsFlag = self:getProperty("specialsFlag") or {} | |
| 474 | + if specialsFlag[RewardTYpe.JOKER] then return nil end | |
| 475 | + | |
| 476 | + local specials = self:getProperty("specials") or {} | |
| 477 | + local spKey, special = self:getSpecialByType(RewardTYpe.KING) | |
| 478 | + if not special then return nil end | |
| 479 | + | |
| 480 | + | |
| 481 | + local roleRecord = {} | |
| 482 | + for _, v in ipairs(record) do | |
| 483 | + if not roleRecord[v.role_id]then | |
| 484 | + roleRecord[v.role_id] = {amount = v.amount } | |
| 485 | + else | |
| 486 | + roleRecord[v.role_id] = {amount = (roleRecord[v.rol_id]["amount"] or 0) + v.amount} | |
| 487 | + end | |
| 488 | + end | |
| 489 | + | |
| 490 | + local count = special["amount"] | |
| 491 | + local roleIds = {} | |
| 492 | + while(count > 0 and next(roleRecord)) do | |
| 493 | + local roleId = math.randWeight(roleRecord, "amount") | |
| 494 | + if roleId then | |
| 495 | + table.insert(roleIds, roleId) | |
| 496 | + local tmpRoleRecord = roleRecord[roleId] | |
| 497 | + tmpRoleRecord["amount"] = tmpRoleRecord["amount"] - 1 | |
| 498 | + | |
| 499 | + if tmpRoleRecord["amount"] <= 0 then roleRecord[roleId] = nil end | |
| 500 | + | |
| 501 | + count = count - 1 | |
| 502 | + end | |
| 503 | + end | |
| 504 | + special["amount"] = count | |
| 505 | + specials[spKey] = special | |
| 506 | + specialsFlag[RewardTYpe.KING] = roleIds | |
| 507 | + self:setProperty("specialsFlag", specialsFlag) | |
| 508 | + self:setProperty("specials", specials) | |
| 509 | + return {role_ids = roleIds, award = special["award"]} | |
| 510 | +end | |
| 511 | + | |
| 512 | + | |
| 513 | +function Capsule:checkSpecialReward() | |
| 514 | + local specials = self:getProperty("specials") or {} | |
| 515 | + if not next(specials) then return nil end | |
| 516 | + local record = self:getProperty("record") or {} | |
| 517 | + if not next(record) then return nil end | |
| 518 | + table.sort(record, function(a, b) return a.create_time < b.create_time end ) | |
| 519 | + local notify = {} | |
| 520 | + | |
| 521 | + local topReward = self:getTop(record) | |
| 522 | + if topReward then | |
| 523 | + for _, roleId in ipairs(topReward.role_ids) do | |
| 524 | + rpcRole(roleId, "paySpecialReward", RewardTYpe.TOP, topReward.award) | |
| 525 | + table.insert(notify, {role_id = roleId, typ = RewardTYpe.TOP, award = topReward.award, amount = 1, create_time= skynet.timex()}) | |
| 526 | + end | |
| 527 | + end | |
| 528 | + | |
| 529 | + local coreReward = self:getCore(record) | |
| 530 | + if coreReward then | |
| 531 | + for _, roleId in ipairs(topReward.role_ids) do | |
| 532 | + rpcRole(roleId, "paySpecialReward", RewardTYpe.CORE, coreReward.award) | |
| 533 | + table.insert(notify, {role_id = roleId, typ = RewardTYpe.CORE, award = topReward.award, amount = 1, create_time= skynet.timex()}) | |
| 534 | + end | |
| 535 | + end | |
| 536 | + local lastReward = self:getLast(record) | |
| 537 | + if lastReward then | |
| 538 | + for _, roleId in ipairs(lastReward.role_ids) do | |
| 539 | + rpcRole(roleId, "paySpecialReward", RewardTYpe.LAST, lastReward.award) | |
| 540 | + table.insert(notify, {role_id = roleId, typ = RewardTYpe.LAST, award = topReward.award, amount = 1, create_time= skynet.timex()}) | |
| 541 | + end | |
| 542 | + end | |
| 543 | + local jokerReward = self:getJoker(record) | |
| 544 | + if jokerReward then | |
| 545 | + for _, roleId in ipairs(jokerReward.role_ids) do | |
| 546 | + rpcRole(roleId, "paySpecialReward", RewardTYpe.JOKER, jokerReward.award) | |
| 547 | + table.insert(notify, {role_id = roleId, typ = RewardTYpe.JOKER, award = topReward.award, amount = 1, create_time= skynet.timex()}) | |
| 548 | + end | |
| 549 | + end | |
| 550 | + local kingReward = self:getKing(record) | |
| 551 | + if kingReward then | |
| 552 | + for _, roleId in ipairs(kingReward.role_ids) do | |
| 553 | + rpcRole(roleId, "paySpecialReward", RewardTYpe.KING, kingReward.award) | |
| 554 | + table.insert(notify, {role_id = roleId, typ = RewardTYpe.KING, award = topReward.award, amount = 1, create_time= skynet.timex()}) | |
| 555 | + end | |
| 556 | + end | |
| 557 | + | |
| 558 | + return notify | |
| 559 | +end | |
| 560 | + | |
| 561 | +function Capsule:checkIncentive(roleId) | |
| 562 | + local goods = self:getProperty("goods") or {} | |
| 563 | + local record = self:getProperty("record") or {} | |
| 564 | + local recordByRole = self:getProperty("recordByRole") or {} | |
| 565 | + local roleRecord = recordByRole[roleId] or {} | |
| 566 | + local incentive = self:getProperty("incentive") | |
| 567 | + | |
| 568 | + | |
| 569 | + local reward | |
| 570 | + -- 最后一抽 TODO | |
| 571 | + if incentive["last"] then | |
| 572 | + local last = true | |
| 573 | + for k, v in pairs(goods) do | |
| 574 | + if v and v.amount then | |
| 575 | + last = false | |
| 576 | + break | |
| 577 | + end | |
| 578 | + end | |
| 579 | + reward = incentive["last"]["award"] | |
| 580 | + end | |
| 581 | + | |
| 582 | + --次数 | |
| 583 | + if incentive["amount"] then | |
| 584 | + local amount = 0 | |
| 585 | + for _, v in pairs(roleRecord) do | |
| 586 | + if (v.calculated or 0) == 0 then | |
| 587 | + amount = amount + v.amount | |
| 588 | + end | |
| 589 | + end | |
| 590 | + | |
| 591 | + local count = math.floor(amount / incentive["amount"]["np"]) | |
| 592 | + local tmpCount = count * incentive["amount"]["np"] | |
| 593 | + for i=1, count do | |
| 594 | + reward = reward.. " " .. incentive["amount"]["award"] | |
| 595 | + end | |
| 596 | + | |
| 597 | + --填充v.calculated 字段,标识已经用于每x抽的计算中。 | |
| 598 | + for _, v in pairs(roleRecord) do | |
| 599 | + if tmpCount <= 0 then break end | |
| 600 | + | |
| 601 | + v.calculated = v.calculated or 0 | |
| 602 | + if v.calculated ~= v.amount then | |
| 603 | + if tmpCount <= v.amount then | |
| 604 | + v.calculated = tmpCount | |
| 605 | + tmpCount = 0 | |
| 606 | + else | |
| 607 | + v.calculated = v.amount | |
| 608 | + tmpCount = tmpCount - v.amount | |
| 609 | + end | |
| 610 | + end | |
| 611 | + | |
| 612 | + end | |
| 613 | + end | |
| 614 | + | |
| 615 | + --概率 | |
| 616 | + if incentive["probabilities"] then | |
| 617 | + local probabilities = math.randomInt(1, 100) | |
| 618 | + if probabilities <= incentive["probabilities"]["np"] then | |
| 619 | + reward = reward .. " " .. incentive["probabilities"]["award"] | |
| 620 | + end | |
| 621 | + end | |
| 622 | + if reward and reward ~= "" then | |
| 623 | + local tmpReward, notify = {}, {} | |
| 624 | + for k, v in pairs(reward:toNumMap()) do | |
| 625 | + tmpReward[k] = (tmpReward[k] or 0) + v | |
| 626 | + end | |
| 627 | + | |
| 628 | + notify = {role_id = roleId, typ = RewardTYpe.incentive, award = reward, amount = 1, create_time= skynet.timex()} | |
| 629 | + table.insert(record, notify) | |
| 630 | + self:setProperty("record", record) | |
| 631 | + return tmpReward,notify | |
| 632 | + end | |
| 633 | + return nil, nil | |
| 634 | +end | |
| 635 | + | |
| 636 | +function Capsule:drawByCount(roleId, count) | |
| 637 | + if count <= 0 then return nil end | |
| 638 | + | |
| 639 | + local goods = self:getProperty("goods") or {} | |
| 640 | + local record = self:getProperty("record") or {} | |
| 641 | + local recordByRole = self:getProperty("recordByRole") or {} | |
| 642 | + | |
| 643 | + local id = self:getProperty("id") | |
| 644 | + local room = self:getProperty("room") | |
| 645 | + local ichibankuji = csvdb["ichibankuji_mainCsv"][id][room] | |
| 646 | + local goods_id = ichibankuji["goods_id"] | |
| 647 | + | |
| 648 | + --奖励, 通知信息 | |
| 649 | + local reward, notify= {}, {} | |
| 650 | + while (goods and next(goods) and count > 0) do | |
| 651 | + local good_id = math.randWeight(goods, "weight") | |
| 652 | + if good_id then | |
| 653 | + local good = goods[good_id] or {} | |
| 654 | + if good.amount > 0 then | |
| 655 | + good.amount = good.amount - 1 | |
| 656 | + for k, v in pairs(good.award:toNumMap()) do | |
| 657 | + reward[k] = (reward[k] or 0) + v | |
| 658 | + end | |
| 659 | + | |
| 660 | + --插入记录 | |
| 661 | + local tmpNotify = {role_id = roleId, good_id = good_id, typ = RewardTYpe.GOODS, award = good.award, amount = 1, quality = good.quality, create_time= skynet.timex()} | |
| 662 | + | |
| 663 | + table.insert(record, tmpNotify) | |
| 664 | + table.insert(notify, tmpNotify) | |
| 665 | + | |
| 666 | + --记录角色的抽奖记录 | |
| 667 | + local tmp = recordByRole[roleId] | |
| 668 | + if not tmp then | |
| 669 | + recordByRole[roleId] = {good_id=notify} | |
| 670 | + else | |
| 671 | + if not tmp[good_id] then | |
| 672 | + tmp[good_id] = notify | |
| 673 | + else | |
| 674 | + tmp[good_id].amount = tmp[good_id].amount + 1 | |
| 675 | + end | |
| 676 | + end | |
| 677 | + | |
| 678 | + good.weight = good.weight - csvdb["ichibankuji_goodsCsv"][goods_id].weight | |
| 679 | + count = count - 1 | |
| 680 | + end | |
| 681 | + end | |
| 682 | + | |
| 683 | + end | |
| 684 | + | |
| 685 | + self:setProperty("recordByRole", recordByRole) | |
| 686 | + self:setProperty("record", record) | |
| 687 | + self:setProperty("goods", goods) | |
| 688 | + local incentiveReward, tmpNotify = self:checkIncentive(roleId) | |
| 689 | + for k, v in pairs(incentiveReward or {}) do | |
| 690 | + reward[k] = (reward[k] or 0) + v | |
| 691 | + end | |
| 692 | + if tmpNotify then table.insert(notify, tmpNotify) end | |
| 693 | + | |
| 694 | + local speciNotify = self:checkSpecialReward(roleId) | |
| 695 | + if speciNotify and next(speciNotify) then table.insert(notify, speciNotify) end | |
| 696 | + | |
| 697 | + return reward, notify | |
| 698 | +end | |
| 699 | + | |
| 700 | +function Capsule:drawAll(roleId) | |
| 701 | + local goods = self:getProperty("goods") or {} | |
| 702 | + local record = self:getProperty("record") or {} | |
| 703 | + local recordByRole = self:getProperty("recordByRole") or {} | |
| 704 | + | |
| 705 | + local reward, notify = {}, {} | |
| 706 | + for good_id, good in pairs(goods) do | |
| 707 | + | |
| 708 | + if good.amount > 0 then | |
| 709 | + notify = {role_id = roleId, good_id = good_id, typ = RewardTYpe.GOODS, award = good.award, amount = good.amount, quality = good.quality, create_time = skynet.timex()} | |
| 710 | + table.insert(record, notify) | |
| 711 | + | |
| 712 | + --记录角色的抽奖记录 | |
| 713 | + local tmp = recordByRole[roleId] | |
| 714 | + if not tmp then | |
| 715 | + recordByRole[roleId] = {good_id=notify} | |
| 716 | + else | |
| 717 | + if not tmp[good_id] then | |
| 718 | + tmp[good_id] = notify | |
| 719 | + else | |
| 720 | + tmp[good_id].amount = tmp[good_id].amount + good.amount | |
| 721 | + end | |
| 722 | + end | |
| 723 | + end | |
| 724 | + | |
| 725 | + while(good.amount > 0) do | |
| 726 | + for k, v in pairs(good.award:toNumMap()) do | |
| 727 | + reward[k] = (reward[k] or 0) + v | |
| 728 | + end | |
| 729 | + good.amount = good.amount - 1 | |
| 730 | + end | |
| 731 | + | |
| 732 | + end | |
| 733 | + | |
| 734 | + local incentiveReward, tmpNotify = self:checkIncentive(roleId) | |
| 735 | + for k, v in pairs(incentiveReward or {}) do | |
| 736 | + reward[k] = (reward[k] or 0) + v | |
| 737 | + end | |
| 738 | + if tmpNotify then table.insert(notify, tmpNotify) end | |
| 739 | + | |
| 740 | + local speciNotify = self:checkSpecialReward(roleId) | |
| 741 | + if speciNotify and next(speciNotify) then table.insert(notify, speciNotify) end | |
| 742 | + | |
| 743 | + self:setProperty("recordByRole", recordByRole) | |
| 744 | + self:setProperty("record", record) | |
| 745 | + self:setProperty("goods", goods) | |
| 746 | + return reward, notify | |
| 747 | +end | |
| 748 | + | |
| 749 | +--@param | |
| 750 | +--[[ | |
| 751 | +@roleId | |
| 752 | +@typ 1=全收 0=单次 | |
| 753 | +@cares 关注{k=v} | |
| 754 | +]]-- | |
| 755 | + | |
| 756 | +function Capsule:draw(roleId, full, cares) | |
| 757 | + if self:getGoodsAmount() == 0 then return 2 end | |
| 758 | + if self:getProperty("typ") == 1 then | |
| 759 | + --是否报名 | |
| 760 | + if self:isRegister(roleId) == false then return 3 end | |
| 761 | + | |
| 762 | + --关注的奖品的数量发生了变化 | |
| 763 | + if cares then | |
| 764 | + local change = self:confirmed(cares) | |
| 765 | + if next(change) then return 4, change end | |
| 766 | + end | |
| 767 | + end | |
| 768 | + | |
| 769 | + if full == 0 then | |
| 770 | + return 5, self:drawByCount(roleId, 1) | |
| 771 | + elseif full == 1 then | |
| 772 | + return 5, self:drawByCount(roleId, 10) | |
| 773 | + elseif full == 2 then | |
| 774 | + return 5, self:drawAll(roleId) | |
| 775 | + end | |
| 776 | +end | |
| 777 | + | |
| 778 | + | |
| 779 | +function Capsule:data() | |
| 780 | + return { | |
| 781 | + id = self:getProperty("id"), | |
| 782 | + room = self:getProperty("room"), | |
| 783 | + typ = self:getProperty("typ"), | |
| 784 | + name = self:getProperty("name"), | |
| 785 | + coin = self:getProperty("coin"), | |
| 786 | + onlineCount = self:getOnlineCount(), | |
| 787 | + record = self:getProperty("record"), | |
| 788 | + --recordByRole = self:getProperty("recordByRole"), | |
| 789 | + rank = self:getProperty("rank"), | |
| 790 | + goods = self:getProperty("goods"), | |
| 791 | + specials = self:getProperty("specials"), | |
| 792 | + incentive = self:getProperty("incentive"), | |
| 793 | + specialsFlag= self:getProperty("specialsFlag"), | |
| 794 | + } | |
| 795 | +end | |
| 796 | + | |
| 797 | +return Capsule | |
| 0 | 798 | \ No newline at end of file | ... | ... |
src/models/Role.lua
src/models/RoleCross.lua
| ... | ... | @@ -210,6 +210,12 @@ RoleCross.bind = function (Role) |
| 210 | 210 | return "成功" |
| 211 | 211 | end |
| 212 | 212 | |
| 213 | + function Role:paySpecialReward(typ, reward) | |
| 214 | + local tmpReward, _= self:award(reward, {log = {desc = "specialsReward", int1=self:getKey(), int2 = typ}}) | |
| 215 | + SendPacket(actionCodes.Capsule_payReward, MsgPack.pack({reward=tmpReward})) | |
| 216 | + return "reward" | |
| 217 | + end | |
| 218 | + | |
| 213 | 219 | end |
| 214 | 220 | |
| 215 | 221 | |
| ... | ... | @@ -370,6 +376,11 @@ function CMD.redPTag(roleId, tag, pms) |
| 370 | 376 | end |
| 371 | 377 | end |
| 372 | 378 | |
| 379 | +function CMD.paySpecialReward(roleId, typ, reward) | |
| 380 | + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId}) | |
| 381 | + role:award(reward, {log = {desc = "specialsReward", int1=self:getKey(), int2 = typ}}) | |
| 382 | +end | |
| 383 | + | |
| 373 | 384 | RoleCross.handle = function(cmd, roleId, ...) |
| 374 | 385 | SRole = SRole or require("models.Role") |
| 375 | 386 | if CMD[cmd] then | ... | ... |
src/models/RoleLog.lua
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,36 @@ 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:refreshing(now) then | |
| 833 | + capsule:init() | |
| 834 | + capsule:create() | |
| 835 | + end | |
| 836 | + self.capsules[key] = capsule | |
| 837 | + end | |
| 838 | + | |
| 839 | + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do | |
| 840 | + for _, val in pairs(data) do | |
| 841 | + if val.typ == 0 then | |
| 842 | + local key = val.id..val.room | |
| 843 | + if not self.capsules[key] then | |
| 844 | + local capsule = require("models.Capsule").new({ key = CAPSULE_ROLE:format(roleId, tonumber(key)), id= val.id, room = val.room, typ = 0, name=val.name}) | |
| 845 | + capsule:init() | |
| 846 | + capsule:create() | |
| 847 | + self.capsules[key] = capsule | |
| 848 | + redisproxy.sadd(CAPSULE_ID_ROLE:format(roleId), key) | |
| 849 | + end | |
| 850 | + end | |
| 851 | + end | |
| 852 | + end | |
| 853 | + end | |
| 854 | + | |
| 824 | 855 | -- 0 为操作成功 |
| 825 | 856 | function Role:addRune(params) |
| 826 | 857 | if params.type and params.id then |
| ... | ... | @@ -1995,6 +2026,7 @@ function RolePlugin.bind(Role) |
| 1995 | 2026 | function Role:onRecoverTimer(now) |
| 1996 | 2027 | self:updateTimeReset(now, true) |
| 1997 | 2028 | self:checkNewEvent(now) |
| 2029 | + self:checkCapsule(now) | |
| 1998 | 2030 | self:saveRoleData(now) |
| 1999 | 2031 | end |
| 2000 | 2032 | |
| ... | ... | @@ -3116,7 +3148,38 @@ function RolePlugin.bind(Role) |
| 3116 | 3148 | return itemRandomOccupy |
| 3117 | 3149 | end |
| 3118 | 3150 | |
| 3151 | + function Role:getCapsuleList(coin) | |
| 3152 | + local capsules = {} | |
| 3153 | + for k, v in pairs(self.capsules) do | |
| 3154 | + if v:getProperty("coin") == coin then | |
| 3155 | + local onlineCount= v:getOnlineCount() | |
| 3156 | + capsules[k] = {id=v:getProperty("id"), room=v:getProperty("room"), typ=v:getProperty("typ"), people=onlineCount[2], coin= v:getProperty("coin")} | |
| 3157 | + end | |
| 3158 | + end | |
| 3159 | + return capsules | |
| 3160 | + end | |
| 3119 | 3161 | |
| 3162 | + function Role:drawCapsule(capsuleId, full, cares) | |
| 3163 | + local capsule = self.capsules[capsuleId] or {} | |
| 3164 | + if next(capsule) then | |
| 3165 | + local roleId = self:getProperty("id") | |
| 3166 | + return capsule:draw(roleId, full, cares) | |
| 3167 | + end | |
| 3168 | + end | |
| 3169 | + | |
| 3170 | + function Role:joinCapsule(capsuleId) | |
| 3171 | + local capsule = self.capsules[capsuleId] or {} | |
| 3172 | + return capsule:data() | |
| 3173 | + end | |
| 3174 | + | |
| 3175 | + function Role:checkCapsule(now) | |
| 3176 | + for _, v in pairs(self.capsules) do | |
| 3177 | + if v:refreshing(now) then | |
| 3178 | + v:init() | |
| 3179 | + v:create() | |
| 3180 | + end | |
| 3181 | + end | |
| 3182 | + end | |
| 3120 | 3183 | end |
| 3121 | 3184 | |
| 3122 | 3185 | return RolePlugin |
| 3123 | 3186 | \ 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"}) | ... | ... |
| ... | ... | @@ -0,0 +1,167 @@ |
| 1 | +require "ProtocolCode" | |
| 2 | +require "shared.init" | |
| 3 | +require "GlobalVar" | |
| 4 | +require "RedisKeys" | |
| 5 | +require "skynet.manager" | |
| 6 | +local 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 | + INCENTIVE = 5, | |
| 20 | +} | |
| 21 | + | |
| 22 | +function rpcRole(roleId, funcName, ...) | |
| 23 | + local fields = ... | |
| 24 | + local agent = datacenter.get("agent", roleId) | |
| 25 | + if agent and agent.serv then | |
| 26 | + if funcName == "getProperties" then | |
| 27 | + return true, skynet.call(agent.serv, "role", funcName, fields) | |
| 28 | + else | |
| 29 | + return true, skynet.call(agent.serv, "role", funcName, ...) | |
| 30 | + end | |
| 31 | + else | |
| 32 | + local roleCross = require("models.RoleCross") | |
| 33 | + if funcName == "getProperties" then | |
| 34 | + return false, roleCross.handle(funcName, roleId, fields) | |
| 35 | + else | |
| 36 | + return false, roleCross.handle(funcName, roleId, ...) | |
| 37 | + end | |
| 38 | + end | |
| 39 | +end | |
| 40 | + | |
| 41 | +function broadCastCapsule(roleId, capsuleId, broadInfo) | |
| 42 | + local capsule = capsules[capsuleId] or {} | |
| 43 | + local register = capsule:getProperty("register") or {} | |
| 44 | + if next(capsule) then | |
| 45 | + for id, _ in pairs(register) do | |
| 46 | + if id ~= roleId then | |
| 47 | + rpcRole(id, "SendPacket", actionCodes.Capsule_notifyChange, MsgPack.pack(broadInfo)) -- 通知对方 | |
| 48 | + end | |
| 49 | + end | |
| 50 | + end | |
| 51 | +end | |
| 52 | + | |
| 53 | +local function getCapsuleId(id, room) | |
| 54 | + return string.format("%d%d", id, room) | |
| 55 | +end | |
| 56 | + | |
| 57 | + | |
| 58 | +local function add(roleId, capsuleId) | |
| 59 | + print(type(capsuleId)) | |
| 60 | + local capsule = capsules[capsuleId] or {} | |
| 61 | + if next(capsule) then | |
| 62 | + capsule:join(roleId) | |
| 63 | + broadCastCapsule(roleId, capsuleId, {changeType = NotifyChangeType.JOIN, roleId = roleId}) | |
| 64 | + return capsule:data() | |
| 65 | + end | |
| 66 | + print("id 不存在: ".. capsuleId) | |
| 67 | + return nil | |
| 68 | +end | |
| 69 | + | |
| 70 | +local function capsuleRefreshing() | |
| 71 | + for _, v in pairs(capsules) do | |
| 72 | + if v:refreshing() then | |
| 73 | + v:init() | |
| 74 | + v:create() | |
| 75 | + end | |
| 76 | + end | |
| 77 | +end | |
| 78 | + | |
| 79 | +--扭蛋机刷新 | |
| 80 | +local function check_capsules() | |
| 81 | + pcall(capsuleRefreshing) | |
| 82 | + skynet.timeout(60, check_capsules) | |
| 83 | +end | |
| 84 | + | |
| 85 | +function CMD.start() | |
| 86 | + local now = skynet.timex() | |
| 87 | + local res = redisproxy:smembers(CAPSULE_INFO) or {} | |
| 88 | + for _, key in pairs(res) do | |
| 89 | + local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(tonumber(key))}) | |
| 90 | + capsule:load() | |
| 91 | + if capsule:isShow() then | |
| 92 | + if capsule:refreshing(now) then | |
| 93 | + capsule:init() | |
| 94 | + capsule:create() | |
| 95 | + end | |
| 96 | + capsules[key] = capsule | |
| 97 | + else | |
| 98 | + redisproxy.del(CAPSULE_PUBLIC:format(tonumber(key))) | |
| 99 | + redisproxy.srem(CAPSULE_INFO, key) | |
| 100 | + end | |
| 101 | + end | |
| 102 | + | |
| 103 | + for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do | |
| 104 | + for _, val in ipairs(data) do | |
| 105 | + if val.type == 1 then | |
| 106 | + local key = string.format("%d%d", val.id, val.room) | |
| 107 | + if not capsules[key] then | |
| 108 | + local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(tonumber(key)), id= val.id, room = val.room, typ = 1, name=val.name}) | |
| 109 | + capsule:init() | |
| 110 | + capsule:create() | |
| 111 | + capsules[key] = capsule | |
| 112 | + redisproxy.sadd(CAPSULE_INFO, key) | |
| 113 | + end | |
| 114 | + end | |
| 115 | + end | |
| 116 | + end | |
| 117 | + | |
| 118 | + check_capsules() | |
| 119 | +end | |
| 120 | + | |
| 121 | +function CMD.list(coin) | |
| 122 | + local tmpCapsules = {} | |
| 123 | + for k, v in pairs(capsules) do | |
| 124 | + if v:getProperty("coin") == coin then | |
| 125 | + local onlineCount= v:getOnlineCount() | |
| 126 | + tmpCapsules[k] = {id=v:getProperty("id"), room=v:getProperty("room"), typ=v:getProperty("typ"), people=onlineCount[2], coin= v:getProperty("coin")} | |
| 127 | + end | |
| 128 | + end | |
| 129 | + return tmpCapsules | |
| 130 | +end | |
| 131 | + | |
| 132 | +function CMD.join(roleId, capsuleId) | |
| 133 | + if capsuleId then | |
| 134 | + return add(roleId, capsuleId) | |
| 135 | + end | |
| 136 | + return nil | |
| 137 | +end | |
| 138 | + | |
| 139 | + | |
| 140 | +function CMD.exit(roleId, capsuleId) | |
| 141 | + local capsule = capsules[capsuleId] or {} | |
| 142 | + if next(capsule) then | |
| 143 | + capsule:exit(roleId) | |
| 144 | + broadCastCapsule(roleId, capsuleId, {changeType = NotifyChangeType.EXIT, roleId = roleId}) | |
| 145 | + end | |
| 146 | +end | |
| 147 | + | |
| 148 | +function CMD.draw_capsule(roleId, capsuleId, typ, cares) | |
| 149 | + local capsule = capsules[capsuleId] or {} | |
| 150 | + if next(capsule) then | |
| 151 | + local ret, reward, notify = capsule:draw(roleId, typ, cares) | |
| 152 | + --if ret > 4 then | |
| 153 | + -- broadCastCapsule(roleId, capsuleId, {changeType = NotifyChangeType.DRAW, roleId = roleId, notify = notify}) | |
| 154 | + --end | |
| 155 | + return ret, reward | |
| 156 | + end | |
| 157 | + return nil | |
| 158 | +end | |
| 159 | + | |
| 160 | +skynet.start(function() | |
| 161 | + skynet.dispatch("lua", function(session, address, cmd, ...) | |
| 162 | + local f = CMD[string.lower(cmd)] | |
| 163 | + skynet.ret(skynet.pack(f(...))) | |
| 164 | + end) | |
| 165 | + | |
| 166 | + skynet.register("capsuled") | |
| 167 | +end) | |
| 0 | 168 | \ 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) | ... | ... |