Shoutbox

Question about "MyStatus" - Printable Version

-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: Question about "MyStatus" (/showthread.php?tid=93566)

Question about "MyStatus" by 5n4k3 on 01-17-2010 at 06:01 PM

I wrote this rather pointless script (just practicing) and it works, but there's something I wanted to ask if you could change.

Here's the Script:
function OnEvent_ChatWndCreated(ChatWnd)
{
    var Message = "Your current status is " + Messenger.MyStatus + "!";
    Message = MsgPlus.RemoveFormatCodes(Message);
    MsgPlus.DisplayToast("", Message)
}

I was wondering if you could make it say in the message your actual status (i.e. "busy" | "online" | "away" | etc) instead of using the numbers associated with each status.

EDIT: I'm also failing to write a script that changes my status to busy every time I send a message if I'm not already set as busy.  So far I came up with this...:
function OnEvent_ChatWndSendMessage(ChatWnd, Message)
{
    if(MyStatus == (7))
    {
    var Message = "/busy";
    Message = MsgPlus.RemoveFormatCodes(Message);
    Messenger.ChatWnd.SendMessage
    }
}
^ guessed a lot

Thanks

~ 5n4k3


RE: Question about "MyStatus" by stoshrocket on 01-17-2010 at 06:29 PM

quote:
Originally posted by 5n4k3
I wrote this rather pointless script (just practicing) and it works, but there's something I wanted to ask if you could change.

Here's the Script:
function OnEvent_ChatWndCreated(ChatWnd)
{
    var Message = "Your current status is " + Messenger.MyStatus + "!";
    Message = MsgPlus.RemoveFormatCodes(Message);
    MsgPlus.DisplayToast("", Message)
}

I was wondering if you could make it say in the message your actual status (i.e. "busy" | "online" | "away" | etc) instead of using the numbers associated with each status.
Use a loop and a couple of arrays to replace the number?

Javascript code:
function OnEvent_ChatWndCreated(ChatWnd)
{
    var Message = "Your current status is " + Messenger.MyStatus + "!";
    var number = new Array("2","3","4","5"....);
    var status = new Array("Appear Offline","Online","Busy","Be Right Back"....);
    for(var i = 0; i<number.length; i++){
        Message = Message.replace(number[i],status[i]);
    }
    Message = MsgPlus.RemoveFormatCodes(Message);
    MsgPlus.DisplayToast("", Message)
}


EDIT: Sorry, had a few errors, should work fine now... As for the second question, I'll answer shortly...
RE: Question about "MyStatus" by 5n4k3 on 01-17-2010 at 07:24 PM

Thanks for that, btw is there a place where I can learn about "arrays", etc?


RE: Question about "MyStatus" by Matti on 01-17-2010 at 07:56 PM

quote:
Originally posted by stoshrocket
Use a loop and a couple of arrays to replace the number?
Don't do this. There is absolutely no need for a loop to simply show the name of the current status, you can perfectly achieve this with an object literal indexed by the status number. Using arrays for this is totally unnecessary since we only need the ability to look up a certain property value (the name) by its identifier (the number).
Javascript code:
// On the top of your script, outside any function definition
var oStatusNames = {
    0:  "unknown",
    2:  "appearing offline",
    3:  "online",
    4:  "busy",
    5:  "be right back",
    6:  "idle",
    7:  "away",
    8:  "in a call",
    9:  "out to lunch"
};
 
// The fixed event handler for chat window created
function OnEvent_ChatWndCreated( ChatWnd )
{
    // Find the name of the current status in our object   
    var status = oStatusNames[ Messenger.MyStatus ];
    // Make a nice message
    var message = "Your current status is " + status + "!";
    // Display a toast
    MsgPlus.DisplayToast( "Your current status", message );
}

As you can see, there's no need for looping through one array and replace all numbers by their status names: you perfectly know what status number you're looking for as you're building the message yourself! There's also no real necessity for calling MsgPlus.RemoveFormatCodes() when you don't add any format codes in the message. Of course, when the message could have been set by the user through some kind of script preference, you're better off removing the format codes, but in this simple example I chose not to.



As for setting your status, you can simply set Messenger.MyStatus yourself, it's not read-only:
Javascript code:
function OnEvent_ChatWndSendMessage( ChatWnd, Message )
{
    // See if I'm not busy yet
    if( Messenger.MyStatus !== 4 ) {
        // Set to busy
        Messenger.MyStatus = 4;
    }
    // Return the unmodified message
    // Never forget to return something for ChatWndSendMessage!
    return Message;
}



quote:
Originally posted by 5n4k3
Thanks for that, btw is there a place where I can learn about "arrays", etc?
I highly recommend learning some JScript/JavaScript if you want to write Plus! scripts. There are many places to learn this, but perhaps the W3Schools tutorials are best suited for newcomers. Just beware that you're not programming in a website environment, so anything related to the place of your script in the HTML or the Document Object Model is not available in a Plus! script. Other than that, the syntax of JavaScript is as good as identical to JavaScript's syntax, therefore it's a very good starting point. :)

Arrays may not be ideal for this example (see above), but they're very interesting to work with. Basically, an array is a numbered list of stuff in which you can add, read, change and remove elements. Have a look at the W3Schools topics on arrays, that'll probably help you understand. ;)
RE: Question about "MyStatus" by stoshrocket on 01-17-2010 at 08:10 PM

Much better solution Matti, thanks :P


RE: Question about "MyStatus" by 5n4k3 on 01-17-2010 at 08:24 PM

Ah thanks guys. Lots to learn... gonna be interesting.

Hmm... I was just thinking... if both ways work why is Matti's way better?


RE: Question about "MyStatus" by CookieRevised on 01-17-2010 at 10:26 PM

Because it does not use a very slow, and completely unneeded, loop. Nor does it need two arrays being stored in memory.

Image what would happen if there are 10000 elements you need to index. Your script would run so slow you would think it has been froozen/crashed.

stoshrocket's script did this:

code:
1) Make a list of names:
    number 1 is BlahBlah
    number 2 is BooBoo
    number 3 is HeyHey

2) Make a list of numbers/indexes
    number 1 is 1
    number 2 is 2
    number 3 is 3

3) Change the list of numbers into a list of names
    Check if the index is still within the bounds of the number list
    if so, lookup name 1 and store it in memory
    Replace index 1 with the value stored in memory
    increase the index by one
    Check if the index is still within the bounds of the number list
    if so, lookup name 2 and store it in memory
    Replace index 2 with the value stored in memory
    increase the index by one
    Check if the index is still within the bounds of the number list
    if so, lookup name 3 and store it in memory
    Replace index 3 with the value stored in memory
    increase the index by one
    Check if the index is still within the bounds of the number list
    if so, ...., if not end the loop

4) Look up the current status

5) Get the correct name in the list of numbers.
So, even if you used an array, you can see that there is really no need for two arrays. The array in step 2 is completely useless because you already have all the names in order in the first array. Making the loop also useless. The second array is simply a list of its own indexes (an index is the number which defines an element of the array).

Matti's script does this:
code:
1) Make a list of status names, indexed and sorted by their literal numeric value: blahblah, BooBoo, HeyHey
2) Look up the current status
3) Get the correct status name in the list of statusses
Matti simply uses Messenger.MyStatus to get the proper element directly from the list.

This is possible since the numeric values of Messenger.MyStatus are known and always the same.

eg: Messenger.MyStatus will always return the number 2 when you are appearing offline. So simply grab the third (counting starts at 0) element out of the predefined string list.



It's like:

You have a piece of paper showing a number  (= Messenger.MyStatus) which tells you behind what curtain your prize (= your status strings like "offline", "online", etc) is.

stoshrocket's method:

First, construct a bunch of curtains and put some prizes behind it.

Second, construct a bunch of new doors and put a new piece of paper behind it like so:
Door 1, instructon on the new piece of paper: open curtain 1
Door 2, instructon on the new piece of paper: open curtain 2
Door 3, instructon on the new piece of paper: open curtain 3
etc..
this is the loop

Next, open the door with the number listed on your original piece of paper.
Then, open the curtain instructed on that new piece of paper you've found behind the door you've opened....

But did you notice how all those doors have the exact same number as the number in the instructions of those new pieces of paper behind each door?

Thus Matti's method:

First, construct a bunch of curtains and put some prizes behind it.
Second, directly open the curtain with the number that is on your original piece of paper....


^^ sorry for the long post, I was bored
:p
RE: Question about "MyStatus" by 5n4k3 on 01-19-2010 at 08:19 AM

I came across another problem with the script:

Javascript code:
function OnEvent_ChatWndSendMessage( ChatWnd, Message )
{
    // See if I'm not busy yet
    if( Messenger.MyStatus !== 4 ) {
        // Set to busy
        Messenger.MyStatus = 4;
    }
    // Return the unmodified message
    // Never forget to return something for ChatWndSendMessage!
    return Message;
}


When my auto-message responds it changes my status to busy. How do I fix that?

EDIT: Spent some time on it and I'm thinking I should use something like

Javascript code:
{
if(Message == "<insert my auto-message>"
Messenger.MyStatus = 7;
}


But it doesn't work.

~ 5n4k3
RE: Question about "MyStatus" by stoshrocket on 01-19-2010 at 02:55 PM

quote:
Originally posted by 5n4k3
I came across another problem with the script:

Javascript code:
function OnEvent_ChatWndSendMessage( ChatWnd, Message )
{
    // See if I'm not busy yet
    if( Messenger.MyStatus !== 4 ) {
        // Set to busy
        Messenger.MyStatus = 4;
    }
    // Return the unmodified message
    // Never forget to return something for ChatWndSendMessage!
    return Message;
}


When my auto-message responds it changes my status to busy. How do I fix that?

EDIT: Spent some time on it and I'm thinking I should use something like

Javascript code:
{
if(Message == "<insert my auto-message>"
Messenger.MyStatus = 7;
}


But it doesn't work.

~ 5n4k3
When the auto message is sent, messenger appears to see it as it being sent in the format "AutoMessage: <automessage>" (test it yourself by creating a toast to popup with every message you send, when "you" send an automessage, it comes up in this format). Therefore, a possible solution would be to check if the message sent starts with "AutoMessage: " ...

Javascript code:
function OnEvent_ChatWndSendMessage( ChatWnd, Message )
{
    //search message for "AutoMessage :"
    var automsg = Message.search("AutoMessage :");
    if(automsg == -1){
        // See if I'm not busy yet
        if( Messenger.MyStatus !== 4 ) {
            // Set to busy
            Messenger.MyStatus = 4;
        }
    }
    // Return the unmodified message
    // Never forget to return something for ChatWndSendMessage!
    return Message;
}


Note: this would just check if your message has "AutoMessage :" in, so if you typed a message with this in it obviously would pick it up, so a better solution might be to check the position?

Still, it's not the most elegant of solutions... As Matti proved earlier there's more than one way to solve a problem.
RE: Question about "MyStatus" by matty on 01-19-2010 at 03:29 PM

quote:
Originally posted by Matti
Javascript code:
// On the top of your script, outside any function definition
var oStatusNames = {
    0:  "unknown",
    2:  "appearing offline",
    3:  "online",
    4:  "busy",
    5:  "be right back",
    6:  "idle",
    7:  "away",
    8:  "in a call",
    9:  "out to lunch"
};



:dodgy:...
I prefer to use the enumeration for status
Javascript code:
// On the top of your script, outside any function definition
var oStatusNames = {
    STATUS_UNKNOWN: 'unknown',
    STATUS_INVISIBLE:   'appearing offline',
    STATUS_ONLINE:  'online',
    STATUS_BUSY:        'busy',
    STATUS_BRB:     'be right back',
    STATUS_IDLE:        'idle',
    STATUS_AWAY:        'away',
    STATUS_INCALL:  'in a call',
    STATUS_OUTLUNCH:    'out to lunch'
};


RE: Question about "MyStatus" by Matti on 01-19-2010 at 04:55 PM

quote:
Originally posted by matty
:dodgy:...
I prefer to use the enumeration for status
Of course, but that would break backwards compatibility. And it'll save you a few bytes.


...

Okay perhaps it's not so much of a big deal. Choose whatever you think is best. :P
RE: Question about "MyStatus" by 5n4k3 on 01-19-2010 at 05:20 PM

Mmm... so is stoshrocket's solution to my auto-message problem the best way?

And if so what's the line:

Javascript code:
if(automsg == -1)



do?

~ 5n4k3
RE: Question about "MyStatus" by stoshrocket on 01-19-2010 at 07:52 PM

quote:
Originally posted by 5n4k3

And if so what's the line:
Javascript code:
if(automsg == -1)


do?
The variable automsg is the return value for "Message.search("AutoMessage :")".

search() returns the position what is searched for, or -1 if it can't be found.

Therefore, that line checks if "AutoMessage :" is in the message sent, if it is then it's (probably) an automessage and won't change your status. Of course, this will trip up if your message sent contains the string "AutoMessage :".
RE: Question about "MyStatus" by CookieRevised on 01-19-2010 at 08:35 PM

shorter and slithly faster:

Javascript code:
function OnEvent_ChatWndSendMessage( ChatWnd, Message )
{
    // Check if it is not an automessage and if we're not busy yet
    if (!/^AutoMessage :/.test(Message) && Messenger.MyStatus !== 4 ) {
        // Set to busy
        Messenger.MyStatus = 4;
    }
    // Return the unmodified message
    // Never forget to return something for ChatWndSendMessage!
    return Message;
}


! means NOT (The boolean True becomes False, and False becomes True)
/blahblah/ is a special syntax used for regular expressions
^  at the beginning of a regular expression means start comparing it from the beginning (aka: don't do a (slower) search).
test(blahblah) is a method of the regular expression object which test the occurance of the regular expression (in the above case '^AutoMessage :') in the string (in the above case the Message variable)
&& performs a logical conjunction (=AND) on two expressions (both expressions must be True for the result to be True)

If Message begins with the string 'AutoMessage :' then /^AutoMessage :/.test(Message) will return True. Otherwise it will return False. Hence the use of ! (=NOT) to change the result of the test to the opposite...

RE: Question about "MyStatus" by roflmao456 on 01-19-2010 at 10:58 PM

there is no space before the colon - only after.

it should be searching for "AutoMessage: "
:P

your full script:

JScript code:
var szStatus = {
    2 : "appear offline",
    3 : "online",
    4 : "busy",
    7 : "away",
    6 : "idle",
   
    // maybe it can happen
    0 : "unknown",
   
    // WLM 8.5
    5 : "brb",
    8 : "in a call",
    9 : "out to lunch"
    };
 
function OnEvent_ChatWndCreated(ChatWnd){
    MsgPlus.DisplayToast("", "Your Messenger Status: " + szStatus[Messenger.MyStatus]);
    }
 
function OnEvent_ChatWndSendMessage(ChatWnd, Message){
    if(Messenger.MyStatus !== STATUS_BUSY && !/^AutoMessage: /.test(Message))
        Messenger.MyStatus = STATUS_BUSY;
    }


@cookiematty: that enumeration for status code you posted returns undefined if like variable[MyStatus]. using it like variable.STATUS_ONLINE will work, however.
RE: Question about "MyStatus" by CookieRevised on 01-19-2010 at 11:39 PM

quote:
Originally posted by roflmao456
@cookie: that enumeration for status code you posted returns undefined if like variable[MyStatus]. using it like variable.STATUS_ONLINE will work, however.
blame matty, he posted it, not me ;)
RE: Question about "MyStatus" by roflmao456 on 01-20-2010 at 02:47 AM

quote:
Originally posted by CookieRevised
quote:
Originally posted by roflmao456
@cookie: that enumeration for status code you posted returns undefined if like variable[MyStatus]. using it like variable.STATUS_ONLINE will work, however.
blame matty, he posted it, not me ;)

[Image: facepalm.jpg]
perhaps i should start looking at names rather than "OFFICIAL TESTER" :P
RE: Question about "MyStatus" by 5n4k3 on 01-20-2010 at 11:20 AM

Thanks guys, it works great.

~ 5n4k3


RE: Question about "MyStatus" by Matti on 01-20-2010 at 12:27 PM

quote:
Originally posted by CookieRevised
quote:
Originally posted by roflmao456
@cookie: that enumeration for status code you posted returns undefined if like variable[MyStatus]. using it like variable.STATUS_ONLINE will work, however.
blame matty, he posted it, not me ;)

Ah yes, you can't use the value of a variable or expression as identifier for a property when you're defining an object literal. "STATUS_ONLINE" is interpreted as a string identifier for the property, it does not take the value of STATUS_ONLINE to use as identifier.

Here are some example snippets, for those interested in what went wrong here:
Javascript code:
var key = "123";
var obj = {
    key : "abc"
};
// obj.key or obj["key"] equals "abc"
// obj[key] is undefined
 
var obj = {
    "key" : "abc"
};
// same object as above
 
var i = 0;
var obj = {
    (i++) : "first",
    (i++) : "second"
};
// gives a syntax error
// property identifier must be a constant number or string
 
var i = 0;
var obj = {};
obj[i++] = "first";
obj[i++] = "second";
// this will work though, the square brackets can take both constant or variable values