1226 lines
No EOL
41 KiB
Lua
1226 lines
No EOL
41 KiB
Lua
local tableInsert = table.insert
|
||
|
||
XNoticeManagerCreator = function()
|
||
local Json = require("XCommon/Json")
|
||
local pcall = pcall
|
||
local XNoticeManager = {}
|
||
|
||
local NoticePicList = {}
|
||
|
||
local NowTextNotice = nil
|
||
local NowPicNotice = nil
|
||
|
||
local InGameNoticeReadList = {}
|
||
local InGameNoticeMap = {}
|
||
local InGameNoticeReadKey = "_InGameNoticeReadKey"
|
||
|
||
local SubMenuNoticeReadList = {}
|
||
local SubMenuNoticeMap = {}
|
||
local SubMenuNoticeReadKey = "_SubMenuNoticeReadKey"
|
||
|
||
local ScrollCountList = {}
|
||
local ScrollCountSaveKey = "_NoticeScrollCountList"
|
||
|
||
local LoginNotice = nil
|
||
local LoginNoticeTimeInfo = {}
|
||
local LoginNoticeCacheKey = "LoginNotice"
|
||
|
||
local TextNoticeHideCache = {}
|
||
local TextNoticeHideCacheKey = "_TextNotice"
|
||
------------------------------------------------------
|
||
local NoticeRequestTimer = nil
|
||
-- 向服务端请求数据的最小间隔周期(秒)
|
||
local NoticeRequestTimerInterval = 10
|
||
local NoticeRequestTimeOut = 30
|
||
local DefaultTextScrollInterval = 10
|
||
|
||
local ScreenShotFlag = false
|
||
local DisableFunction = false --功能屏蔽标记(调试模式时使用)
|
||
|
||
local XNoticeType = {
|
||
-- 顶部文字滚动公告
|
||
ScrollText = 0,
|
||
-- 主界面广告图
|
||
ScrollPic = 1,
|
||
-- 游戏内公告
|
||
InGame = 2,
|
||
-- 登陆公告
|
||
Login = 3,
|
||
-- 主界面二级菜单
|
||
SubMenu = 4,
|
||
}
|
||
|
||
-- 自动向服务端请求数据的间隔周期(秒)
|
||
local RequestInterval = {
|
||
[XNoticeType.ScrollText] = 30,
|
||
[XNoticeType.ScrollPic] = 60,
|
||
[XNoticeType.InGame] = 120,
|
||
[XNoticeType.Login] = 0,
|
||
[XNoticeType.SubMenu] = 120,
|
||
}
|
||
|
||
local LastRequestTime = {
|
||
[XNoticeType.ScrollText] = 0,
|
||
[XNoticeType.ScrollPic] = 0,
|
||
[XNoticeType.InGame] = 0,
|
||
[XNoticeType.SubMenu] = 0,
|
||
}
|
||
|
||
local NoticeRequestHandler = {
|
||
[XNoticeType.ScrollText] = function(notice) XNoticeManager.HandleRequestScrollTextNotice(notice) end,
|
||
[XNoticeType.ScrollPic] = function(notice) XNoticeManager.HandleRequestScrollPicNotice(notice) end,
|
||
[XNoticeType.InGame] = function(notice) XNoticeManager.HandleRequestInGameNotice(notice) end,
|
||
[XNoticeType.SubMenu] = function(notice) XNoticeManager.HandleRequestSubMenuNotice(notice) end,
|
||
}
|
||
|
||
local NoticeRequestFailHandler = {
|
||
[XNoticeType.ScrollText] = function() XNoticeManager.HandleRequestScrollTextNotice() end,
|
||
[XNoticeType.ScrollPic] = function() XNoticeManager.HandleRequestScrollPicNoticeFail() end,
|
||
[XNoticeType.InGame] = function() XNoticeManager.HandleRequestInGameNotice() end,
|
||
[XNoticeType.SubMenu] = function() XNoticeManager.HandleRequestSubMenuNotice() end,
|
||
}
|
||
|
||
----------------------------------初始化公告cdn路径 beg----------------------------------
|
||
local NoticeCdnUrl = {}
|
||
local NoticeFileName = {
|
||
[XNoticeType.ScrollText] = "ScrollTextNotice.json",
|
||
[XNoticeType.ScrollPic] = "ScrollPicNotice.json",
|
||
[XNoticeType.InGame] = "GameNotice.json",
|
||
[XNoticeType.Login] = "LoginNotice.json",
|
||
[XNoticeType.SubMenu] = "SecondMenuNotice.json",
|
||
}
|
||
|
||
function XNoticeManager.GetNoticeUrl(noticeType)
|
||
return NoticeCdnUrl[noticeType]
|
||
end
|
||
|
||
function XNoticeManager.InitNoticeCdnUrl()
|
||
local noticePathPrefix = CS.XGame.ClientConfig:GetString("NoticePathPrefix")
|
||
for k, v in pairs(NoticeFileName) do
|
||
NoticeCdnUrl[k] = noticePathPrefix .. CS.XInfo.Identifier .. "/" .. CS.XRemoteConfig.ApplicationVersion .. "/" .. v
|
||
end
|
||
end
|
||
----------------------------------初始化公告cdn路径 end----------------------------------
|
||
----------------------------------获取公网ip地址 beg----------------------------------
|
||
local Ip = ""
|
||
local IpUrlIndex = 0
|
||
local IpUrls = {
|
||
"https://ipv4.icanhazip.com/",
|
||
"https://api.ipify.org/"
|
||
}
|
||
|
||
function XNoticeManager.RequestIp()
|
||
IpUrlIndex = IpUrlIndex + 1
|
||
if IpUrlIndex > #IpUrls then
|
||
return
|
||
end
|
||
|
||
local request = CS.UnityEngine.Networking.UnityWebRequest.Get(IpUrls[IpUrlIndex])
|
||
local requestEnd = function()
|
||
if request.isNetworkError or request.isHttpError then
|
||
XNoticeManager.RequestIp()
|
||
end
|
||
|
||
Ip = request.downloadHandler.text
|
||
|
||
request:Dispose()
|
||
end
|
||
|
||
CS.XTool.WaitNativeCoroutine(request:SendWebRequest(), requestEnd)
|
||
end
|
||
|
||
function XNoticeManager.GetIp()
|
||
return Ip
|
||
end
|
||
----------------------------------获取公网ip地址 end----------------------------------
|
||
--------------------------cache beg--------------------------
|
||
function XNoticeManager.ReadTextNoticeHideCache()
|
||
local cache = CS.UnityEngine.PlayerPrefs.GetString(tostring(XPlayer.Id) .. TextNoticeHideCacheKey)
|
||
if string.IsNilOrEmpty(cache) then
|
||
return
|
||
end
|
||
|
||
TextNoticeHideCache = Json.decode(cache)
|
||
|
||
for k, v in pairs(TextNoticeHideCache) do
|
||
if XTime.GetServerNowTimestamp() > v.EndTime then
|
||
TextNoticeHideCache[k] = nil
|
||
end
|
||
end
|
||
|
||
end
|
||
|
||
function XNoticeManager.SaveTextNoticeHideCache()
|
||
if not TextNoticeHideCache then
|
||
return
|
||
end
|
||
|
||
CS.UnityEngine.PlayerPrefs.SetString(tostring(XPlayer.Id) .. TextNoticeHideCacheKey, Json.encode(TextNoticeHideCache))
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
end
|
||
|
||
function XNoticeManager.GetInGameNoticeReadKey()
|
||
return tostring(XPlayer.Id) .. InGameNoticeReadKey
|
||
end
|
||
|
||
function XNoticeManager.SaveInGameNoticeReadList()
|
||
if not InGameNoticeReadList then return end
|
||
|
||
local saveContent = ""
|
||
local splitMark = "\n"
|
||
for _, v in pairs(InGameNoticeReadList) do
|
||
local list = {}
|
||
tableInsert(list, v.Id)
|
||
tableInsert(list, v.Index)
|
||
tableInsert(list, (v.IsRead and 1 or 0))
|
||
tableInsert(list, v.EndTime)
|
||
tableInsert(list, v.ModifyTime)
|
||
|
||
local tempStr = table.concat(list, "\t")
|
||
saveContent = string.format("%s%s%s", tempStr, splitMark, saveContent)
|
||
end
|
||
|
||
CS.UnityEngine.PlayerPrefs.SetString(XNoticeManager.GetInGameNoticeReadKey(), saveContent)
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
|
||
XEventManager.DispatchEvent(XEventId.EVENT_ACTIVITY_NOTICE_READ_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.ReadInGameNoticeReadList()
|
||
InGameNoticeReadList = {}
|
||
if not CS.UnityEngine.PlayerPrefs.HasKey(XNoticeManager.GetInGameNoticeReadKey()) then
|
||
return
|
||
end
|
||
|
||
local dataStr = CS.UnityEngine.PlayerPrefs.GetString(XNoticeManager.GetInGameNoticeReadKey())
|
||
|
||
local msgTab = string.Split(dataStr, '\n')
|
||
if not msgTab or #msgTab <= 0 then
|
||
return
|
||
end
|
||
|
||
for _, content in ipairs(msgTab) do
|
||
if (not string.IsNilOrEmpty(content)) then
|
||
local tab = string.Split(content, '\t')
|
||
if tab then
|
||
local readInfo = {
|
||
Id = tostring(tab[1]),
|
||
Index = tonumber(tab[2]),
|
||
IsRead = tonumber(tab[3]) > 0,
|
||
EndTime = tonumber(tab[4]),
|
||
ModifyTime = tonumber(tab[5]),
|
||
}
|
||
if readInfo.ModifyTime and readInfo.EndTime and readInfo.EndTime > XTime.GetServerNowTimestamp() then
|
||
local dataKey = XNoticeManager.GetGameNoticeReadDataKey(readInfo, readInfo.Index)
|
||
InGameNoticeReadList[dataKey] = readInfo
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function XNoticeManager.GetSubMenuNoticeReadKey()
|
||
return tostring(XPlayer.Id) .. SubMenuNoticeReadKey
|
||
end
|
||
|
||
function XNoticeManager.SaveSubMenuNoticeReadList()
|
||
if not SubMenuNoticeReadList then return end
|
||
|
||
local saveContent = ""
|
||
local splitMark = "\n"
|
||
for _, v in pairs(SubMenuNoticeReadList) do
|
||
local list = {}
|
||
tableInsert(list, v.Id)
|
||
tableInsert(list, v.EndTime)
|
||
tableInsert(list, v.TipResetTime)
|
||
tableInsert(list, v.LastReadTime)
|
||
|
||
local tempStr = table.concat(list, "\t")
|
||
saveContent = string.format("%s%s%s", tempStr, splitMark, saveContent)
|
||
end
|
||
-- XLog.Warning("save",saveContent)
|
||
CS.UnityEngine.PlayerPrefs.SetString(XNoticeManager.GetSubMenuNoticeReadKey(), saveContent)
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
|
||
XEventManager.DispatchEvent(XEventId.EVENT_ACTIVITY_SUBMENU_READ_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.ReadSubMenuNoticeReadList()
|
||
SubMenuNoticeReadList = {}
|
||
if not CS.UnityEngine.PlayerPrefs.HasKey(XNoticeManager.GetSubMenuNoticeReadKey()) then
|
||
return
|
||
end
|
||
|
||
local dataStr = CS.UnityEngine.PlayerPrefs.GetString(XNoticeManager.GetSubMenuNoticeReadKey())
|
||
|
||
local msgTab = string.Split(dataStr, '\n')
|
||
if not msgTab or #msgTab <= 0 then
|
||
return
|
||
end
|
||
|
||
for _, content in ipairs(msgTab) do
|
||
if (not string.IsNilOrEmpty(content)) then
|
||
local tab = string.Split(content, '\t')
|
||
if tab then
|
||
local readInfo = {
|
||
Id = tostring(tab[1]),
|
||
EndTime = tonumber(tab[2]),
|
||
TipResetTime = tonumber(tab[3]),
|
||
LastReadTime = tonumber(tab[4]),
|
||
}
|
||
if readInfo.EndTime and readInfo.EndTime > XTime.GetServerNowTimestamp() then
|
||
SubMenuNoticeReadList[readInfo.Id] = readInfo
|
||
end
|
||
end
|
||
end
|
||
end
|
||
--XLog.Warning("ReadSubMenuNoticeReadList",SubMenuNoticeReadList)
|
||
end
|
||
|
||
function XNoticeManager.GetScrollCountSaveKey()
|
||
return tostring(XPlayer.Id) .. ScrollCountSaveKey
|
||
end
|
||
|
||
function XNoticeManager.SaveScrollCountList()
|
||
if not ScrollCountList then
|
||
return
|
||
end
|
||
local saveContent = ''
|
||
for _, v in pairs(ScrollCountList) do
|
||
saveContent = saveContent .. v.id .. '\t'
|
||
saveContent = saveContent .. v.maxCount .. '\t'
|
||
saveContent = saveContent .. v.nowCount .. '\t'
|
||
saveContent = saveContent .. v.overTime .. '\n'
|
||
end
|
||
|
||
CS.UnityEngine.PlayerPrefs.SetString(XNoticeManager.GetScrollCountSaveKey(), saveContent)
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
end
|
||
|
||
function XNoticeManager.ReadScrollCountList()
|
||
ScrollCountList = {}
|
||
if not CS.UnityEngine.PlayerPrefs.HasKey(XNoticeManager.GetScrollCountSaveKey()) then
|
||
return
|
||
end
|
||
local dataStr = CS.UnityEngine.PlayerPrefs.GetString(XNoticeManager.GetScrollCountSaveKey())
|
||
local msgTab = string.Split(dataStr, '\n')
|
||
if not msgTab or #msgTab <= 0 then
|
||
return
|
||
end
|
||
|
||
for _, content in ipairs(msgTab) do
|
||
if (not string.IsNilOrEmpty(content)) then
|
||
local tab = string.Split(content, '\t')
|
||
if tab then
|
||
local countInfo = {
|
||
id = tostring(tab[1]),
|
||
maxCount = tonumber(tab[2]),
|
||
nowCount = tonumber(tab[3]),
|
||
overTime = tonumber(tab[4]),
|
||
}
|
||
if countInfo.overTime and countInfo.overTime > XTime.GetServerNowTimestamp() then
|
||
ScrollCountList[countInfo.id] = countInfo
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
--------------------------cache end--------------------------
|
||
--------------------------text beg--------------------------
|
||
function XNoticeManager.HandleRequestScrollTextNotice(notice)
|
||
-- XLog.Warning("new text notice",notice)
|
||
NowTextNotice = notice
|
||
|
||
if not XNoticeManager.CheckTextNoticeValid(notice) then
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_NOTICE_CLOSE_TEXT_NOTICE)
|
||
else
|
||
XLuaUiManager.Open("UiNoticeTips")
|
||
end
|
||
|
||
if NowTextNotice then
|
||
local key = XNoticeManager.GetTextNoticeKey(NowTextNotice)
|
||
if not ScrollCountList or not ScrollCountList[key] then
|
||
XNoticeManager.CreateDefaultScrollCountData(NowTextNotice)
|
||
end
|
||
end
|
||
end
|
||
|
||
function XNoticeManager.GetTextNoticeKey(notice)
|
||
return notice.Id .. "_" .. notice.ModifyTime
|
||
end
|
||
|
||
function XNoticeManager.CreateDefaultScrollCountData(notice)
|
||
local key = XNoticeManager.GetTextNoticeKey(notice)
|
||
local countInfo = {
|
||
id = key,
|
||
maxCount = notice.ScrollTimes,
|
||
nowCount = 0,
|
||
overTime = notice.EndTime,
|
||
}
|
||
ScrollCountList[key] = countInfo
|
||
end
|
||
|
||
function XNoticeManager.CheckTextNoticeValid(notice)
|
||
notice = notice or NowTextNotice
|
||
|
||
if not XNoticeManager.CheckNoticeValid(notice) then
|
||
return false
|
||
end
|
||
|
||
if not XNoticeManager.CheckTextNoticeHideCache(notice) then
|
||
return false
|
||
end
|
||
|
||
if notice.ShowInFight < 1 and not CS.XFight.IsOutFight then
|
||
return false
|
||
end
|
||
|
||
if notice.ShowInPhotograph < 1 and ScreenShotFlag then
|
||
return false
|
||
end
|
||
|
||
local key = XNoticeManager.GetTextNoticeKey(notice)
|
||
if ScrollCountList[key]
|
||
and ScrollCountList[key].nowCount > ScrollCountList[key].maxCount then
|
||
|
||
return false
|
||
end
|
||
|
||
return true
|
||
end
|
||
|
||
function XNoticeManager.GetTextNoticeContent()
|
||
if not NowTextNotice then
|
||
return
|
||
end
|
||
return NowTextNotice.Content
|
||
end
|
||
|
||
function XNoticeManager.AddTextNoticeCount()
|
||
if not NowTextNotice then
|
||
return
|
||
end
|
||
|
||
local key = XNoticeManager.GetTextNoticeKey(NowTextNotice)
|
||
|
||
if not ScrollCountList[key] then
|
||
XNoticeManager.CreateDefaultScrollCountData(NowTextNotice)
|
||
end
|
||
|
||
ScrollCountList[key].nowCount = ScrollCountList[key].nowCount + 1
|
||
|
||
XNoticeManager.SaveScrollCountList()
|
||
end
|
||
|
||
function XNoticeManager.GetTextNoticeScrollInterval()
|
||
if not NowTextNotice then
|
||
return DefaultTextScrollInterval
|
||
end
|
||
return tonumber(NowTextNotice.ScrollInterval) or DefaultTextScrollInterval
|
||
end
|
||
|
||
|
||
function XNoticeManager.ChangeTextNoticeHideCache(notice)
|
||
notice = notice or NowTextNotice
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
local key = XNoticeManager.GetTextNoticeKey(notice)
|
||
if not TextNoticeHideCache[key] then
|
||
TextNoticeHideCache[key] = {
|
||
Id = key,
|
||
IsHide = 1,
|
||
EndTime = notice.EndTime
|
||
}
|
||
else
|
||
TextNoticeHideCache[key].IsHide = not TextNoticeHideCache[key].IsHide
|
||
end
|
||
|
||
XNoticeManager.SaveTextNoticeHideCache()
|
||
end
|
||
|
||
|
||
function XNoticeManager.CheckTextNoticeHideCache(notice)
|
||
notice = notice or NowTextNotice
|
||
if not notice then
|
||
return false
|
||
end
|
||
|
||
local key = XNoticeManager.GetTextNoticeKey(notice)
|
||
if not TextNoticeHideCache[key] then
|
||
return true
|
||
end
|
||
|
||
return TextNoticeHideCache[key].IsHide < 0
|
||
end
|
||
--------------------------text end--------------------------
|
||
----------------------Scroll Pic beg----------------------
|
||
|
||
function XNoticeManager.HandleRequestScrollPicNoticeFail()
|
||
if not NowPicNotice then
|
||
return
|
||
end
|
||
|
||
NowPicNotice = nil
|
||
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_NOTICE_PIC_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.HandleRequestScrollPicNotice(notice)
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
if NowPicNotice and NowPicNotice.Id == notice.Id and NowPicNotice.ModifyTime == notice.ModifyTime then
|
||
return
|
||
end
|
||
|
||
NowPicNotice = notice
|
||
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_NOTICE_PIC_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.GetScrollPicList()
|
||
XNoticeManager.RequestNoticeByType(XNoticeType.ScrollPic, true)
|
||
if not NowPicNotice then
|
||
return
|
||
end
|
||
|
||
local scrollPicList = {}
|
||
for _, v in ipairs(NowPicNotice.Content) do
|
||
local isOpen = true
|
||
|
||
if not v.BeginTime or not v.EndTime or not v.AppearanceDay or not v.AppearanceTime
|
||
or not v.DisappearanceCondition or not v.AppearanceCondition then
|
||
isOpen = false
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if XTime.GetServerNowTimestamp() >= tonumber(v.BeginTime) and XTime.GetServerNowTimestamp() < tonumber(v.EndTime) then--是否在开放区间内(日期)
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if #v.AppearanceDay > 0 then
|
||
for _, day in ipairs(v.AppearanceDay) do
|
||
if day == XDataCenter.FubenDailyManager.GetNowDayOfWeekByRefreshTime() then--是否位于可以显示的周目
|
||
isOpen = true
|
||
end
|
||
end
|
||
else
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if #v.AppearanceTime > 0 then
|
||
for _, time in ipairs(v.AppearanceTime) do
|
||
if XTime.GetServerNowTimestamp() - XTime.GetTodayTime(0, 0, 0) >= time[1] and XTime.GetServerNowTimestamp() - XTime.GetTodayTime(0, 0, 0) < time[2] then--是否位于可以显示的时间段
|
||
isOpen = true
|
||
end
|
||
end
|
||
else
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if #v.DisappearanceCondition > 0 then
|
||
for _, condition in ipairs(v.DisappearanceCondition) do--是否符合不显示的条件
|
||
if XConditionManager.CheckCondition(condition) then
|
||
isOpen = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if #v.AppearanceCondition > 0 then
|
||
for _, condition in ipairs(v.AppearanceCondition) do
|
||
if not XConditionManager.CheckCondition(condition) then--是否不符合显示条件
|
||
isOpen = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if not XNoticeManager.IsWhiteIp(v.WhiteLists) then
|
||
isOpen = false
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
v.Interval = tonumber(v.Interval)
|
||
table.insert(scrollPicList, v)
|
||
end
|
||
end
|
||
|
||
return scrollPicList
|
||
end
|
||
----------------------Scroll Pic end----------------------
|
||
----------------------InGame Notice beg----------------------
|
||
function XNoticeManager.HandleRequestInGameNotice(notice)
|
||
InGameNoticeMap = {}
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
if type(notice) ~= "table" then
|
||
XLog.Error("InGame notice invalid format: " .. tostring(notice))
|
||
return
|
||
end
|
||
|
||
for _, v in ipairs(notice) do
|
||
if XNoticeManager.CheckNoticeValid(v) then
|
||
if not InGameNoticeMap[v.Type] then
|
||
InGameNoticeMap[v.Type] = {}
|
||
end
|
||
|
||
local content = {}
|
||
for _, item in ipairs(v.Content) do
|
||
if XNoticeManager.IsWhiteIp(item.WhiteLists) then
|
||
table.insert(content, item)
|
||
end
|
||
end
|
||
|
||
if #content > 0 then
|
||
v.Content = content
|
||
table.insert(InGameNoticeMap[v.Type], v)
|
||
end
|
||
end
|
||
end
|
||
|
||
for _, v in pairs(InGameNoticeMap) do
|
||
XNoticeManager.InitInGameReadList(v)
|
||
|
||
local sortFunc = function(l, r)
|
||
return l.Order > r.Order
|
||
end
|
||
table.sort(v, sortFunc)
|
||
end
|
||
end
|
||
|
||
function XNoticeManager.GetInGameNoticeMap(type)
|
||
return InGameNoticeMap[type]
|
||
end
|
||
|
||
function XNoticeManager.CheckHaveNotice(type)
|
||
XNoticeManager.RequestNoticeByType(XNoticeType.InGame, true)
|
||
if not InGameNoticeMap then
|
||
return false
|
||
end
|
||
|
||
if not InGameNoticeMap[type] or not next(InGameNoticeMap[type]) then
|
||
return false
|
||
end
|
||
|
||
return true
|
||
end
|
||
|
||
function XNoticeManager.CheckInGameNoticeRedPoint(type)
|
||
if not InGameNoticeMap or not InGameNoticeMap[type] then
|
||
return false
|
||
end
|
||
|
||
for _, notice in pairs(InGameNoticeMap[type]) do
|
||
for i, _ in ipairs(notice.Content) do
|
||
if XNoticeManager.CheckInGameNoticeRedPointIndividual(notice, i) then
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function XNoticeManager.InitInGameReadList(noticeList)
|
||
if not noticeList then
|
||
return
|
||
end
|
||
|
||
if not InGameNoticeReadList then
|
||
InGameNoticeReadList = {}
|
||
end
|
||
|
||
for _, noticeData in pairs(noticeList) do
|
||
for i, _ in pairs(noticeData.Content) do
|
||
local dataKey = XNoticeManager.GetGameNoticeReadDataKey(noticeData, i)
|
||
if not InGameNoticeReadList[dataKey] then
|
||
InGameNoticeReadList[dataKey] = {}
|
||
InGameNoticeReadList[dataKey].Id = noticeData.Id
|
||
InGameNoticeReadList[dataKey].EndTime = noticeData.EndTime
|
||
InGameNoticeReadList[dataKey].Index = i
|
||
InGameNoticeReadList[dataKey].IsRead = false
|
||
InGameNoticeReadList[dataKey].ModifyTime = noticeData.ModifyTime
|
||
end
|
||
end
|
||
end
|
||
|
||
XEventManager.DispatchEvent(XEventId.EVENT_ACTIVITY_NOTICE_READ_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.GetGameNoticeReadDataKey(noticeData, index)
|
||
return noticeData.Id .. "_" .. noticeData.ModifyTime .. "_" .. index
|
||
end
|
||
|
||
function XNoticeManager.CheckInGameNoticeRedPointIndividual(notice, index)
|
||
if not InGameNoticeReadList then
|
||
return false
|
||
end
|
||
|
||
local redPointKey = XNoticeManager.GetGameNoticeReadDataKey(notice, index)
|
||
if not InGameNoticeReadList[redPointKey] then
|
||
return false
|
||
end
|
||
|
||
return not InGameNoticeReadList[redPointKey].IsRead
|
||
end
|
||
|
||
function XNoticeManager.ChangeInGameNoticeReadStatus(dataKey, isRead)
|
||
if not InGameNoticeReadList then
|
||
return
|
||
end
|
||
|
||
InGameNoticeReadList[dataKey].IsRead = isRead
|
||
XNoticeManager.SaveInGameNoticeReadList()
|
||
end
|
||
----------------------InGame Notice end----------------------
|
||
-------------------------Sub Menu beg------------------------
|
||
--[[ 二级菜单配置 json数据格式
|
||
{"Id":每次生成配置时的唯一标识,
|
||
"ModifyTime":配置最后修改时间,
|
||
"Content":配置具体内容,可以包含多个按钮 [
|
||
"Id":唯一按钮Id,
|
||
"Title":按钮名称,
|
||
"SubTitle":按钮描述(显示在第二行),
|
||
"JumpType":1表示网址,2表示游戏内跳转,
|
||
"JumpAddr":跳转地址,
|
||
"BeginTime":开始显示时间,
|
||
"EndTime":结束显示时间,
|
||
"AppearanceDay":一周内出现的日子,不填则为全部出现,
|
||
"AppearanceTime":每天出现的时间段,不填则为全天出现,
|
||
"TipResetTime":红点重置时间,
|
||
"ModifyTime":最后修改时间 ] * N }
|
||
--]]
|
||
function XNoticeManager.HandleRequestSubMenuNotice(notice)
|
||
SubMenuNoticeMap = {}
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
if type(notice) ~= "table" then
|
||
XLog.Error("SubMenu notice invalid format: " .. tostring(notice))
|
||
return
|
||
end
|
||
|
||
for _, v in ipairs(notice.Content) do
|
||
if XNoticeManager.CheckNoticeValid(v) then
|
||
table.insert(SubMenuNoticeMap, v)
|
||
end
|
||
end
|
||
|
||
XNoticeManager.InitSubMenuReadList(notice)
|
||
end
|
||
|
||
function XNoticeManager.GetMainUiSubMenu()
|
||
XNoticeManager.RequestNoticeByType(XNoticeType.SubMenu, true)
|
||
if not SubMenuNoticeMap then
|
||
return
|
||
end
|
||
|
||
--XLog.Warning("start",SubMenuNoticeMap)
|
||
|
||
local subMenuList = {}
|
||
for _, v in ipairs(SubMenuNoticeMap) do
|
||
local isOpen = true
|
||
|
||
if not v.BeginTime or not v.EndTime or not v.AppearanceDay or not v.AppearanceTime then
|
||
isOpen = false
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if XTime.GetServerNowTimestamp() >= tonumber(v.BeginTime) and XTime.GetServerNowTimestamp() < tonumber(v.EndTime) then--是否在开放区间内(日期)
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if #v.AppearanceDay > 0 then
|
||
for _, day in ipairs(v.AppearanceDay) do
|
||
if day == XDataCenter.FubenDailyManager.GetNowDayOfWeekByRefreshTime() then--是否位于可以显示的周目
|
||
isOpen = true
|
||
end
|
||
end
|
||
else
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
isOpen = false
|
||
if #v.AppearanceTime > 0 then
|
||
for _, time in ipairs(v.AppearanceTime) do
|
||
if XTime.GetServerNowTimestamp() - XTime.GetTodayTime(0, 0, 0) >= time[1] and XTime.GetServerNowTimestamp() - XTime.GetTodayTime(0, 0, 0) < time[2] then--是否位于可以显示的时间段
|
||
isOpen = true
|
||
end
|
||
end
|
||
else
|
||
isOpen = true
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if v.DisappearanceCondition and #v.DisappearanceCondition > 0 then
|
||
for _, condition in ipairs(v.DisappearanceCondition) do--是否符合不显示的条件
|
||
if XConditionManager.CheckCondition(condition) then
|
||
isOpen = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if v.AppearanceCondition and #v.AppearanceCondition > 0 then
|
||
for _, condition in ipairs(v.AppearanceCondition) do
|
||
if not XConditionManager.CheckCondition(condition) then--是否不符合显示条件
|
||
isOpen = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
if not XNoticeManager.IsWhiteIp(v.WhiteLists) then
|
||
isOpen = false
|
||
end
|
||
end
|
||
|
||
if isOpen then
|
||
table.insert(subMenuList, v)
|
||
end
|
||
end
|
||
|
||
return subMenuList
|
||
end
|
||
|
||
function XNoticeManager.CheckSubMenuRedPoint()
|
||
if not SubMenuNoticeMap then return false end
|
||
|
||
for _, data in pairs(SubMenuNoticeMap) do
|
||
if XNoticeManager.CheckSubMenuRedPointIndividual(data.Id) then
|
||
return true
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function XNoticeManager.InitSubMenuReadList(notice)
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
if not SubMenuNoticeReadList then
|
||
SubMenuNoticeReadList = {}
|
||
end
|
||
|
||
for _, noticeData in pairs(notice.Content) do
|
||
local dataKey = noticeData.Id
|
||
if not SubMenuNoticeReadList[dataKey] then
|
||
SubMenuNoticeReadList[dataKey] = {}
|
||
SubMenuNoticeReadList[dataKey].Id = noticeData.Id
|
||
SubMenuNoticeReadList[dataKey].LastReadTime = 0
|
||
end
|
||
SubMenuNoticeReadList[dataKey].EndTime = noticeData.EndTime
|
||
SubMenuNoticeReadList[dataKey].TipResetTime = noticeData.TipResetTime or 0
|
||
end
|
||
|
||
XEventManager.DispatchEvent(XEventId.EVENT_ACTIVITY_SUBMENU_READ_CHANGE)
|
||
-- CsXGameEventManager.Instance:Notify(XEventId.EVENT_ACTIVITY_SUBMENU_READ_CHANGE)
|
||
end
|
||
|
||
function XNoticeManager.CheckSubMenuRedPointIndividual(id)
|
||
if not SubMenuNoticeReadList then
|
||
return false
|
||
end
|
||
|
||
local data = SubMenuNoticeReadList[id]
|
||
if not data then
|
||
return false
|
||
end
|
||
|
||
if data.TipResetTime > XTime.GetServerNowTimestamp() then return false end
|
||
return data.LastReadTime < data.TipResetTime
|
||
end
|
||
|
||
function XNoticeManager.ChangeSubMenuReadStatus(dataKey, time)
|
||
if not SubMenuNoticeReadList then
|
||
return
|
||
end
|
||
|
||
SubMenuNoticeReadList[dataKey].LastReadTime = time or XTime.GetServerNowTimestamp()
|
||
--XLog.Warning("ChangeSubMenuReadStatus",SubMenuNoticeReadList)
|
||
XNoticeManager.SaveSubMenuNoticeReadList()
|
||
end
|
||
-------------------------Sub Menu end------------------------
|
||
|
||
----------------------------------------login beg----------------------------------------
|
||
|
||
function XNoticeManager.RequestLoginNotice(cb)
|
||
local requestCb = function(notice)
|
||
local valid = XNoticeManager.CheckNoticeValid(notice, os.time())
|
||
if not valid then
|
||
if cb then
|
||
cb(valid)
|
||
end
|
||
|
||
local msgtab = {}
|
||
msgtab.error = valid
|
||
CS.XRecord.Record(msgtab, "24000", "RequestLoginNoticeError")
|
||
return
|
||
end
|
||
|
||
if LoginNotice and LoginNotice.Id == notice.Id and LoginNotice.ModifyTime == notice.ModifyTime then
|
||
if cb then
|
||
cb(valid)
|
||
end
|
||
|
||
local msgtab = {}
|
||
msgtab.error = valid
|
||
CS.XRecord.Record(msgtab, "24006", "RequestLoginNoticeError")
|
||
return
|
||
end
|
||
|
||
LoginNotice = notice
|
||
local openNotice = false
|
||
if XNoticeManager.CheckLoginNoticeDailyAutoShow(LoginNotice) then
|
||
openNotice = true
|
||
end
|
||
CS.XRecord.Record("24005", "RequestLoginNoticeEnd")
|
||
if cb then
|
||
cb(valid, openNotice)
|
||
end
|
||
end
|
||
CS.XRecord.Record("24004", "RequestLoginNoticeStart")
|
||
XNoticeManager.RequestNotice(XNoticeType.Login, requestCb, requestCb, RequestInterval[XNoticeType.Login])
|
||
end
|
||
|
||
function XNoticeManager.AutoOpenLoginNotice()
|
||
if XNoticeManager.CheckLoginNoticeDailyAutoShow(LoginNotice) then
|
||
if not XNoticeManager.CheckNoticeValid(LoginNotice, os.time()) then
|
||
return
|
||
end
|
||
|
||
XLuaUiManager.Open("UiLoginNotice", LoginNotice)
|
||
XNoticeManager.RefreshLoginNoticeTime()
|
||
end
|
||
end
|
||
|
||
function XNoticeManager.OpenLoginNotice()
|
||
if not LoginNotice then
|
||
XNoticeManager.RequestLoginNotice(function(isValid)
|
||
if isValid then
|
||
XLuaUiManager.Open("UiLoginNotice", LoginNotice)
|
||
XNoticeManager.RefreshLoginNoticeTime()
|
||
return true
|
||
end
|
||
end)
|
||
else
|
||
if not XNoticeManager.CheckNoticeValid(LoginNotice, os.time()) then
|
||
return false
|
||
end
|
||
|
||
XLuaUiManager.Open("UiLoginNotice", LoginNotice)
|
||
XNoticeManager.RefreshLoginNoticeTime()
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
|
||
function XNoticeManager.ReadLoginNoticeTime()
|
||
local cache = CS.UnityEngine.PlayerPrefs.GetString(LoginNoticeCacheKey)
|
||
if string.IsNilOrEmpty(cache) then
|
||
return
|
||
end
|
||
|
||
LoginNoticeTimeInfo = Json.decode(cache)
|
||
end
|
||
|
||
function XNoticeManager.CheckLoginNoticeDailyAutoShow(notice)
|
||
if not notice then
|
||
return
|
||
end
|
||
|
||
local id = notice.Id .. notice.ModifyTime
|
||
local resetTime = CS.XReset.GetNextDailyResetTime() - CS.XDateUtil.ONE_DAY_SECOND
|
||
if LoginNoticeTimeInfo[id] and LoginNoticeTimeInfo[id].Time > resetTime then
|
||
return false
|
||
end
|
||
|
||
return true
|
||
end
|
||
|
||
function XNoticeManager.RefreshLoginNoticeTime()
|
||
if not LoginNotice then
|
||
return
|
||
end
|
||
|
||
local id = LoginNotice.Id .. LoginNotice.ModifyTime
|
||
LoginNoticeTimeInfo[id] = {
|
||
Id = id,
|
||
-- 此处有可能无法获取到真实时间(尚未与服务端同步时间)
|
||
Time = XTime.GetServerNowTimestamp()
|
||
}
|
||
|
||
CS.UnityEngine.PlayerPrefs.SetString(LoginNoticeCacheKey, Json.encode(LoginNoticeTimeInfo))
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
end
|
||
|
||
----------------------------------------login end----------------------------------------
|
||
----------------------------image process beg----------------------------
|
||
function XNoticeManager.LoadPicFromLocal(url, successCb)
|
||
if NoticePicList and NoticePicList[url] then
|
||
if successCb then
|
||
successCb(NoticePicList[url])
|
||
end
|
||
return NoticePicList[url]
|
||
end
|
||
|
||
local fileName = XNoticeManager.GetImgNameByUrl(url)
|
||
CS.XTool.LoadLocalNoticeImg(fileName, function(texture)
|
||
if not texture then
|
||
XNoticeManager.LoadPic(url, successCb)
|
||
else
|
||
NoticePicList[url] = texture
|
||
if successCb then
|
||
successCb(texture)
|
||
end
|
||
end
|
||
end)
|
||
end
|
||
|
||
function XNoticeManager.LoadPic(url, successCb)
|
||
local request = CS.XUriPrefixRequest.Get(url, function()
|
||
return CS.UnityEngine.Networking.DownloadHandlerTexture(true)
|
||
end, NoticeRequestTimeOut, false)
|
||
|
||
CS.XTool.WaitCoroutine(request:SendWebRequest(), function()
|
||
if request.isNetworkError or request.isHttpError then
|
||
return
|
||
end
|
||
|
||
local texture = request.downloadHandler.texture;
|
||
if not texture then
|
||
return
|
||
end
|
||
|
||
local fileName = XNoticeManager.GetImgNameByUrl(url)
|
||
CS.XTool.SaveNoticeImg(fileName, texture)
|
||
|
||
NoticePicList[url] = texture
|
||
if successCb then
|
||
successCb(texture)
|
||
end
|
||
|
||
request:Dispose()
|
||
end)
|
||
end
|
||
|
||
function XNoticeManager.GetImgNameByUrl(url)
|
||
local _, _, _, fileName = url:find("(.+)/(.+)")
|
||
return fileName
|
||
end
|
||
----------------------------image process end----------------------------
|
||
|
||
--function XNoticeManager.UrlDecode(s)
|
||
-- s = string.gsub(s, '%%(%x%x)', function(h)
|
||
-- return string.char(tonumber(h, 16))
|
||
-- end)
|
||
-- return s
|
||
--end
|
||
|
||
function XNoticeManager.CheckNoticeValid(notice, nowTime)
|
||
if not notice then
|
||
return false
|
||
end
|
||
|
||
nowTime = nowTime or XTime.GetServerNowTimestamp()
|
||
if nowTime < notice.BeginTime then
|
||
return false
|
||
end
|
||
|
||
if nowTime > notice.EndTime then
|
||
return false
|
||
end
|
||
|
||
if not XNoticeManager.IsWhiteIp(notice.WhiteLists) then
|
||
return false
|
||
end
|
||
|
||
return true
|
||
end
|
||
|
||
function XNoticeManager.IsWhiteIp(whiteList)
|
||
if not whiteList then
|
||
return true
|
||
end
|
||
|
||
if string.IsNilOrEmpty(Ip) then
|
||
return false
|
||
end
|
||
|
||
for _, whiteIp in pairs(whiteList) do
|
||
if string.find(Ip, whiteIp) then
|
||
return true
|
||
end
|
||
end
|
||
|
||
return false
|
||
end
|
||
|
||
function XNoticeManager.RequestNoticeByType(noticeType, proactiveRequest)
|
||
local successCb = NoticeRequestHandler[noticeType]
|
||
local failCb = NoticeRequestFailHandler[noticeType]
|
||
local interval = proactiveRequest and NoticeRequestTimerInterval or RequestInterval[noticeType]
|
||
-- XLog.Warning("RequestNoticeByType", NoticeRequestTimerInterval, "type", RequestInterval[noticeType], "主动", proactiveRequest)
|
||
XNoticeManager.RequestNotice(noticeType, successCb, failCb, interval)
|
||
end
|
||
|
||
function XNoticeManager.RequestNotice(noticeType, successCb, failCb, interval)
|
||
if DisableFunction or not noticeType then
|
||
return
|
||
end
|
||
|
||
local nowTime = XTime.GetServerNowTimestamp()
|
||
--if ((not nowTime) or (not noticeType) or (not interval)) then
|
||
-- XLog.Warning("XNoticeManager nowTime", nowTime,"noticeType", noticeType,"LastRequestTime", LastRequestTime[noticeType],"interval", interval)
|
||
--end
|
||
if LastRequestTime[noticeType] and LastRequestTime[noticeType] > 0
|
||
and nowTime - LastRequestTime[noticeType] < interval then
|
||
return
|
||
end
|
||
LastRequestTime[noticeType] = nowTime
|
||
|
||
local url = XNoticeManager.GetNoticeUrl(noticeType)
|
||
if string.IsNilOrEmpty(url) then
|
||
return
|
||
end
|
||
-- XLog.Debug("notice type:" .. tostring(noticeType) .. ",url :" .. url ..", mgr:" .. tostring(XNoticeManager))
|
||
local request = CS.XUriPrefixRequest.Get(url, nil, NoticeRequestTimeOut, false, true)
|
||
CS.XTool.WaitCoroutine(request:SendWebRequest(), function()
|
||
if not request then
|
||
if failCb then
|
||
failCb()
|
||
end
|
||
return
|
||
end
|
||
|
||
if request.isNetworkError or
|
||
request.isHttpError or
|
||
not request.downloadHandler or
|
||
string.IsNilOrEmpty(request.downloadHandler.text) then
|
||
if failCb then
|
||
failCb()
|
||
end
|
||
return
|
||
end
|
||
|
||
local ok, notice = pcall(Json.decode, request.downloadHandler.text)
|
||
if not ok then
|
||
XLog.Error("XNoticeManager json 解码失败. 数据是:", request.downloadHandler.data)
|
||
if failCb then
|
||
failCb()
|
||
end
|
||
return
|
||
end
|
||
|
||
if not notice then
|
||
if failCb then
|
||
failCb()
|
||
end
|
||
return
|
||
end
|
||
|
||
if successCb then
|
||
successCb(notice)
|
||
end
|
||
|
||
request:Dispose()
|
||
end)
|
||
end
|
||
|
||
function XNoticeManager.InitTimer()
|
||
if NoticeRequestTimer then
|
||
return
|
||
end
|
||
|
||
for noticeType, _ in pairs(RequestInterval) do
|
||
XNoticeManager.RequestNoticeByType(noticeType)
|
||
end
|
||
|
||
NoticeRequestTimer = XScheduleManager.ScheduleForever(function()
|
||
for noticeType, _ in pairs(RequestInterval) do
|
||
XNoticeManager.RequestNoticeByType(noticeType)
|
||
end
|
||
end, NoticeRequestTimerInterval * 1000)
|
||
end
|
||
|
||
function XNoticeManager.OnLogin()
|
||
XNoticeManager.ReadScrollCountList()
|
||
XNoticeManager.ReadInGameNoticeReadList()
|
||
XNoticeManager.ReadTextNoticeHideCache()
|
||
XNoticeManager.ReadSubMenuNoticeReadList()
|
||
|
||
XNoticeManager.InitTimer()
|
||
end
|
||
|
||
function XNoticeManager.OnLogout()
|
||
if NoticeRequestTimer then
|
||
XScheduleManager.UnSchedule(NoticeRequestTimer)
|
||
NoticeRequestTimer = nil
|
||
end
|
||
|
||
for _, v in pairs(NoticePicList) do
|
||
if v and v:Exist() then
|
||
CS.UnityEngine.Object.Destroy(v)
|
||
end
|
||
end
|
||
NoticePicList = {}
|
||
end
|
||
|
||
--检测请求开关
|
||
function XNoticeManager.CheckFuncDisable()
|
||
return XSaveTool.GetData(XPrefs.NoticeTrigger)
|
||
end
|
||
|
||
function XNoticeManager.ChangeFuncDisable(state)
|
||
DisableFunction = state
|
||
XSaveTool.SaveData(XPrefs.NoticeTrigger, DisableFunction)
|
||
end
|
||
|
||
|
||
function XNoticeManager.Init()
|
||
DisableFunction = XMain.IsDebug and XNoticeManager.CheckFuncDisable()
|
||
XNoticeManager.InitNoticeCdnUrl()
|
||
XNoticeManager.RequestIp()
|
||
XNoticeManager.ReadLoginNoticeTime()
|
||
|
||
XEventManager.AddEventListener(XEventId.EVENT_USER_LOGOUT, XNoticeManager.OnLogout)
|
||
XEventManager.AddEventListener(XEventId.EVENT_LOGIN_DATA_LOAD_COMPLETE, XNoticeManager.OnLogin)
|
||
XEventManager.AddEventListener(XEventId.EVENT_PHOTO_ENTER, function()
|
||
ScreenShotFlag = true
|
||
end)
|
||
XEventManager.AddEventListener(XEventId.EVENT_PHOTO_LEAVE, function()
|
||
ScreenShotFlag = false
|
||
end)
|
||
end
|
||
|
||
XNoticeManager.Init()
|
||
return XNoticeManager
|
||
end |