[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  General
. . -> [Subject]  Help with Triggers, Is This Possible?...

Help with Triggers, Is This Possible?...

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Pages: 1  2 3  

Posted by Fiendish   USA  (2,533 posts)  [Biography] bio   Global Moderator
Date Reply #15 on Wed 04 May 2011 03:31 AM (UTC)

Amended on Wed 04 May 2011 04:58 AM (UTC) by Fiendish

Message
Nick Gammon said:

But the first thing a Diku MUD does is say:


Enter your character's name, or type new: 


So without writing to the screen, you didn't see that. And you sat and waited. Then you wrote to Nick Gammon and complained that his client "doesn't work".

So, text is processed (eg, for colours) and then written to the screen immediately. So you see login prompts, and "press <return> to continue" etc. And command prompts for MUDs that have them.

Nuts.
Wait... does this mean you can't trigger on a login prompt? That seems like a bug. :\

I only bring this up now because processing triggers before display would seem to make it possible to modify text in place rather easily.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #16 on Wed 04 May 2011 03:59 AM (UTC)
Message
Fiendish said:
Wait... does this mean you can't trigger on a login prompt? That seems like a bug. :\

Well, MUSHclient is heavily line-oriented. Telnet lines in particular end in "\r\n". If the content we've received so far doesn't have a "\r\n" at the end, the safest thing to do is assume the whole line hasn't been received yet. And you can't trigger on a partial line.

Most login prompts don't end with \r\n, because they expect your input to be echoed at the end of that line. If there was an \r\n after the prompt, your input would be below it.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (23,042 posts)  [Biography] bio   Forum Administrator
Date Reply #17 on Wed 04 May 2011 08:20 AM (UTC)
Message
Fiendish said:

Nuts.
Wait... does this mean you can't trigger on a login prompt? That seems like a bug. :\


Well you see Fiendish, a careful attention to design makes the difference between a program that works some of the time, and one that works all of the time. ;)

TCP/IP is stream-oriented. That is, you get data streaming in, you don't get definite transactions. So in the absolutely worst case, instead of a single packet with "Enter your character's name, or type new: ", you would get something like this:


E
<1 second pause>
n
<1 second pause>
t
<1 second pause>
e
<1 second pause>
r
<1 second pause>
 
<1 second pause>
y
<1 second pause>
o
<1 second pause>
u
<1 second pause>
r
<1 second pause>
...


In other words, each letter in its own packet. Now MUSHclient's state machine can handle that. The ANSI codes, even if they are split across packets, are just processed as they arrive, and then when the state transitions to "end of colour information" the colour is recorded.

Some clients don't do that. And they are they ones that have the occasional "bad colour" because the colour code happened to be split across packets.

Now for a slightly less extreme example:


Enter 
<1 second pause>
 your 
<1 second pause>
 chara
<1 second pause>
acter'
<1 second pause>
's nam
<1 second pause>
me, or
<1 second pause>
r type
<1 second pause>
e new:
<1 second pause>
: 
<1 second pause>


Do you want at trigger to fire after "Enter" and then another after " your" and then another after "chara" and so on? Do you not see where this is going to lead you? How does this hypothetical trigger match something like "Enter your"?

In the same way that we process colour codes (like ESC [40m) at the "m" and not before, we invoke triggers when the line has "arrived", that is, at the newline character.

In any case, there is a plugin handler for people that want to match on "login" prompts and do something. Search the plugin callbacks for "OnPluginPartialLine". That is an extra call, at the end of a packet when no more packets are available, so you can "pre-trigger" on the line.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Fiendish   USA  (2,533 posts)  [Biography] bio   Global Moderator
Date Reply #18 on Wed 04 May 2011 08:28 AM (UTC)
Message
Quote:
Search the plugin callbacks for "OnPluginPartialLine".

Ooh, interesting.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Fiendish   USA  (2,533 posts)  [Biography] bio   Global Moderator
Date Reply #19 on Mon 15 Aug 2011 05:37 AM (UTC)
Message
I want to revisit this thread, because I actually still want to do exactly what Onoitsu2 and Shadowfyr were talking about.

The requirements are:
1) replace all or part of a line of text. (Omit from output + Note works great)
2) have other triggers fire on the result. (no way without Simulate)

I've been looking at the code for Simulate and Note and they both end up in DisplayMsg which then leads to StartNewLine and ultimately we get down to ProcessPreviousLine. And that's where the current state of things breaks down from what would be REALLY nice for a lot of people who talk to me about switching to MUSHclient. Because triggers don't fire in ProcessPreviousLine on text that has replaced a line after an omit. And I really want it to. I understand concerns about creating infinite loops, so it would be prudent to only allow a given trigger to fire once per server line, but other triggers should be allowed to fire on replacement text.

And I can't really think of any negative effects from making this the standard behavior for Note as long as it only happens in triggers that omit from output. Notes in an omitting trigger essentially show the player a different view than what the server sent. The player should be able to later trigger on their current world view without having to know that somewhere hidden in the background, invisible to them, the server is sending something else.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Etzli   USA  (4 posts)  [Biography] bio
Date Reply #20 on Thu 18 Aug 2011 05:43 AM (UTC)
Message
I'm in agreement with Fiendish regarding the requirements.

I will say that a simple way to substitute partial text within the line (and retain color for the rest of it) a la z/CMUD would be wonderful. In fact, a function like 'suboutput(pattern, newoutput, [enabletrigger])' would be extremely simple and useful in a lot of cases. Of course, the 'enabletrigger' bit would be true or false, depending if you want to be able to trigger off the new output, and would allow a secondary script to run on the replacement text.

The way I have it envisioned is it would turn something like:

( 4) (K)(M)(G)(H) a bag of Aardwolf (146)

into:
( 4) (KMGH) AardBag (146)

The first trigger would be one to change the flags (K)(M)(G)(H) on any item to (KMGH) and the second would be to change "a bag of Aardwolf" to "Aardbag."

I do understand it has potential to create infinite loops, but that really should fall on the person doing the scripting, not the author of a client.

Of course, it's also late in the night for me, and while this makes absolute sense to me, it might not be what Fiendish is looking for, and for that, I apologize. Either way, I'd really love to see a simple way to sub output and return the rest of the line undisturbed.
[Go to top] top

Posted by Nick Gammon   Australia  (23,042 posts)  [Biography] bio   Forum Administrator
Date Reply #21 on Thu 18 Aug 2011 08:56 PM (UTC)
Message
A while ago, during testing, infinite loops weren't just a possibility, they happened all the time. Consider the "match-all" trigger (ie. matching "*") which outputs something (which the match-all trigger then matches again).

But let's say for a moment that we put in a limit (eg. no triggering more than once on a line) then would you say you would want to trigger more than once? For example, trigger "A" changes "Fiendish" to "That Rascal Fiendish" and trigger B changes "5 HP" into ("<low HP> 5 HP").

If we only match once (on the newly displayed line) then only one change gets made. If we match more than once, what limit do you impose?

Indeed, if a "prompt" trigger matches more than once there is the potential for "xp counting" triggers to be wrong (if it matches twice you count the XP twice).

Then you have the issue, if a line matches, and gets omitted and redisplayed, what line do subsequent triggers match on? The original? Or the modified one?

I'm not saying I refuse to change it. But I think you need to clearly think through what the change would be, exactly. To just modify it to match "note" lines would certainly send virtually every world file and plugin into a loop, because the "match all" idiom is used so much.

Take a look at this:

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

(How MUSHclient processes text arriving from the MUD)

Then specify where in that flow process you would make changes, and what they would be. Also any additional flags you might want (eg. match only original lines, match only "note" lines, only match once, protect a particular "note" line from matching, etc.).


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Fiendish   USA  (2,533 posts)  [Biography] bio   Global Moderator
Date Reply #22 on Fri 19 Aug 2011 04:54 AM (UTC)

Amended on Fri 19 Aug 2011 05:18 AM (UTC) by Fiendish

Message
Quote:
infinite loops weren't just a possibility, they happened all the time
I see the nb comment about stack overflows.

Quote:
If we only match once (on the newly displayed line) then only one change gets made.
Precisely this.

Quote:
If we match more than once, what limit do you impose?
I would impose the limit that a given trigger can only fire once (the repeat on same line checkbox should re-fire as many times as necessary until done and then not fire again after that) for each new line index. Rather than checking all triggers, check only the ones that have not yet fired from a listing that resets upon each new line.

Quote:
Indeed, if a "prompt" trigger matches more than once there is the potential for "xp counting" triggers to be wrong (if it matches twice you count the XP twice).
One reason why any given trigger should only be allowed to fire once per line.

Quote:
Then you have the issue, if a line matches, and gets omitted and redisplayed, what line do subsequent triggers match on? The original? Or the modified one?
Subsequent trigger checks should be matched against the new line, not the original line. The once-per-line limit should not reset until new unrelated data is shown.

Example for above statements:

Say there are four triggers, numbered in order of sequence...
1) match="{channel_tag}*", omits from output, sends SimNote("%1")
2) match="Fiendish says*", omits from output
3) match="*Fiendish*", omits from output, sends SimNote("%1jerkface%2")
4) match="*", omits from output, sends SimNote(string.gsub("%1","pants","Fiendish"))

Now the first trigger is in a plugin. As far as the user knows, it doesn't exist. As far as the user knows, the server sends the output of the resulting Note. The second trigger is created by the user to just block all instances of me saying something. The third is created to replace my name in other instances with something more suitable. The fourth trigger is only there because I'm not feeling hugely creative right now and am having a hard time thinking of more legitimate loops from reprocessing.

So when the mud sends:
Quote:
{channel_tag}Fiendish says your pants are on backwards.
Trigger 1 fires, removing the {channel_tag} and leaving just
Quote:
Fiendish says your pants are on backwards.
Trigger 2 fires, eliminating the line. Triggers 3 and 4 do not fire.

And when the mud sends:
Quote:
{channel_tag}Your pants say that Fiendish is on backwards.
Trigger 1 fires again. Trigger 2 does not fire. Trigger 3 fires and produces
Quote:
Your pants say that jerkface is on backwards.
Trigger 4 fires and produces
Quote:
Your Fiendish say that jerkface is on backwards.
Trigger 3 does not fire again. Trigger 4 does not fire again.

Now I know that Etzli wants a new function/option that handles substitution as a special case. And maybe that's the best way to deal with this. Or maybe Simulate isn't so bad for this particular use case?

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #23 on Fri 19 Aug 2011 05:11 AM (UTC)
Message
This probably isn't helpful in the context of MUSHclient, but I've thought a little about how I would implement this within Aspect. In my concept, triggers listen on a line source, and act as line sources themselves. By default, a trigger listens on the primary source (the lines coming in directly from the MUD). However, you could have a trigger listen to another trigger, allowing changes to propagate. Unrelated triggers are left unaffected.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Fiendish   USA  (2,533 posts)  [Biography] bio   Global Moderator
Date Reply #24 on Fri 19 Aug 2011 05:17 AM (UTC)
Message
Quote:
In my concept, triggers listen on a line source, and act as line sources themselves.
As far as I can tell, this is what Simulate does. But I keep hearing that Simulate is to be avoided.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #25 on Fri 19 Aug 2011 03:27 PM (UTC)
Message
No, Simulate pipes a line back to the primary source. Triggers should act as a line source themselves. Only triggers that know what they're getting into (i.e. are chained to this trigger) receive the newly-emitted line from the first trigger.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (23,042 posts)  [Biography] bio   Forum Administrator
Date Reply #26 on Fri 19 Aug 2011 09:59 PM (UTC)
Message
Out of curiosity, how do other clients handle this issue? If possible give examples, and describe how they avoid issues of looping.

I don't mean specifically "triggering on notes" as they may not have the concept of notes. But how do they handle the underlying problem that is trying to be solved?

Assuming for the moment (which may not be correct) that they allow textual substitution in the incoming line (the line you are triggering on), which alters how further triggers "see" the line, how do you handle things like multiple plugins both wanting to see (say) "{channel_tag}*" - if one trigger removes "{channel_tag}"?

Also if textual substitution is permitted, how to they handle colour boundaries on the source text?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Etzli   USA  (4 posts)  [Biography] bio
Date Reply #27 on Sat 20 Aug 2011 01:24 AM (UTC)

Amended on Sat 20 Aug 2011 06:22 AM (UTC) by Etzli

Message
The way they are handled is through priority. Example:

Trigger1 and Trigger2 have the same trigger patterns, but send different scripts for whatever reason. The trigger with the lower priority number will always fire first, and therefore, the trigger with the higher priority number will fire last. This can be seen in CMUD with the priority showing in the xml (and on the options tabs).

I imagine color boundaries are handled by "remembering" the location of the block of text being substituted. For instance, say the block of text was:

Quote:
This is a text block which I am substituting.


and you were wanting to substitute 'text block' with 'block of text.' The client sees that 'text block' starts at position 11 in the string (though with ansi codes, it'll count the beginning of the previous escape sequence) and ends on position 20. The rest of the string is stored in a temporary variable, preserving the ansi codes with it. The text is then substituted at position 11, therefore changing it to:

Quote:
This is a block of text which I am substituting.


Again, with the ansi escape sequences, the actual position will be much higher (e[1;34m, for example, adding another 7 characters) and the client would have to account for this.

My statement on color boundaries is pure speculation, as this is how I would imagine it works, but since I don't have the actual code itself, I cannot accurately give the proper procedure. That's the downside of non-open sourced clients.

As for how other clients prevent infinite loops, it's really on the part of the scripter to prevent infinite loops. What I mean by this is given a trigger that substitutes a line, if a scripter substitutes that line back to the original, that'll no doubt cause the infinite loop. Again with guessing, but it wouldn't surprise me if other clients put the text in a queue to be processed before being printed on the screen, something like below:

Quote:
Step one: Text received from MUD, place in internal queue.


Quote:
Step two: Is received text supposed to trigger substitution? If so, execute trigger. If not, proceed to step four.


Quote:
Step three: Is new text supposed to trigger a substitution? If so, repeat step two.


Quote:
Step four: Display text on screen.


Again, this is all speculation, and in a fantasy world, I'd be 100% right about the procedure, but maybe it'll serve as a ground point to implement what's being asked here today.
[Go to top] top

Posted by Nick Gammon   Australia  (23,042 posts)  [Biography] bio   Forum Administrator
Date Reply #28 on Sat 20 Aug 2011 05:48 AM (UTC)
Message
Etzli said:

The way they are handled is through priority. Example:

Trigger1 and Trigger2 have the same trigger patterns, but send different scripts for whatever reason. The trigger with the lower priority number will always fire first, and therefore, the trigger with the higher priority number will fire last.


So if Trigger1 changes the text, then Trigger2 won't fire at all? Because now the text is different?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Etzli   USA  (4 posts)  [Biography] bio
Date Reply #29 on Sat 20 Aug 2011 06:19 AM (UTC)
Message
Nick Gammon said:

So if Trigger1 changes the text, then Trigger2 won't fire at all? Because now the text is different?


Correct. Here's an example of how it goes:


TriggerID:        Test1
Trigger Pattern:  This is a test.
Trigger Output:   Sub with "This test is complete."
Trigger Priority: 0

TriggerID:        Test2
Trigger Pattern:  This is a test.
Trigger Output:   Print "This trigger should not fire."
Trigger Priority: 10


Now print to the screen "This is a test." Test1 will fire, subbing it with "This test is complete." Since Test2 has a higher priority, it never fires because the text is no longer "This is a test." Reverse the priorities, and both triggers fire.
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


103,053 views.

This is page 2, subject is 3 pages long:  [Previous page]  1  2 3  [Next page]

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]