Shoutbox

[Release] Exit WLM - 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: [Release] Exit WLM (/showthread.php?tid=68391)

[Release] Exit WLM by Spunky on 11-13-2006 at 03:07 AM

Haven't really worked on this too much, but I found it useful (both for a practical use and for teaching myself some new practices).

You basically just type /exitwlm <seconds> and it will signout at that time.
There is a warning at 5 seconds which also allows the user to cancel the countdown. I set a limit of at least 10 seconds as there is no point in having it any sooner than that.

If no-one finds it useful, new scripters can still learn things from it...


RE: [Release] Exit WLM by NanaFreak on 11-13-2006 at 03:12 AM

that is cool Spunky.... i havent used yet but i am going to look at the code to see how you did it :P

nice

edit: i thought that it closed and exited WLM not sign out... you can do this by typing /signout :P


RE: [Release] Exit WLM by MicroWay on 11-13-2006 at 03:16 AM

For my "very powerfull" skils on coding, I'll use your Script for learning purpose :P
Thanks
;)


RE: [Release] Exit WLM by markee on 11-13-2006 at 03:19 AM

I was hoping this was actually going to exit out of messenger completely :sad:

Anyway, it looks quite good, I think with a little bit of adjustment the script should also be able to sign someone out of WLM at a particular time of the day as like a reminder to go to bed or something like that.  Also it could be useful for parents or bosses to stop people from using WLM all day if they wished, especially if a kind of cool down ferature was in place to stop someone signing back in for a set period of time after the script has signed you out, or possibly between set periods of time.  And if you really wanted to expand on it further you could also make the time periods user dependant too.

Anyway good job on the script, I hope you like my ideas to help you develop the script further.

EDIT:

quote:
Originally posted by NanaFreak
edit: i thought that it closed and exited WLM not sign out... you can do this by typing /signout
You might be able to do that but this script has a timer in it so you can set it to sign you out in like 30sec or something.
RE: [Release] Exit WLM by Spunky on 11-13-2006 at 03:21 AM

I had some of those ideas myself, but didn't know if the idea was going to be "popular" lol. I might develop it then to have more features such as parental controls etc ;)

EDIT: As for exiting WLM completely, I think it's possible if I can find a way to close processes (or include an exe that can do it and open it from the script)


RE: [Release] Exit WLM by matty on 11-13-2006 at 03:51 AM

Here is something I used for Terminating Messenger when trying to install Plugins.

code:
/*

Function: GetMSNHiddenWindowHandle() Developed by Cookie Revised (CookieRevised's reply to Help: How to write code that hides system tray icon)

Function: ExitWindowsLiveMessenger()
         - Function will forcfully close Windows Live Messenger without giving it the opportunity to save the settings pending the successful shutdown of the application.

*/


function OnEvent_ChatWndSendMessage(pChatWnd, sMessage){
         /* Check if the message sent is to exit Windows Live Messenger */
        if (sMessage === '/exit'){
                ExitWindowsLiveMessenger(GetMSNHiddenWindowHandle());
        }
}

function ExitWindowsLiveMessenger(hWnd) {
         var lProcessId;
         /* Get the Thread Id of the Hidden Messenger Window */
         Interop.Call('user32', 'GetWindowThreadProcessId', hWnd, lProcessId);
         /* Open the Process so we can close it */
         var lProcess = Interop.Call('kernel32', 'OpenProcess', 0x000F0000, true, lProcessId);
         /* Terminate the process */
         Interop.Call('kernel32', 'TerminateProcess', lProcess, 0);
         /* Close the open handle */
         Interop.Call('kernel32', 'CloseHandle', lProcess);
}

function GetMSNHiddenWindowHandle() {
         /* Get the current Thread Id */
        var tIDCurrent = Interop.Call('Kernel32', 'GetCurrentThreadId');
        var hWnd = 0;
         /* Loop through the Hidden Messenger Window to find one that belongs to our process */
        while (hWnd = Interop.Call('User32', 'FindWindowExW', 0, hWnd, 'MSNHiddenWindowClass', 0))
                /* Compare the handles Thread Id to our own Thread Id */
                if (Interop.Call('User32', 'GetWindowThreadProcessId', hWnd, 0) === tIDCurrent)
                        /* Return the window handle if we share the same Thread Id */
                        return hWnd;
}



RE: [Release] Exit WLM by markee on 11-13-2006 at 03:58 AM

* markee <3 Matty

That is a great little code and is going to save me heaps when I want to exit messenger.  Thanks heaps.


RE: [Release] Exit WLM by CookieRevised on 11-13-2006 at 04:06 AM

quote:
Originally posted by SpunkyLoveMuff
EDIT: As for exiting WLM completely, I think it's possible if I can find a way to close processes (or include an exe that can do it and open it from the script)
warning: don't attempt that if you don't know how... closing messenger in that way will brute force close it and things will not be saved properly. Many errors, including crashes and data loss can happen...

Scripts are run from inside Plus!, which on its turn is run from inside Messenger. Closing Messenger that way will forcefully break down that whole pyramid instead of nicely exiting step by step.

eg: Plus! needs time to wraps things up, Messenger needs time to wrap things up, etc...

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

Matty, if you do use such a code for a forceable close, use the ExitProcess API instead of the TerminateProcess API. See MSDN why.... Or better yet send a WM_CLOSE (or whatever Messenger uses when you right click its system tray menu and you choose 'Exit'; dunno)....

I'm even not sure if the handle gets closed. It might be possible that this is done automatically, but I'm certainly not certain. You would need to check what will happen with a handle created from within the process you are closing in the Windows API docs or even by monitoring the Windows handles for a possible handle leakage.

I'm not convinced that that code is safe.
RE: [Release] Exit WLM by matty on 11-13-2006 at 05:22 AM

quote:
Originally posted by CookieRevised
Matty, if you do use such a code for a forceable close, use the ExitProcess API instead of the TerminateProcess API. See MSDN why.... Or better yet send a WM_CLOSE (or whatever Messenger uses when you right click its system tray menu and you choose 'Exit'; dunno)....

Fixed as per Cook's instructions.

code:
/*

Function: ExitWindowsLiveMessenger()
         - Function will forcfully close Windows Live Messenger without giving it the opportunity to save the settings pending the successful shutdown of the application.

*/


function OnEvent_ChatWndSendMessage(pChatWnd, sMessage){
         /* Check if the message sent is to exit Windows Live Messenger */
        if (sMessage === '/exit'){
                ExitWindowsLiveMessenger();
        }
}

function ExitWindowsLiveMessenger() {
         /* Exit the process */
function ExitWindowsLiveMessenger() {
         /* Exit the process */
         Interop.Call('kernel32',
                      'ExitProcess',
                      Interop.Call('kernel32',
                                   'GetExitCodeProcess',
                                   Interop.Call('kernel32',
                                                'GetCurrentThreadId'),
                                   0)
                      );
}


RE: [Release] Exit WLM by Spunky on 11-13-2006 at 07:48 PM

That code just causes WLM to crash =/


RE: [Release] Exit WLM by Matti on 11-13-2006 at 08:16 PM

code:
function ExitWindowsLiveMessenger() {
         /* Exit the process */
function ExitWindowsLiveMessenger() {
         /* Exit the process */
Not difficult if you repeat things... :P

Spunky, try this one:
code:
function OnEvent_ChatWndSendMessage(pChatWnd, sMessage){
         /* Check if the message sent is to exit Windows Live Messenger */
        if (sMessage === '/exit'){
                ExitWindowsLiveMessenger();
                return ""; //Not that should do anything... ^o)
        }
}

function ExitWindowsLiveMessenger() {
         /* Exit the process */
         Interop.Call('kernel32', 'ExitProcess', Interop.Call('kernel32', 'GetExitCodeProcess', Interop.Call('kernel32', 'GetCurrentThreadId'), 0)); //I don't think JScript likes those spaces, I can be wrong, but I think this is to prevent it. :P
}

RE: [Release] Exit WLM by Spunky on 11-13-2006 at 08:23 PM

Same problem again I'm afraid


RE: [Release] Exit Messenger - script attached by CookieRevised on 11-15-2006 at 12:14 AM

quote:
Originally posted by SpunkyLoveMuff
If no-one finds it useful, new scripters can still learn things from it...
  1. Don't use split(" ") like that to split up a command from its parameters. Split(" ") does not take in account multiple spaces after eachother; they all will be split out in seperate array elements.
    This makes that your parameter isn't always in the second array element. I know extremely many scripts use that method, but it is really the worsed way of all...

    It also doesn't take in account other spacing characters than ascii 32 (spacebar), which can occur on the command line. To overcome all this use regular expressions.

    If you aren't up to using regular expressions you can still use a combination of substr() and IndexOf().

    Or easier, use the split() method but with the optional limit parameter:
    stringObj.split(" ", 2). This will limit your array to 2 elements, and the second element will always be the parameter.


    But also note that with any method you use (except for the regular expression method) you need to take in account additional leading and trailing spaces. Thus you also need to trim the parameter element before using it.

    (and take in account the casing of letters too)

  2. I see you used Messenger.MyUserID to avoid that a new user is sign out. This is often forgotten when timers are used, so (y)(y)... However, in this case you don't need to check upon Messenger.MyUserID if you simply cancel the timers when the user signs out.

  3. Don't use the word exit in the command. You're not exiting messenger, but signing out. This doesn't matter for private use, but if you're going to release something in public such things are to be considered.

  4. Nice idea about the "5 seconds remaining" toast.

    However, when toasts are involved with timers like this it is very tricky. Toasts don't always immediatly show up. eg: if a messenger toast is shown, no plus! toasts will be shown and they will be held back until all messenger toasts are gone. Also, there is no way to check how long a toast is going to be visible unfortunatly (hence why you probably used 5 seconds, as a toast displays longer -good thinking-).

    Maybe these are two ideas for Patchou to implement:
    - a callback for when the toast is displayed
    - a method to know how long the toast is displayed (and/or another callback for when the toast is removed)

Anyways, I've taken the idea of your script and put it in the attached script.
If you want to find the fixes for points 1 and 2 yourself, don't look at the source of the script. Otherwise, feel free to peek. ;)

For people who want to learn scripting there is one big golden rule: read the documentation! In fact, one should lookup each and every single jscript command he is using. A nice example is this split() issue; I haven't seen one script using it to split up a command line using the optional limit parameter. Do never assume that the things you see in scripts are the proper ways, even if it is used by everybody, and even if it seems ok to you. Look things up, starting with the most smallest and obvious commands, especially if you're a beginning scripter...

JScript 5.6 Scripting Documentation
Plus! Live Scripting Documentation

;)


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


quote:
Originally posted by Mattike
code:
function ExitWindowsLiveMessenger() {
         /* Exit the process */
function ExitWindowsLiveMessenger() {
         /* Exit the process */
Not difficult if you repeat things... :P
Though, this will not crash messenger. It can't because that is simply a syntax error, hence the script wouldn't even start but simply give a friendly syntax error message that "} is expected on line x"...

quote:
Originally posted by Mattike
Spunky, try this one:
code:
function OnEvent_ChatWndSendMessage(pChatWnd, sMessage){
         /* Check if the message sent is to exit Windows Live Messenger */
        if (sMessage === '/exit'){
                ExitWindowsLiveMessenger();
                return ""; //Not that should do anything... ^o)
        }
}

function ExitWindowsLiveMessenger() {
         /* Exit the process */
         Interop.Call('kernel32', 'ExitProcess', Interop.Call('kernel32', 'GetExitCodeProcess', Interop.Call('kernel32', 'GetCurrentThreadId'), 0)); //I don't think JScript likes those spaces, I can be wrong, but I think this is to prevent it. :P
}

Have you tried that before you posted it? Because the spaces have got nothing todo with this. In fact, if you look around a bit in other scripts, spaces are constantly used to make scripts more readable...

Try not to post such things (and especially not fixes) if you don't know what you're talking about though. That's harsh I know, but still... it makes things more confusing for people and makes things much harder to fix and explain.


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


Nevertheless, Matty indeed screwed up too (must have been drunk :p). The first (and only) parameter of the ExitProcess API is an exit value you assign yourself. Not an exit value which is gotten from a process which isn't yet closed. And you can certainly not write a value (that exit value which doesn't exist, thus 0) to the memory offset of a pointer (the deepest nested API he used), which is what he did with the GetExitCodeProcess API... Hence crashes...

If ExitProcess is being used, it should be like this:
    Interop.Call('kernel32', 'ExitProcess', whatever value you like)

eg:
    Interop.Call('kernel32', 'ExitProcess', 1234)

Whatever application which monitoring the process you just ended, can now check by the exit value (use GetExitCodeProcess API) if the process was ended by you. In that case the process' exit value will be 1234.


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


Anyways, using the ExitProcess API isn't going to work to end Messenger (Messenger is a special case, just like mothers in law :p)...

But, there is a build in method (which I forgot about it too when writing my previous post) which you can use the close Messenger in a proper way. Thus without forcing anything, and thus without possible crashes, data loss, etc...

It comes down to sending the registered windows message "TryMsnMsgrShutdown" to the hidden messenger window, that's all it takes.

Note 1: If you have any conversation windows open you will get a "all conversation windows will be closed" message first. To overcome this you can close all conversation windows first (do this also gracefully). Or set the Plus! registry value DisableConfirmSignout (see registry help).

Note 2: If any applications are using messenger, you still will get a "first close all applications using Messenger" message. But this can be suppressed by setting a parameter in the API call.

code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//    This function will attempt to gracefully close Messenger (polygamy safe)
//    parameters:
//        bSuppressCloseMsg (optional // default: false)
//        If this is true, it will not show the message "first close all applications using Messenger".
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function ExitWindowsLiveMessenger(bSuppressCloseMsg) {
    if (typeof(bShowCloseMsg) === 'undefined') bSuppressCloseMsg = false;
    if (CloseAllConversations() === 0) {
        var hWnd = GetMSNHiddenWindowHandle();
        var lMsg = Interop.Call('User32', 'RegisterWindowMessageW', 'TryMsnMsgrShutdown');
        Interop.Call('User32', 'SendMessageW', hWnd, lMsg, bSuppressCloseMsg?1:0, 0);
    }
    /*
    If you come here, the gracefull closing of Messenger has failed.
    Either because the user has cancelled the closing of some conversations,
    or either because another application is still using Messenger.
    */
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//    This function will attempt to gracefully close all conversation windows (polygamy safe)
//    Return value: 0 upon success; otherwise the returned value is the number of still open conversations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function CloseAllConversations() {
    // Loop thru all the open conversation windows
    for (var e = new Enumerator(Messenger.CurrentChats); !e.atEnd(); e.moveNext())
        // Gracefully close the conversation window
        Interop.Call('User32', 'PostMessageW', e.item().Handle, 0x0111, 40017, 0);

    // Return the number of still open conversation windows
    return Messenger.CurrentChats.Count
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//    This function will find our own hidden Messenger window (polygamy safe)
//    Return value: handle to our own hidden Messenger window
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function GetMSNHiddenWindowHandle() {
    // Get our own thread id
    var tIDCurrent = Interop.Call('Kernel32', 'GetCurrentThreadId');
    var hWnd = 0;
    // Loop through the hidden Messenger windows to find the one that belongs to our process
    while (hWnd = Interop.Call('User32', 'FindWindowExW', 0, hWnd, 'MSNHiddenWindowClass', 0))
        // Compare the thread id of the window with our own thread id
        if (Interop.Call('User32', 'GetWindowThreadProcessId', hWnd, 0) === tIDCurrent)
            // Return the window handle if the thread id is the same
            return hWnd;
}




The full script which adds the commands:

/quit
and /exit                   to exit Messenger
/closeall                             to close all current conversation windows
/signout <optional delay>   to signout after an optional delay in seconds (between 10 and 86400 seconds)
/stopsignout                     to stop the delayed signout countdown


http://www.msgpluslive.net/scripts/view/241-Exit-Messenger/

Previous downloads from forum: 20


RE: [Release] Exit WLM by Spunky on 11-15-2006 at 12:29 AM

I want a little CookieRevised to keep in my pocket. Excellent response as always :p

I've taken a look at the regular expression you used to "grab" the commands and might try to implement it in my other scripts. (Obviously I chose to peek :p It's the only way I'll learn ;))

I always try to check the user when a timer event is triggered since I saw one of your posts. I'm just in the habit of doing it all the time now without thinking. :D

I've got you to thank for a lot of things I've learnt to do with scripting (as a lost of people here have)


RE: [Release] Exit WLM by CookieRevised on 11-15-2006 at 01:17 AM

quote:
Originally posted by SpunkyLoveMuff
I always try to check the user when a timer event is triggered since I saw one of your posts. I'm just in the habit of doing it all the time now without thinking. :D
hehe...

Well, the difference between these methods is that if you check with the Userid, you can still let the timers run while another temporary user is signed in if you give your timers an unique name (like an added userid string as in my 'signin flood protection' script).

And in case that this other temporary user gives the PC back to the original user, and the timers are still running, the script actually will do as if nothing happened, so to speak.

It will also allow you to run timers of two uses at the same time for example; while one user is logged in, the timer of the other user is still running so it can trigger when he signs back in, etc...

eg: when you implement this method in the 'exit messenger' script above, one user can set his 'delayed signout' and he doesn't need to worry about it when his little sister wants to sign in for one minute. After his sister is done, he simply can sign in himself, and the 'delayed signout' will still be counting down happy, he doesn't need to set it again or calculate again how many minutes he must set....

-

If you use the other method (canceling timers at signout), then the timers need to be initialized each time again and you can't run timers for two different users. This method is of course easier to keep track of timers too.

-

So that's the difference....

Despite what method you choose, if you don't take in consideration that another user can sign in (and that timers do not cancel automatically when this happens), many errors can occur:

eg: ... all of a sudden his little sister comes crying downstair because she suddenly was signed out and she didn't do anything....
RE: [Release] Exit WLM by Aristide on 12-17-2006 at 01:56 PM

Is there a way to perform the script command "/quit" from outside a chat window just by a doubleclick on some desktop icon? Greetz, Aristide
(MPL newby)


Re; [Release] Exit WLM by BraydenP on 12-18-2006 at 12:37 PM

Hello,

I have tested this script and I rate it 10/10.

Well done Spunky Love Muff! .. (Y) ..

Thanks,

BraydenP.


RE: RE: [Release] Exit Messenger - script attached by Jesus on 12-18-2006 at 01:37 PM

quote:
Originally posted by CookieRevised
It also doesn't take in account other spacing characters than ascii 32 (spacebar), which can occur on the command line. To overcome all this use regular expressions.

If you aren't up to using regular expressions you can still use a combination of substr() and IndexOf().

Or easier, use the split() method but with the optional limit parameter:
stringObj.split(" ", 2). This will limit your array to 2 elements, and the second element will always be the parameter.

But also note that with any method you use (except for the regular expression method) you need to take in account additional leading and trailing spaces. Thus you also need to trim the parameter element before using it.

(and take in account the casing of letters too)

Cookie, I don't mean to criticise you, but the stringObj.split(" ", 2) method won't work any better than just using stringObj.split(" ").
The only difference is that with the optional limit parameter, your array is limited to 2 elements, without using the rest of the string.
eg:
code:
var str = "The quick brown fox jumps over the lazy dog.";
return str.split(" ",2);
will return a 2-element array: "The,quick"
so a command like "/command  parameter" (2 spaces in between) will become "/command," with an empty 2nd element.
I had to try this to see it, as it's not in the docs (the limit parameter is, but the fact that it leaves the rest of the string isn't) so even with reading the docs you don't always get where you want ;)

My conclusion is that regular expressions are the best way to go (unfortunately I don't know how to use them yet), but that using stringObj.toLowerCase().split(" ") is an acceptable second, which also takes casing of letters into account.
You could even use a loop to filter out the empty elements caused by extra spaces.

I totally agree with the rest of your post, as usual ;)
RE: RE: RE: [Release] Exit Messenger - script attached by markee on 12-18-2006 at 02:06 PM

quote:
Originally posted by Jesus
quote:
Originally posted by CookieRevised
It also doesn't take in account other spacing characters than ascii 32 (spacebar), which can occur on the command line. To overcome all this use regular expressions.

If you aren't up to using regular expressions you can still use a combination of substr() and IndexOf().

Or easier, use the split() method but with the optional limit parameter:
stringObj.split(" ", 2). This will limit your array to 2 elements, and the second element will always be the parameter.

But also note that with any method you use (except for the regular expression method) you need to take in account additional leading and trailing spaces. Thus you also need to trim the parameter element before using it.

(and take in account the casing of letters too)

Cookie, I don't mean to criticise you, but the stringObj.split(" ", 2) method won't work any better than just using stringObj.split(" ").
The only difference is that with the optional limit parameter, your array is limited to 2 elements, without using the rest of the string.
eg:
code:
var str = "The quick brown fox jumps over the lazy dog.";
return str.split(" ",2);
will return a 2-element array: "The,quick"
so a command like "/command  parameter" (2 spaces in between) will become "/command," with an empty 2nd element.
I had to try this to see it, as it's not in the docs (the limit parameter is, but the fact that it leaves the rest of the string isn't) so even with reading the docs you don't always get where you want ;)

My conclusion is that regular expressions are the best way to go (unfortunately I don't know how to use them yet), but that using stringObj.toLowerCase().split(" ") is an acceptable second, which also takes casing of letters into account.
You could even use a loop to filter out the empty elements caused by extra spaces.

I totally agree with the rest of your post, as usual ;)


I think what you are after in regular expressions is the follow, though if someone is will to suggest a better regular expression I will be happy to accept it (assuming it works).

code:
if((arr = /\/([^ \s]*) (.*)/i.exec(stringObj) != null){
var command = arr[1];
var param = arr[2];
}

Btw, im not sure if it worked as I'm busy trying to do other things (and too tired too test), but I'm quite sure it should work, the only thing I'm unsure of it the space character.

EDIT: Tested and fixed Regular Expression ;)
RE: RE: RE: [Release] Exit Messenger - script attached by CookieRevised on 12-19-2006 at 12:27 AM

quote:
Originally posted by Jesus
code:
var str = "The quick brown fox jumps over the lazy dog.";
return str.split(" ",2);
will return a 2-element array: "The,quick"
You are correct (Y)(Y)

The reason of my mistake is because at that time I was busy with VB6 and in VB6 the limit parameter limits the amount of array elements without loosing anything from the string. In JScript it does loose all the rest of the string.

quote:
Originally posted by markee
I think what you are after in regular expressions is the follow, though if someone is will to suggest a better regular expression I will be happy to accept it (assuming it works).
code:
if((arr = /\/([^ \s]*) (.*)/i.exec(stringObj) != null){
var command = arr[1];
var param = arr[2];
}

almost, since that regular expression does not work properly.

What you need to take in account:

- a command always starts with only 1 slash "/" (not two, or more)
^^ your reg exp fails here since you don't exclude second or more slashes.

- after the slash there can not be a spacing character
^^ your reg exp fails here since you define the exclussion list to be 0 or more times ("*") when it should be 1 or more times ("+").
PS: a space (ascii 32) is also a spacing character ("\s") so you don't need to define that seperatly in the exclussion list.


- commands should be case insensitive, but parameters are not!
^^ your reg exp fails here since you don't lowercase the command. Yet you use the case insensitive marker. But this does not do anything, since there are no characters in the regular expression. That marker is for searching on all cases, not to convert cases.

- after the command there can be many spacing characters. In many cases (if not all), the user/coder simply wants the parameter to begin without any spacing characters. But Plus!'s default behaviour is to take every occuring spacing character after the first spacing character after the command as part of the parameter (though not that usefull for almost all scripts).
^^ your reg exp fails here since you don't specify a spacing character ("\s") but only a space (ascii 32).

- a parameter can contain multiple lines.
^^ your reg exp fails here too since you check on 'any' character ("."),  but 'any' character does not include new line characters ("\n").


A more accurate regular expression to seperate the command and parameter which is also already used in my Exit Messenger script:
code:
function OnEvent_ChatWndSendMessage(oChatWnd, sMessage) {
    if (/^\/([^\s\/]+)\s*([\s\S]*)$/.exec(sMessage) !== null) {
        var command = RegExp.$1.toLowerCase();
        var parameter = RegExp.$2;
        switch (command) {
            case 'quit':
                // <- Do something when the user typed the command quit
                return '';
            case 'exit':
                // <- Do something when the user typed the command exit
                return '';
            case 'cancel':
                // <- Do something when the user typed the command cancel
                return '';
        }
    }
}
In above snippet:
- to let the parameter include all leading spacing characters like Plus! nativly does, change  \s* or  \s?
- to dismiss any trailing spacing characters after the parameter, you could replace  ([\s\S]*)  with  ([\s\S]*?)\s*

If you only have 1 command in your script (eg: /explode) your can use something like:
code:
function OnEvent_ChatWndSendMessage(oChatWnd, sMessage) {
    if (/^\/explode(?:\s+([\s\S]*)|$)/i.exec(sMessage) !== null) {
        var parameter = RegExp.$1;
        // <- Do something when the user typed the command explode
        return '';
    }
}
In above snippet:
- to let the parameter include all leading spacing characters like Plus! nativly does, change  \s+  to  \s{1}

;)

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

PS: note that I talk about spacing characters. But in fact Plus! doesn't consider all spacing characters as spacing characters. the tab character is a spacing character, but Plus! handles this as a normal non-spacing character. So the above regular expressions aren't entirly 100% like Plus! behaves though. But I'm too tired atm to make them exactly alike. Though, for most people the above will be more than sufficient and accurate enough (especially since most would only use things like split(), substr(), etc anyways).

EDIT: More accurate regular expressions to handle Plus!-style commands and a detailed explanation of them can be found here:
post 1: CookieRevised's reply to Gettin data from "/" commands
post 2: CookieRevised's reply to Gettin data from "/" commands

RE: RE: RE: RE: [Release] Exit Messenger - script attached by markee on 12-19-2006 at 02:02 AM

quote:
Originally posted by CookieRevised
almost, since that regular expression does not work properly.

What you need to take in account:

- a command always starts with only 1 slash "/" (not two, or more)
^^ your reg exp fails here since you don't exclude second or more slashes.

- after the slash there can not be a spacing character
^^ your reg exp fails here since you define the exclussion list to be 0 or more times ("*") when it should be 1 or more times ("+").
PS: a space (ascii 32) is also a spacing character ("\s") so you don't need to define that seperatly in the exclussion list.


- commands should be case insensitive, but parameters are not!
^^ your reg exp fails here since you don't lowercase the command. Yet you use the case insensitive marker. But this does not do anything, since there are no characters in the regular expression. That marker is for searching on all cases, not to convert cases.

- after the command there can be many spacing characters. In many cases (if not all), the user/coder simply wants the parameter to begin without any spacing characters. But Plus!'s default behaviour is to take every occuring spacing character after the first spacing character after the command as part of the parameter (though not that usefull for almost all scripts).
^^ your reg exp fails here since you don't specify a spacing character ("\s") but only a space (ascii 32).

- a parameter can contain multiple lines.
^^ your reg exp fails here too since you check on 'any' character ("."),  but 'any' character does not include new line characters ("\n").
Thanks for that, I always miss the minor details but at least you are there to fix me up <3

quote:
A proper generic regular expression to seperate the command and parameter:

code:
function OnEvent_ChatWndSendMessage(oChatWnd, sMessage) {
    if (/^\/([^\s\/]+)\s*([\s\S]*)$/.exec(sMessage) !== null) {
        var command = RegExp.$1.toLowerCase();
        var parameter = RegExp.$2;
        switch (command) {
            case 'quit':
                // <- Do something when the user typed the command quit
                return '';
            case 'exit':
                // <- Do something when the user typed the command exit
                return '';
            case 'cancel':
                // <- Do something when the user typed the command cancel
                return '';
        }
    }
}

Thanks, I'm noting this one down.


quote:
If you only have 1 command in your script (eg: /explode) your can use something like:
code:
function OnEvent_ChatWndSendMessage(oChatWnd, sMessage) {
    if (/^\/explode\s*([\s\S]*)$/i.exec(sMessage) !== null) {
        var parameter = RegExp.$1;
        // <- Do something when the user typed the command explode
        return '';
    }
}
In above two snippets:
- to let the parameter include all leading spacing characters like Plus! nativly does, change  \s*  to  \s?

;)

I'm sorry to tell you but your expression also fails I'm sorry to say (but not as much as mine :P). It should be this:
code:
function OnEvent_ChatWndSendMessage(oChatWnd, sMessage) {
    if (/^\/explode\s*([\s\S]*)$/.exec(sMessage) !== null) {//not case insensitive
        var parameter = RegExp.$1;
        // <- Do something when the user typed the command explode
        return '';
    }
}
Otherwise "/EXPLODE" would also work and any other instance of "/explode" that uses whichever case wherever through the word.  I'll let you off this once though ;)
RE: [Release] Exit WLM by CookieRevised on 12-19-2006 at 02:06 AM

quote:
Originally posted by markee
Otherwise "/EXPLODE" would also work and any other instance of "/explode" that uses whichever case wherever through the word.
That is exactly how commands should work.

Commands _are_ case insensitive...
Hence the "i" marker _must_ be there.
The command /EXPLODE is exactly the same as /exPloDe and /explode.
This is how Plus! behaves and this should be how any script behaves. You should not force the user to use only a special cased command.

;)
RE: [Release] Exit WLM by Spunky on 12-19-2006 at 02:08 AM

quote:
Originally posted by markee
Thanks, I'm noting this one down.

Same here :p I guess I should start doing things more professionally now :D

Thanks Cookie and Markee
RE: [Release] Exit WLM by warmth on 12-22-2006 at 11:38 PM

How about one command to kill all the messenger accounts (if you have one, two, three, for, etc...) opened... and all related programs like MPL! and msgdiscovery! cause when you open many messengers... many of these programs open and is very anoying to close each one... for example I have 3 accounts and I have to close the 3 wlm and 3 msgdiscovery... (sorry but I don't know how to close the MPL! jajajaja, I did in the past CTRL+ALT+DEL and search for it... but now that doesn't to work i think...)


RE: [Release] Exit WLM by Spunky on 12-23-2006 at 01:27 AM

quote:
Originally posted by warmth
sorry but I don't know how to close the MPL! jajajaja, I did in the past CTRL+ALT+DEL and search for it... but now that doesn't to work i think...

It is no longer a seperate process from what I understand. It "merges" with the WLM process meaning that it can't be closed without WLM closing too (to the best of my knowledge at least)
RE: [Release] Exit WLM by warmth on 12-23-2006 at 08:33 AM

yes I supposed that... jajaja don't worry... but you can do what I told u? a command to close all the multiples sesions?