Raw game output - matching for escapes

Posted by damccull on Fri 18 Jan 2013 09:36 AM — 10 posts, 33,200 views.

USA #0
Is there a way to manipulate or parse the raw game output, to include its ansi codes, in a script? In other words, I don't want the script to read lines from the buffer after they've been parsed, but I want to get the raw ansi codes used to color the text from my script.

One of the games I play has a 'sound' engine built into it. Basically it plays ANSI sounds. The sound commands are sent to the client in a specific format that is preceded by 'esc[' and I need to be able to match on that character in a trigger because there is no other way the sounds are marked.

Additionally, using triggers themselves seems to not allow matching of non-printable characters. 8bitMUSH uses some of these so called non-printable characters like the music note. Is it possible to match against these in order to trigger a script in some other way than the built in Triggers functionality?
Amended on Fri 18 Jan 2013 10:14 AM by damccull
Australia Forum Administrator #1
OnPluginPacketReceived callback should do it for you.
USA #2
Hi Nick,
thanks for the quick reply. I don't suppose you'd be up to helping a bit more would you? If so, I have the following in my plugin:

sound_start_reg = rex.new("\e\[(.+)")

function OnPluginPacketReceived (sText)
soundstring = sound_start_reg:match(sText)
--if(soundstring ~= nil) then
Note(soundstring)
--end
end

but it keeps giving this:

Run-time error
Plugin: bitPlayPlugin (called from world: 8bitmush)
Immediate execution
missing terminating ] for character class (pattern offset: 7)
stack traceback:
[C]: in function 'new'
[string "Plugin"]:152: in main chunk
[WARNING] C:\Users\David\AppData\Roaming\MushClient\worlds\plugins\PlayMusic.xml


However if I change the regex to
sound_start_reg = rex.new("\e\\[(.+)")

then it just returns 'nil' when it triggers
USA #3
Here's the script from Nick's backspace plugin:

function OnPluginPacketReceived (s)

repeat 

  i = string.find (s, "\b") -- find backspace
  
  if i then 
    if i <= 1 then
      s = string.sub (s, 2)  -- just delete the backspace
    elseif i == 2 then
      s = string.sub (s, 3)  -- deleting first character
    else
      s = string.sub (s, 1, i - 2) .. string.sub (s, i + 1)
    end -- if i > 1
  end  -- if backspace found

until not i

return s
  
end -- function OnPluginPacketReceived

Basically, it places the packet in s, makes i find the location or if one exists using string.find, manipulates it to delete the backspace, and loops until it runs out of backspaces, terminating the repeat with the until.

You could literally replace the "\b" with any character, deleting the non-printable character, and add a short script to make the client do something?


Hope it helps!
Amended on Sat 19 Jan 2013 12:08 AM by Fadedparadox
USA #4
Well, I don't want to delete the non-printable characters. Actually I suppose I do. But what I really want is between the non-printable characters. I need to act on that part, not the characters themselves. That's why I was trying to use regular expressions to capture that part.
USA #5
If you just want what's between them, would you be able to match the ones on each side, gen the positions, then use them to take everything between?
Australia Forum Administrator #6

sound_start_reg = rex.new("\e\[(.+)")


Inside Lua strings you have to "escape" backslashes with a backslash.
So if you want the regular expression parser to see them you need to put extra ones there.



sound_start_reg = rex.new("\\e\\[(.+)")

USA #7
Nick, thanks for that! It made my code partially work.

Now I'm experiencing strange output. With the code:


sound_start_reg = rex.new("\\e\\[M[FBX](.+)\\x0E")

function OnPluginPacketReceived (sText)
	s, e, soundstring = sound_start_reg:match(sText)
	--if(soundstring ~= nil) then
		Note(soundstring)
	--end
   return sText
end


I'm getting

table: 06A9D040


I'm expecting a string though...
Amended on Sat 19 Jan 2013 09:38 AM by damccull
USA #8
Haha, I'm lame. Ok, I figured out what a table is in lua. This is my first attempt at lua, so I didn't realize it is a data structure. I thought I was getting some crazy stuff.


soundstring[1]


This seems to return my string properly.

Update: Here's my final code for the detection/removal of the codes.

sound_start_reg = rex.new("(\\e\\[(M[FBX].+)\\x0E)")

function OnPluginPacketReceived (sText)
   s, e, soundstring = sound_start_reg:match(sText)
   outstring = ""
   if(soundstring ~= nil) then
      outermatch = soundstring[1]
      innermatch = soundstring[2]
      outstring = sText:sub(0,s)
      outstring = outstring .. "|" .. sText:sub(e+1)
      return outstring
   end
end
Amended on Sat 19 Jan 2013 05:48 PM by damccull
Australia Forum Administrator #9
Glad it's working. For a simple match string.match (in Lua) could be an easier way of doing regular expressions. Try looking that up in the help.