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
➜ General
➜ [lua plugin] Questions
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Shamo
(7 posts) Bio
|
Date
| Sun 16 Nov 2008 12:11 PM (UTC) |
Message
|
Hello there,
I'm new to MSUHclient and scripting, I'm doing a little status bar for monks from 3 kingdoms as a little project to learn things.
So far I've been able to parse the infos I need and display a miniwindow with a gauge in it.
If you don't mind, I'd like to use this thread when I can't find the answers I seek in those many help files.
So here is the first:
I'd like to use the fonts loaded for the world output (to fit the user settings). I can't find a function that gives access to it, how can I do that? | Top |
|
Posted by
| Worstje
Netherlands (899 posts) Bio
|
Date
| Reply #1 on Sun 16 Nov 2008 06:38 PM (UTC) |
Message
| I believe one of Nick's Aardwolf example plugins shows this. Or he posted a reply somewhere explaining how to do this. I can't fully remember, though.
In the bare essence, you could find out rather easily yourself. Open your ThreeKingdoms.mcl file (or whatever your worldfile is called) in notepad or another text editor. It's a readable format just like plugins are. Search for the name of your font, and see what property it appears in. I found out just now that it is stored in the output_font_name attribute. So, to get it, you would simply use GetOption("output_font_name"). You can then call the WindowFont() method with that data.
Of course, you also need to figure out other characteristics. But I bet output_font_height, output_font_weight and output_font_charset might be able to help with that. There might be more (that don't appear in my world file), so best you can do to make sure you find all settings is to make a bogus world, change all the font settings to non-defaults (preferably easy to recognise), and then see how you can fit that in with WindowFont() and such. :) | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #2 on Mon 17 Nov 2008 04:37 AM (UTC) |
Message
|
print (GetAlphaOption "output_font_name") -- eg. Dina
print (GetOption "output_font_height") -- eg. 8
Thus, I am using Dina 8 pt in my output window.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Shamo
(7 posts) Bio
|
Date
| Reply #3 on Thu 20 Nov 2008 06:07 PM (UTC) |
Message
| Thanks! Works great. Seems I could have find the answer myself if looking after it harder ... I'm getting better at it tho.
I have another newb question tho, related to an old post:
http://www.gammon.com.au/forum/?id=7430
In the mud I'm in now (Toril) the prompt can have mainly 2 forms:
"< 183h/183H 236p/236P 120v/120V P: std > "
"< 252h/179H 229p/229P 120v/120V T: Ginewe TC: few scratches E: bugbear EC: few wounds P: std > "
And there also can be an " (AFK) " tag at the end.
The regexp I came up with:
^\< (?P<hp>\d+)h\/(?P<maxhp>\d+)H (?P<psp>\d+)p\/(?P<maxpsp>\d+)P (?P<mv>\d+)v\/(?P<maxmv>\d+)V (?:T\: (?P<tn>[a-zA-Z ]+) TC\: (?P<tc>[a-zA-Z ]+) E\: (?P<en>[a-zA-Z ]+) EC\: (?P<ec>[a-zA-Z ]+) )?P\: (?P<pos>\w{3}) (?:\(AFK\) )?\> $
I got my plugin to work, but it was always one "tick" too late, as you probably guessed already problem is the mud doesn't send a newline after displaying the current status.
So I looked in the forum for a similar problem and saw the post mentioned before and guessed it could solve my problem (I'm still not sure).
So had to "translate" the regexp to fit (only a simple version so far, outside fight) and here are the lines I tried:
"\n< .+h/.+H .+p/.+P .+v/.+V P: ... > "
"\n< .+h/.+H .+p/.+P .+v/.+V P: .+ > "
However I can't get it to work properly (it get installed but doesn't do anything) ... To tell the truth I'm not even sure I understand how it is supposed to work. Here is the modified code:
---------------------------------------------------
<?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< .+h/.+H .+p/.+P .+v/.+V P: .+ > ", "%1\n"))
end -- function OnPluginPacketReceived
]]>
</script>
</muclient>
| Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #4 on Thu 20 Nov 2008 07:32 PM (UTC) |
Message
| Try removing the \n from the start of the regexp. If the prompt comes in a packet which has no \n (in other words, the prompt starts the packet), there will be no leading \n. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Shamo
(7 posts) Bio
|
Date
| Reply #5 on Thu 20 Nov 2008 07:48 PM (UTC) |
Message
| Ok I've figured it out, but didn't solve it yet.
The problem comes from the ANSI tags, I asked the function to display the packets. That's what I usualy get:
packet: '
[32m<[0;32m 183h[0;32m/183H[0;32m 236p[0;32m/236P[0;32m 120v[0;32m/120V[0;32m P:[0;33m sit [0;32m> [0m'
Sometimes it gets splited in two, but will take care of that once I get this one right.
So first I make things easier by getting the base regexp smaller:
"\n<.+> "
That's enough to be sure it catches a prompt. Then I add the needed ANSI tags:
"\n\[32m<.+> \[0m"
It works but it displays an error:
Error number: 0
Event: Run-time error
Description: [string "Plugin"]:5: malformed pattern (missing ']')
stack traceback:
[C]: in function 'gsub'
[string "Plugin"]:5: in function <[string "Plugin"]:3>
Called by: Function/Sub: OnPluginPacketReceived called by Plugin Add_NewLine_To_Prompt
Reason: Executing plugin Add_NewLine_To_Prompt sub OnPluginPacketReceived
Am I being dumb saying it's a bug from the client? "\[" shouldn't require a "]". I'm stuck there atm. | Top |
|
Posted by
| Shamo
(7 posts) Bio
|
Date
| Reply #6 on Thu 20 Nov 2008 08:02 PM (UTC) |
Message
| My bad:
http://www.wowwiki.com/Pattern_matching
Should have used %[ instead of \[
I'll get it to work hehe, thanks for helping tho! | Top |
|
Posted by
| Worstje
Netherlands (899 posts) Bio
|
Date
| Reply #7 on Thu 20 Nov 2008 08:04 PM (UTC) Amended on Thu 20 Nov 2008 08:06 PM (UTC) by Worstje
|
Message
| Try \\[ instead.
One \ is used to escape the physical doublequotes in the code (like in "\n" being translated to a newline character). But you need to escape the [ for the regular expression, which means the way the string is interpreted by gsub. As such, you'd want the equivalent of "\\n" which ends up being seen as a literal \n, on which the function next acts.
So in your case, \[ is already filtered out by the string processing to read [. The gsub function will see a [, and as such, complain there's no closing ] character.
You should double-up all backslash characters like \\ if they are relevant to the regular expression rather than the string itself.
(Damn this is a pain to explain. Heh.)
Edit: And apparently I was completely wrong. Oh well. Too many languages in my head. :) | Top |
|
Posted by
| Shamo
(7 posts) Bio
|
Date
| Reply #8 on Thu 20 Nov 2008 08:50 PM (UTC) |
Message
| Thanks tho, I learnt something hehe
Anyway, here is the working version ... Added a little tweak to skip the next \n after forcing one.
<![CDATA[
skip_next_nl = false
function OnPluginPacketReceived (s)
if skip_next_nl then
local ssub = string.sub(s, 1, 3)
if string.find(ssub,"\n") ~= nil then
s = string.sub(s, 3)
skip_next_nl = false
end --if
end --if
local pattern = "%[32m<.+>"
if string.find(s, pattern) ~= nil then
s = s .. "\n"
skil_next_nl = true
end -- if
return s
end -- function OnPluginPacketReceived
]]>
It's not 100% safe, someone could make my screen looking by typing "[32m<>" in the chat ... But should do (I'd make use of a fix tho). | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #9 on Thu 20 Nov 2008 09:14 PM (UTC) |
Message
|
Quote: It's not 100% safe, someone could make my screen looking by typing "[32m<>" in the chat ... But should do (I'd make use of a fix tho).
You can prevent that by including the escape character for ANSI codes in the pattern. Instead of "%[32m" use "\27%[32m". Most MUD servers strip ANSI codes from user input, so you'll be safe from this sort of spoofing. | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #10 on Thu 20 Nov 2008 09:23 PM (UTC) |
Message
| Also, many MUDs send the IAC GO/EOR code instead of a newline after the prompt, which topic was also discussed in much detail here. If your MUD does, then you can simplify and improve your solution by replacing IAC GO/EOR with a newline whenever you encounter it. That works more reliably, since it's just two characters instead of a whole string of them, and there's also a builtin Mushclient way of converting IAC GO/EOR to newlines. | Top |
|
Posted by
| Shamo
(7 posts) Bio
|
Date
| Reply #11 on Tue 16 Dec 2008 05:17 PM (UTC) Amended on Tue 16 Dec 2008 07:05 PM (UTC) by Shamo
|
Message
| Unfortunatly it doesn't use IAC GO/EOR code, but indeed do u se that escape character.
local buffer = ""
pattern = "%[32m<.+%[0;32m> " .. string.char(27) .. "%[0m"
function OnPluginPacketReceived (s)
buffer = buffer .. s
s = ""
local current_line = buffer
local newline_index, _ = string.find(buffer,"\n")
while newline_index ~= nil do
current_line = string.sub(buffer, 1, newline_index)
local _, prompt_inside = string.find(current_line, pattern)
if prompt_inside ~= nil then
newline_index = prompt_inside
current_line = string.sub(buffer, 1, newline_index) .. "\n"
end -- if
buffer = string.sub(buffer, newline_index + 1)
s = s .. current_line
newline_index, _ = string.find(buffer,"\n")
end -- while
if string.find(buffer, pattern) ~= nil then
s = s .. buffer .. "\n"
buffer = ""
end -- if
return s
end -- function OnPluginPacketReceived
This is what I do to rebuild prompts, I'm well aware it's a bit ugly to read hehe. Feel free to comment tho.
Problem I had without:
No newline at then end of last prompt, then had trouble to add one since sometimes it was splitted in several packets. Also had an issue when packets looked like this: "<prompt>You sit down."
What it basicaly does:
Concat packets until newline or until it matches a prompt and then send it. In the later case it adds a newline at the end of the prompt.
It generates some not needed blank lines, so I use an additional trigger to remove them all.
My problem now comes from MCCP compression. When I login if this script is enable what I get as packets are compressed datas, and of course it doesn't work at all. It can even crashes the connection. It's really strange tho, cause if I disable, connect, wait a bit (won't work if I don't wait long enough) and then enable it ... It works fine even tho the compression is still acive. It acts like at the uncompression part activate after OnPluginPacketReceived at first and then before ... Quite puzzling. Gonna look deeper in the forum for an answer, and will edit if I find any.
EDIT: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=8956
I didn't really get it, but I guess that's what I was looking for. Is there a way to edit the above script of mine so it keeps doing the same but don't corrupt the compression?
Side question, when is the compression negociated? Sometimes I have to wait like 2 mins before enabling the plugin, sometimes it's fine after 30s. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #12 on Wed 17 Dec 2008 05:27 AM (UTC) |
Message
| The OnPluginPacketReceived function gets the uncompressed data. That is, if no compression is active, the raw packet, or after compression, what it decompressed to.
However there is a potential problem with the packet that starts the compressed stream. That would be partly compressed and partly uncompressed. If you modify that packet it is likely to crash.
One approach would be to wait until compression has started. You could call GetInfo (208) and wait until it was non-zero. However this wouldn't work if compression never became active.
http://www.gammon.com.au/scripts/doc.php?function=GetInfo
Another approach would be to test for the packet that starts the compression by looking for IAC SB COMPRESS WILL SE (or IAC SB COMPRESS2 IAC SE). See http://www.gammon.com.au/mccp/protocol.html for details about that. A packet containing either of those sequences would contain compressed and uncompressed data. Hopefully it would not be split between packets, although there is no guarantee. Any such packet you would ignore and not change. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | 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.
34,140 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top