TinTin++ Mud Client The TinTin++ message board

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
TinTin++ Mud Client

A better way for colour matching

 
Post new topic   Reply to topic    The TinTin++ message board Forum Index -> Finished Scripts
View previous topic :: View next topic  
Author Message
LokiChaos



Joined: 27 Oct 2009
Posts: 61

PostPosted: Sat Apr 16, 2016 10:23 pm    Post subject: A better way for colour matching Reply with quote

Colour-aware triggers are very helpful, but also a pain to write. Regex combined with multiple escaped characters, muds will send stateful SGR codes (that 0\; or 1\; may or may not be there!) and there are two ways to set the colours to the standard 16 if the mud supports 256-color mode, this makes for time spent with {CONVERT META} on, or pouring over raw logs to find the control codes and what is and is not consistent... When you are finished you have a mess of a pattern that most would barely consider readable.

Now, some have taken to using variables to hide away the mess, and recoup readability. However, it is not a perfect solution. You're limited to that set of fixed codes, leaving omitted attributes to foul matches. What about 256-color mode? Declare two actions? Pff!

There is a better way, first an example:
Code:

#act {@sgrinit{}@sgrp{yellow}[CLAN] %*@sgrfin{}} {#nop code here;}

At first it seems a bit verbose, you have at least two seemingly extra function calls, and why functions at all? Are variables not good enough?

Well lets take a look at what it actually creates:
Code:

#OK. {~\e[{0\;38\;5\;3|38\;5\;3|0\;33|33}m[CLAN] %*} NOW TRIGGERS {#nop code here;} @ {5}

What is that mess!? Can that really be better? Lets break it down:
@sgrinit{} returns '~' to make the pattern colour-aware, but it also sets the state for the SGR system.
@sgrp{yellow} returns '\e[{0\;38\;5\;3|38\;5\;3|0\;33|33}m' If you pick this apart you can see it actually is just a match against all of the possible SGR codes you might expect for "yellow" Specifically it matches against 4 options: 256 colour vs standard 16 and with or without the reset code to ensure it's dim.
@sgrfin{} returns nothing, but cleans up the state variable

That regex patten is long, longer than it has to be, {(|0\Wink(38\;5\;3|33)} would have shorter, but it also takes up more % references. @sgrp{} ALWAYS will return a pattern that takes up exactly ONE % reference, no matter what colour, attribute, or even a reset code it is attempting to generate a pattern for. This consistency means you can always keep track of what %[1-99] references and you can ignore what is going on internally.

Still, for this example, a single colour, it appears to be overkill, and there is no reason you couldn't just shove a bunch of these patterns in a var table... or is there?

@sgrp{} actually tracks the attribute state from the prior call, depending on how you have it set, it will be more or less strict about patterns. My MUD won't send a bold attribute code if it is already set. So I can expect subsequent codes to omit that if they will still be high-intensity, @sgrp{} will take this into account and will generate patterns that don't include the missing "1\;"

Now a more advanced example:
Code:

#act {@sgrinit{}@sgrp{!yellow}[CLAN] %*'@sgrp{!red}@sgrfin{}} {#nop code here;}
#OK. {~\e[{38\;5\;3|33}m[CLAN] %*'\e[{38\;5\;1|31}m} NOW TRIGGERS {#nop code here;} @ {5}

Shorter patterns, it skipped the "0\;" because they are not needed, the line starts with no attributes set and default fg/bg, so strictly only the fg colour needs to be set. In both patterns it skips it because it is unnecessary and the MUD won't send a patterns that resets things again. If the attribute is changing then it will /require/ it be part of the pattern.

There are 4 levels of "strictness": force (!!) which requires the attribute to be set, strict (!) which forces it to be there if it is changing and to not if the attribute is unchanged, if the state is unknown then it will produce a pattern that matches either. default (no prefix) will requite the attribute if it is being changed, but otherwise will match w/ or w/o it. Finally lax (?) will always assume the state is unknown and will match both w/ and w/o.

Finally the code:
https://github.com/LokiChaos/Materiamagica-on-tintin/blob/master/lib/vt.tt

Minor adaptation might be needed for your use, but the general logic is sound.

I'm still tweaking it and probably a few bugs lurking about, but feel free to give it a try.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    The TinTin++ message board Forum Index -> Finished Scripts All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Get TinTin++ Mud Client at SourceForge.net. Fast, secure and Free Open Source software downloads Get TinTin++ Mud Client at SourceForge.net. Fast, secure and Free Open Source software downloads
TinTin++ Homepage

Powered by phpBB © 2001, 2002 phpBB Group