![]() | ||||||||||||||||
|
Lyntin main faq features screenshots development wishlist contact us SF project page RSS Newsfeed wiki Using Lyntin installing downloading plugin repository documentation Hosted by |
tutorial 1: basic commands in Lyntin 4.0documentation> tutorial 1: basic commands in Lyntin 4.0 last updated: Thursday, November 29th SummaryThis tutorial walks through the basics of building a module that adds commands to Lyntin. It's very basic and assumes you haven't done any module hacking in Lyntin before. It does assume you have a working knowledge of Python. If you don't, you should go to http://www.python.org/ and read through their tutorials and such. Revisions
Step 1: defining the problem we're trying to solveMy typical mud session involves using an xterm and ssh'ing to a server in Texas and then launching Lyntin from there. As such I don't have many of the "features" in the tkui available (until I get around to building a cursesui). I have a tendency to idle a lot as I'm working in other windows. I find it's difficult to flip back to the xterm window and figure out what's going on--I need some kind of status section of the xterm which my actions can dump status information on. Like how long I've been idle for. What I want to build is a module that will keep a dict of status name and value variables and display it in the xterm title bar. Step 2: building the module skeleton
First thing I do is build a quickie module that I can start
working with. I name it
/home
|-- /will
|-- /tutorial
|-- statusbar.py
I start Lyntin up with: runlyntin.py -c tutorial.ini My tutorial.ini config file looks like this: [Lyntin] datadir: /home/willg/tutorial moduledir: /home/willg/tutorial If you're using Windows, you'll probably want to make a copy of runlyntin.pyw and edit one of them to have boot options like this:
bootoptions = {"ui": "tk",
"datadir": "/path/to/tutorial/directory",
"moduledir": ["/path/to/tutorial/directory"],
"readfile": [],
"snoopdefault": 1}
When Lyntin starts up, it loads all the modules in the directories
specified by the I open my favorite editor and type the following (or copy and paste it from previously existing modules):
from lyntin import exported
from lyntin.modules import modutils
# this will hold the command information for adding to
# Lyntin later on
commands_dict = {}
# this will hold the statusbar status name and value variables
# for display in the title bar
statusbar_dict = {}
def ststatus_cmd(ses, args, input):
"""
This command allows you to set a new name/value pair in the
xterm title bar.
"""
exported.write_message("You typed #statusbar!")
commands_dict["setstatus"] = (setstatus_cmd, "name value= sortkey=")
def load():
""" Initializes the module by binding all the commands."""
modutils.load_commands(commands_dict)
def unload():
""" Unbinds the commands (for when we reimport the module)."""
modutils.unload_commands(commands_dict)
That's my basic module shell. Let's walk through the pieces. The first 2 lines are: from lyntin import exported from lyntin.modules import modutils
The The next section:
# this will hold the command information for adding to
# Lyntin later on
commands_dict = {}
# this will hold the statusbar status name and value variables
# for display in the title bar
statusbar_dict = {}
def ststatus_cmd(ses, args, input):
"""
This command allows you to set a new name/value pair in the
xterm title bar.
"""
exported.write_message("You typed #statusbar!")
creates some module variables and then defines the command we're going to build. Commands take three arguments:
The next line: commands_dict["setstatus"] = (setstatus_cmd, "name value= sortkey=")
tosses an item of the name Finally: def load(): """ Initializes the module by binding all the commands.""" modutils.load_commands(commands_dict) def unload(): """ Unbinds the commands (for when we reimport the module).""" modutils.unload_commands(commands_dict)
which defines the That's it for the skeleton. Now we launch Lyntin using the command line listed above and see if Lyntin has problems importing the new module.
Oops! I spelled
Ahh--it loaded fine. I also did a Now to add some functionality to our setstatus command. Step 3: adding functionalityWe will use the sys module, so we need to add an import line to the top of the file: import sys The argparser will parse the input the user typed in and associate the tokens with the arguments and stick them in the args dict. For some types it'll convert the input into a recognizable value (all boolean values get converted to 0 or 1) and it'll do type checking as well. It's pretty intense--and way outside the scope of this document. Anyhow, so all our values are in that args dict. So we'll add the following code:
def ststatus_cmd(ses, args, input):
"""
This command allows you to set a new name/value pair in the
xterm title bar.
"""
global statusbar_dict
name = args["name"]
value = args["value"]
sortkey = args["sortkey"]
if not sortkey:
sortkey = name
ui = str(exported.get_engine().getUI().__class__)
if not value:
if statusbar_dict.has_key(name):
del statusbar_dict[name]
else:
statusbar_dict[name] = (value, sortkey)
output = []
for mem,(value,sortkey) in statusbar_dict.items():
output.append( (sortkey, mem, mem + ": " + value + " "))
output.sort()
output = [ x[2] for x in output ]
if ui.find("Textui") != -1:
sys.stdout.write("\33]2;" + "".join(output) + "\07")
sys.stdout.flush()
else:
exported.write_error("setstatus: textui support only.")
Let's break this down into chunks. The first chunk:
def ststatus_cmd(ses, args, input):
"""
This command allows you to set a new name/value pair in the
xterm title bar.
"""
global statusbar_dict
name = args["name"]
value = args["value"]
sortkey = args["sortkey"]
if not sortkey:
sortkey = name
ui = str(exported.get_engine().getUI().__class__)
We pick up the values we're interested in from the args dict then
assign a value to the sortkey if the user didn't specify one. The
next line is a bit tricky... We're using the The next chunk:
if not value:
if statusbar_dict.has_key(name):
del statusbar_dict[name]
else:
statusbar_dict[name] = (value, sortkey)
If there is no value, we're going to delete the name/value pair from the statusbar_dict altogether. Otherwise we add the new item or alter the existing item. The next chunk:
output = []
for mem,(value,sortkey) in statusbar_dict.items():
output.append( (sortkey, mem, mem + ": " + value + " "))
output.sort()
output = [ x[2] for x in output ]
Because they've altered one of the status bar items, we need to redisplay the new status bar in the xterm window. First we need to figure out what's in it. We go through the statusbar_dict and create a list of tuples with the sortkey first, and the thing to display second. Then we sort this list. Then we use a list comprehension to convert the list of tuples into a list of just the values to display. And lastly:
if ui.find("Textui") != -1:
sys.stdout.write("\33]2;" + "".join(output) + "\07")
sys.stdout.flush()
else:
exported.write_error("setstatus: textui and tkui support only.")
The textui writes text to stdout so we just pipe it to stdout. Though because Lyntin is multi-threaded this isn't an incredibly great idea since it could potentially cause issues. But that's a problem for another time. Step 4: finishing it upNow that you have a nice statusbar module, you might want to consider getting it added to the Lyntin code repository. Instructions for that are at http://lyntin.sourceforge.net/repository.php. At a minimum, you'll want to add a module doc-string explaining what the module does and what deficiencies it has as well as some module attributes such as who wrote it, when, and what version. Step 5: viewing the complete module
"""
This module defines the command #setstatus which allows a user
to set the title bar using name/value pairs which are tracked
and sorted individually. This has many uses amongst which
are display of hit points, experience points, and other statistics
in a static place.
"""
__author__ = "Will Guaraldi"
__version__ = "1.0"
__date__ = "January 4, 2003"
import sys
from lyntin import exported
from lyntin.modules import modutils
# this will hold the command information for adding to
# Lyntin later on
commands_dict = {}
# this will hold the statusbar status name and value variables
# for display in the title bar
statusbar_dict = {}
def setstatus_cmd(ses, args, input):
"""
This command allows you to set a new name/value pair in the
xterm title bar.
"""
global statusbar_dict
name = args["name"]
value = args["value"]
sortkey = args["sortkey"]
if not sortkey:
sortkey = name
ui = str(exported.get_engine().getUI().__class__)
if not value:
if statusbar_dict.has_key(name):
del statusbar_dict[name]
else:
statusbar_dict[name] = (value, sortkey)
output = []
for mem,(value,sortkey) in statusbar_dict.items():
output.append( (sortkey, mem, mem + ": " + value + " "))
output.sort()
output = [ x[2] for x in output ]
if ui.find("Textui") != -1:
sys.stdout.write("\33]2;" + "".join(output) + "\07")
sys.stdout.flush()
else:
exported.write_error("setstatus: textui support only.")
commands_dict["setstatus"] = (setstatus_cmd, "name value= sortkey=")
def load():
""" Initializes the module by binding all the commands."""
modutils.load_commands(commands_dict)
def unload():
""" Unbinds the commands (for when we reimport the module)."""
modutils.unload_commands(commands_dict)
Rock on! |
|||||||||||||||