This could be a first - two updates in the same month. In actuality, I suspect Mesmerizer 1.6.4 and The Enforcer 1.1.2 will be released early next month.
Mesmerizer 1.6.4
Mesmerizer 1.6.4 fixes another minor bug reported by Allison from Trance Lab, as well as a permissions error that caused the Mesmerizer to be no-copy (although you could obtain a fresh copy if needed via a redelivery). However, the focus of this update is mostly on making leashing work more effectively in preparation for the new CHAOS Collar range. Previously, leashing was implemented by internally using the follow command with the addition of a visible chain. Follow works fine, but it allows the sub to trail behind their owner, and in high-lag sims there can be a good distance built up between them This doesn't look right if the sub is supposed to be leashed to the dom. So Mesmerizer 1.6.4 gives leash its own more aggressive mechanism to stay close to the dom. The follow command retains its original behavior.
Another minor enhancement is the addition of a built-in Mesmerizer variable called "hypnotist" that will be set (if the wearer is in trance) to the key of their hypnotist. If no trance is in effect, the variable will be set to "none". The primary purpose of this is to allow Enforcer programming to test whether the wearer is in the middle of a trance before doing something that might be disruptive.
For example, suppose that you want to periodically send the sub some text from The Enforcer, using the Mesmerizer's text command inside an event notecard "SendText" that requeues itself every 10 minutes while the sub is still online. That requeuing would likely use the !eventin command, possibly using !checkonline first to determine whether the sub is actually online, and only executing !eventin if they are. However, if the sub is in trance, the text command is likely to overwrite trance text and generally disturb the flow of the trance.
One way to check that the sub is both logged in (eliminating the need to call !checkonline) and not in trance is to invoke the SendText notecard not directly via !eventin, but indirectly by making the sub signal the event, and as part of that signal, include whether or not a trance is active.
To do this, you need a second notecard, which we'll name "SignalSendText". All this notecard does is send a signal command to the sub, using a command like:
^signal "SendText" "$$hypnotist"
This SignalSendText event is the event that would be scheduled via !eventin inside the SendText notecard, and if you want to run the event manually, it's what you would cause to fire. SignalSendText tells the sub's Mesmerizer to signal a SendText Enforcer event, and pass the value of the Mesmerizer symbol hypnotist in the event's data variable. Note the use of the double-$ which suppresses variable expansion in The Enforcer, and instead replaces the double-$ with a single $ in the command sent to the Mesmerizer so that the variable expansion will happen in the Mesmerizer, and be returned to The Enforcer in the signaled event.
If the sub isn't logged in, there will be no Mesmerizer there to execute the signal, so no more events will be scheduled. If they are logged in, then they'll signal the SendText event, which should check the value of $data to see if they're in trance. If their Mesmerizer is 1.6.4 (or later), this symbol will contain either their hypnotist's key, or "none" if they're not in trance. An older Mesmerizer will likely not have the variable hypnotist defined, so the "$hypnotist" in the second parameter to signal will be replaced by "hypnotist" - this is the original behavior for expansion of undefined symbols that I mentioned when I changed it in The Enforcer - The Mesmerizer still uses the original behavior, at least for now.
This technique of having The Enforcer send a signal command to the Mesmerizer is a straightforward way to obtain information from the Mesmerizer that would otherwise be unavailable to The Enforcer. The parameter to signal is fairly limited - while you can pass a list as the parameter to collect multiple pieces of data at once, each list element is pretty much constrained to being obtained via variable expansion. But if you want to keep track of some state information for which there isn't a built-in variable, you can sometimes use a Mesmerizer trigger to maintain your own state variable for use in a signal. If you find yourself doing this, let me know, and I may well add a built-in variable if whatever you're tracking is of general utility.
The Enforcer 1.1.2
Hot on the heels of The Enforcer 1.1.1 comes another bug-fix release, to address a bug found (yet again) by Allison. This bug concerns variable expansion and how that plays with the use of "::" as an argument separator in Mesmerizer commands. Previously, variable expansion was done before parsing out the arguments from a command, so if a variable that was expanded contained two successive colons as a substring, that would be interpreted as an argument separator. This is almost never what's intended. Enforcer 1.1.2 fixes this so that the argument separators are parsed first, before variable expansion takes place. At the same time, I fixed another bug where external whitespace surrounding the arguments was not being ignored.
A related but distinct bug arises from expansion of symbols that contain either single or double quote marks. Since the double-colon is used to separate arguments of a Mesmerizer command, quote marks are really only significant in expressions, or in commands that are to be sent to the Mesmerizer. Usually you know if a variable expansion might contain one of these characters, and (at least within expressions) you can use the other one to delimit the words of the expression. However, if the variable is obtained from "outside" (for instance, it's the name of an object that was sat-on), then it might contain either or both types of quote mark.
To allow for this, while providing a potentially useful new function, The Enforcer 1.1.2 will contain a new command: !charmap. This command takes three arguments - the first is a string, which can contain "unsafe" characters since it's in an argument position; the second is a map, and the third is the name of a variable into which the mapped string will be written. The map (the middle argument) tells !mapchar which characters should be replaced, and what they should be replaced with. It is simply a string that contains pairs of characters, and if the first character in a pair appears in the input string, then it will be replaced by the second character in the output string. So for instance:
!charmap This value contains both " and ' and neither are matched :: "' :: output
will result in $output containing the string "This value contains both ' and ' and neither are matched" (without the surrounding double-quotes). The map-string may not be very legible in a browser, but it contains two characters - a double-quote followed by a single quote, and it tells !charmap to replace any double-quotes with single quotes. So !charmap can be used to "sanitize" unknown strings by replacing potentially troublesome characters with more innocuous ones.
Note that because whitespace surrounding a command argument is now ignored, if you want to write a map that involves space characters, you need to make sure that space is neither the first nor last character of the map. Usually this is easy - you just put character pairs that contain a space character somewhere other than at the start or end of the map. If you can't do this (for instance, if you're writing a map to convert space characters to underscores), then you need to add a dummy pair so that the space is internal to the map. So a map that converts spaces to underscores might look something like:
!charmap $input :: .. _ :: output
The map string is four characters: two periods, a space and an underscore. So it consists of two pairs - the first maps a period to a period, which is a no-op, and its sole purpose is so that the next pair, which maps a space to an underscore, is not at the start of the map so that the space in it will not be ignored.
!charmap has a lot of other potentially interesting uses, which is why I decided to expose it as a general-purpose command rather than building in a specific sanitization rule. For instance, it could be used to convert a string to lowercase via a map such as:
AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
To be sure, this is a fairly inefficient way of down-casing a string, but previously it wasn't even possible in The Enforcer.