Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » Finished MUD Scripts
Caled
Sorcerer


Joined: 21 Oct 2000
Posts: 821
Location: Australia

PostPosted: Sun Jun 10, 2001 2:31 am   

an anti anti-trigger system, originally for Achaea
 
This is a system I wrote for Achaea. It is actually no longer useful for Achaea as the offensive skill it was designed to negate was completely changed (no less than a week after I wrote the script ).
I've decided to put it up here anyway because it could be modified and used for people whose muds randomly insert characters (such as *) in order to foil triggers.

The skill this script was designed to foil is called "hypnosis" in Achaea. A person would hypnotise you, then say a trigger word that would set off what you had been hypnotised with. The cure was to simply say the hypnoword. There was a list of "hypnowords" that were known to everyone.

The difficult part was that people would "mutter" the word - which would randomly replace letters in the word with periods (.)

So:
"mutter hypnosis"
would return something like:
Zugg mutters, "H..no.is."

The script I wrote basically "de-mutters" muttered words - if they are on the list.

I'm placing the script in the next reply, then I'll comment on how it works etc in a 3rd reply.

Caled
zMud 6.16
Reply with quote
Caled
Sorcerer


Joined: 21 Oct 2000
Posts: 821
Location: Australia

PostPosted: Sun Jun 10, 2001 2:33 am   
 
OKay...here is the script itself. For some reason one of the triggers doesnt import correctly, but it isnt a crucial trigger so it doesnt matter.
 

#CLASS {Curing|Venoms|Snakes|Hypnosis}
#ALIAS checkmutter {#VARIABLE hwordlength %len( @orimutterword);#UNTIL (@periodpos = 0) {#VARIABLE periodpos %pos( ., @mutterword);#ADDITEM periodposlist %pos( ., @mutterword);#VARIABLE mutterword %delete( @mutterword, @periodpos, 1);#VARIABLE mutterword %insert( A, @mutterword, @periodpos)};#DELITEM periodposlist 0;mutterword=@orimutterword;checklist}
#ALIAS checklist {#FORALL @{hypnoword_@hwordlength} {checkword %i}}
#ALIAS sorthlist {#FORALL @hypnowordtotal {#VARIABLE currentsortword %proper( %i);#VARIABLE hwordlen %len( %i);#ADDITEM hypnoword_@hwordlen @currentsortword}}
#ALIAS checkword { #VARIABLE chypnoword %1;#FORALL @periodposlist {#VARIABLE periodins %copy( @chypnoword, %i, 1);#VARIABLE mutterword %delete( @mutterword, %i, 1);#VARIABLE mutterword %insert( @periodins, @mutterword, %i)};#IF (@mutterword = @chypnoword) {say @mutterword;#ECHO Match found!!;:spam: HYPNOWORD - @chypnoword;#ABORT 1} { mutterword=@orimutterword}}
#ALIAS properlist {#FORALL @hypnowordtotal {#DELITEM hypnowordtotal %i;#ADDITEM hypnowordtotal %proper( %i)}}
#VAR hypnowordtotal {Epicurus|Yggdrasil|Horrendous|Hashan|Subterfuge|Concoctions|Slithering|Vituperate|Slain|Liability|Pachacacha|Seleucar|Wisdom|Constantine|Pazuzu|Archon|Sultan|Averroes|Filled|Shallam|Shastaan|Domination|Spirituality|Necromancy|Tomacula|Applying|Assassin|Beaches|Potato|The|Zarathustra|Obelisk|Regent|Seneschal|Flame|Fortune|Serpents|Philosophy|Chivalry|Judgement|Voltaire|Going|Smoking|Assassinate|Nicator|Stormbringer|Farewell|Vizier|Overseer|Yudhishthira|Polyargos|Quorum|Logosian|Chrysalis|Quixotic|Quohog|Marathon|A}
#VAR hypnoword_1 {A}
#VAR hypnoword_10 {Horrendous|Subterfuge|Slithering|Vituperate|Pachacacha|Domination|Necromancy|Philosophy}
#VAR hypnoword_11 {Concoctions|Constantine|Zarathustra|Assassinate}
#VAR hypnoword_12 {Spirituality|Stormbringer|Yudhishthira}
#VAR hypnoword_3 {The}
#VAR hypnoword_5 {Slain|Flame|Going}
#VAR hypnoword_6 {Hashan|Wisdom|Pazuzu|Archon|Sultan|Filled|Potato|Regent|Vizier|Quorum|Quohog}
#VAR hypnoword_7 {Shallam|Beaches|Obelisk|Fortune|Smoking|Nicator}
#VAR hypnoword_8 {Epicurus|Seleucar|Averroes|Shastaan|Tomacula|Applying|Assassin|Serpents|Chivalry|Voltaire|Farewell|Overseer|Logosian|Quixotic|Marathon}
#VAR hypnoword_9 {Yggdrasil|Liability|Seneschal|Judgement|Polyargos|Chrysalis}
#VAR hypnowordtotal_bak {epicurus|yggdrasil|horrendous|hashan|subterfuge|concoctions|slithering|vituperate|slain|liability|pachacacha|seleucar|wisdom|constantine|pazuzu|archon|sultan|averroes|filled|shallam|shastaan|domination|spirituality|necromancy|tomacula|applying|assassin|beaches|potato|the|zarathustra|obelisk|regent|seneschal|flame|fortune|serpents|philosophy|chivalry|judgement|voltaire|going|smoking|assassinate|nicator|stormbringer|farewell|vizier|overseer|yudhishthira|polyargos|quorum|logosian|chrysalis|quixotic|quohog|marathon|A}
#TRIGGER {* mutters, "(%x) %x*} {#IF (%pos( ., %1) > 0) {} {#ABORT 1};periodposlist=%null;orimutterword=%1;mutterword=@orimutterword;checkmutter}
#TRIGGER {* mutters, "({@hypnowordtotal})."} {say %1}
#TRIGGER {* mutters, "({@hypnowordtotal}) %x *"} {say %1}
#TRIGGER {* mutters, "(%x)."} {#IF (%pos( ., %1) > 0) {} {#ABORT 1};periodposlist=%null;orimutterword=%1;mutterword=@orimutterword;checkmutter}
#CLASS 0


Caled
zMud 6.16
Reply with quote
Caled
Sorcerer


Joined: 21 Oct 2000
Posts: 821
Location: Australia

PostPosted: Sun Jun 10, 2001 2:35 am   
 
The script works as follows:
1) The triggers capture the muttered word into a variable, then execute the "checkmutter" alias.
2) The checkmutter alias records the positions of all periods (.) into a stringlist, as well as recording the length of the word. It then executes the "checklist" alias.
3) The checklist alias uses the length of the word to decide which stringlist of hypnowords to use (the hypnowords are sorted into different stringlists according to their length...so 5-letter hypnowords will all be in "@hypnoword_5"). Once it has decided this, it executes the "checkword" alias with respect to the selected stringlist.
4) The checkword alias compares each word in the stringlist to the muttered word and stops if it finds a match.

The "sorthlist" sorts hypnowords in the "hypnowordtotal" list into other lists dependant on their length.

The "properlist" alias changes all words in the "hypnowordtotal" list to proper case - something that I had to do at a later date to fix a mistake I made .

The reason I had to have the words sorted into lists dependant on their lengths is because of speed problems.

To test it out, enter commands like this, in the command line:

#say Zugg mutters, ~"Slit.er..g."

and the triggers will fire off this. The word above is "Slithering".

Lastly.....
It was a post made by Tarn a long time ago, where he said it should be possible to trigger even against randomly inserted characters designed to foil triggers that inspired me to do this - if there is an easier (and more importantly, a faster) way of doing this, could someone tell me?



Caled
zMud 6.16
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Thu Jan 10, 2002 11:57 pm   
 
quote:

It was a post made by Tarn a long time ago, where he said it should be possible to trigger even against randomly inserted characters designed to foil triggers that inspired me to do this - if there is an easier (and more importantly, a faster) way of doing this, could someone tell me?



Oops, sorry, your question slipped 'under my radar'.

My original posts concerned the following problem:

'Proper' mud output looks like:
You see Bob.

Sometimes the mud chooses to output this as:
Yo* see Bob.

Problem: Recognize the second string to 'really' be the former.

Solution: 1 trigger.

Pattern:
(*)~*(*)

Value:
#var line %concat(%1,"*",%2)
#trigger {@line} {#show Bob Detected!} junktrig
#exec "Bob is here."
#untrigger {@line} junktrig

Where the #exec contains the 'real line' and this will try to match it against any line containing a '*'.

I've made this considerably longer than it has to be for a few reasons:
1) I think this is the clearest way to present it so that others can adapt it to their needs.
2) In practice, you may want to do the Replace differently, for instance if you know asterisks will only mask one character, use that knowledge instead of using the full '*' wildcard.
3) You may want to add more #exec's if there are 1 or two more different things that might be mangled.

Note: Before using this in a real mud, I think you might want to do something like adding a low priority trigger to absorb the stuff sent by the #exec's if they don't match.

Tested 6.16.

-Tarn
Reply with quote
Kjata
GURU


Joined: 10 Oct 2000
Posts: 4379
Location: USA

PostPosted: Fri Jan 11, 2002 1:35 am   
 
I also have a solution. This one works with a random number of asterisks in random places as long as you know the correct string and as long as the output is not so mangled that multiple lines may match (but when it gets this worse, the output is usually no longer readable). Here it goes:
#TRIGGER {~*} {#VAR mangled %line;#VAR temp @real;#WHILE (%pos("*", @mangled)) {#VAR temp %delete(@temp, %pos("*", @mangled), 1);#VAR mangled %delete(@temp, %pos("*", @mangled), 1)};#IF (@mangled = @temp) {#SH We have a match!} {#VAR real ""}}

Lets use as an example a problem someone once posted when you are poisoned. The text is not exactly like this, but you get the idea:
Kjata bites you hard, sending poison through your veins.
A p*ickl* sens*tion runs th*ough your b*dy.

We could trigger off the first line, but the problem is that the second line might be different and then instead of curing simple posion, you might have to cure paralysis or some other affliction. However, since what we are trying to catch is the poison message, we can create a trigger that will fire off the first line and set @real to "A pric kly sensation runs through your body." (The space is because the forum thinks I'm swearing.)

This script could be modifyied and made better. Maybe instead of comparing agaisnt a single line at the end, we could use a stringlist with various different patterns that you know will get mangled. But the basic concept remains the same - look at the position of each asterisk in the mangled line, delete the corresponding characters in the correct line and the asterisks in the mangled line, and then compare the two lines with the characters and asterisks removed.

Kjata
Reply with quote
Tarn
GURU


Joined: 10 Oct 2000
Posts: 867
Location: USA

PostPosted: Fri Jan 11, 2002 2:21 am   
 
quote:

This one works with a random number of asterisks in random places as long as you know the correct string and as long as the output is not so mangled that multiple lines may match



Mine has the same virtues and limitations (multiple asterisks randomly distributed are fine, and you have to have enough of the original string intact that the match is unique because there's no 'cost' function to find the closest match). Jouster demonstrated an approach probably slightly faster than your explicit character replacement scheme (two Octobers ago?) which I think has fallen out of the archive (he went left to right comparing each character, giving a free pass to wildcards in the mangled string). Someone with the handle of 'UselessInfo' posted what amounts to a mostly functional cost function on 4/5/01 that might be helpful for mangled single words in particular.

My bias is towards scripts that 'look' simple, and then towards speed.

Yours might speed up a bit if you replace the stars in the mangled string with characters from the same place in the intact string instead of deleting a character both from the intact and mangled strings. That way, you don't have to fix the intact ones every time; they stay perfect. It's also often much quicker to replace one character in a variable length string than to delete a character from it, but I haven't run speed trials in zMud on this. You could also run a quick length check on the mangled string to make sure it's right before doing anything more complicated.

All of these speed issues become important mainly when you've got a big list of things to match against.

-Tarn
Reply with quote
Caled
Sorcerer


Joined: 21 Oct 2000
Posts: 821
Location: Australia

PostPosted: Fri Jan 11, 2002 6:13 am   
 
The example given by Kjata "prickly sensation" is direct from Achaea. Some time after I wrote that hypnosis one, I came up with a better way of doing it for the paralysis.

#VAR curaremsg {A prickly sensation blah blah blah}
#TR {(*)~*(*)~*(*)~*(*)} {
#IF (%pos(%1,@curaremsg) > 0) {#C0 5706;#ABORT 1}
#IF (%pos(%2,@curaremsg) > 0) {#C0 5706}
}
The reason I have it check %1 and %2 is because there is a comma in there somewhere, and if the comma is in %1 it wont match.

This system is very simple, and except on the rare occasion that there are only 2 *'s in the line, it never fails.
I havnt given the entire thing here - people in Achaea can copy that trig if they wish,
but they will notice nasty things such as it firing off people grinning over the guild channel etc.
There are ways to stop it doing that, but I'll leave that up to the more resourceful to figure out.

Let Sarapis (the achaean author) throw all the
anti trigger stuff at us that he likes: there
will always be a way around it, and I dont feel that I'm cheating,
cos I only use it to colour the affs anyway.
Its quite simple to modify it so that it works for multiple affliction messages, but at this
stage in Achaea, paralysis from curare venom is the only one that scrambles.

Caled
(edited to tell you that the ***** up above must be some sort of "anti-profanity" mechanism built into this forum...should read "pri ckly" - without a space in the middle
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » Finished MUD Scripts All times are GMT
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

© 2009 Zugg Software. Hosted by Wolfpaw.net