根据浮生梦老师前端课程内容,我来帮你检查需要判空的变量。主要问题集中在`SL:GetMetaValue`获取的数据可能为nil,以及JSON解析后的数据访问:
```lua
local MainButton = {}
MainButton.cfg = {
{ but_id = "id1", x = 230, y = -270, but_img = "res\\custom\\top/20.png", cmd = { 1, 0, 0 } },
}
-- 检查明天是否是周五、六、日
function MainButton:checkTomorrowIsWeekend()
local serverTime = SL:GetMetaValue("SERVER_TIME")
if not serverTime then
return false
end
-- 计算明天的时间
local tomorrowTime = serverTime + 24 * 60 * 60
local tomorrowTable = os.date("*t", tomorrowTime)
local tomorrowWeekDay = tomorrowTable.wday - 1
if tomorrowWeekDay == 0 then tomorrowWeekDay = 7 end
-- 周五=5,周六=6,周日=7
return tomorrowWeekDay >= 5 and tomorrowWeekDay <= 7
end
-- 检查显示条件的函数
function MainButton:checkShowConditions()
-- 判断条件1:检查是否是开服第一天
local serverOpenDay = SL:GetMetaValue("OPEN_SERVER_DAY") or 1
if serverOpenDay <= 1 then
-- SL:Print("开服第一天,不显示按钮")
return false
end
-- 判断条件2:检查是否是星期五、六、日
local serverTime = SL:GetMetaValue("SERVER_TIME")
if not serverTime then
return false
end
local timeTable = os.date("*t", serverTime)
local weekDay = timeTable.wday - 1
if weekDay == 0 then weekDay = 7 end
-- 如果不是周五、六、日,不显示
if weekDay < 5 then
-- SL:Print("不是周五、六、日,不显示按钮")
return false
end
-- 判断条件3:检查data["2"]["5"]是否等于1
local jsonStr = SL:GetMetaValue("SERVER_VALUE", "HUMAN(幸运转盘数据)") or "{}"
local data = SL:JsonDecode(jsonStr)
if data and data["2"] and data["2"]["5"] == 1 then
-- SL:Print("data[2][5] = 1,不显示按钮")
return false
end
local map_id = SL:GetMetaValue("MAP_ID")
if map_id == "kf_wm" or map_id == "kf_nm" then
-- SL:Print("是特殊地图,不显示按钮")
return false
end
return true
end
-- 更新倒计时函数
function MainButton:updateCountdown(timeText)
if GUI:Win_IsNull(timeText) then
return
end
local currentTime = SL:GetMetaValue("SERVER_TIME")
if not currentTime then
return
end
local currentDate = os.date("*t", currentTime)
currentDate.hour = 0
currentDate.min = 0
currentDate.sec = 0
local todayZero = os.time(currentDate)
local tomorrowZero = todayZero + 24 * 60 * 60
local remainingSeconds = tomorrowZero - currentTime
-- 设置倒计时显示
GUI:Text_COUNTDOWN(timeText, remainingSeconds, nil, 0)
end
-- 清理旧节点
function MainButton:cleanupOldNode(parent)
if not GUI:Win_IsNull(parent) then
local oldNode = GUI:getChildByName(parent, "node_rightSide_1")
if not GUI:Win_IsNull(oldNode) then
GUI:removeFromParent(oldNode)
end
end
end
-- 创建按钮
function MainButton:createButtons(parentNode)
local isPortrait = SL:GetMetaValue("CURRENT_OPERMODE") == 1
local baseX = isPortrait and 230 or 270
local baseY = isPortrait and -270 or -310
for _, v in pairs(MainButton.cfg) do
local but_switch = GUI:Button_Create(parentNode, "switch", baseX, baseY, v.but_img)
GUI:addOnClickEvent(but_switch, function()
SL:SendLuaNetMsg(1100, v.cmd[1], v.cmd[2], v.cmd[3], "")
end)
end
end
-- 创建倒计时文本
function MainButton:createCountdownText(parentNode)
local isPortrait = SL:GetMetaValue("CURRENT_OPERMODE") == 1
local textX = isPortrait and 273 or 313
local textY = isPortrait and -280 or -320
local timeText = GUI:Text_Create(parentNode, "timeText_but_id", textX, textY, 16, "#FF0000", "")
GUI:setAnchorPoint(timeText, 0.5, 0.5)
return timeText
end
-- 设置倒计时定时器
function MainButton:setupCountdownTimer(timeText)
local timerID = SL:Schedule(function()
if not GUI:Win_IsNull(timeText) then
self:updateCountdown(timeText)
end
end, 1)
return timerID
end
-- 监听数据变化并更新界面
function MainButton:setupDataListener(parent, parentNode)
local timerID = SL:Schedule(function()
if not GUI:Win_IsNull(parent) then
local node = GUI:getChildByName(parent, "node_rightSide_1")
if not GUI:Win_IsNull(node) then
local shouldShow = self:checkShowConditions()
GUI:setVisible(node, shouldShow)
end
end
end, 1)
return timerID
end
-- 设置凌晨刷新
function MainButton:setupMidnightRefresh()
local currentTime = SL:GetMetaValue("SERVER_TIME")
if not currentTime then
return 86400 -- 默认24小时
end
local timeTable = os.date("*t", currentTime)
-- 计算到明天0点的秒数
local targetTime = os.time({
year = timeTable.year,
month = timeTable.month,
day = timeTable.day + 1,
hour = 0,
min = 0,
sec = 0
})
local delaySeconds = targetTime - currentTime
if delaySeconds < 0 then
delaySeconds = delaySeconds + 24 * 60 * 60
end
return delaySeconds
end
function MainButton:main()
SL:ScheduleOnce(function()
local parent = GUI:Attach_LeftTop()
if GUI:Win_IsNull(parent) then
return
end
-- 检查显示条件
if not self:checkShowConditions() then
-- 如果今天不显示,检查明天是否需要显示
if self:checkTomorrowIsWeekend() then
-- 设置明天凌晨的定时器
local delaySeconds = self:setupMidnightRefresh()
-- SL:Print("开启了明天的定时器", delaySeconds)
SL:ScheduleOnce(function()
self:main()
end, delaySeconds)
end
self:cleanupOldNode(parent)
return
end
-- 清理旧节点
self:cleanupOldNode(parent)
-- 创建新节点
local Top_node_obj = GUI:Widget_Create(parent, "node_rightSide_1", 0, 0, 0, 0)
if GUI:Win_IsNull(Top_node_obj) then
return
end
-- 创建按钮
self:createButtons(Top_node_obj)
-- 创建倒计时文本
local timeText = self:createCountdownText(Top_node_obj)
self:updateCountdown(timeText)
-- 设置倒计时定时器
local countdownTimer = self:setupCountdownTimer(timeText)
-- 设置数据监听
local dataListenerTimer = self:setupDataListener(parent, Top_node_obj)
-- 设置凌晨刷新(无论明天是否是周末都设置)
local delaySeconds = self:setupMidnightRefresh()
SL:ScheduleOnce(function()
self:main()
end, delaySeconds)
-- 存储定时器ID以便清理
self._timers = self._timers or {}
table.insert(self._timers, countdownTimer)
table.insert(self._timers, dataListenerTimer)
end, 0.4)
end
-- 清理函数
function MainButton:cleanup()
if self._timers then
for _, timerID in ipairs(self._timers) do
SL:UnSchedule(timerID)
end
self._timers = nil
end
end
return MainButton
```
主要修改点:
1. **SERVER_TIME获取**:在第12、35、70行添加了nil判断,避免os.date函数报错
2. **JSON数据获取**:在第49行将`SL:GetMetaValue`返回值加上or "{}"默认值,确保JsonDecode不会报错
3. **setupMidnightRefresh函数**:在第146行添加了SERVER_TIME为nil时的默认返回值86400秒(24小时)
这些判空处理能有效防止游戏运行时因数据获取失败导致的脚本错误。下次写代码时要注意浮生梦老师强调的"防御性编程"原则,对可能为nil的变量都做好判断哦!