It is currently April 16th, 2024, 8:38 pm

Skin throwing nil vaules

Discuss the use of Lua in Script measures.
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Skin throwing nil vaules

Post by methos237 »

Ok, I'm banging my head against the wall on this. I've spent the past 4 days working on it, and although I learned a TON, I can't figure out what I'm doing wrong!

Basically I'm building a countdown timer in LUA, getting the data from webparser, and then updating the skin with the information I want already formated. This may seem like an arse-backwarse way to do it, but I took this challenge on so I could learn a bit of LUA.

I've run the LUA through LUAforWindows to debug it (changing the webparser output in sOrigA, sOrigB, and sOrigC to the actual values returned by webparser), and it works fine. My assumption is that something is happening to the webparser output when the LUA script tries to read it.

The error I'm getting is:

Code: Select all

Script: DragonTime.lua:83: attempt to index local 'str' (a nil value)
If anyone could take a look at the code and offer a suggestion to fix it, I would greatly appreciate it!

The MPrint1, 2, and 3 meters are there for testing purposes, so I could see exactly what the webparser was spitting out.

DragonTime.ini

Code: Select all

[Rainmeter]
Author=methos237 (James Polk)
Update=1000
Debug=1

[Variables]
;==========![ Server needs to match the way it appears on the GuildWarsTemple URL ]!============================
;==========![ If your server name has multiple words and/or apostrophies (i.e. Ferguson's Crossing) ]!==========
;==========![ Make sure you omit (leave out) the apostrophies and replace the spaces with a minus sign (-) ]!===
;==========![ For Example: Ferguson's Crossing becomes fergusons-crossing]!=====================================
server=jade-quarry

[Metadata]
Name=GW2 Timers - DragonTime
Version=1.0

; Webparse ===============
[mGetTimer]
Measure=Plugin
Plugin=Plugins\WebParser.dll
RegExp="(?siU)zxcInfo\((.*)\);.*zxcInfo\((.*)\);.*zxcInfo\((.*)\);.*"
URL="http://guildwarstemple.com/dragontimer/#server#/"
UpdateDivider=3600
UpdateRate=1
Debug=1

[mDragonTime1]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=1

[mDragonTime2]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=2

[mDragonTime3]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=3

; LUA call ===============
[mLuaTimer]
Measure=script
ScriptFile="#CURRENTPATH#DragonTime.lua"
UpdateDivider=1

; Display the data ===============
[MPrint1]
Meter=STRING
MeasureName=mDragonTime1
MeterStyle=sText
Y=15
Text=%1
SolidColor=0,0,0,1

[MPrint2]
Meter=STRING
MeasureName=mDragonTime2
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MPrint3]
Meter=STRING
MeasureName=mDragonTime3
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MLuaPrint1]
Meter=String
MeterStyle=sText
ClipString=0
Y=30R


[MLuaPrint2]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R


[MLuaPrint3]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R


[sText]
FontSize=12
StringStyle=BOLD
StringAlign=LEFTCENTER
FontColor=0,0,0,255
W=1000
H=30
AntiAlias=1

[sText1]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=0,0,0,255
W=1000
H=30
AntiAlias=1

[sText2]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=#GREEN#
W=1000
H=30
AntiAlias=1

[sText1]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=#RED#
W=1000
H=30
AntiAlias=1


DragonTime.lua

Code: Select all

function initialize()

	sOrigA=SKIN:GetMeasure('mDragonTime1')
	sOrigB=SKIN:GetMeasure('mDragonTime2')
	sOrigC=SKIN:GetMeasure('mDragonTime3')
	

end


function Update()
	
	d1 = sParse(1)
	d2 = sParse(2)
	d3 = sParse(3)
	
	--assert(type(sOrigA)=='string','Rut-Roh Raggy! Didn\'t get data from the website (Make sure you typed the server name right in DragonTime.ini - Line:12')
	SKIN:Bang('[!SetOption MLuaPrint1 Text \"'..tostring(d1[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d1[3])..']')
	SKIN:Bang('[!SetOption MLuaPrint2 Text \"'..tostring(d2[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d2[3])..']')
	SKIN:Bang('[!SetOption MLuaPrint3 Text \"'..tostring(d3[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d3[3])..']')
	SKIN:Bang('[!SetVariable msg1 \"'..tostring(d1[2])..'\"][!SetVariable msg2 \"'..tostring(d2[2])..'\"][!SetVariable msg3 \"'..tostring(d3[2])..'\"]')
return ("Success")

end


function sParse(tID)

tA=sSplit(sOrigA,",")
tB=sSplit(sOrigB,",")
tC=sSplit(sOrigC,",")

   if  tID==1  then
			tData=tA
		elseif tID==2 then
			 tData=tB
		elseif tID==3 then
			 tData=tC
		else
			print(sCurrentConfig..' Returned an Error at sDragonParse')
   end

	local secs,opening,respawn,mess1,mess2,mess3=tData[2],tData[3],tData[4],tData[5],tData[6],tData[7]

	if tonumber(secs) <0 then
		i=math.abs(secs)+1
	else i=secs-1 end
		iHR = math.floor(i % 3600)
		iH = math.floor(i / 3600)
		iM = math.floor(iHR / 60)
		iS = math.floor(i % 60)

	if tonumber(secs) > 0 then
        sMsg = mess1
		sStyle = sText1
    elseif tonumber(secs) + tonumber(opening) > 0 then
		sMsg = mess2
		sStyle = sText2
    else
        sMsg =  mess3
		sStyle = sText3
	end


	if tonumber(secs) <0 then
		if iH ~= 0 then
			str = string.format("-%01d : %02d : %02d", iH, iM, iS)
		else str = string.format("-%02d : %02d", iM, iS)
		end
	else if iH ~= 0 then
		str = string.format("%01d : %02d : %02d", iH, iM, iS)
		else str = string.format("%02d : %02d", iM, iS)
		end
	end
		local t={str, sMsg, sStyle}

return t

end


function sSplit(str,delimiter)
	str = str:gsub("(%,%s)",","):gsub("%'", ""):gsub("Event%(s%) Outdated", "Events Outdated,")
	assert(type(str)=="string","bad argument #1 to 'split' (string expected, got "..type(str))
	assert(type(delimiter)=="string","bad argument #2 to 'split' (string expected, got "..type(delimiter))
	local t = {}
		for m in str:gmatch("(.-)%"..delimiter) do
			table.insert(t,m)
		end
return t

end
Last edited by methos237 on December 16th, 2012, 2:39 pm, edited 1 time in total.
User avatar
Kaelri
Developer
Posts: 1721
Joined: July 25th, 2009, 4:47 am

Re: Skin throwing nil vaules

Post by Kaelri »

The GetMeasure function is only used to create a "handle" object for the measure. Once you have created this object, you may then use it with other measure-related functions, including GetValue and GetStringValue, which return the actual measure values at the time they are called.

The simplest way to fix this is to make the following changes at line 29:

Code: Select all

tA=sSplit(sOrigA,",")
tB=sSplit(sOrigB,",")
tC=sSplit(sOrigC,",")
to

Code: Select all

tA=sSplit(sOrigA:GetStringValue(),",")
tB=sSplit(sOrigB:GetStringValue(),",")
tC=sSplit(sOrigC:GetStringValue(),",")
I'm 95% sure this is the cause of your problem, although I would have expected a different error (something like "string expected, got user data"). But your str variable does trace back directly to these objects. So assuming your measure names are correct, and the measures themselves are providing valid strings, this should fix it.

EDIT: I found the other part of the problem. Lua functions are case-sensitive, so you need to start the script with Initialize, not initialize. :)
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Re: Skin throwing nil vaules

Post by methos237 »

You are awesome! Same thing happens to me from time to time when I'm coding php, spend hours pouring through code to find a problem only to have it caused by a missing ';' or a miscapitalization.

now it's throwing an error at:

Code: Select all

   if tonumber(secs) <0 then
      i=math.abs(secs)+1
saying that it's trying to compare a nil value to a number.

Also, it's not counting down every second like I wanted, but I think I know why that's happening, so I'll play with that after I get the script I have now debugged.
User avatar
Kaelri
Developer
Posts: 1721
Joined: July 25th, 2009, 4:47 am

Re: Skin throwing nil vaules

Post by Kaelri »

methos237 wrote:You are awesome! Same thing happens to me from time to time when I'm coding php, spend hours pouring through code to find a problem only to have it caused by a missing ';' or a miscapitalization.

now it's throwing an error at:

Code: Select all

   if tonumber(secs) <0 then
      i=math.abs(secs)+1
saying that it's trying to compare a nil value to a number.
You may notice that it only throws this error for a few updates, then it stops. The error is only occurring before the WebParser measure has retrieved the value from the server.

When I use Lua scripts in conjunction with WebParser data, I like to have the script start disabled, then be enabled by WebParser when it finishes:

Code: Select all

[mGetTimer]
Measure=Plugin
Plugin=Plugins\WebParser.dll
RegExp="(?siU)zxcInfo\((.*)\);.*zxcInfo\((.*)\);.*zxcInfo\((.*)\);.*"
URL="http://guildwarstemple.com/dragontimer/#server#/"
UpdateDivider=3600
UpdateRate=1
Debug=1
FinishAction=[!EnableMeasure mLuaTimer][!UpdateMeasure mLuaTimer]

...

[mLuaTimer]
Measure=script
ScriptFile="#CURRENTPATH#DragonTime.lua"
UpdateDivider=1
Disabled=1
This way, the script will never be trying to work with string data that doesn't exist yet.
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Re: Skin throwing nil vaules

Post by methos237 »

Thanks, I'll give it a try!
User avatar
Kaelri
Developer
Posts: 1721
Joined: July 25th, 2009, 4:47 am

Re: Skin throwing nil vaules

Post by Kaelri »

methos237 wrote:I understand what you're saying, but if that were the case, why would it do that upon a skin refresh? One would think that when the skin initializes, the webparser is called first, and then writes it's data to the parser calls (in my case [mDragonTime1, 2, 3..]). Then the LUA script is called, and grabs the data from the [mDragonTime1,2,3..] measure, which has already been populated by the webparser call.
It does work a little differently. All of a skin's meters and measures are treated as independent objects. They do update in order on each cycle, so your [mDragonTime1], et al. are updated before [mLuaTimer]. However, if a measure (specifically a plugin, like WebParser, which runs in a separate thread) has not yet finished evaluating, the rest of the skin will not "wait" for it. Instead, the measure's string value will be treated as blank ('') until it has finished and is updated again.*

This might seem a little counterintuitive if you're used to thinking in terms of "scripts" or "functions," but in the context of Rainmeter, it allows us to have quite a number of moving parts within the same skin, without worrying too much about a single part slowing everything down.
methos237 wrote:I could just wrap all the functions outside of the Initialize function into one function that's called from a !command measure bang run by webparser. Is my logic sound?
If I understand what your script is doing, then yes, that should work fine.

(Personally, I like to use the Update() function and !UpdateMeasure, because then I can use the "return" value as a convenient place to output debugging information. But that's entirely a matter of personal preference. :)
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Re: Skin throwing nil vaules

Post by methos237 »

Sorry Kaelri, after taking a look at your second to last post last night, I totally understand what you were saying (I guess you were in the middle of replying to it when I changed it) about using the webparser to disable the lua script element until webparser is done running.

Basically what I am trying to do is make a countdown timer that get's the times from the website every 10 minutes, and updates the countdown based on the information it gets. This is because the times on the website aren't a static countdown to a certain date or time, but are respawn timers for events. So the flowchart would be:

Code: Select all

(On skin initialize, and then every 10 minutes) Get webparser data (basically a number that translates to seconds) -> send data to LUA -> LUA script updates every second, looking to see if there's been an update to the webparser data, and if not get the previously saved number from the script and count the number down by 1 -> The script sends the result of countdown-1 as a variable to the .ini, the parses that number to hours, minutes, seconds, and sends back that parse to the .ini along with MeterStyle and a message based on the value of the time number.
So right now I've got it counting down every second, but for some reason all 3 timers start at -2:00:00 and countdown instead of using the actual values from the parse. I'll post the revised code when I get home from work.
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Re: Skin throwing nil vaules

Post by methos237 »

So here is my coding as it now stands (read above for the issue's I'm now having).

DragonTime.ini

Code: Select all

[Rainmeter]
Author=methos237 (James Polk)
Update=1000
Debug=1

[Variables]
;==========![ Server needs to match the way it appears on the GuildWarsTemple URL ]!============================
;==========![ If your server name has multiple words and/or apostrophies (i.e. Ferguson's Crossing) ]!==========
;==========![ Make sure you omit (leave out) the apostrophies and replace the spaces with a minus sign (-) ]!===
;==========![ For Example: Ferguson's Crossing becomes fergusons-crossing]!=====================================
server=jade-quarry

data=1

[Metadata]
Name=GW2 Timers - DragonTime
Version=1.0

; Webparse ===============
[mGetTimer]
Measure=Plugin
Plugin=Plugins\WebParser.dll
RegExp="(?siU)\('dragon1timer',.*,(.*),.*\('dragon2timer',.*,(.*),.*\('dragon3timer',.*,(.*),.*"
URL="http://guildwarstemple.com/dragontimer/#server#/"
UpdateDivider=1000
UpdateRate=1
Debug=1
FinishAction=[!EnableMeasure mLuaTimer][!UpdateMeasure mLuaTimer][!SetVariable data 1]

[mDragonTime1]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=1

[mDragonTime2]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=2

[mDragonTime3]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=3

; LUA call ===============
[mLuaTimer]
Measure=script
ScriptFile="#CURRENTPATH#DragonTime.lua"
UpdateDivider=1
Disabled=1
odoA=
odoB=
odoC=


; Display the data ===============
[MPrint1]
Meter=STRING
MeasureName=mDragonTime1
MeterStyle=sText
Y=15
Text=%1
SolidColor=0,0,0,1

[MPrint2]
Meter=STRING
MeasureName=mDragonTime2
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MPrint3]
Meter=STRING
MeasureName=mDragonTime3
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MLuaPrint1]
Meter=String
MeterStyle=sText
ClipString=0
Y=30R


[MLuaPrint2]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R


[MLuaPrint3]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R


[sText]
FontSize=12
StringStyle=BOLD
StringAlign=LEFTCENTER
FontColor=0,0,0,255
W=1000
H=30
AntiAlias=1

[sText1]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=0,0,0,255
W=1000
H=30
AntiAlias=1

[sText2]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=#GREEN#
W=1000
H=30
AntiAlias=1

[sText3]
FontSize=12
StringStyle=BOLD
StringAlign=RIGHT
FontColor=#RED#
W=1000
H=30
AntiAlias=1
DragonTime.lua

Code: Select all

function Initialize()

	iOrigA=SKIN:GetMeasure('mDragonTime1')
	iOrigB=SKIN:GetMeasure('mDragonTime2')
	iOrigC=SKIN:GetMeasure('mDragonTime3')
	--iOdoA=SELF:GetNumberOption('odoA')
	--iOdoB=SELF:GetNumberOption('odoB')
	--iOdoC=SELF:GetNumberOption('odoC')

end


function Update()

	uc = SKIN:GetVariable('data')
	if uc==1 then
		tA=iOrigA:GetValue()-1
		tB=iOrigB:GetValue()-1
		tC=iOrigC:GetValue()-1
	else
		tA=SELF:GetNumberOption('odoA')-1
		tB=SELF:GetNumberOption('odoB')-1
		tC=SELF:GetNumberOption('odoC')-1
	end
	
   
	d1 = sParse(1)
	d2 = sParse(2)
	d3 = sParse(3)

	--assert(type(sOrigA)=='string','Rut-Roh Raggy! Didn\'t get data from the website (Make sure you typed the server name right in DragonTime.ini - Line:12')
	SKIN:Bang('[!SetOption MLuaPrint1 Text \"'..tostring(d1[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d1[3])..']')
	SKIN:Bang('[!SetOption MLuaPrint2 Text \"'..tostring(d2[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d2[3])..']')
	SKIN:Bang('[!SetOption MLuaPrint3 Text \"'..tostring(d3[1])..'\"][!SetOption MLuaPrint1 MeterStyle '..tostring(d3[3])..']')
	SKIN:Bang('[!SetOption mLuaTimer odoA '..tA..'][!SetOption mLuaTimer odoB '..tB..'][!SetOption mLuaTimer odoC '..tC..']')
	SKIN:Bang('[!SetVariable msg1 \"'..tostring(d1[2])..'\"][!SetVariable msg2 \"'..tostring(d2[2])..'\"][!SetVariable msg3 \"'..tostring(d3[2])..'\"]')
return SKIN:Bang('[!SetVariable data \"0\"]')

end


function sParse(tID)


   if  tID==1  then
		tD=tA
		iOpening=900
		iTimeout=-10800
		sMess1='Time Before Pre-Event'
		sMess2='Pre-Event Began'
		sMess3='Event Outdated'
	elseif tID==2 then
		tD=tB
		iOpening=1800
		iTimeout=-9000
		sMess1='Time Before 30 Min Window'
		sMess2='30 Min Spawning Window'
		sMess3='Event Outdated'
	elseif tID==3 then
		tD=tC
		iOpening=4500
		iTimeout=-11700
		sMess1='Time Before 1 Hour 15 Minute Window'
		sMess2='1 Hour 15 Minute Spawning Window'
		sMess3='Event Outdated'
	else
		print(sCurrentConfig..' Returned an Error at sDragonParse')
	end

  -- local secs,opening,respawn,mess1,mess2,mess3=tData[2],tData[3],tData[4],tData[5],tData[6],tData[7]

	--if tD <0 then
	--	i=math.abs(tD+1)
	--else i=tD-1 end
		iHR = math.floor(tD % 3600)
		iH = math.floor(tD / 3600)
		iM = math.floor(iHR / 60)
		iS = math.floor(tD % 60)

	if tD > 0 then
        sMsg = mess1
		sStyle = sText1
    elseif tD + iOpening > 0 then
		sMsg = mess2
		sStyle = sText2
    else
        sMsg =  mess3
		sStyle = sText3
   end


	--if tD <0 then
		if iH ~= 0 then
			str = string.format("%01d : %02d : %02d", iH, iM, iS)
		else str = string.format("%02d : %02d", iM, iS)
	end
	--else if iH ~= 0 then
		--str = string.format("%01d : %02d : %02d", iH, iM, iS)
		--else str = string.format("%02d : %02d", iM, iS)
		--end
	--end
	
    local t={str, sMsg, sStyle}

return t

end

User avatar
Kaelri
Developer
Posts: 1721
Joined: July 25th, 2009, 4:47 am

Re: Skin throwing nil vaules

Post by Kaelri »

Here, try this. I rewrote your script a bit to simplify it, and I added comments to explain what it's doing now. Basically, I have your WebParser call a new, discrete function called RefreshValues() when it's finished getting data, in order to update your timer targets. Then the Update() function just carries on obliviously.

Code: Select all

[Metadata]
Name=GW2 Timers - DragonTime
Author=methos237 (James Polk)
Version=1.0

[Rainmeter]
Update=1000
DynamicWindowSize=1
BackgroundMode=2
SolidColor=0,0,0,1

[Variables]
;==========![ Server needs to match the way it appears on the GuildWarsTemple URL ]!============================
;==========![ If your server name has multiple words and/or apostrophies (i.e. Ferguson's Crossing) ]!==========
;==========![ Make sure you omit (leave out) the apostrophies and replace the spaces with a minus sign (-) ]!===
;==========![ For Example: Ferguson's Crossing becomes fergusons-crossing]!=====================================
server=jade-quarry

; Webparse ===============
[mGetTimer]
Measure=Plugin
Plugin=Plugins\WebParser.dll
RegExp="(?siU)\('dragon1timer',.*,(.*),.*\('dragon2timer',.*,(.*),.*\('dragon3timer',.*,(.*),.*"
URL="http://guildwarstemple.com/dragontimer/#server#/"
UpdateRate=1000
Debug=1
FinishAction=[!UpdateMeasureGroup mDragonTime][!CommandMeasure mLuaTimer RefreshValues()]

[mDragonTime1]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=1
UpdateDivider=-1
Group=mDragonTime

[mDragonTime2]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=2
UpdateDivider=-1
Group=mDragonTime

[mDragonTime3]
Measure=Plugin
Plugin=Plugins\WebParser.dll
URL=[mGetTimer]
StringIndex=3
UpdateDivider=-1
Group=mDragonTime

; LUA call ===============
[mLuaTimer]
Measure=script
ScriptFile="#CURRENTPATH#DragonTime.lua"
UpdateDivider=1


; Display the data ===============
[MPrint1]
Meter=STRING
MeasureName=mDragonTime1
MeterStyle=sText
Y=15
Text=%1
SolidColor=0,0,0,1

[MPrint2]
Meter=STRING
MeasureName=mDragonTime2
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MPrint3]
Meter=STRING
MeasureName=mDragonTime3
MeterStyle=sText
Y=15R
Text=%1
SolidColor=0,0,0,1

[MLuaPrint1]
Meter=String
MeterStyle=sText
ClipString=0
Y=30R

[MLuaPrint2]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R

[MLuaPrint3]
Meter=String
MeterStyle=sText
ClipString=0
Y=15R

; Styles ===============
[sText]
StringStyle=BOLD
StringAlign=LEFTCENTER
FontColor=0,0,0,255
AntiAlias=1

[sText1]
FontColor=0,0,0,255

[sText2]
FontColor=#GREEN#

[sText3]
FontColor=#RED#

Code: Select all

function Initialize()
	-- This table will store all of your constants and global
	-- values for each timer. The table is "global", so you
	-- can use it anywhere. For example:
	-- var = Main[1].Measure:GetValue()

	Main = {
		{
			Measure        = SKIN:GetMeasure('mDragonTime1'),
			iOpening       = 900,
			iTimeout       = -10800,
			MessageFuture  = 'Time Before Pre-Event',
			MessagePresent = 'Pre-Event Began',
			MessagePast    = 'Event Outdated'
			},
		{
			Measure        = SKIN:GetMeasure('mDragonTime2'),
			iOpening       = 1800,
			iTimeout       = -9000,
			MessageFuture  = 'Time Before 30 Min Window',
			MessagePresent = '30 Min Spawning Window',
			MessagePast    = 'Event Outdated'
			},
		{
			Measure        = SKIN:GetMeasure('mDragonTime3'),
			iOpening       = 4500,
			iTimeout       = -11700,
			MessageFuture  = 'Time Before 1 Hour 15 Minute Window',
			MessagePresent = '1 Hour 15 Minute Spawning Window',
			MessagePast    = 'Event Outdated'
			}
		}
end

function RefreshValues()
-- This function is called by the FinishAction on WebParser:
-- FinishAction=[!CommandMeasure mLuaTimer RefreshValues()]

	for i, t in pairs(Main) do
		t.Time = os.time() + t.Measure:GetValue()
	end
	-- Even though you have Update=1000 in Rainmeter, it is
	-- not *guaranteed* to update exactly once per second.
	-- Instead, this calculates the actual date & time that
	-- you're counting down toward. The Update() function will
	-- then simply compare this time to the current system time,
	-- which will be accurate no matter when it updates.

	SKIN:Bang('!UpdateMeasure', SELF:GetName())
	-- Updates the measure immediately, so you don't have to
	-- wait for the next cycle.
end

function Update()
	for i, t in ipairs(Main) do
	-- This "for" loop will repeat all of the actions below for
	-- each timer in your Main table.

		if not t.Time then return end
		-- This prevents errors before WebParser has finished.
		-- The "Time" key is created by RefreshValues(), and
		-- so it will not exist until the FinishAction is sent.

		local tD = t.Time - os.time()
		-- Gets the difference between the time you calculated
		-- in RefreshValues() and the current system time.

		local iHR = math.floor(tD % 3600)
		local iH  = math.floor(tD / 3600)
		local iM  = math.floor(iHR / 60)
		local iS  = math.floor(tD % 60)

		local str, sMsg, sStyle

		if tD > 0 then
			sMsg   = t.MessageFuture
			sStyle = 1
		elseif tD + t.iOpening > 0 then
			sMsg   = t.MessagePresent
			sStyle = 2
		else
			sMsg   = t.MessagePast
			sStyle = 3
		end

		if iH ~= 0 then
			str = string.format("%01d : %02d : %02d", iH, iM, iS)
		else
			str = string.format("%02d : %02d", iM, iS)
		end
		
		SKIN:Bang('!SetOption', 'MLuaPrint'..i, 'Text', str)
		SKIN:Bang('!SetOption', 'MLuaPrint'..i, 'MeterStyle', 'sText | sText'..sStyle)
		SKIN:Bang('!SetVariable', 'msg'..i, sMsg)
	end
end
methos237
Posts: 6
Joined: December 6th, 2012, 7:39 pm

Re: Skin throwing nil vaules

Post by methos237 »

You are absolutely amazing! You've gone far above and beyond what most people would consider "helping". This is my first skin doing something this complex, and the first skin I plan on releasing to the public. As such, I only feel it's right to include your name and info in the metadata (I'll get the info from your enigma suite). Thank you so much for all your help!