Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Lua ➜ String.gsub-ing packets?

String.gsub-ing packets?

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


Posted by Rivius   (99 posts)  Bio
Date Sun 08 Jan 2012 04:41 PM (UTC)
Message
In a game I play, if a line is detected to be an illusion, you will get a subsequent line telling you so. eg.


A cloudy tendril lashes at you, filling your mind with disturbing images.
Your eye immediately notices the flaws in what is obviously an illusion.


I've decided that instead of going through the pain of using triggers to ignore the afflictions added by the previous line (since one can use illusions to do far more than make you think you've been hit with something), I modified the packets directly to be prefixed by some text so that they wouldn't be matched. This is the code I am using now within a plugin:


function OnPluginPacketReceived(text)
	local i = string.find(text, "\nYour eye immediately notices the flaws in what is obviously an illusion%.")
	if i then
		local t = string.sub(text, 1, i - 1)
		t = string.gsub(t, "%[", "%%[")
		return string.gsub(text, t, string.gsub(t, "\n", "\nIllusion Detected: "))
	end
end


The problem is, this works for most illusions, but some seem to escape it somehow. I'm not sure why, either. I figured there's just something wrong with the way I'm substituting things and I'm hoping someone has a better way to go about it that would work for every line. The example I provided in the beginning is one line that simply didn't detect once.

Most things detect just fine, however, such as:


Illusion Detected: A sudden headache makes you rub your temples for relief.
Your eye immediately notices the flaws in what is obviously an illusion.


^ is an output after successful modification.
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #1 on Sun 08 Jan 2012 09:28 PM (UTC)

Amended on Sun 08 Jan 2012 09:30 PM (UTC) by Twisol

Message
Due to the vagaries of the Internet, packets aren't guaranteed to be received exactly as they were sent. In the absolute worst case, you can receive a single character at a time (which will probably never happen, but it's not disallowed). What might be happening is that you're getting a packet where the second line is cut off part of the way through, or even separated from the first line completely, and the rest is received in the next packet. MUSHclient guarantees that triggers will always have a full line to match on, but OnPluginPacketReceived bypasses that mechanism.

Furthermore, it might be possible to receive two illusions in a single network packet. As it stands, your code will only modify the first. You can use the Debug Packets window to view the raw data in each incoming and outgoing packet, which can help to confirm my guesses.


local EOL = "\n"

function detect_illusions(l1, l2)
  if l2 == "Your eye immediately notices the flaws in what is obviously an illusion." then
    l1 = "Illusion Detected: " .. l1
  end
  
  return l1
end

local prev_text = ""
function OnPluginPacketReceived(text)
  text = prev_text .. text

  local lines = utils.split(text, EOL)

  -- save incomplete line
  prev_text = table.remove(lines) or ""
  -- also save previous line so we can check it after
  -- the incomplete line is finished
  prev_text = (table.remove(lines) or "").. prev_text

  local prev_line = table.remove(lines, 1)
  for i,line in ipairs(lines) do
    line = detect_illusions(prev_line, line)
    prev_line, lines[i] = line, line
  end

  return table.concat(lines, EOL)
end


This approach basically means that the most recent line received won't be displayed, but if there's a way to tell for sure that a line isn't an illusion - for example, if illusions cannot contain colors - you can flush the buffer there. Of course, this code doesn't handle color sequences, and stuff like MXP or telnet negotiation sequences is included in the packet, unlike triggers where it's just the text.

(Also, I haven't tested this code. I hope it helps though!)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #2 on Mon 09 Jan 2012 05:55 AM (UTC)
Message
Data may cross packet boundaries also. There was a plugin a while back that built up a "whole" packet by waiting for a newline, or something like that.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Rivius   (99 posts)  Bio
Date Reply #3 on Fri 15 Mar 2013 01:44 PM (UTC)
Message
Hi, again. I've reapproached this topic a bit, as I've found need for it once more. This is the current version of my code, and it successfully handles multi-line illusions:


function OnPluginPacketReceived(pkt)
	local imtch = string.match(pkt, "(.*)[\r\n]Your eye immediately notices the flaws in what is obviously an illusion%.[\r\n]")
	if imtch then
		local fixed = string.gsub(imtch, "\n", "\nIllusion filtered and ignored: ")
		pkt = string.gsub(pkt, string.gsub(imtch, "([%[%]])", "%%%1"), fixed)
	end
	return pkt
end
end


I'm not sure if that's the best way in the world to do it, but it works fine in most illusions, including coloured ones. However, there is another type of illusion that is placed in a room and only fires upon entrance. It looks like this:

http://dl.dropbox.com/u/16429247/gamm.html

And my code doesn't seem to modify these lines as desired. I'm completely unsure of why this is and would like to find a way to investigate and get around this.


Also, a question, is this recommendable speed-wise, or should I just abandon this approach altogether?
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.


16,415 views.

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

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.