Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » zMUD General Discussion
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Thu Mar 07, 2002 4:37 am   

Scripting
 
I resently created the following script for a client called Mushclient and someone who had zmud asked me if they could use it. Not knowing how zmud did things I never the less assumed that the only major problem would be replacing client specific code. After all it makes sense to use 'existing' scripting languages than making someone learn a new one. Boy was I wrong....

So here is the question. How do I do the following in zmud.. (The code is in vbscript)



sub SetReb (TrigName, Output, Wildcards)
dim a, sTest, sMatch, sGrab, sOut
int b
int tim
tim = 0
sTest = Wildcards(2)
sMatch = "(in"
b = InStr(1, sTest, sMatch, 1)
sGrab = right(sTest, len(sTest) - (b+2))
sMatch = "d"
b = InStr(1, sGrab, sMatch, 1)
if b > 0 then
tim = 1440
sGrab = right(sGrab, len(sGrab) - (b+1))
end if
sMatch = "h"
b = InStr(1, sGrab, sMatch, 1)
if b > 0 then
tim = tim + CInt(left(sGrab, b-1)) * 60
sGrab = right(sGrab, len(sGrab) - (b+1))
end if
sMatch = "m"
b = InStr(1, sGrab, sMatch, 1)
if b > 0 then
tim = tim + CInt(left(sGrab, b-1))
sGrab = right(sGrab, len(sGrab) - (b+1))
end if
sMatch = "s"
b = InStr(1, sGrab, SMatch, 1)
if b > 0 then
b = Cint(left(sGrab, b-1))
if b > 30 then
tim = tim + 1
end if
end if
world.setvariable "TTRB", CStr(tim)
world.addtimer "RebootTimer", 0, 1, 0, "", 1, "RepReboot"
world.enabletimer "RebootTimer", 1
sOut = Rttt(tim)
world.setstatus "Reboot is in " & sOut
end sub




sub RepReboot (TimerName)
dim sRet, sOut, sTest
int tim
sRet = world.getvariable ("TTRB")
tim = CInt(sRet)
tim = tim - 1
sOut = Rttt(tim)
world.setstatus "Reboot is in " & sOut
world.setvariable "TTRB", CStr(tim)
if tim < 1 then
world.enabletimer "RebootTimer", 0
end if
end sub




function Rttt(tim)
dim sRet, sOut
int temp
int temp2
temp = tim
if temp > 1440 then
sOut = " 1d "
temp = temp - 1440
end if
if temp > 60 then
temp2 = Int(temp/60)
temp = temp - (temp2 * 60)
sOut = sOut & CStr(temp2) & "h "
end if
sOut = sOut & temp & "m."
Rttt = sOut
end function




Trigger used to activate everything.
Trigger on: *The next reboot is *
Send: <nothing>
Call script: SetReb




Mushclient commands>
world.setvariable - Sets a persistant variable in the client.
world.addtimer - Creates a timer with the following settings:
str Name, int Hours, int Minutes, int Seconds, str Output, int flags, str script
world.enabletimer - Enables or disables a timer with True(1) = on
world.setstatus - Sets the texts stored in the clients status line.
world.getvariable - Retrieve the contents of a persistance variable.


-----------------------------------


if schrodinger_cat is alive {
call functional_code
else
call crash_windows
}
Reply with quote
iljhar
GURU


Joined: 10 Oct 2000
Posts: 1116
Location: USA

PostPosted: Thu Mar 07, 2002 5:22 am   
 
Can you please give us an example of the output you receive from the mud? You'll have to give us a breakdwon of the VBScript. For instance, what does sTest = Wildcards(2) do? I can see that you're passing a string to SetReb(), the string looks something like blah blah (in 1d 3h 2m 40s), but it doesn't always have to have the day, hour, minute or second. So you take the info and it looks like you break that down into minutes. Then you set a global variable to that time and report it. Am I fairly close or way off? We can do this with alarms, no problem, just have to get a bit more info.

Iljhar
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Thu Mar 07, 2002 6:56 am   
 
Hmm. Ok... Figured people would know basic. ;) lol

Triggers pass 3 parameters when they go off, the name of the trigger (TrigName), the stuff that it sends to the mud (Output) and an array of all wildcards it grabbed (Wildcards).

In this case the wild cards would be:

Wildcard (1) = empty or a single space (do to a bug with the mud prompts).

Wildcard (2) = anything not part of the text used to match the trigger.

In this case the text from the mud is something like:

The next reboot is scheduled for 06:03 CET (GMT+1) on Friday (in 22h 13m 45s).

Since it is usually possible to match on part of a line the '*The next reboot is *' will grab it, though it is not exactly spoof proof. ;)

The first subroutine looks for '(in' and cuts off all the non-critical stuff. It then proceeds to search for 'd', 'h', 'm' and 's', retrieves the values for each and multiplies them as needed to get total number of minutes. It also checks the second and adds one minute if over 30 seconds are shown. This same sub creates the timer if it does not already exist and enables it (in case it did exist but was turned off). It then store the result of its calculations in a persistant variable called TTRB, calls the function to figure out what to display and sets the status line info to show 'Reboot is in <whatever>'.

The timer is set to go off every minute and calls the second sub 'RepReboot'. Since it is a timer calling it the only input is the name of the timer that called it (TimerName). This sub retrieves the value in TTRB, then decresses it by one. It then calls the function again to get the correct output and sets the status line to the new information.

And yes, the information in the trigger text can have the days, hours, minutes and second, just the hours and second, just the hours or any other combination, so you can't assume it will contain any of them til you check.

You pretty much got it 100% right even without my explaination. ;)

------------------------------


if schrodinger_cat is alive {
call functional_code
else
call crash_windows
}
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Thu Mar 07, 2002 7:05 am   
 
Hmm. It also looks like this forum works better with Infernal Exploder, which I unfortunately despise and use only under threat of bodily injury. ;) I can deal with the odd menu behavior, but the text around the message text box is a nearly black blue on a completely black background. :p

Only thing I can read it the underlined Forum Code when using Opera. lol

------------------------------


if schrodinger_cat is alive {
call functional_code
else
call crash_windows
}
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Sun Mar 10, 2002 12:37 am   
 
Ok. Having gotten no response for several days I decided to take a crack at this myself. :p

The following is what I need to have happen at login to the mud:

#MATH days 0
#MATH hours 0
#MATH minutes 0
#TRIG {The next reboot is * ~(in (&days)d (&hours)h (&minutes)m *} {}
#ST {The mud will reboot in (@days)d (&hours)h (&minutes)m.}

EX of the trigger line:

The next reboot is scheduled for 08:03 CET (GMT+1) on Sunday (in 7h 18m 26s).

The problem is as you can see, the d, h and m are not always there to match, so I need some way to make them optional.

Now second problem has to do with executing multiple commands in an alarm. The following is roughly what I need (assuming they can be simply nested in the command), but...



#ALARM 1:00 {
#MATH minutes @minute - 1
#IF (minutes < 0) {#MATH hours @hours - 1
#MATH minutes 59}
#IF (hours < 0) {#MATH days @days - 1
#MATH hours 23}
#IF (days < 0) {#MATH days 0}
#ST {The mud will reboot in (@days)d (&hours)h (&minutes)m.}
}


However I some how doubt this will work the way I have it.

------------------------------


main {
if schrodinger_cat is alive
call functional_code()
else
call crash_windows();
}
Reply with quote
TaisharMalkier
Novice


Joined: 28 Sep 2001
Posts: 45
Location: USA

PostPosted: Mon Mar 11, 2002 3:47 pm   
 
Ok, here is a brute force way of doing what i think you want to do...

Make up a separate trigger for all of the possible combinations of *d *h *m *s based on this line....
The next reboot is scheduled for 06:03 CET (GMT+1) on Friday (in 22h 13m 45s).
#TR {The next reboot is scheduled for * in (&days)d (&hours)h (&mins)m (&secs)s).} {}
#TR {The next reboot is scheduled for * in (&days)d (&hours)h (&mins)m).} {#VAR secs 0}
#TR {The next reboot is scheduled for * in (&days)d (&hours)h (&secs)s).} {#VAR mins 0}
#TR {The next reboot is scheduled for * in (&days)d (&hours)h).} {#VAR mins 0;#VAR secs 0}
#TR {The next reboot is scheduled for * in (&days)d (&mins)m (&secs)s).} {#VAR hours 0}
#TR {The next reboot is scheduled for * in (&days)d (&mins)m).} {#VAR hours 0;#VAR secs 0}
#TR {The next reboot is scheduled for * in (&days)d (&secs)s).} {#VAR hours 0;#VAR mins 0}
#TR {The next reboot is scheduled for * in (&hours)h (&mins)m (&secs)s).} {#VAR days 0}
#TR {The next reboot is scheduled for * in (&hours)h (&mins)m).} {#VAR days 0;#VAR secs 0}
#TR {The next reboot is scheduled for * in (&hours)h (&secs)s).} {#VAR days 0;#VAR mins 0}
#TR {The next reboot is scheduled for * in (&mins)m (&secs)s).} {#VAR days 0;#VAR hours 0}
#TR {The next reboot is scheduled for * in (&mins)).} {#VAR days 0;#VAR hours 0;#VAR secs 0}
#TR {The next reboot is scheduled for * in (&secs)s).} {#VAR days 0;#VAR hours 0;#VAR mins 0}

Contain rather than hurt.
Hurt rather than maim.
Maim rather than kill.
Kill rather than be killed.
Reply with quote
Troubadour
GURU


Joined: 14 Oct 2000
Posts: 556
Location: USA

PostPosted: Mon Mar 11, 2002 6:32 pm   
 
A less brutish method would be:


#TR {The next reboot is scheduled for %d:%d CET ~(GMT+1~) on %w ~(in (*)~).} {
#VAR days 0
#VAR hours 0
#VAR minutes 0
#LOOP %numwords(%1) {
#CASE %ismember(%rightback(%word(%1,%i),1),{d|h|m|s})
{#VAR days %leftback(%word(%1,%i), 1)}
{#VAR hours %leftback(%word(%1,%i), 1)}
{#VAR minutes %leftback(%word(%1,%i), 1)}
{#NOOP cause we don't care about seconds}
}
}

The status trigger is independent of any other triggers and alarms. Note the use of the tilde to separate the label from the variable.


#ST {The mud will reboot in @days~d @hours~h @minutes~m~.}


So your alarm would now be:


#ALARM 1:00 {
#ADD minutes -1
#IF (@minutes < 0) {#ADD hours -1; #VAR minutes 59}
#IF (@hours < 0) {#MATH days %max(0, @days - 1); #VAR hours 23}
}


Troubadour
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Mon Mar 11, 2002 10:34 pm   
 
I like your solution Troubadour. Unfortunately since I wanted to make is work in both the newer and old free version of zmud it won't work. V3.62 didn't support %ismember. :p

The irony is that I also have been working on the problem myself and just got through tracking down the last few glitches a few minutes before logging on.

Do to limits in 3.62 and the lack of %ismember I ended up with the following:

#TR {The next reboot is scheduled for * on * ~(in (*) ~).}
{#VA temp "%1";
#VA temp1 "";
#VA temp2 "";
#VA temp3 "";
#VA temp1 %word(@temp, 1);
#VA temp2 %word(@temp, 2);
#VA temp3 %word(@temp, 3);
#REA SetReb.txt}

Why read a file? Because 3.62 liked to page fault and eat anything longer than the above. :p

(SetReb.txt)
#VA Dy 0
#VA Hr 0
#VA Min 0
#MATH Tln1 %len(@temp1) - 1
#VA Fpos %pos(d,@temp1)
#VA temp4 %left(@temp1,@Tln1)
#IF (Fpos >0) {#VA Dy @temp4}
#VA Fpos %pos(h,@temp1)
#IF (Fpos >0) {#VA Hr @temp4}
#VA Fpos %pos(m,@temp1)
#IF (Fpos >0) {#VA Min @temp4}
#MATH Tln2 %len(@temp2) - 1
#VA Fpos %pos(d,@temp2)
#VA temp4 %left(@temp2,@Tln2)
#IF (Fpos >0) {#VA Dy @temp4}
#VA Fpos %pos(h,@temp2)
#IF (Fpos >0) {#VA Hr @temp4}
#VA Fpos %pos(m,@temp2)
#IF (Fpos >0) {#VA Min @temp4}
#MATH Tln3 %len(@temp3) - 1
#VA Fpos %pos(d,@temp3)
#VA temp4 %left(@temp3,@Tln3)
#IF (Fpos >0) {#VA Dy @temp4}
#VA Fpos %pos(h,@temp3)
#IF (Fpos >0) {#VA Hr @temp4}
#VA Fpos %pos(m,@temp3)
#IF (Fpos >0) {#VA Min @temp4}
#ST The mud will reboot in @{Dy}d @{Hr}h @{Min}m.

#ALARM 1:00 {#MATH Min @Min - 1;
#IF (@Min < 0) {#MATH Hr @Hr - 1};
#IF (@Min < 0) {#VA Min 59};
#IF (@Hr < 0) {#MATH Dy @Dy - 1};
#IF (@Hr < 0) {#VA Hr 23};
#ST The mud will reboot in @{Dy}d @{Hr}h @{Min}m.}

It works, even if 3.62 forces it to be uglier than necessary, like the extra #IFs above to do more than one thing. lol

Thanks for the help anyway and I will definitely add your version to the post I plan to make on my mud, for those who don't need to use the really ugly version. ;)

------------------------------


main {
if schrodinger_cat is alive
call functional_code()
else
call crash_windows();
}
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Wed Mar 13, 2002 12:24 am   
 
Sigh... Ok. I have given up on compatibility with the free version of zmud. lol

However I had to make the following changes to your script to get it to work in 6.16:



#TR {The next reboot is scheduled for %d:%d CET ~(GMT+1~) on %w ~(in (*)~).} {
#VAR days 0
#VAR hours 0
#VAR minutes 0
#LOOP %numwords(%1) {
#VAR temp %rightback(%word(%1,%i),1)
#VAR temp2 %leftback (%word(%1,%i),1)
#CASE %ismember(@temp,{d|h|m|s}) {#VAR days @temp2} {#VAR hours @temp2} {#VAR minutes @temp2} {#NOO}
}
}


Since I got syntax errors with the way you had it, both when all on the same line as #CASE and when on seperate line.

It now works as expected, however....

The alarm does not seem to do anything. :p

It does not appear to ever trigger, or if it does I see no results. I have tried explicitly setting it to *:01:00, to -1:00, etc. Even tried entering it in the command windows on a single line. (Though this oddly produces 1:00:00 in contradiction to the help file description.) and in each case an alarm is created with the oppropriate script, but it never executes, no matter how much time expires. :p

------------------------------


main {
if schrodinger_cat is alive
call functional_code()
else
call crash_windows();
}
Reply with quote
Shadowfyr
Newbie


Joined: 07 Mar 2002
Posts: 7
Location: USA

PostPosted: Wed Mar 13, 2002 6:56 am   
 
Ok. My last post on here for now.. Seems the alarm, contrary to the documentation, does not operate correctly using 'any' combo of 1:00 *:01:00, etc. It does trigger on minutes, but 'only' if you use 1 by itself. Since this is all I wanted it is not a big deal, but I can't figure out why it won't work as described for me. But I don't feel like persueing it, having fixed the main problem I had. ;)

Thanks for the help. ;)

------------------------------


main {
if schrodinger_cat is alive
call functional_code()
else
call crash_windows();
}
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » zMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
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

© 2009 Zugg Software. Hosted by Wolfpaw.net