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


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Suggestions
. . -> [Subject]  Allowing multiple Send/Script calls on same line, Repeat on same line

Allowing multiple Send/Script calls on same line, Repeat on same line

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


Pages: 1 2  3  

Posted by Kevnuke   USA  (145 posts)  [Biography] bio
Date Fri 05 Mar 2010 02:35 AM (UTC)

Amended on Fri 05 Mar 2010 02:36 AM (UTC) by Kevnuke

Message
I recently read every single entry in the release notes section for MUSHclient. And yes, it took a while, but it was worth it. For one thing it gave me a good idea of what the client is capable of and gave me a few ideas for suggestions. I'm glad to see telnet subnegotiation was simplified since I was here last. (More on that in a different post.) Ultimately I discovered the reason that something I was trying to do wasn't working. MUSHclient allows a trigger to match the same pattern more than once on the same line of text from a MUD. What it will -not- do is send the contents of the Send box or parse a script in the Script box more than once on the same line. This is very annoying when I am trying to make one trigger to capture the contents of my rift on achaea and I have to make a seperate trigger for each herb/item to do so.

For example:

[  90] prickly ash bark    [ 100] sileris   [2050] skullcap--the line coming from the MUD might look like this
"[\s*(\d+)]\s(prickly ash bark|sileris|skullcap)"--I was planning to use a trigger like this with all the herbs in the list
print ("%2", %1)--This is just an example, I actually was trying to do something like inr["%2"]=%1

I was wondering if a flag could be added to the triggers that allows one to send for -each- match on a trigger that repeats on same line.
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #1 on Fri 05 Mar 2010 02:39 AM (UTC)

Amended on Fri 05 Mar 2010 02:42 AM (UTC) by Twisol

Message
How bizarre. For the record, I've confirmed this with the following:

<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="testers"
   regexp="y"
   repeat="y"
   send_to="12"
   sequence="100"
  >
  <send>Note("Got")</send>
  </trigger>
</triggers>


Simulate("testers testers\r\n")


Output: two yellow-colored words "testers", but only one note "Got".


I'm personally in favor of not even bothering with a separate option and just applying a fix to all "Repeat on same line" reflexes.

'Soludra' on Achaea

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

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Fri 05 Mar 2010 03:08 AM (UTC)
Message
It is supposed to do that. From the help:


Repeat on same line

If checked, the trigger is matched repeatedly against the same line (this only applies to regular expressions). This lets you colour individual words which might appear more than once on a line.


It colours multiple words, but the send text (or script or whatever) is only done once. In any case it would be hard to identify which wildcard you wanted in each iteration of the script.

This is mentioned here:

Template:post=8903 Please see the forum thread: http://gammon.com.au/forum/?id=8903.


In your case, since it looks like the text is simple, a simple regex in Lua would process the matching line, and break it up for you.

- Nick Gammon

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

Posted by Kevnuke   USA  (145 posts)  [Biography] bio
Date Reply #3 on Fri 05 Mar 2010 03:14 AM (UTC)
Message
You mean the rex library in Lua? O.o
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #4 on Fri 05 Mar 2010 03:35 AM (UTC)

Amended on Fri 05 Mar 2010 03:39 AM (UTC) by Twisol

Message
I think he means something more like string.match, the normal string library. Though 'rex' is an interface to the exact same library MUSHclient uses for matching.

Assuming the line always has one to three sets of herbs (and also assuming this is for the herb-storing Rift in, say, Achaea or another IRE game), you could probably use this pattern instead:

^[\s*(\d+)] ([a-z '-]+?)\s*(?:[\s*(\d+)] ([a-z '-]+?)\s*(?:[\s*(\d+)] ([a-z '-]+?))?)?$


It's not pretty - ugly as a matter of fact - but it does work. Example trigger:

<triggers>
  <trigger
   enabled="y"
   match="^[\s*(\d+)] ([a-z '-]+?)\s*(?:[\s*(\d+)] ([a-z '-]+?)\s*(?:[\s*(\d+)] ([a-z '-]+?))?)?$"
   name="herbtrigger"
   regexp="y"
   repeat="y"
   send_to="12"
   sequence="100"
  >
  <send>if GetTriggerOption("herbtrigger", "script") == "" then
  local func_name = "_" .. GetUniqueID()
  _G[func_name] = function(name, line, matches, styles)
    tprint(matches)
  end
  SetTriggerOption("herbtrigger", "script", func_name)
end</send>
  </trigger>
</triggers>


This trigger takes advantage of the fact that the Send box is run before the Script function in order to make it an atomic unit, by setting the trigger's script field when it's first triggered. It's not something you'd really do often, and it's unrelated to the matter at hand, but in case you were wondering...

Example output:
-- Simulate("[  90] prickly ash bark    [ 100] sileris   [2050] skullcap\r\n")

0="[  90] prickly ash bark    [ 100] sileris   [2050] skullcap"
1="90"
2="prickly ash bark"
3="100"
4="sileris"
5="2050"
6="skullcap"

-- /Simulate("[  90] prickly ash bark\r\n")
0="[  90] prickly ash bark"
1="90"
2="prickly ash bark"
3=false
4=false
5=false
6=false




Nick: To you I must ask, why does "Repeat on same line" behave this way anyways? It seems inconsistent with what you would expect.

'Soludra' on Achaea

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

Posted by Kevnuke   USA  (145 posts)  [Biography] bio
Date Reply #5 on Fri 05 Mar 2010 05:16 AM (UTC)

Amended on Fri 05 Mar 2010 05:19 AM (UTC) by Kevnuke

Message
That's the problem, if i only have one or two herbs in my rift then that won't work. And you lost me at the "'-" part of that pattern O.o Not sure what that does.. but anyway, I'm not sure how hard it would be to just make it so it would Send or parse a script function each time a repeat on same line trigger matched. And if it worked the way i was trying to use it, th wildcards match would be simple, Nick. Just the first and second wildcard for -each- match. Like according to the trigger it would just print the name of the herb and how many of them there were for that herb. Oh and i wouldn't mind if you dissected that pattern for me ^^, looks like a couple backreferences in there, am i right?
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Fri 05 Mar 2010 05:19 AM (UTC)
Message
Well, bearing in mind the client was developed over 10 years, and that triggers colouring stuff on lines was done early, and scripting was added later.

However I think also that the event "the trigger matches a line" has a corresponding "the send box is executed" (or the script). The multiple-colouring is really a sub-event, if you see what I mean.

Really, processing that extra stuff is something you can simply do with a string.gmatch, iterating over the line you matched on.

The other thing to consider is, changing something like that is a *major* change that is likely to break a lot of existing scripts.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #7 on Fri 05 Mar 2010 05:29 AM (UTC)

Amended on Fri 05 Mar 2010 05:30 AM (UTC) by Nick Gammon

Message
It's easy to process the line in Lua, don't get too worked up about trying to do it in a huge regexp in the trigger. As long as the trigger matches the general idea, do the fiddly stuff in Lua, eg.


test = [[
  [  23] yarrow             [ 588] colewort           [ 144] wormwood
  [ 192] kombu              [ 158] reishi             [ 103] arnica
  [1305] coltsfoot          [ 201] yellowtint         [ 251] pearl
  [ 304] moonstone          [1077] platinum           [1200] gold
  [ 425] greentint          [ 297] marble             [1497] wood
  [ 502] rope               [  90] redtint            [ 279] amethyst
  [ 188] jade               [ 359] bloodstone         [ 298] bluetint
  [ 240] ruby               [ 105] turquoise          [ 351] beryl
  [ 260] emerald            [ 405] onyx               [ 300] gems
  [ 281] opal               [ 244] purpletint         [ 399] cloth
  [ 225] coral              [ 880] steel              [ 288] garnet
  [ 303] sapphire           [  21] goldtint           [ 100] coal
  [ 678] salt               [ 600] sulfur             [ 169] pennyroyal
  [ 682] sparkleberry       [ 152] earwort            [1056] marjoram
  [ 107] rosehips           [  11] sage               [ 180] silver
  [ 129] myrtle             [ 170] horehound          [  39] galingale
  [ 909] calamus            [ 174] kafe               [  29] merbloom
  [ 385] iron               [  26] juniper            [ 416] mistletoe
  [ 219] spices             [ 436] diamond            [ 328] leather
  [ 165] chervil            [ 200] sargassum
]]

for num, herb in string.gmatch (test, "%[%s*(%d+)%] (%a+)") do
  print (num, herb)
end -- for

--> Output

23 yarrow
588 colewort
144 wormwood
192 kombu
158 reishi
103 arnica
1305 coltsfoot
201 yellowtint
251 pearl
304 moonstone
1077 platinum
1200 gold
425 greentint
297 marble
1497 wood
502 rope
90 redtint
279 amethyst
188 jade
359 bloodstone
298 bluetint
240 ruby
105 turquoise
351 beryl
260 emerald
405 onyx
300 gems
281 opal
244 purpletint
399 cloth
225 coral
880 steel
288 garnet
303 sapphire
21 goldtint
100 coal
678 salt
600 sulfur
169 pennyroyal
682 sparkleberry
152 earwort
1056 marjoram
107 rosehips
11 sage
180 silver
129 myrtle
170 horehound
39 galingale
909 calamus
174 kafe
29 merbloom
385 iron
26 juniper
416 mistletoe
219 spices
436 diamond
328 leather
165 chervil
200 sargassum


- Nick Gammon

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

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #8 on Fri 05 Mar 2010 05:33 AM (UTC)
Message
Kevnuke said:

That's the problem, if i only have one or two herbs in my rift then that won't work. And you lost me at the "'-" part of that pattern O.o Not sure what that does.. but anyway, I'm not sure how hard it would be to just make it so it would Send or parse a script function each time a repeat on same line trigger matched. And if it worked the way i was trying to use it, th wildcards match would be simple, Nick. Just the first and second wildcard for -each- match. Like according to the trigger it would just print the name of the herb and how many of them there were for that herb. Oh and i wouldn't mind if you dissected that pattern for me ^^, looks like a couple backreferences in there, am i right?


Nope! I'll dissect it for you, but first notice that it did match when I only gave it one herb listing. It just filled matches 3 to 6 as 'false', which is perfectly useful as a "hey, this only had one (or two) herb" flag.

The basic 'component' here is this:

\[\s*(\d+)\] ([a-z '-]+?)


This will match, for example, "[ 100] eagle's feather". You have \[\s*(\d+)\] that does that, you should recognize it. Then there's ([a-z '-]+?), which is a character group being captured. It matches the herb's name, which can have (lowercase) letters, spaces, apostrophes, and dashes. I don't know if any riftables have dashes, but I threw it in there just in case. You know the + at the end, but when it's modified by a ?, it becomes non-greedy. This is so that it doesn't swallow up the trailing spaces that come before the next item in the list.

Lets call that section HERBREX. This doesn't mean anything and you can't use that name in practice, it's just for explanatory purposes here. Replacing the above section with HERBREX in the full regex, it looks like this:

^HERBREX\s*(?:HERBREX\s*(?:HERBREX)?)?$


Now maybe you can see, it matches either one, two, or three HERBREX's. :)

'Soludra' on Achaea

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

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #9 on Fri 05 Mar 2010 05:39 AM (UTC)

Amended on Fri 05 Mar 2010 05:40 AM (UTC) by Twisol

Message
Nick Gammon said:
Well, bearing in mind the client was developed over 10 years, and that triggers colouring stuff on lines was done early, and scripting was added later.

[...]

The other thing to consider is, changing something like that is a *major* change that is likely to break a lot of existing scripts.

Fair point!

Nick Gammon said:
However I think also that the event "the trigger matches a line" has a corresponding "the send box is executed" (or the script). The multiple-colouring is really a sub-event, if you see what I mean.

I always considered it to be something that acted on matches, not lines. The typical use case has a match per line, which is why this perspective was unchallenged for so long, but when you have multiple matches on the same line, it clearly breaks down. I would much prefer that the whole trigger act per-match rather than per-line, simply because if you have a simple pattern and you want it to match multiple times on a single line, that's what you would expect. But I understand that it's far too late by now.

'Soludra' on Achaea

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

Posted by Kevnuke   USA  (145 posts)  [Biography] bio
Date Reply #10 on Fri 05 Mar 2010 11:52 PM (UTC)

Amended on Sat 06 Mar 2010 12:35 AM (UTC) by Nick Gammon

Message
As far as I've seen, none of the achaean riftable items have apostrophes or dashes, at least not the herbs, anyway. and the "?:" is a quantifier that means 0 or 1 of the item it points to? I looked for it in the PCRE file but maybe I just missed it. But as far as being a major change... that's why I suggested that it could just be a flag option. Not sure if that makes huge a difference in terms of coding it. I know some Lua, a little more than just basics, but I still have trouble wrapping the finer points of coding logic around my brain. I know you gave an example above for how it could be done, but i'm not sure I would know how to change it to work for something else. And on a final note, I was actually planning to use it in a plugin to set the number of herbs in my rift as part of a curing system, when I figured out how to get it working. Thanks for all the input and help so far.

EDIT: And i'm aware of the plugin callbacks like OnPluginLineReceived and such but i'm not sure if that would make things any easier, as far as the actual coding goes. Could that be used to replace a trigger entirely since it gets called before everything else?

And just to be clear i have a table called "inr" and an index for each herb, like for the item "prickly ash bark" the index is "ash", i want the trigger to capture the name of the herb and how many there are. I know the name conversion can be done with a simple table like:

herbs = {["prickly ash bark"] = "ash", ["bayberry bark"] = "bayberry", etc}

and in the trigger it would look like this:

if herbs["%2"] then
    inr[herbs["%2"]] = %1
end

if i used the trigger I used earlier with %1 being the number and %2 being the name of the herb in the output.
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #11 on Sat 06 Mar 2010 12:46 AM (UTC)
Message
I just don't think that having the trigger repeat on the same line, and pass the match each time to your script is going to make your life much easier.

Take this line for example:


  [  23] yarrow             [ 588] colewort           [ 144] wormwood


A fairly simple trigger will match that, eg.:


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="^(\s*\[\s*\d+\] \w+){1,3}\s*$"
   regexp="y"
   send_to="2"
   sequence="100"
  >
  <send>matched! %%0 = %0</send>
  </trigger>
</triggers>


Now that gives you a match on that type of line and no other types, and then you run the string.gmatch over %0 to pull out the 3 lots of data.

But to do "repeat on same line" you have to narrow the regexp down to the part that repeats, in other words something that matches on, say "[ 23] yarrow". And then you set it to repeat, OK, that is your plan right?

But now it can be spoofed. I could say to you:


Nick says, "Hey Kevnuke, guess what? [  99] yarrow [ 777] colewort [ 200] wormwood"


And your trigger will fire and start processing data incorrectly. That is why the "repeat on same line" was really for colouring words, eg. if you have a friend "Nick" you can make a trigger that colours "Nick" every time, even multiple times on the same line. But for scripting? I don't think it is as useful.

- Nick Gammon

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

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #12 on Sat 06 Mar 2010 02:07 AM (UTC)
Message
Kevnuke said:
As far as I've seen, none of the achaean riftable items have apostrophes or dashes, at least not the herbs, anyway.

Eagle's feather. Lady's slipper.

Kevnuke said:
and the "?:" is a quantifier that means 0 or 1 of the item it points to? I looked for it in the PCRE file but maybe I just missed it.

Nope. Example: \d+? means "zero or one", but (?:\d+) means "don't save this capture group". You can think of ?: as a modifier for the opening ( of the capture.

Kevnuke said:
EDIT: And i'm aware of the plugin callbacks like OnPluginLineReceived and such but i'm not sure if that would make things any easier, as far as the actual coding goes. Could that be used to replace a trigger entirely since it gets called before everything else?

Yes, it could be, and in fact I know someone who's doing just that for his own custom (and rather advanced) system. But in general you'd just be rewriting exactly what MUSH itself does.

'Soludra' on Achaea

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

Posted by Kevnuke   USA  (145 posts)  [Biography] bio
Date Reply #13 on Wed 10 Mar 2010 11:14 PM (UTC)

Amended on Wed 10 Mar 2010 11:15 PM (UTC) by Kevnuke

Message
Twisol said:

Eagle's feather. Lady's slipper.

Those are not -herbs-..
They are used for concoctions by the forestal classes.
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #14 on Wed 10 Mar 2010 11:17 PM (UTC)

Amended on Wed 10 Mar 2010 11:22 PM (UTC) by Twisol

Message
Lady's slipper is absolutely an herb! You find it in the grasslands. (I think I know my herbs, I'm a long-time Sylvan. ;) )

Also, you can find non-herb items on the same line as herb items in the rift, so if you don't account for all possibilities in the match, you'll have a hard time getting a match when you should be. Match the general case, and trim down to the specific case in script.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[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.


93,884 views.

This is page 1, subject is 3 pages long: 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]