"Prompt Newline" Script broken in new Lua engine

Posted by Lywellyn on Sat 21 Oct 2006 07:02 AM — 14 posts, 67,040 views.

USA #0
Nick's "Prompt Newline" script no longer works in the new Lua engine introduced in 3.80 (I upgraded from 3.78 to 3.82). The entire file is below. I can't figure out how to fix it myself (I code in VBScript, not Lua), so I was wondering if anyone (see: Nick :D) could fix up the code so that it'll work as it should (namely, allow me to trigger on the last line of the prompt). Thanks!

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient[
  <!ENTITY prompt_regexp "^Alisha   \- \((.*?)\/(.*?) (.*?)\/(.*?) (.*?)\/(.*?) (.*?) (.*?)\/(.*?)\) (.*?)$" > 
]>
<!-- MuClient version 3.59 -->

<!-- Plugin "Add_Newline_To_Prompt" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Add_Newline_To_Prompt"
   author="Nick Gammon"
   id="8316c19c35a9ebdb46055874"
   language="Lua"
   purpose="Adds a newline to prompt lines"
   date_written="2004-12-13 12:08:00"
   requires="3.59"
   version="1.0"
   >
<description trim="y">
Detects prompt lines without a newline, and if found, adds one.

Change ENTITY line on 3rd line of plugin to be a regular expression 
that matches your prompt.

</description>

</plugin>

<!--  Script  -->

<script>

  re = rex.new ("&prompt_regexp;")

<![CDATA[

partial = ""  -- partial line from last time through

function OnPluginPacketReceived (s)

  -- add packet to what we already have (excluding carriage-returns)
  
  partial = partial .. string.gsub (s, "\r", "")
  
  t = {}  -- table of lines to be returned
  
  -- iterate over each line
  
  partial = string.gsub (partial, "(.-)\n", 
    function (line) table.insert (t, line) end)
  
  -- look for prompt

  if (re:match (partial)) then
    table.insert (t, partial)
    partial = ""
  end -- if found prompt

  if table.getn (t) > 0 then
    table.insert (t, "")  -- to get final linefeed
  end -- if
    
  -- return table of lines, concatenated with newlines between each one
  return table.concat (t, "\n")
  
end -- function OnPluginPacketReceived
]]>
</script>

</muclient>
USA #1
Is there an error message that it gives, or does it run and fail to do what it says it should do?
USA #2
For the most part, it causes my last prompt line (I use two) to not appear until a command is actually sent.

But it also creates this wierd effect: It causes MUD output to output more than once. For example:

EXAMPLE OF NORMAL OUTPUT

Welcome to the MUD!

This MUD was established in 1995 by Mr. X.
Please make sure to read the rules upon login.


EXAMPLE OF OUTPUT WITH BROKEN PLUGIN

Welcome to the MUD!

This MUD was established in 1995 by Mr. X.
Welcome to the MUD!

This MUD was established in 1995 by Mr. X.
Please make sure to read the rules upon login.
Welcome to the MUD!

etc...


Eventually, the "looped output" would stop; it's not an infinite thing, but it causes triggers to fire repeatedly if certain MUD output is repeated.

I hope I made sense with this.
Russia #3
The plugin looks strange, maybe it's some early version or just a demo that was never meant to be used?

From the looks of it, the script adds incoming text to the "partial" var until a prompt is found. There's no loop - you are just seeing the same text displayed multiple times.
USA #4
That's why I quoted the word "loop"...I knew that it wasn't an actual loop, but you'd think it was by looking at the MUD output. :p

I can't remember if I found this script on the site here somewhere, or if Nick wrote it for me sometime in the past, but either way, it was definitely meant to be used...because until I installed the new Lua engine, it worked flawlessly.
Australia Forum Administrator #5
I confirm that the original plugin seems to go into a major loop, I am investigating why this is happening. Meanwhile, a simpler plugin may solve the problem, this worked for me with the SMAUG prompt:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Sunday, October 22, 2006, 7:40 AM -->
<!-- MuClient version 3.82 -->

<!-- Plugin "Add_NewLine_To_Prompt" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Add_NewLine_To_Prompt"
   author="Nick Gammon"
   id="1f68b8da856ceccb6f2ea308"
   language="Lua"
   purpose="Forces a newline after a prompt line"
   date_written="2006-10-22 07:38:36"
   requires="3.82"
   version="1.0"
   >

</plugin>


<!--  Script  -->


<script>
<![CDATA[
function OnPluginPacketReceived (s)
  return (string.gsub (s, "\n<.+/.+hp .+/.+m .+/.+mv .+/.+xp.*> ", "%1\n"))
end -- function OnPluginPacketReceived
]]>
</script>

</muclient>



You will need to change the "string.gsub" line to match your prompt.

The above one matches a prompt like:


<100/100hp 143/143m 210/210mv 0/343xp>


Judging by your regexp, yours will be something like this:


\nAlisha   - %(.+/.+ .+/.+ .+/.+ .+ .+/.+%) .+


This simpler plugin makes the assumption that a prompt line totally appears in a single packet. This may or may not always be true. You could try this, if it works then fine, otherwise see below.
Amended on Sat 21 Oct 2006 10:17 PM by Nick Gammon
Australia Forum Administrator #6
I think the reason the other one loops is that the behaviour of string.gsub has changed in Lua 5.1. If you want to try your original plugin, change this:


-- iterate over each line
  
  partial = string.gsub (partial, "(.-)\n", 
    function (line) table.insert (t, line) end)


To this:


-- iterate over each line
  
  partial = string.gsub (partial, "(.-)\n", 
    function (line) 
      table.insert (t, line) 
      return ""
    end)


You can make this change even if you are using earlier versions of MUSHclient. The behaviour of string.gsub used to be that, if you didn't return anything, it replaced the matching string with nothing.

Now, it keeps the original string, which accounts for the loops or extra data.

The new line (in bold) forces a return of nothing, which will work with both versions.
USA #7
I knew you'd be my hero, Nick! The fix to the original plugin seems to work fine.

For the sake of argument, I did also try the simpler one you offered with the regex of my prompt you offered. It didn't do anything to my final prompt line, so it couldn't be matched by my triggers.

But that's okay, since the original plugin with the fix you provided works flawlessly. Thanks again! :D
Australia Forum Administrator #8
I'm glad it works, and when I re-read my post I see I was a bit loose with my language.

The original plugin returned nothing, in the sense that it didn't have a return statement (in that loop). Thus, it effectively returned nil.

The new version returns "" which is different from nil, it is an empty string. To Lua, nil means "no data" which is conceptually different from the empty string. An empty string is a string which happens to be of length zero.
Ukraine #9
Hellow everyone.

I decided to use simple script from Nick.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Sunday, October 22, 2006, 7:40 AM -->
<!-- MuClient version 3.82 -->

<!-- Plugin "Add_NewLine_To_Prompt" generated by Plugin Wizard -->

<muclient>
<plugin
name="Add_NewLine_To_Prompt"
author="Nick Gammon"
id="1f68b8da856ceccb6f2ea308"
language="Lua"
purpose="Forces a newline after a prompt line"
date_written="2006-10-22 07:38:36"
requires="3.82"
version="1.0"
>

</plugin>


<!-- Script -->


<script>
<![CDATA[
function OnPluginPacketReceived (s)
return (string.gsub (s, "\n<.+/.+hp .+/.+m .+/.+mv .+/.+xp.*> ", "%1\n"))
end -- function OnPluginPacketReceived
]]>
</script>

</muclient>

All seems to be fine. But here one "NO".

In some situations new line converts to space. I don't know why.

My mud works on ROM 2.4.

Example:

Normal situation.
"
<prompt>

Some one looks to u.

<prompt>

"

Error situation.
"
<prompt>
[>>SPACE HERE<<]Some one looks to u.

<prompt>

"

This is very BAD! May be Nick or someone knows solution to this problem?
Amended on Tue 22 Jul 2008 07:06 AM by Madjack
Australia Forum Administrator #10
Well I would change the regular expression to look for more than one space.

Change:

return (string.gsub (s, "\n<.+/.+hp .+/.+m .+/.+mv .+/.+xp.*> ", "%1\n"))

to:

return (string.gsub (s, "\n<.+/.+hp .+/.+m .+/.+mv .+/.+xp.*>%s*", "%1\n"))
Ukraine #11
Problem in other things... Because of prompt always detects and new line always adding. Forexample:

function OnPluginPacketReceived (s)
mask = "[0-9]+\/[0-9]+h [0-9]+\/[0-9]+m [0-9]+v %[[0-9]+\.[0-9]+g%] [0-9]+\:00 \| .+ \| .+ \>";
buf = (string.gsub(s, mask, "!%1!\n"));
return buf;
end -- function OnPluginPacketReceived


--

!160/160h 162/162m 119v [52.1g] 17:00 | Some room | NWE >!
[>>SPACE HERE<<]Some action was happend.

!160/160h 162/162m 119v [52.1g] 17:00 | Some room | NWE >!

--

I guess i found in wich bug... It occurs when trigger omit from output some line and sends with or without echo some command to mud. In other ways after prompt always new line adding.

P.S. Sorry for my english=) I hope u understand what i meaned.
Amended on Tue 22 Jul 2008 08:42 AM by Madjack
Ukraine #12
Problem was localized. Prompt new line works properly when LUA script don't use Send ( SendNoEcho, SendImmediate ).

When Trigger fires and calls functions in my script that executes Send("command1") we have next:

"
<prompt>

Something that trigger eats.
some actions <--- Sent through Send("some actions");

<prompt>
[>>SPACE HERE<<] First line of result of "Some actions".
next lines.

<prompt>

"

Without triggers and scripts all fine like that:

"
<prompt>

some actions <--- Sent through command window

First line of result of "Some actions".
next lines.

<prompt>

"

May be this information will help to find good solution.
Ukraine #13
I have found solution. It works for now. May be it will works foreve now. I hope.

--
function OnPluginPacketReceived (s)
mask = "[0-9]+\/[0-9]+h [0-9]+\/[0-9]+m [0-9]+v %[[0-9]+\.[0-9]+g%] [0-9]+\:00 \| .+ \| .+\>";
if(string.find(s, mask)) then
buf = (string.gsub(s, mask, "%1\n"));
return buf .. "\n";
end -- if
return s;
end -- function OnPluginPacketReceived
--

But problem is still here when 2 or more prompts in one packet. Then replaces only last prompt.
For example
s = "<prompt> some action <prompt>";
then will "<prompt> some action\n<prompt>\n"