New return value for SendXxx family of functions.

Posted by Worstje on Sun 12 Aug 2007 04:26 PM — 11 posts, 48,960 views.

Netherlands #0
Right now, the SendXxx family of functions have the following possible return values:

eWorldClosed : The world is closed
eItemInUse : Cannot be called from within OnPluginSent script callback
eOK: Sent OK

What I am missing is a way to determine if it was REALLY sent. If an OnPluginSend of ANY plugin happens to reject what I am sending, my tracking could be off. Of course, I could add an elaborate procedure with OnPluginSent, a table (or list in Python) with commands I've been trying to send and a wrapper around it, but it will get clumsy and make what could be a simple if statement into a project of its own.

Suppose you could write the following:

local sentMedicine = world.SendNoEcho("take medicine")
if (sentMedicine == ePluginBlocked) then
  -- Apparently this is not a time to take our medicine.
  -- Echo it.
  World.Note("Warning: you have not taken your hourly medicine!")
end


I believe it should be possible, since the OnPluginSend really does get called from the various Send() functions according to my tests. The only disadvantage is that it might break some scripts, so in that case I suggest only putting it in the more recently added 'SendSpecial' function which might break less existing scripts.
Amended on Sun 12 Aug 2007 04:29 PM by Worstje
USA #1
OnPluginSend already can assign a true or false to be returned. It shouldn't be too hard to make the false send back a different error code than it already does. Just adding a new error code shouldn't interfere with existing scripts if they check for eOK. It would just add other option to check for ePluginBlocked or whatever it would be called.

I haven't poked around with OnPluginSend much. Can you test to see if eOK is not sent back?

local sentMedicine = world.SendNoEcho("take medicine")
if (sentMedicine ~= eOK) then
  -- Apparently this is not a time to take our medicine.
  -- Echo it.
  World.Note("Warning: you have not taken your hourly medicine!")
end
Netherlands #2
I've done a quick test with a different plugin, and both cases return 0 (=eOK).
USA #3
As I said, I haven't played around with the function. From the help file, I mistakenly got the impression that an error would be returned:

OnPluginSend
'
'  MUSHclient is sending 'sText' to the MUD
'  Return TRUE to send the text, FALSE to discard it
'
Function OnPluginSend (sText)
  OnPluginSend = vbTrue  ' process it
End Function

The issue with trying to see if the send was blocked is that sometimes the send goes through fine, sometimes people will modify the string that is sent, and other times it just sends other strings as well. I agree that there should be some way to tell if the last send was modified in some way, but it could be tricky to figure out the best way to deal with this.
Amended on Sun 12 Aug 2007 08:49 PM by Shaun Biggs
Australia Forum Administrator #4
The problem with that idea is that sends are not synchronous.

When you call 'Send' the text to be sent is queued (after any speedwalks) and pulled out of the queue later on. When it is pulled out of the queue the function OnPluginSend is called.

The callback OnPluginSent was designed for things like the automapper (and other stuff like you are talking about) where you want to keep track of what was actually sent, rather than what was queued.

Here is a possibility of what might happen:

  • You are busy speedwalking with 30 seconds to go (30 directions with a 1 second delay between each one)
  • You send SendNoEcho("take medicine")
  • You get no error
  • 15 seconds later you cancel the speedwalk queue
  • The "take medicine" is in the queue and gets cancelled as well


Conceivably the test could be added to SendImmediate, which does not suffer from this problem. I see from the source that the call to OnPluginSend is done by the routine directly called by SendImmediate, so with a bit of reworking that could be done.

However the idea of using OnPluginSent is a bit more reliable. Say for example you manually typed "take medicine" - a test in OnPluginSent would catch that.
Netherlands #5
Well, I don't care about speedwalks (it is about the only MUSHclient feature I don't use at all), so that's fine with me. The issue with using the OnPluginSen(d|t) callback isn't as useful for a few reasons:

1) You'd need to use a plugin and can not use the function in your worlds triggers.

2) The code to deal with this would be spread out over the place where you call it and the place where you 'reject' it.

2a) With OnPluginSend, you may run into the issue that some function tries to execute another tell (if I haven't taken medicine, tell my doctor that I may get ill some time today). This one will always go through, which might not be acceptable when you are using OnPluginSent to stop certain actions. (Okay, it is a weird example situation and I can't think of a better one right this moment, but I have the feeling it is a restriction which I would rather quickly run into, knowing my insane usage of OnPluginSent). This would only handle blocking of messages by -this- plugin, and not by others.

2b) With OnPluginSent, you could only react to allowed actions.. and not to actions that aren't allowed.

2c) 2a and 2b mean that the only conceivable way of using it would be a timer with a very short interval, which has the disadvantage of needing timers enabled AND being unable to send things in one trigger dependant on the result of another, unless daisy-chaining (which would be a very ugly solution imho.)

3) Every plugin-author would have to re-invent this particular system to be able to use it. Or require a certain basic plugin to be available, which in turn would call an alias or method using CallPlugin().

4) If you only want to know whether a certain text could be sent in a certain situation (e.g. aliases a1, a2, a3 all Send() the same thing, but a3 checks whether it was sent), this could possibly confuse the script and needs extra flags to be passed and reset. Not impossible, but not a clean solution either. *forgot this originally, added with edit*

How about adding said check and return value to the SendSpecial (with Immediate=True) and SendImmediate functions then? For others, just return eOK since it is a technical impossibility to return it at that point, if I understand properly.
Amended on Sun 12 Aug 2007 10:09 PM by Worstje
Netherlands #6
Bump.

(Sorry about seeming/being impatient, it's just that I'm going away for a while and figured a reminder might be useful in the case this topic was forgotten..)
Australia Forum Administrator #7
Right.

I'll look into that shortly, along with another problem I noticed while I was playing with the toolbar mentioned here:


http://www.gammon.com.au/forum/?id=4951

It seems I can't find out the pixel address of the top left-hand corner of the current world, relative to the desktop.

The function GetWorldWindowPosition returns the location of the world window *relative* to the client space of the main window:

http://www.gammon.com.au/scripts/doc.php?function=GetWorldWindowPosition

The function GetMainWindowPosition returns the location of the main window:

http://www.gammon.com.au/scripts/doc.php?function=GetMainWindowPosition


However the world window is in the client area of the main window (that is, allowing for toolbars, menus etc.) so I can't find out where the world window is on the screen - unless someone has a way?

I wanted to be able to position the custom toolbar just under the start of the world window, automagically, whereever that is.
USA #8
This is the returned information from the autoit active window info tool, that control id# is the same on all the systems I've run mushclient on, by possibly looking for the handle of that control you might be able to do something.

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Size: X: 0 Y: 72 W: 1024 H: 602
Control ID: 59648
ClassNameNN: MDIClient1
Text:
Style: 0x56000001
ExStyle: 0x00000200


Another approach would be to find the height of the toolbars area, but that can be off by quite a bit, if a person uses toolbars on the side, or has them split between top and bottom. I know this for a fact as I have made a toolbar addon for mushclient that uses UDPSends and has an expandable pane with several buttons that can be renamed and actions set via udpsends as well. And the code to properly place it in the toolbar area is quite twisted and a hack onto of a hack on top of, yup you guessed it, another hack.
It in all honestly is probably the most messed up coding I've ever seen, but it works wonderfully. It might yield some hints or just a push in the right direction, I can e-mail you the source for it, and mark the area with a large comment block.


Laterzzz,
Onoitsu2
USA #9
I think there is an unwritten rule in Windows API development. Something along the lines of, "If X can be derived from Y and Z, never provide a simple function for returning X, and more importantly, hide Y in some strange fashion, so that all the third party developer has to work with is Z." lol
Australia Forum Administrator #10
I am a bit surprised no-one has asked for this before. The stuff that is already there, while useful, could be more useful if you knew where the client area started.