HomeServer/Server/AllServer/GameServer/Subscribe.lua

659 lines
22 KiB
Lua
Raw Permalink Normal View History

2024-11-20 15:41:09 +08:00
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