HomeServer/Server/AllServer/GameServer/Subscribe.lua
2024-11-20 15:41:37 +08:00

659 lines
22 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local skynet = require "skynet"
local oo = require "Class"
local log = require "Log"
local pb = require "pb"
local dataType = require "DataType"
local errorInfo = require "ErrorInfo"
local activity = require "Activity"
local json =require "json"
local redisKeyUrl = require "RedisKeyUrl"
local Subscribe = oo.class()
--初始时间戳
local initTime = 0
--构造函数
function Subscribe:Init()
end
-- 每次登录需要进行修改的数据
function Subscribe:LoginInitData(player)
--初始化内存
if player.gameData.subscribe == nil then
player.gameData.subscribe={ isDrawRewardAll = false , isDrawRewardAllTime = os.time()}
end
--处理重置时间
if not skynet.server.common:IsSameDay(os.time(),player.gameData.subscribe.isDrawRewardAllTime) then
--修改奖励为已发送
player.gameData.subscribe.isDrawRewardAll = false
player.gameData.subscribe.isDrawRewardAllTime = os.time()
end
--取消订阅推送
self:UpdateOnlineTime( player , 1)
end
--获取订阅消息信息
function Subscribe:GetSubscribeInfo(player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SSubscribeGetSubscribeInfo", c2sData.data ))
s2cData.cmd = pb.enum("MsgType","CMD_S2C_SubscribeGetSubscribeInfo")
--参数
local subscribeType = c2sData.data.subscribeType
--返回信息
local data =self:GetPlayerSubscribeInfo(player,subscribeType)
s2cData.data = assert(pb.encode("S2CSubscribeGetSubscribeInfo", data))
end
--获取玩家订阅数据,subscribeType 类型1 微信,。。。
function Subscribe:GetPlayerSubscribeInfo(player,subscribeType)
local data = {}
data.subscribeInfo={}
--获取已订阅的数据,这里直接取redis里面的数据订阅信息只存redis
local redisKey = string.format(redisKeyUrl.ThirdSubscribe, player.account)
--获取订阅信息
local subscribeDataStr = skynet.server.redis:hget(redisKey,subscribeType)
--存在订阅信息
if subscribeDataStr ~= nil then
--反序列化
local subscribeData = json:decode(subscribeDataStr)
if subscribeData == nil or next(subscribeData) == nil then
log.debug(string.format("微信订阅序列号错误,redisKey:%s,subscribeType:%s,subscribeData:%s",redisKey,tostring(subscribeType),subscribeDataStr))
return data
end
for key, value in pairs(subscribeData) do
--是否未过期
if value.expireTime > os.time() or value.expireTime == 0 then
local subscribe = {}
subscribe.subscribeId = value.subscribeId
if value.subscribeStatus == 2 then--已推送,这里显示成已订阅
subscribe.subscribeStatus = 1
else
subscribe.subscribeStatus = value.subscribeStatus
end
table.insert(data.subscribeInfo, subscribe)
end
end
else
log.debug(string.format("微信订阅不存在任何订阅信息,redisKey:%s,subscribeType:%s",redisKey,tostring(subscribeType)))
end
--是否领取所有订阅奖励
data.isDrawRewardAll=(player.gameData.subscribe ~= nil and player.gameData.subscribe.isDrawRewardAll ~= nil and player.gameData.subscribe.isDrawRewardAll) and true or false
return data
end
--table去重
function RemoveRepeat(t)
local unique={}
for _, value in ipairs(t) do
unique[value] = true
end
local newt={}
for index,_ in pairs(unique) do
table.insert(newt,index)
end
return newt
end
--订阅消息
function Subscribe:SubscribeMsg(player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SSubscribeSubscribeMsg", c2sData.data ))
s2cData.cmd = pb.enum("MsgType","CMD_S2C_SubscribeSubscribeMsg")
--参数
local subscribeType = c2sData.data.subscribeType
local subscribeIdList = c2sData.data.subscribeIdList
local uniqueId = c2sData.data.uniqueId
local isAllSubscribe = c2sData.data.isAllSubscribe
--subscribeIdList去重复
subscribeIdList = RemoveRepeat(subscribeIdList)
--返回信息
local data = {}
--订阅状态 1 订阅成功2 订阅失败
data.subscribeStatus = 2
data.subscribeIdList = subscribeIdList
--判断参数
if subscribeType == nil or subscribeIdList == nil or next(subscribeIdList) ==nil or uniqueId == nil then
log.debug("参数错误")
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
return
end
--订阅类型配置
local cfgSubscriptions = skynet.server.gameConfig:GetAllCfg("Subscription")
if not cfgSubscriptions then
log.debug("cfgSubscriptions is nil")
return
end
--获取已订阅的数据,这里直接取redis里面的数据订阅信息只存redis
local redisKey = string.format(redisKeyUrl.ThirdSubscribe, player.account)
--获取订阅信息
local subscribeDataStr = skynet.server.redis:hget(redisKey,subscribeType)
--反序列化对象
local subscribeData = {}
--存在数据
if subscribeDataStr then
--反序列化
subscribeData = json:decode(subscribeDataStr)
end
for _, subscribeId in ipairs(subscribeIdList) do
local cfgSubscription = {}
for _,value in pairs(cfgSubscriptions) do
if value.id == subscribeId then
cfgSubscription = value
end
end
if not next(cfgSubscription) then
log.error("cfgSubscription is nil")
s2cData.code = errorInfo.ErrorCode.NoExistCfg
return
end
--是否开放订阅
if cfgSubscription.subscribeLvl > player.gameData.level then
log.error("cfgSubscription.subscribeLvl > player.gameData.level")
-- s2cData.code = errorInfo.ErrorCode.LevelLimit
-- return
goto coroutine
end
--判断是否已订阅,已订阅先删除
for index, value in ipairs(subscribeData) do
if value.subscribeId == subscribeId then
log.debug(string.format("该玩家 %d 已经订阅该类型 %d,订阅id %d",player.userId,subscribeType,value.subscribeId))
-- s2cData.code = errorInfo.ErrorCode.ActivityClosed
-- return
goto coroutine
elseif value.subscribeId == subscribeId then
table.remove(subscribeData,index)
break
end
end
--获取结束时间 0永久订阅
local expireTime = 0
if cfgSubscription.subscribeTriggerTime > 0 then
expireTime=skynet.server.common:GetAfterSomeHour(cfgSubscription.subscribeTriggerTime)
end
--添加新的订阅信息
table.insert(subscribeData,{ subscribeId = subscribeId,--任务id
subscribeStatus = 1,--1已订阅2已推送,3 取消订阅
triggerTimestamp = initTime,--触发时间戳
expireTime = expireTime,
uniqueId = uniqueId}) --订阅有效期0永久订阅
::coroutine::
end
--保存数据到redis
if next(subscribeData) then
--保存rendis
skynet.server.redis:hset(redisKey,subscribeType,json:encode(subscribeData))
--保存到全部订阅数据
skynet.server.redis:sadd(redisKeyUrl.ThirdSubscribeSetKeys,player.account)
--订阅状态 1 订阅成功2 订阅失败
data.subscribeStatus = 1
end
--是否首次全部订阅
if player.gameData.subscribe==nil then
player.gameData.subscribe={ isDrawRewardAll = false , isDrawRewardAllTime = os.time()}
end
--没有领取奖励
if not player.gameData.subscribe.isDrawRewardAll and isAllSubscribe then
--local isConAllSubscribe = true
-- --计算已经订阅数量
-- for _, value in ipairs(cfgSubscriptions) do
-- if value.subscribeTriggerTime <=0 then
-- for _, value2 in ipairs(subscribeData) do
-- if value.id ~= value2.subscribeId then
-- isConAllSubscribe = false
-- break
-- end
-- end
-- end
-- if not isConAllSubscribe then
-- break
-- end
-- end
-- --发奖奖励
-- if isConAllSubscribe then
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
--发放奖励
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_120")
player:GiveReward(cfgSValue.miniProgramAllSubReward ,eventId,1)
--修改奖励为已发送
player.gameData.subscribe.isDrawRewardAll = true
player.gameData.subscribe.isDrawRewardAllTime = os.time()
--返回值
data.rewardId = cfgSValue.miniProgramAllSubReward
--end
end
s2cData.data = assert(pb.encode("S2CSubscribeSubscribeMsg", data))
end
--取消订阅
function Subscribe:UnSubscribe(player, c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SSubscribeUnSubscribe", c2sData.data ))
s2cData.cmd = pb.enum("MsgType","CMD_S2C_SubscribeUnSubscribe")
--参数
local subscribeType = c2sData.data.subscribeType
local subscribeId = c2sData.data.subscribeId
--返回信息
local data = {}
data.subscribeId = subscribeId
--判断参数
if subscribeType == nil or subscribeId == nil then
log.debug("参数错误")
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
return
end
--订阅类型配置
local cfgSubscriptions = skynet.server.gameConfig:GetAllCfg("Subscription")
if not cfgSubscriptions then
log.error("cfgSubscriptions is nil")
s2cData.code = errorInfo.ErrorCode.NoExistCfg
return
end
local cfgSubscription = {}
for _,value in pairs(cfgSubscriptions) do
if value.id == subscribeId then
cfgSubscription = value
end
end
if not next(cfgSubscription) then
log.error("cfgSubscription is nil")
s2cData.code = errorInfo.ErrorCode.NoExistCfg
return
end
--是否开放订阅
if cfgSubscription.subscribeLvl > player.gameData.level then
log.error("cfgSubscription.subscribeLvl > player.gameData.level")
s2cData.code = errorInfo.ErrorCode.LevelLimit
return
end
--获取已订阅的数据,这里直接取redis里面的数据订阅信息只存redis
local redisKey = string.format(redisKeyUrl.ThirdSubscribe, player.account)
--获取订阅信息
local subscribeDataStr = skynet.server.redis:hget(redisKey,subscribeType)
--反序列化对象
local subscribeData = {}
--存在数据
if subscribeDataStr then
--反序列化
subscribeData = json:decode(subscribeDataStr)
end
--是否存在
local exist =false
--判断是否已订阅
for index, value in ipairs(subscribeData) do
--是否有延时过期
if value.subscribeId == subscribeId and cfgSubscription.subscribeTriggerTime > 0 then
value.subscribeStatus = 3 --1 已订阅2 未订阅3 取消订阅
exist = true
break
elseif value.subscribeId == subscribeId then
table.remove(subscribeData,index)
exist = true
break
end
end
--获取结束时间 0永久订阅
local expireTime = 0
if cfgSubscription.subscribeTriggerTime > 0 then
expireTime=skynet.server.common:GetAfterSomeHour(cfgSubscription.subscribeTriggerTime)
end
--如果不存在数据则添加
if #subscribeData == 0 or (exist == false and cfgSubscription.subscribeTriggerTime > 0) then
--添加新的订阅信息
table.insert(subscribeData,{ subscribeId = subscribeId,--任务id
subscribeStatus = 3,--1 已订阅2 已推送3 取消订阅
triggerTimestamp = initTime,--触发时间戳
expireTime = expireTime,--订阅有效期0永久订阅
uniqueId = "uniqueId"}) --唯一id这里随便填写不会推送
end
--保存rendis
skynet.server.redis:hset(redisKey,subscribeType,json:encode(subscribeData))
--订阅状态 1 订阅成功2 订阅失败
data.subscribeStatus = 3
s2cData.data = assert(pb.encode("S2CSubscribeUnSubscribe", data))
end
--更新离线时间 类型目前只有微信1
function Subscribe:UpdateOfflineTime(player,subscribeType)
function Do()
log.debug("触发离线订阅 时间计算accid:",player.account)
local cfgLevel = skynet.server.gameConfig:GetPlayerCurCfg( player , "Level" , player.gameData.level )
if not cfgLevel then
log.debug("cfgLevel is nil")
return true
end
--获取已订阅的数据,这里直接取redis里面的数据订阅信息只存redis
local redisKey = string.format(redisKeyUrl.ThirdSubscribe, player.account)
--获取订阅信息
local subscribeDataStr = skynet.server.redis:hget(redisKey,subscribeType)
--反序列化对象
local subscribeData = {}
--不存在存在数据
if not subscribeDataStr or subscribeDataStr == "" then
log.debug("微信订阅 subscribeDataStr is nil")
return true
end
--反序列化
subscribeData = json:decode(subscribeDataStr)
--未订阅
if not subscribeData or next(subscribeData) == nil then
log.debug("微信订阅 subscribeData is nil")
return true
end
local isUpdate =false
--判断是否已订阅
for _, value in ipairs(subscribeData) do
--游戏更新不走离线逻辑
if value.subscribeId == 8 then
goto continue
end
--未过期,未推送
if (value.expireTime > os.time() or value.expireTime == 0) and value.subscribeStatus == 1 then
--默认0
local triggerTimestamp = initTime
--更新推送时间
if value.subscribeId == 1 then
triggerTimestamp = os.time()+cfgLevel.offlineUpperTime
elseif value.subscribeId == 2 then--花盆植物全部成熟
if player.gameData.flowerpot ~= nil and next( player.gameData.flowerpot) ~=nil then
for k1, v1 in pairs( player.gameData.flowerpot ) do
if (triggerTimestamp ==0 or triggerTimestamp > v1.flowerpotInfo.totalTime) and v1.flowerpotInfo.totalTime > os.time() then
triggerTimestamp = v1.flowerpotInfo.totalTime
end
end
end
elseif value.subscribeId == 3 then--好味食堂进货完成
if player.gameData.shop[skynet.server.cuisineShop.ShopType] ~= nil
and player.gameData.shop[skynet.server.cuisineShop.ShopType].restockInfos~=nil
and player.gameData.shop[skynet.server.cuisineShop.ShopType].restockInfos.finishTime > os.time() then
triggerTimestamp = player.gameData.shop[skynet.server.cuisineShop.ShopType].restockInfos.finishTime
end
elseif value.subscribeId == 4 then--萌宠乐园出游完成
if player.gameData.shop[skynet.server.petShop.shopType] ~= nil
and player.gameData.shop[skynet.server.petShop.shopType].petTravel ~=nil
and next(player.gameData.shop[skynet.server.petShop.shopType].petTravel) ~= nil
and player.gameData.shop[skynet.server.petShop.shopType].petTravel[1].finishTime >os.time() then
triggerTimestamp = player.gameData.shop[skynet.server.petShop.shopType].petTravel[1].finishTime
end
elseif value.subscribeId == 5 then--朝夕渔店鱼饵补充
local nowtamp = os.time()
local now = os.date("*t", nowtamp)
--12点提醒一次
if now.hour < 12 then
triggerTimestamp = os.time({ year = now.year, month = now.month, day=now.day, hour=12, min=0, sec=0 })
else
triggerTimestamp = os.time({ year = now.year, month = now.month, day=now.day, hour=12, min=0, sec=0 })+ 24 * 60 * 60
end
elseif value.subscribeId == 6 then--恋家置业租房完成
--长租
if player.gameData.houseRent.longLeaseInfo ~= nil and next(player.gameData.houseRent.longLeaseInfo) ~=nil then
for _, house in ipairs(player.gameData.houseRent.longLeaseInfo) do
if house.remainRentTime > triggerTimestamp and house.leaseStatus == 2 then
triggerTimestamp = house.remainRentTime
end
end
end
--短租
if player.gameData.houseRent.shortLeaseInfo ~= nil and next(player.gameData.houseRent.shortLeaseInfo) ~=nil then
for _, house in ipairs(player.gameData.houseRent.shortLeaseInfo) do
if house.remainRentTime > triggerTimestamp and house.leaseStatus == 2 then
triggerTimestamp = house.remainRentTime
end
end
end
elseif value.subscribeId == 7 then--艺间造型剪刀补充
local curShop = player.gameData.shop[ skynet.server.styleShop.shopType ]
triggerTimestamp = (19 - curShop.energy.energy) * 120 + curShop.energy.nextRefillTime
--如果已经满了,就不通知了
if triggerTimestamp < os.time() then
triggerTimestamp=0
end
elseif value.subscribeId == 8 then--游戏更新
--游戏更新时间,这里暂时写死
triggerTimestamp=self:GameUpdateTime()
end
--已经满足条件
if triggerTimestamp<0 then
triggerTimestamp=os.time()
end
--更新缓存
value.triggerTimestamp=triggerTimestamp
log.debug(string.format("微信订阅 更新触发时间 subscribeId:%d,triggerTimestamp:%d",value.subscribeId ,value.triggerTimestamp))
--已推送修改成未推送
if value.subscribeStatus == 2 then
value.subscribeStatus = 1
end
isUpdate =true
end
::continue::
end
--暂无更新
if not isUpdate then
log.debug("微信订阅 没有更新")
return true
end
--获取订阅信息
skynet.server.redis:hset(redisKey,subscribeType,json:encode(subscribeData))
log.debug("微信订阅离线处理完成!")
return true
end
local ret,err = pcall(Do)
if not ret or not err then
local account = player.basicInfo.accountName
local userId = player.userId
log.debug("内部错误信息 Subscribe:UpdateOfflineTime ", account , userId ,ret ,err)
return false
end
return true
end
--更新在线,在线不推送任何订阅 类型目前只有微信1
function Subscribe:UpdateOnlineTime(player,subscribeType)
local cfgLevel = skynet.server.gameConfig:GetPlayerCurCfg( player , "Level" , player.gameData.level )
if not cfgLevel then
return
end
--获取已订阅的数据,这里直接取redis里面的数据订阅信息只存redis
local redisKey = string.format(redisKeyUrl.ThirdSubscribe, player.account)
--获取订阅信息
local subscribeDataStr = skynet.server.redis:hget(redisKey,subscribeType)
--反序列化对象
local subscribeData = {}
--不存在存在数据
if not subscribeDataStr or subscribeDataStr == "" then
return
end
--反序列化
local subscribeInfoList = json:decode(subscribeDataStr)
--未订阅
if not subscribeInfoList or next(subscribeInfoList) == nil then
return
end
local isUpdate =false
--倒序遍历删除不影响table后续索引
for i = #subscribeInfoList, 1, -1 do
local subscribeInfo = subscribeInfoList[i]
--不存在存在数据
if subscribeInfo == nil or next(subscribeInfo) == nil then
goto coroutine
end
--判断是否过期
if subscribeInfo.expireTime < os.time() and subscribeInfo.expireTime ~= 0 then
--删除订阅信息
table.remove(subscribeInfoList,i)
else --未过期,在线 暂时取消推送
--更新缓存
subscribeInfo.triggerTimestamp = 0 --当前在线,没有推送时间
end
-- 跳出当前循环
::coroutine::
end
--更新redis
if next(subscribeInfoList) ~= nil then
--更新订阅信息
skynet.server.redis:hset(redisKey,subscribeType,json:encode(subscribeInfoList))
else
--删除
skynet.server.redis:hdel(redisKey,subscribeType)
--删除索引
skynet.server.redis:srem(redisKeyUrl.ThirdSubscribeSetKeys,player.account)
end
log.debug("在线订阅处理完成")
end
--游戏更新时间
function Subscribe:GameUpdateTime()
--手动设置时间
local uptime={
year = 2054,month = 07,day = 20,
hour = 12,min = 12,sec = 12,
}
return os.time(uptime)
end
skynet.server.subscribe = Subscribe
return Subscribe