 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Fri Jan 23, 2009 5:53 pm
Assistance with functions (in lua and zscript) needed |
For the longest time, I had been looking for a time differential script to tell me the time between two periods. I had one, but it was buggered to pieces because it wasn't smart enough that going from the 31st of one month to the 1st of the next month did not constitute a full month.
Recently, I found a perfect one written in Lua. It came off the lua-users wiki, and is written as so:
| Code: |
local timeDiff = function(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end |
The example they provide to show how the script works is:
| Code: |
local td=timeDiff(os.time{year=2007,month=10,day=5,hour=10,min=10,sec=5},os.time{year=2006,month=11,day=6,hour=10,min=10,sec=5})
for i,v in pairs(td) do print(i,v) end |
I figured I'd be able to integrate the script into CMUD, and I had been partially successful, but now require assistance.
What I have right now is an alias that has what's posted in the script verbatim, plus this change in the example:
| Code: |
local td=timeDiff(os.time{year=zs.param(1),month=zs.param(2),day=zs.param(3),hour=zs.param(4),min=zs.param(5),sec=zs.param(6)},os.time{year=zs.param(7),month=zs.param(8),day=zs.param(9),hour=zs.param(10),min=zs.param(11),sec=zs.param(12)})
zs.var.difference=(td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs")
|
Now the alias works nicely, and if I have to go that route, I suppose that's what I'll have to do. I'd rather not, however, and use it as a function. The problem is, I'm not even sure how I'm going to get it into a function. #RETURN {#LUA blahblahblahb} doesn't work, and #RETURN @luafunc(%1,%2,...,%11,%12) doesn't work properly.
So, any ideas how I can turn that alias into a function so that when I do:
gt @timediff(2009,1,23,12,00,00,2009,1,1,12,00,00)
it'll properly show up as:
(Group) Charneus: 0yrs 0mos 23dys 0hrs 0mns 0scs
?
An added bonus would if it could return up to what is populated so I'm not spammed with all that every time (for instance, it'd show 23dys instead of all the 0s in it, although with the hours/mins/secs, I would personally want that left alone).
I greatly appreciate it and look forward to hearing suggestions.
Charneus |
|
|
|
 |
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Fri Jan 23, 2009 6:57 pm |
I can't help with your exact question, but if you can't get it to work, I can give you my zscript function for converting dates into seconds since Jan 1, 2000. I made it so I could get time differences easily.
|
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sat Jan 24, 2009 9:26 pm |
That's the thing - I have a script that does that, except that it doesn't calculate months correctly for some reason. That's why I chose this route... and this one DOES work perfectly, like I said, but I can't get it to work as a function. I thought I had it right before, but when I do things like @timediff(%db(@database, item), %time("yyyy,mm,dd,hh,nn,ss")), it returns something about 'day' or 'month' not being a valid field. *sigh*
Charneus |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Sat Jan 24, 2009 10:40 pm |
Ok, so this timeDiff() function works entirely correctly in CMUD - the example prints
min 0
day 28
month 10
sec 0
hour 23
year 0
just like you'd expect. The only problem is getting the return from Lua back into zScript. There're a couple of ways of going about this depending on how exactly you want it to be printed - but the main mechanic you're going to be using is the simple lua "return" keyword, which will return a value in Lua back into zScript. Try this:
| Code: |
<func name="hax" language="Lua" id="1">
<value>return "lol"</value>
</func> |
And then running "#say @hax()" on the command line to see what I mean - the return value is returned from the function just fine. So all you need to do is format the table that timeDiff is returning in some pretty way and then use the return keyword to return it. Perhaps:
local finalstring = ""
for i,v in pairs(td) do finalstring = finalstring .. i .. " " .. v .. " " end
return finalstring
This code will return the string "min 0 day 28 month 10 sec 0 hour 23 year 0 " - you can optionally trim the final space off if you like. Once you've got the right format, you can just do:
guildchat Time Difference: @TimeDifference(balghag)
and presto.
Finally, here is what I did on the command line to mke sure that the above example was correct:
| Code: |
local timeDiff = function(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end
local td=timeDiff(os.time{year=2007,month=10,day=5,hour=10,min=10,sec=5},os.time{year=2006,month=11,day=6,hour=10,min=10,sec=5})
print(td)
local finalstring = ""
for k,v in pairs(td) do finalstring = finalstring .. k .. " " .. v .. " " end
print(finalstring) |
Hope this helps. |
|
|
|
 |
Tech GURU

Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Sat Jan 24, 2009 10:50 pm |
Not sure what you had trouble with but I was able to fairly easily convert you alias to a function. I did remove the local and make it a global function that I put in an onLoad event. If you going keep calling it, you don't want it being defined each time. I also made sure you don't print when the time unit is 0.
| Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<event event="onLoad" priority="60" copy="yes">
<value>function timeDiff(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end
</value>
</event>
<func name="deltaDate" copy="yes">
<value>local td=timeDiff(os.time{year=zs.param(1),month=zs.param(2),day=zs.param(3),hour=zs.param(4),min=zs.param(5),sec=zs.param(6)},os.time{year=zs.param(7),month=zs.param(8),day=zs.param(9),hour=zs.param(10),min=zs.param(11),sec=zs.param(12)})
local result = td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs"
return string.gsub(result, " 0..." , "" ,6)</value>
<arglist>$year,$mon,$day,$hour,$min,$sec,$year1,$mon1,$day1,$hour1,$min1,$sec1</arglist>
</func>
</cmud> |
I called it like this
| Code: |
| gt @deltaDate(2009,1,13,12,00,00,2002,1,1,2,03,10) |
[Edit] Ninjaed by Fang. Doh!!! |
|
_________________ Asati di tempari! |
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sun Jan 25, 2009 1:10 am |
Hmm... I tried Tech's with what I had intentions of doing, and it comes up with this:
Using:
#SAY @luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@timestats, starttime))
returns:
'field 'year' missing in date table (line 1)'
Same thing returns for:
#say @luatime(%time(yyyy),%time(mm),%time(dd),%time(hh),%time(nn),%time(ss),%db(@afkstats,starttime))
So, apparently it's not going to take a database value (value is "2009,01,23,18,06,23")...
Can anyone think of a workaround for this?
Charneus
By the way, it still prints 0yrs. Also, is there a way to make it still print hours/minutes/seconds even if they are zero? I just don't want to see 0yrs 0mos 0dys. :P |
|
Last edited by charneus on Sun Jan 25, 2009 1:14 am; edited 1 time in total |
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Sun Jan 25, 2009 1:14 am |
Trouble is that the %db function returns a single argument, the string "2009,01,23,18,06,23". This function expects those numbers to be passed individually as separate arguments - use the %word function with the comma as a separator to get them out.
If it was me, though, I'd be using lua's time-related functions to store the start time anyway, so it'd be in the right format to pass straight to the function.
Also, as it stands this code will print numbers even if they're 0. |
|
|
|
 |
chris-74269 Magician
Joined: 23 Nov 2004 Posts: 364
|
Posted: Sun Jan 25, 2009 1:44 am |
I use:
| Code: |
#lua {zs.var.currenttime=os.time(t)}
|
You can make an alarm to keep the currenttime updated, so do it whenever you want to call it. To get a time difference, just have the new event set #lua {zs.var.blahblahtime=os.time(t)} Then just do a @currenttime-@blahblahtime to get the number of seconds between, unless you are wanting to know the months/ect b/t the dates and I'm misreading this works. |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sun Jan 25, 2009 2:21 am |
Chris, you are misreading it, because I want the years/months/days/hours/minutes/seconds. :P
Fang, I'll do the %word and get back to you on this. Thanks for that suggestion. I didn't even think of it.
Charneus |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sun Jan 25, 2009 2:52 am |
Heh. So I guess it's going to get really messy whenever I want to do time differences in my scripts...
I say that because I now have to do:
| Code: |
| %time("yyyy"),%time("mm"),%time("dd"),%time("hh"),%time("nn"),%time("ss"),%word(%db(@timestats, starttime),1,","),%word(%db(@timestats, starttime),2,","),%word(%db(@timestats, starttime),3,","),%word(%db(@timestats, starttime),4,","),%word(%db(@timestats, starttime),5,","),%word(%db(@timestats, starttime),6,",") |
I tried doing this in a function as well:
| Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<func name="timedb" copy="yes">
<value>#RETURN %concat(%time("yyyy"),",",%time("mm"),",",%time("dd"),",",%time("hh"),",",%time("nn"),",",%time("ss"),",",%word(%1,1,","),",",%word(%1,2,","),",",%word(%1,3,","),",",%word(%1,4,","),",",%word(%1,5,","),",",%word(%1,6,","))</value>
</func>
</cmud>
|
But even that didn't work when I did @luatime(@timedb(%db(@timestats,starttime)), that didn't work. Even removed the concat and tried it returning the value alone. Nothing. *sigh* Unless I'm missing something here. %word(%db(@timestats,starttime)) didn't work, either.
Charneus |
|
|
|
 |
Tech GURU

Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Sun Jan 25, 2009 8:04 am |
Ok.. you didn't mention how you wanted to used it. Try this code.
| Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<event event="onLoad" priority="20" copy="yes">
<value>function timeDiff(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end
function buildTable(timeStr)
tt = {
year = tonumber(string.sub( timeStr, string.find(timeStr,"%d+")) ),
month = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",5) )),
day = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",8 ))),
hour = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",11) )),
min = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",14) )),
sec = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",17) ))
}
return tt
end</value>
</event>
<func name="deltaDate" copy="yes">
<value>
t1 = os.time(buildTable(zs.param(1)))
t2= os.time(buildTable(zs.param(2)))
td=timeDiff(t1,t2)
local result = td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs"
return string.gsub(result, "0... ?" , "" ,6)</value>
<arglist>$time1,$time2</arglist>
</func>
<var name="timestats" type="Record" copy="yes">starttime=2009,01,23,18,06,23</var>
</cmud> |
I used the following to run it.
| Code: |
| #SAY @deltaDate(%time("yyyy,mm,dd,hh,nn,ss"),%db(@timestats, starttime)) |
|
|
_________________ Asati di tempari! |
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sun Jan 25, 2009 8:53 am |
That did it. Thanks a lot, Tech (and Fang, who provided it in the first place!)
I'm still learning lua, so hopefully I'll get much better at it in the future.
Charneus |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Sun Jan 25, 2009 10:01 am |
| charneus wrote: |
| Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<func name="timedb" copy="yes">
<value>#RETURN %concat(%time("yyyy"),",",%time("mm"),",",%time("dd"),",",%time("hh"),",",%time("nn"),",",%time("ss"),",",%word(%1,1,","),",",%word(%1,2,","),",",%word(%1,3,","),",",%word(%1,4,","),",",%word(%1,5,","),",",%word(%1,6,","))</value>
</func>
</cmud>
|
But even that didn't work |
Just for future reference, the reason for this is because Lua is still expecting multiple arguments, whereas this function returns a single argument, a string. You need to be very careful using comma-separated lists like this to remember what counts as a single argument (the whole string) and what doesn't. The commas need to be outside the string, in the code, for this to work, and zScript doesn't support that syntax.
In lua it'd be easy because you could just have multiple returns:
| Code: |
| func timedb () return zs.time("yyyy"), zs.time("mm"), zs.time("dd") ... etc etc ... zs.time("ss") end |
And, because Lua is smart, it'll then understand that each return from that function is a separate argument to whatever it's passed to. |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Mon Jan 26, 2009 2:02 am |
Ok... this is starting to get annoying. Here's the script I've been setting up with this time difference script. I'm going to add many more, but only if I can solve this problem first.
| Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<class name="AwayScript" copy="yes">
<class name="AFKAliases" copy="yes">
<alias name="away" parsearg="false" copy="yes">
<value>#IF (%null( %-1) AND @away=1) {
; #SEND "gt :@Chas just returned from "%concat( "@B<(@W=@Y", %db(@afkstats,afkmsg), "@W=@B)>@C")", gone for "@luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@afkstats,afkstarttime))
away=0
catchtells
#T- "AFKTriggers"
} {
away=1
#ADDKEY afkstats afkmsg %-1
; #SEND "gt :@Cis away. Reason: @B<(@W=@Y"%-1"@W=@B)>@C"
#T+ "AFKTriggers"
catchtells
#ADDKEY afkstats afkstarttime %time( "yyyy,mm,dd,hh,nn,ss")
}</value>
</alias>
</class>
<class name="AFKTriggers" copy="yes">
<trigger priority="43130" copy="yes">
<pattern>^(%w) just sent you a tell.$</pattern>
<value>#IF (%1!=%db( @afkstats, lastreply)) {
#SEND "reply @CHi, "%1"! Sorry, but Charneus is not here right now. Reason: @B<(@W=@Y"%db( @afkstats, afkmsg)"@W=@B)>@C. He's been gone for "@luatime(%time("yyyy,mm,dd,hh,nn,ss"), %db(@afkstats, afkstarttime))"."
#ADDKEY afkstats lastreply %1
}</value>
</trigger>
</class>
<class name="AFKVariables" copy="yes">
<var name="away" copy="yes">1</var>
<var name="afkstats" type="Record" copy="yes">lastreply|afkmsg=Gone for a bit.|afkstarttime=2009,01,25,19,49,40|away=0</var>
</class>
</class>
</cmud> |
The @luatime and onLoad are in different folders. The problem that I'm getting now is this:
| Code: |
| [string "code"](17) bad argument #2 to 'sub' (number expected, got nil). |
Not sure what is going on... I do:
#SAY @luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@afkstats, afkstarttime))
and it works perfectly. I can even put phrases around it and it works perfectly. However, in the script itself, it fails to work perfectly. Now, looking over something, I found that if I take out the quotes in %time("blahblahb") and enter it on the command line, it comes back as the same error. Looking at compiled code for the trigger, it's returning %time as literal.
| Code: |
0000 PUSHEXP 0016
0008 JUMP 0100
0016 PARAMREF 1
0024 VARREF @afkstats <afkstats> (class Aardwolf)
0052 STR 'lastreply'
0072 FUNCREF db (2)
0084 NEQ
0088 SETEXP 0 0
0100 PUSHLOC 0116
0108 JUMP 0544
0116 LITERAL "reply @CHi, "
0136 PARAMREF 1
0144 CONCAT
0148 LITERAL "! Sorry, but Charneus is not here right now. Reason: @B<(@W=@Y"
0220 CONCAT
0224 VARREF @afkstats <afkstats> (class Aardwolf)
0252 STR 'afkmsg'
0268 FUNCREF db (2)
0280 CONCAT
0284 LITERAL "@W=@B)>@C. He's been gone for "
0324 CONCAT
0328 LITERAL "yyyy,mm,dd,hh,nn,ss"
0356 FUNCREF time (1)
0368 VARREF @afkstats <afkstats> (class Aardwolf)
0396 STR 'afkstarttime'
0416 FUNCREF db (2)
0428 USERFUNC @luatime (2) <luatime> (class Aardwolf)
0456 CONCAT
0460 LITERAL "."
0472 CONCAT
0476 CMD send (1)
0488 STR 'afkstats'
0504 STR 'lastreply'
0524 PARAMREF 1
0532 CMD addkey (3)
0544 CMD if (2) |
Not sure if that's relevant or not, but it's the only thing I can think of...
Charneus |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Mon Jan 26, 2009 9:49 pm |
Now it's doing it on the command line, too... keeps saying the same thing. Not sure what is going on...
Charneus |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Thu Jan 29, 2009 5:06 pm |
No one has a clue/answer? Or did everyone just assume the whole thing was fixed? :P
Still looking for help. It'd be much appreciated. Nothing changed except for the fact it doesn't work now.
Charneus |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Thu Jan 29, 2009 6:58 pm |
Well, if this is what you're trying to do with this, then I'd make the entire thing from lua - you can store the time you left (as returned by os.time(), the format that the function expects) in a CMUD variable if you want it to be saved across sessions - that complicates things inasmuch as you'd need to use zs.var.somevar = os.time() rather than somevar = os.time(), but it's not too much hassle.
Since the time would already be in the right format that way, you don't need to do anything except pass off the time to the function. Your alias would look something like this:
| Code: |
if zs.params() and afk then
local timegone = timeDiff(os.time(),afk.start)
zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
afk=nil
zs.send("catchtells")
zs["t-"]("AFKTriggers")
else
afk = { msg = zs.params(), start = os.time() }
zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
zs["t+"]("AFKTriggers")
zs.send("catchtells")
end |
This script requires the original, unchanged timeDiff function from the first post. I've tested it and it works fine. If you want your afk status to be stored over sessions, just change all references to afk to zs.var.varofyourchoice. Hopefully this is enough to show you how to change the trigger to use the Lua table as well.
Finally, here is the exact alias I used to test this, 100% working:
| Code: |
<alias name="afk" language="Lua" id="1">
<value><![CDATA[if not timeDiff then
timeDiff = function(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end
end
if zs.params() and afk then
local timegone = timeDiff(os.time(),afk.start)
zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
afk=nil
zs.send("catchtells")
zs["t-"]("AFKTriggers")
else
afk = { msg = zs.params(), start = os.time() }
zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
zs["t+"]("AFKTriggers")
zs.send("catchtells")
end]]></value>
</alias> |
|
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Thu Jan 29, 2009 7:01 pm |
Oh, and one final thing - you might want to change the logic to include what to do if you type "afk" on its own while you're not afk already. At the moment it'll just put a nil value into afk.msg - you probably want to have some kind of "no message specified" message in that case. The logic tree then, I think, would be:
| Code: |
if zs.params() == "" and afk then
first part of existing code
else
local msg = zs.params() == "" and "no reason given" or zs.params()
afk = {msg = msg, start = os.time() }
rest of existing code
end |
|
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Thu Jan 29, 2009 7:12 pm |
Okay, now I'm confused. I can't tell if the first line should be if zs.params() and afk then or if not zs.params() and afk then - neither seems to work how I'd expect.
EDIT: Okay, I realised what it is - zs.params() doesn't return false if it's empty, it returns a null string, which isn't false in Lua. The first line should be if zs.params() == "" and afk then. Here is the corrected alias:
| Code: |
<alias name="afk" language="Lua" id="1">
<value><![CDATA[if not timeDiff then
timeDiff = function(t2,t1)
local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
for i,v in ipairs({'sec','min','hour','day','month','year'}) do
diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
carry = diff[v] < 0
if carry then diff[v] = diff[v] + colMax[i] end
end
return diff
end
end
if zs.params() == "" and afk then
local timegone = timeDiff(os.time(),afk.start)
zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
afk=nil
zs.send("catchtells")
zs["t-"]("AFKTriggers")
else
afk = { msg = zs.params(), start = os.time() }
zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
zs["t+"]("AFKTriggers")
zs.send("catchtells")
end]]></value>
</alias> |
|
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Fri Jan 30, 2009 2:22 am |
| Fang Xianfu wrote: |
Oh, and one final thing - you might want to change the logic to include what to do if you type "afk" on its own while you're not afk already. At the moment it'll just put a nil value into afk.msg - you probably want to have some kind of "no message specified" message in that case. The logic tree then, I think, would be:
| Code: |
if zs.params() == "" and afk then
first part of existing code
else
local msg = zs.params() == "" and "no reason given" or zs.params()
afk = {msg = msg, start = os.time() }
rest of existing code
end |
|
Awesome. Thanks for the fix on it. My question is, though, will the variables be saved if, for instance, CMUD shut down, or my computer crashed? Like I said, I'm still learning Lua, and don't know if CMUD stores it internally or if it's wiped away after the program closes. If not, then I'll have to go the zs.var route.
The reason I'm quoting this particular part of your posts is because it doesn't appear to be working. Either that, or I'm missing something. I have it set up like this now:
| Code: |
if zs.params() == "" and afk then
local timegone = timeDiff(os.time(),afk.start)
local result = timegone.year .. "y " .. timegone.month .. "m " .. timegone.day .. "d " .. timegone.hour .. "h " .. timegone.min .. "m " .. timegone.sec .. "s"
zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. string.gsub(result, "0. ?" , "" ,6) .. ".")
afk=nil
zs.send("catchtells")
zs["t-"]("AFKTriggers")
else
local msg = zs.params() == "" and "No reason given." or zs.params()
afk = {msg = msg, start = os.time() }
afk = { msg = zs.params(), start = os.time() }
zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
zs["t+"]("AFKTriggers")
zs.send("catchtells")
end |
which mimics the way you said to put it so it'd return 'No reason given' but it doesn't. It just returns:
Charneus is away. Reason: <(==)>.
Any idea on that? Oh, and as you may have noticed, I took Tech's return result and fixed it so that it returns only the populated values. Of course, I still want to do a return where it'll always show minutes and seconds, but only hours/days/months/years if populated. Guess I'll have to do several if/thens unless someone else has a better idea on it.
Charneus |
|
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Fri Jan 30, 2009 2:34 am |
As an addition:
I still need to work on the trigger aspect. Not exactly sure how I'm going to go about doing that, though. I suppose I can learn a bit about Lua. It's probably simple enough anyway. I think the trigger itself is why I wanted it to be a function this entire time, too. That way, I don't have to have globs of the same code in every section that utilizes the time difference.
Charneus |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Jan 30, 2009 3:23 am |
You've duplicated the line that defines the afk table - remove the second line trying to do that (line 11) and it should work properly.
Incidentally, I hope that you get that the "x and y or z" syntax is sort of like the %if function - it's an inline if command. If x is true it returns y, else z. You can read about why that's the case in programming in lua, or just accept that it is :P |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Jan 30, 2009 3:57 am |
And okay, for the trigger, hmm. You're probably going to want to add some code to the timeDiff function like I used in my first post in this thread to make the output from timeDiff a bit prettier. That way you don't have to muck about with all the formatting gubbins in your trigger.
However, it's essentially copying the zs.send("gt... blahblah") line from the alias with some different text around it. afk.msg has the afk reason. You can use something like afk.lastreply to store the name of the person who spoke to you - you might find it worthwhile to store the time they last replied to you and - making handy use of your nice new timeDiff function :P - reply anyway if they last spoke to you a long time ago.
You may want to keep timeDiff as it is and make a new timePretty function that'll take a time table like timeDiff (and also os.date) returns and return a nice string as a result. That way you can use timeDiff for situations where you're not displaying the time, and timePretty for the times when you do. It'd be a good place to keep your code for removing empty ones, too. Something like:
| Code: |
function timePretty (timetable)
local finalstring
for k,v in timetable do
if v>0 then finalstring = finalstring .. v .. k .. " "
end
return finalstring or "unknown" |
Not tested, but that's what I mean - just a function that'll take the table and make it look nice. Then you can use timePretty in your alias and trigger, and timeDiff itself in actual comparisons of the time.
So yeah, you'll end up just needing something like
| Code: |
if afk.lastreply ~= zs.param(1) then
zs.send("reply I'm away right know. Reason: " .. afk.msg .. " Away for: " .. timePretty(timeDiff(afk.start,os.time())))
afk.lastreply = zs.param(1)
end |
The more complex one I was thinking about would look like:
| Code: |
if (afk.lastreply ~= zs.param(1)) or (os.time()-afk.lastreplytime > 600) then
zs.send("reply I'm away right know. Reason: " .. afk.msg .. " Away for: " .. timePretty(timeDiff(afk.start,os.time())))
afk.lastreply = zs.param(1)
afk.lastreplytime = os.time()
end |
|
|
|
|
 |
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Fri Jan 30, 2009 6:00 am |
| charneus wrote: |
| will the variables be saved if, for instance, CMUD shut down, or my computer crashed? |
No, they will not. |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Jan 30, 2009 1:10 pm |
Arde is correct in this case, but I don't think it matters - because you'll need to restart CMUD manually, and for you to do that, you need to not be AFK any more.
|
|
|
|
 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|