Activity.lua 5.28 KB
local Activity = class("Activity", require("shared.ModelBase"))
local string_format = string.format

Activity.ActivityType = {
	Sign = 1,  -- 签到
}


local function checkActivityType(activityType)
	if type(activityType) == "string" then
		activityType = Activity.ActivityType[activityType]
	end
	return activityType or 0
end


function Activity:ctor(properties)
	Activity.super.ctor(self, properties)

	self._isOpen = {}
end


Activity.schema = {
	actime 		= {"table", {}},  -- 最近检查某项活动的开始时间  {id = time}
	act1		= {"table", {}},  -- {0 = day, 1= -1, 2 = -1} == 签到活动
}

function Activity:data()
	return {
		actime = self:getProperty("actime"),
		act1 = self:getProperty("act1"),
	}
end


function Activity:updateProperty(params)
	local type, default = table.unpack(self.schema[params.field])

	if params.delta then
		self:incrProperty(params.field, params.delta)
		if not params.notNotify then
			self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field))
		end
		return true
	end
	if params.value then
		self:setProperty(params.field, params.value)
		if not params.notNotify then
			self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field))
		end
		return true
	end
	return false
end


function Activity:isOpenRaw(activityType, now)
	activityType = checkActivityType(activityType)
	local actData = csvdb["activity_ctrlCsv"][activityType]
	if not actData then return end

	if actData.time == "" then -- 关闭
		return false
	end

	local st = 0
	local et = 0
	local now = skynet.timex()

	if actData.ttype == 0 then -- 时间开放
		local openTimes = actData.time:toArray(false, "=")
		if openTimes[1] ~= "0" then
			st = toUnixtime(openTimes[1]..string_format("%02x", RESET_TIME))
		end
		if openTimes[2] ~= "0" then
			et = toUnixtime(openTimes[2]..string_format("%02x", RESET_TIME))
		end
 	elseif actData.ttype == 1 then -- 周期开放
 		local openTimes = actData.time:toArray(true, "=")
 		local resetTime = toUnixtime(tostring(openTimes[1]) .. string_format("%02x", RESET_TIME))
 		local r = math.floor((now - resetTime) / (openTimes[3] * 86400))
 		st = resetTime + r * (openTimes[3] * 86400)
 		et = st + openTimes[2] * 86400
	else
		return
	end

	if now >= st and (et == 0 or now < et) then
		return true, st
	end
	return false
end

-- 缓存开放
function Activity:isOpen(activityType)
	activityType = checkActivityType(activityType)
	return self._isOpen[activityType]
end

function Activity:getActData(actType)
	actType = checkActivityType(actType)
	return self:getProperty("act" .. actType)
end

function Activity:updateActData(actType, data, notNotify)
	actType = checkActivityType(actType)
	self:updateProperty({field = "act" .. actType,  value = data, notNotify = notNotify})
end


-- 跨天刷新 --登录刷新
function Activity:checkActivityStatus(now, isCrossDay, notify)
	self._isOpen = {}
	local actime = self:getProperty("actime")
	local change = false
	for actType, actData in pairs(csvdb["activity_ctrlCsv"]) do
		local isOpen, startTime = self:isOpenRaw(actType, now)
		self._isOpen[actType] = isOpen

		if isOpen then
			if actime[actType] and actime[actType] == startTime then -- 还是之前的状态 开放中
			else  -- 重置
				actime[actType] = startTime
				self:closeActivity(actType, notify, true)
				self:initActivity(actType, isCrossDay, notify)
				change = true
			end
		else
			if actime[actType] then
				self:closeActivity(actType, notify)
				actime[actType] = nil
				change = true
			end
		end
	end
	if change then
		self:updateProperty({field = "actime", value = actime, notNotify = not notify})
	end
end

local activityFunc = {}

activityFunc[Activity.ActivityType.Sign] = {
	-- ["check"] = function(self, actType, notify) -- 检查
	-- end,
	["init"] = function(self, actType, isCrossDay, notify)
		if not isCrossDay then
			activityFunc[Activity.ActivityType.Sign]["crossDay"](self, actType, notify)
		end
	end,
	-- ["close"] = function(self, actType, notify)
	-- end,
	["crossDay"] = function(self, actType, notify)
		local curData = self:getActData(actType)
		curData[0] = (curData[0] or 0) + 1
		local actData = csvdb["new_signInCsv"]
		if curData[0] > #actData then return end -- 满了就忽略了

		-- 没满更新一下
		self:updateActData(actType, curData, not notify)
	end,
}

function Activity:initActivity(actType, isCrossDay, notify)
	if activityFunc[actType] and activityFunc[actType]['close'] then
		activityFunc[actType]["init"](self, actType, isCrossDay, notify)
	end
end

function Activity:closeActivity(actType, notify, notUpdateAct)
	if activityFunc[actType] and activityFunc[actType]['close'] then
		activityFunc[actType]["close"](self, actType, notify)
	end
	self:updateActData(actType, Activity.schema["act" .. actType][2], not notify or notUpdateAct)
end

function Activity:refreshDailyData(notify)
	for actType, status in pairs(self._isOpen) do
		if status then
			if activityFunc[actType] and activityFunc[actType]['crossDay'] then
				activityFunc[actType]["crossDay"](self, actType, notify)
			end
		end
	end
end

function Activity:checkActivity(notNotify, activityType, ...)
	if not activityType then return end
	if not self:isOpen(activityType) then return end
	if activityFunc[activityType] and activityFunc[activityType]['check'] then
		activityFunc[activityType]["check"](self, activityType, not notNotify, ...)
	end
end


return Activity