2008-10-21 12:51:57 UTC
Ok, i thought i might just try and put together a little step-by-step procedure on how to collect tells, messages or whatever else you want in ggmud using lua scripting.
(Examples are taken from the only mud i played in 12 years... LegendMUD
http://www.legendmud.org)
1) collect the exact wording of all messages you want to intercept and decide if you want to split them in categories/groups that you might wish to have displayed in different extra windows.
Ok lets start: To collect the exact wordings i need to know what i am after, so...
- I would like to grab personal messages I either send out or receive to or from other players. In in addition to that I want to grab messages I send or recieve to or from the group I am actually in.
- I would like to grab messages off several different Channels like 'Chat' 'Auction' 'Info' 'Clan' and display these type in a different window each...
So I think about a layout and start collecting corresponding messages from the mud:
I decided to make 5 windows:
Window "Tells": will contain all kinds of tells (private communication to people or group)
Messages like:
1 You tell a pardoner, 'hi'
2 A pardoner tells you, 'r u going2 kill m3?'
3 You tell the group, 'Hi.'
4 A harem girl tells the group, 'Hmm.'
In LegendMUD fortunately those kinds of tells have only one pattern
and don't choose different patterns randomly so these 4 messages will suffice
Channel-Windows "<Channel>": will contain all activity on the respective Channel... Channels i want to collect are CHAT, AUCTION, INFO and CLAN
Messages like:
5 [Chat] Mikhail: hi, anyone else out there ?
6 [Chat] Mikhail waves hello to the world!
As channel messages are built the same for each channel, these two also will suffice
2) create triggerable patterns
This step might sound difficult but easy untrained people can get through it easily. As you just need to strip the messages down to the parts that always stay the same. In order to do that you can insert variables to replace the non-fixed parts so you can use whatever is not fixed later. (variables are indicated by %-sign followed by a number). Be careful as even blanks are important creating triggers. if you include a blank in the pattern, it wont show in the collecting variables. (as ' is used in the messages i'll use > < to surround pattern parts in the explanations)
lets do this slowly for message 1
Message 1
You tell a pardoner, 'hi'
Pattern 1
%1 tell %2, '%3
I want to extract who sent the tell, therefore
i place the first variable %1 infront of > tell <
I want to extract who the tell is sent to, therefore
the 2nd variable %2 is set between > tell < and >, '<
I want to extract the content of the tell sent, therefore
i place the 3rd variable %3 after >, '<
You might realize that i left out the trailing ' ... i did that
because it might be possible that someone quotes something in their
tell. So the initial ' of the quote would cause my pattern to stop
extracting the tell content at that point if i would place >'< after %3
As a consequence, the content of %3 will have a trailing '
which i can take care about later
so if this pattern1 is applied to message 1 i get the variables
%1 = You
%2 = a pardoner
%3 = hi'
lets create the patterns for the other messages
Message 2
A pardoner tells you, 'r u going2 kill m3?'
Pattern 2
%1 tells %2, '%3
Message 3
You tell the group, 'Hi.'
Pattern 3
%1 tell %2, '%3
Message 4
A harem girl tells the group, 'Hmm.'
Pattern 4
%1 tells %2, '%3
Message 5
[Chat] Mikhail: hi, anyone else out there ?
Pattern 5
[%1]%2: %3
Message 6
[Chat] Mikhail waves hello to the world!
Pattern 6
[%1]%2
Message 7
[Clan: 1337] Mikhail: hi, anyone else out there ?
Pattern 7
[Clan: %1] %2: %3
Ok now that we have all patterns we identify those we really need to take care about...
As patterns 1 and 3 ... as well as patterns 2 and 4 are the same we only need one of each set
so
%1 tell %2, '%3
%1 tells %2, '%3 will be extracted to the tell-window
The only difference is the 3rd person singular 's' which we use to determine if you or someone else sent the tell.
I am not sure why but when I created this script I realized that message 6 is covered by message 5... could be a bug or I just have no clue... i would expect pattern 5 to only shoot if a there is a : between two texts but it fires as is even if there is no :
Well as i figured that i just worked that fact into my script and got a good result.
As other channel messages use the same pattern i just need 1 of these
so
[%1]%2: %3 will be extracted to the channel-%1-windows
As clan messages are slightly different to channel messages we need the pattern
[Clan: %1] %2: %3 to extract clan messages to the Clan Window
3) creating the script
go to your home directory and create a new file 'myGGMudScript.lua'
open the empty file in a text editor
4) filling the file with life (whenever I write some code-snippets, I will put <code> before and </code> after the snippet. I will also include line numbers to be able to refer to them as i give explanations. At the end of this tutorial you will find the whole script without line numbers for an easy copy/paste... just remember not to copy the leading <code> or trailing </code>
first we create the triggers we need in order to extract all chosen messages
so for messages 1 and 2 we use
<code>
01 trigger("%1 tell %2, '%3", "sendYourTellsToTellWindow")
02 trigger("%1 tells %2, '%3", "sendOthersTellsToTellWindow")
</code>
thats how triggers in lua-script look like. the trigger has 2 arguments. the 1st argument is the pattern and the 2nd argument is the function to be called when the trigger is released. the variables defined in the trigger will be send to the called function in natural order.
so basically what lines 01 and 02 do is call the methods 'sendYourTellsToTellWindow' or respectively 'sendOthersTellsToTellWindow' with the arguments %1, %2, %3.
for messages 5 we need the trigger
<code>
03 trigger("[%1]%2: %3", "sendToChannelWindow")
</code>
and for message 7 we use
<code>
04 trigger("[Clan: %1] %2: %3", "sendToClanWindow")
</code>
now we have the triggers needed and we also named a few functions we will have to create to use the information caught by the triggers and report them into extra windows.
next step is to create the function ... the basic layout of a lua function looks like:
function FUNCTIONNAME(FUNCTIONPARAMETERS)
FUNCTIONCODE
end
function parameters are a number of plain words which will be variables within the function code. the function code can be 1 or more lines of lua scripting code
so if we create our first function for tells you sent we define
<code>
05 function sendYourTellsToTellWindow(teller, recipient, message)
06 if(recipient=="the group") then tellcolor="$c0014" else tellcolor="$c0010" end
07 printInTellWindow(teller, recipient, message, tellcolor, "$c0007")
08 end
</code>
wow... first function... what does it to ?
in lines 05 and 08 i define the function layout as shown above
in lines 06 and 07 i implemented lua code to do stuff
line 06: if the recipient of the tell is the group, then the first part of the shown tell will be colored with ansicolor $0014 (00=black background 14=light cyan) for tells you send to the group or $0010 (00=black background 10=light green foreground) for tells you send to other people
line 07: we call another function and add the colors next to the tell-contents $0007 means grey font on black background
lets make a similar function for tells sent by other people
<code>
09 function sendOthersTellsToTellWindow(teller, recipient, message)
10 if(recipient=="the group") then tellcolor="$c0006" else tellcolor="$c0009" end
11 printInTellWindow(teller, recipient, message, tellcolor, "$c0007")
12 end
</code>
this function does exactly what the other did just that it used colors
$0006 (00=black background 06=dark cyan foreground) on tells sent by others to the group
$0009 (00=black background 09=light red foreground) on tells sent by users to you
as both functions use a third function 'printInTellWindow' we ought to implement that one too
<code>
13 function printInTellWindow(teller, recipient, message, tellcolor, msgcolor)
14 if teller=="You" then tellgrammar = " tell " else tellgrammer = " tells " end
15 window("TellWindow", tellcolor..teller..tellgrammar..recipient..": "..msgcolor.."'"..message)
16 end
</code>
yes... thats all you need to collect tells sent to or from you in an extra window in a way that you easily see the difference by colors
line 14: i want the message shown to obey correct grammar so i check who is the teller and set the verb tell into the correct form
line 15: window is the ggmud-lua-command to put a message to an extra window. it takes 2 arguments, the window name and content to be added to the window. The name here is static and is 'TellWindow', the content we have to create from our strings we so carefully prepared... lua uses '..' to concatenate strings/variables so in case the tell message was:
You tell the group, 'Hi.'
the variables will now contain:
teller = You
recipient = the group
message = Hi.'
tellcolor = $0014
msgcolor = $0007
tellgrammar = tell
so the concatenation in line 15 will result in
(light cyan color)You tell the group: (light grey color)'Hi.'
which will be sent to the "TellWindow"
,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._
now you earned yourself a break ... well i think at least i did
,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._
well we got so far as to collect all tells sent/received and print
them into a TellWindow.
now we want to do the same for channels and clan messages
the triggers are already given in lines 03 and 04
first to channel messages: line 03 calls the function 'sendToChannelWindow'
<code>
17 function sendToChannelWindow(channel, sender, message)
18 if (channel=="Auction" or channel=="Chat" or channel=="Info") then
19 if string.sub(sender,0,1)==" " then sender = string.sub(sender, 2) end
20 if(message==nil) then
21 sendChannelEmote(channel, sender, "$c0010")
22 else
23 sendChannelMessage(channel, sender, message, "$c0011", "$c0007")
24 end
25 end
26 end
</code>
ok to the code
line 18: legendmud has more than those 3 channels, but i only want to watch those therefore i check which channel released my trigger and only do something if it was one of those mentioned
line 19: i strip a leading blank off the senders name in case there is one
line 20: i check if there is a message at all ... if not it was a channel-emote
line 21: if there is no message i call the function sendChannelEmote and pass the channelname, and the sender which is in this case the channel-emote, followed by a color
line 23: if there is a message i call the function sendChannelMessage and pass the channelname, the senders name and the message followed by 2 color codes
lines 24 - 26: as well as you have to finish a function structure with an end, lua also expects if-then-else-calls to be finished with an end
now we again have 2 more function wich we will need to implement
<code>
27 function sendChannelEmote(channel, emote, msgcolor)
28 window (channel, msgcolor..emote)
29 end
</code>
and
<code>
30 function sendChannelMessage(channel, sender, message, sendercolor, messagecolor)
31 window(channel, sendercolor..sender..": "..messagecolor..message)
32 end
</code>
line 28: prints an emote and
line 31: prints a message to the according window with the name of the channel
last but not least i want to be kept up to date about clan messages. therefore i use the trigger of line 04 to call this function
<code>
33 function sendToClanWindow(clan, sender, message)
34 sendChannelMessage("Clan", sender, message, "$c0011", "$c0007")
35 end
</code>
hey ... that function call in line 34 we already used... yes, as it is convenient we just just the function sendChannelMessage again. This time we just dont send a channel message to a window with the channel message, instead we send a message from the clan-channel to a window called 'Clan'
now save the scriptfile
5) enter the script-file into the preferences of ggmud
Options -> Preferences -> LUA startup
there you can enter the complete path to your lua file
[drive:]/[homedirectory/]myGGMudscript.lua
now save the configuration exit ggmud and restart ggmud.
right after the restart you should see the triggers of lines 01 - 04 beeing initiated below the program information, like
##################################################
# G G M U D 0.8.1 #
# written by #
# Gabriele Greco #
##################################################
#OK. TINTIN-CHAR is now {#}
#Ok. {[%1]%2: %3} now triggers {&sendToChannelWindow} @ {scripting}
#Ok. {[Clan: %1] %2: %3} now triggers {&sendToClanWindow} @ {scripting}
#Ok. {%1 tell %2, '%3} now triggers {&sendYourTellsToTellWindow} @ {scripting}
#Ok. {%1 tells %2, '%3} now triggers {&sendOthersTellsToTellWindow} @ {scripting}
well at that point this tutorial should be concluded, i hope the stuff
makes sense and helps you with your (first) attempts on lua-scripting in ggmud.
If you find any errors/mistakes feel free to point them out.
Thx for reading and best regards... have fun with your mu*
Ingo Gambin
,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,
Actually i think you need to put the trigger-lines at the end of the file
as ggmud/lua expects to first find a function in the script
,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,-._,
function sendYourTellsToTellWindow(teller, recipient, message)
if(recipient=="the group") then tellcolor="$c0014" else tellcolor="$c0010" end
printInTellWindow(teller, recipient, message, tellcolor, "$c0007")
end
function sendOthersTellsToTellWindow(teller, recipient, message)
if(recipient=="the group") then tellcolor="$c0006" else tellcolor="$c0009" end
printInTellWindow(teller, recipient, message, tellcolor, "$c0007")
end
function printInTellWindow(teller, recipient, message, tellcolor, msgcolor)
if teller=="You" then tellgrammar = " tell " else tellgrammer = " tells " end
window("TellWindow", tellcolor..teller..tellgrammar..recipient..": "..msgcolor.."'"..message)
end
function sendToChannelWindow(channel, sender, message)
if (channel=="Auction" or channel=="Chat" or channel=="Info") then
if string.sub(sender,0,1)==" " then sender = string.sub(sender, 2) end
if(message==nil) then
sendChannelEmote(channel, sender, "$c0010")
else
sendChannelMessage(channel, sender, message, "$c0011", "$c0007")
end
end
end
function sendChannelEmote(channel, emote, msgcolor)
window (channel, msgcolor..emote)
end
function sendChannelMessage(channel, sender, message, sendercolor, messagecolor)
window(channel, sendercolor..sender..": "..messagecolor..message)
end
function sendToClanWindow(clan, sender, message)
sendChannelMessage("Clan", sender, message, "$c0011", "$c0007")
end
trigger("%1 tell %2, '%3", "sendYourTellsToTellWindow")
trigger("%1 tells %2, '%3", "sendOthersTellsToTellWindow")
trigger("[%1]%2: %3", "sendToChannelWindow")
trigger("[Clan: %1] %2: %3", "sendToClanWindow")