capsuled.lua 8.19 KB
require "ProtocolCode"
require "shared.init"
require "GlobalVar"
require "RedisKeys"
require "skynet.manager"
skynet = require "skynet"
csvdb = require "shared.csvdata"
redisproxy = require "shared.redisproxy"
datacenter = require "skynet.datacenter"

local capsules = {}
local CMD = {}

NotifyChangeType = {
    JOIN = 1,
    EXIT = 2,
    DRAW = 3,
    SPECIAL = 4,
}

skynet.register_protocol {
    name = "role",
    id = 101,
    pack = skynet.pack,
    unpack = skynet.unpack,
}

local function rpcRole(roleId, funcName, ...)
    local fields = ...
    local agent = datacenter.get("agent", roleId)
    if agent and agent.serv then
        if funcName == "getProperties" then
            return true, skynet.call(agent.serv, "role", funcName, fields)
        else
            return true, skynet.call(agent.serv, "role", funcName, ...)
        end
    else
        local roleCross = require("models.RoleCross")
        if funcName == "getProperties" then
            return false, roleCross.handle(funcName, roleId, fields)
        else
            return false, roleCross.handle(funcName, roleId, ...)
        end
    end
end

function getNameByRoleId(roleId)
    local status, name = rpcRole(roleId, "getProperty", "name")
    return name

end

function broadCastCapsule(roleId, capsuleId, broadInfo)
    local capsule = capsules[capsuleId]
    if not capsule then print("not capsule :" .. capsuleId) return end

    local register = capsule:getProperty("register") or {}
    if next(capsule) then
        for id, _ in pairs(register) do
            if id ~= roleId then
                rpcRole(id, "SendPacket", actionCodes.Capsule_notifyChange, MsgPack.pack(broadInfo)) 	-- 通知对方
            end
        end
    end
end

function broadCastSpecial(roleId, capsuleId, broadInfo)
    if not broadInfo or not next(broadInfo) then return end
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return end

    local register = capsule:getProperty("register") or {}
    for id, _ in pairs(register) do
        if id ~= roleId then
            if broadInfo[id] then
               rpcRole(id, "paySpecialReward", id, broadInfo[id])
            end
        end
    end
end

local function add(roleId, capsuleId)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("add not capsule: " .. capsuleId) return end
    if next(capsule) then
        capsule:join(roleId)
        broadCastCapsule(roleId, capsuleId, {notifyType= NotifyChangeType.JOIN, roleId = roleId})
        return capsule:data(roleId)
    end
    print("id 不存在: ".. capsuleId)
    return nil
end

local function capsuleRefreshing(now)
    for _, v in pairs(capsules) do
        if v:refreshing(now) then
            print("刷新机器looooook....")
            print(v:getProperty("id"))
            print(v:getProperty("room"))
            v:init()
            v:create()
        end
    end
end

--扭蛋机刷新
local function check_capsules()
    local now = skynet.timex()
    pcall(capsuleRefreshing, now)
    skynet.timeout(100, check_capsules)
end

function CMD.reset()
    local now = skynet.timex()
    local res = redisproxy:smembers(CAPSULE_INFO) or {}
    for _, key in pairs(res) do
        redisproxy:del(CAPSULE_PUBLIC:format(key))
        redisproxy:srem(CAPSULE_INFO, key)
    end

    for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
        for _, val in ipairs(data) do
            if val.type == 1 then
                local key = val.id..val.room
                local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key), id= val.id, room = val.room, typ = 1, name=val.name})
                capsule:init()
                capsule:create()
                capsules[key] = capsule
                redisproxy:sadd(CAPSULE_INFO, key)
            end
        end
    end
end

function CMD.start()
    local now = skynet.timex()
    local res = redisproxy:smembers(CAPSULE_INFO) or {}
    for _, key in pairs(res) do
        local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key)})
        capsule:load()
        if capsule:isShow() then
            if capsule:refreshing(now) then
                capsule:init()
                capsule:create()
            end
            capsules[key] = capsule
        else
            redisproxy:del(CAPSULE_PUBLIC:format(key))
            redisproxy:srem(CAPSULE_INFO, key)
        end
    end

    for _, data in pairs(csvdb["ichibankuji_mainCsv"]) do
        for _, val in ipairs(data) do
            if val.type == 1 then
                local key = val.id..val.room
                if not capsules[key] then
                    if now < val.hide_time then
                        local capsule = require("models.Capsule").new({ key = CAPSULE_PUBLIC:format(key), id= val.id, room = val.room, typ = 1, name=val.name})
                        capsule:init()
                        capsule:create()

                        capsules[key] = capsule
                        redisproxy:sadd(CAPSULE_INFO, key)
                    end
                end
            end
        end
    end

    check_capsules()
end

function CMD.list(id)
    local tmpCapsules = {}
    for k, v in pairs(capsules) do
        if v:getProperty("id") == id then
            local onlineCount= v:getOnlineCount()
            tmpCapsules[k] = {id=v:getProperty("id"), room=v:getProperty("room"), typ=v:getProperty("typ"), people=onlineCount[2], coin= v:getProperty("coin")}
        end
    end
    return tmpCapsules
end

function CMD.join(roleId, capsuleId)
    if capsuleId then
        return add(roleId, capsuleId)
    end
    return nil
end


function CMD.exit(roleId, capsuleId)
    if capsuleId then
        local capsule = capsules[capsuleId]
        if not capsule then skynet.error("not capsule: " .. capsuleId) return end

        capsule:exit(roleId)
        broadCastCapsule(roleId, capsuleId, {notifyType = NotifyChangeType.EXIT, roleId = roleId})
    else
        for id, capsule in pairs(capsules) do
            if next(capsule) then
                capsule:exit(roleId)
                broadCastCapsule(roleId, id, {notifyType = NotifyChangeType.EXIT, roleId = roleId})
            end
        end
    end
end

function CMD.draw_capsule(roleId, capsuleId, full, drawsNum, cares)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return 2 end

    local ret, drawReward = capsule:draw(roleId, full, drawsNum, cares)
    if ret > 5 then
        --broadCastCapsule(roleId, capsuleId, {notifyType = NotifyChangeType.DRAW, notify = notify})
        broadCastSpecial(roleId, capsuleId, drawReward["specials"])
    end
    drawReward["specials"] = nil
    return ret, drawReward, capsule:data(roleId)
end

function CMD.register(roleId, capsuleId)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return nil end

    return capsule:register(roleId)
end

function CMD.goods_stock(capsuleId)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return 0 end

    return capsule:getGoodsAmount(), capsule:getProperty("token")
end

function CMD.capsule_data(roleId, capsuleId)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return nil end

    return capsule:data(roleId)
end

function CMD.page_record(capsuleId, up, idx)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return nil end

    return capsule:pageRecord(up, idx)
end

function CMD.get_special_nty(roleId, capsuleId)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return nil end

    return capsule:getSpecialNotify(roleId)
end

function CMD.clear_special_nty(roleId, capsuleId, good_ids)
    local capsule = capsules[capsuleId]
    if not capsule then skynet.error("not capsule: " .. capsuleId) return nil end

    return capsule:clearSpecialNty(roleId, good_ids)
end

skynet.start(function()
    skynet.dispatch("lua", function(session, address, cmd, ...)
        local f = CMD[string.lower(cmd)]
        skynet.ret(skynet.pack(f(...)))
    end)

    skynet.register("capsuled")
    globalCsv = csvdb["GlobalDefineCsv"]
end)