def writeSocket(self, message, tag=None): """ Writes data to the socket. @param message: the data to be written to the mud @type message: string @param tag: Used to tag data being sent to the mud for identification when it comes out of the to_mud_hook. Simply passed through as-is by lyntin internals. @type tag: varies """ for line in message.strip().split("\n"): exported.hook_spam("to_mud_hook", { "session": self, "data": line, "tag": tag }) if self._socket: retval = self._socket.write(str(message)) if retval: exported.write_error("socket write: %s" % retval) else: # if we don't have a socket then we can't do any non-lyntin-command # stuff. exported.write_error( "No connection. Create a session.\n(See also: #help, #help session)" ) return
def writeSocket(self, message, tag=None): """ Writes data to the socket. @param message: the data to be written to the mud @type message: string @param tag: Used to tag data being sent to the mud for identification when it comes out of the to_mud_hook. Simply passed through as-is by lyntin internals. @type tag: varies """ for line in message.strip().split("\n"): exported.hook_spam("to_mud_hook", {"session": self, "data": line, "tag": tag}) if self._socket: retval = self._socket.write(str(message)) if retval: exported.write_error("socket write: %s" % retval) else: # if we don't have a socket then we can't do any non-lyntin-command # stuff. exported.write_error("No connection. Create a session.\n(See also: #help, #help session)") return
def tickon_cmd(ses, args, input): """ Turns on the ticker for this session. see also: tick, tickon, tickoff, ticksize, tickwarnsize category: commands """ global myscheduler if not hasattr(ses, "_ticker"): ses._ticker = DEFAULT_TICKER.copy() tick_tagname = ses.getName() + "tick" tickwarn_tagname = ses.getName() + "tickwarn" # quick check to make sure there isn't already a tick event # for this session if myscheduler.getEventById(tick_tagname): exported.write_error("tickon: ticker is already enabled.", ses) return _addtickevents(ses) ses._ticker["enabled"] = 1 exported.write_message("tickon: session %s ticker enabled." % ses.getName(), ses)
def snoop_cmd(ses, args, input): """ Sets the session specified into or out of snooping mode. When a session is in snoop mode, you will see mud data from that session regardless of what session is the current session. examples: #snoop a -- tells you whether a is in snoop mode #snoop a on -- sets snoop mode for a category: commands """ snoopsession = args["session"] mode = args["mode"] ses = exported.get_session(snoopsession) if ses == None: exported.write_error("snoop: session '%s' does not exist." % snoopsession) return if mode != None: ses.setSnoop(mode) if exported.get_config("snoop", ses, 1) == 1: exported.write_message("snoop: snooping is enabled for %s." % snoopsession) else: exported.write_message("snoop: snooping is disabled for %s." % snoopsession)
def unschedule_cmd(ses, args, input): """ Allows you to remove a scheduled event by id. To remove all events scheduled use *. To see a list of the events and ids for the current session use the #sched command. examples: #unschedule * #unschedule 44 category: commands """ global myscheduler id = args["str"] quiet = args["quiet"] if id: ret = myscheduler.removeById(id) if not ret: if id == "*": exported.write_error( "unschedule: no scheduled events to unschedule.") else: exported.write_error("unschedule: id '%s' is not valid." % id) return if not quiet: exported.write_message("events removed:\n%s" % "\n".join(ret)) return exported.write_message("not implemented yet.")
def tickon_cmd(ses, args, input): """ Turns on the ticker for this session. see also: tick, tickon, tickoff, ticksize, tickwarnsize category: commands """ global myscheduler if not hasattr(ses, "_ticker"): ses._ticker = DEFAULT_TICKER.copy() tick_tagname = ses.getName() + "tick" tickwarn_tagname = ses.getName() + "tickwarn" # quick check to make sure there isn't already a tick event # for this session if myscheduler.getEventById(tick_tagname): exported.write_error("tickon: ticker is already enabled.", ses) return _addtickevents(ses) ses._ticker["enabled"] = 1 exported.write_message( "tickon: session %s ticker enabled." % ses.getName(), ses)
def changeSession(self, name=''): """ Changes the current session to another named session. If they don't pass in a name, we get the next available non-common session if possible. @param name: the name of the session to switch to @type name: string """ if name == '': keys = self._sessions.keys() # it's a little bit of finagling here to make sure # that the common session is the last one we would # switch to name = self._current_session.getName() keys.remove(name) if not name == "common": keys.remove("common") keys.append("common") self.set_current_session(self._sessions[keys[0]]) # if they pass in a name, we switch to that session. elif self._sessions.has_key(name): self.set_current_session(self._sessions[name]) else: exported.write_error("No session of that name.")
def unschedule_cmd(ses, args, input): """ Allows you to remove a scheduled event by id. To remove all events scheduled use *. To see a list of the events and ids for the current session use the #sched command. examples: #unschedule * #unschedule 44 category: commands """ global myscheduler id = args["str"] quiet = args["quiet"] if id: ret = myscheduler.removeById(id) if not ret: if id == "*": exported.write_error("unschedule: no scheduled events to unschedule.") else: exported.write_error("unschedule: id '%s' is not valid." % id) return if not quiet: exported.write_message("events removed:\n%s" % "\n".join(ret)) return exported.write_message("not implemented yet.")
def chr_cmd(ses, args, input): """ Allows you to assign arbitrary characters to variables. For example, if you wanted to assign ASCII char 7 to variable ctrlG you could do: #chr {ctrlG} {7} Since this creates a variable, you should remove the variable with the unvariable command. Note: This won't work if you don't have the variable module loaded. category: commands """ var = args["var"] ascii = args["ascii"] quiet = args["quiet"] vm = exported.get_manager("variable") if not vm: exported.write_error("chr: no variable manager found.") return if ascii < 0 or ascii > 127: exported.write_error("chr: ascii argument out of range of 0 to 127.") return vm.addVariable(ses, var, chr(ascii)) if not quiet: exported.write_message("chr: variable %s added." % var)
def highlight_cmd(ses, args, input): """ With no arguments, prints all highlights. With one argument, prints all highlights which match the arg. With multiple arguments, creates a highlight. Highlights enable you to colorfully "tag" text that's of interest to you with the given style. Styles available are: styles foreground colors background colors bold black grey b black blink red light red b red reverse green light green b green underline yellow light yellow b yellow blue light blue b blue magenta light magenta b magenta cyan light cyan b cyan white light white b white Highlights handle * at the beginning and end of non-regular expression texts. Highlights will handle regular expression texts as well. See "#help regexp" for more details. Note: blink, underline, and reverse may not be available in all ui's. examples: #highlight {green} {Sven arrives.} #highlight {reverse,green} {Sven arrives.} #highlight {blue} {r[^.*?says:]} which is the same as: #highlight {blue} {*says:} category: commands """ style = args["style"] text = args["text"] quiet = args["quiet"] if not text: data = exported.get_manager("highlight").getInfo(ses, style, 1) if not data: data = ["highlight: no highlights defined."] exported.write_message("highlights:\n" + "\n".join(data), ses) return style = style.lower() stylelist = style.split(",") for mem in stylelist: if mem not in ansi.STYLEMAP: exported.write_error("highlight: '%s' not a valid style.\nCheck out the highglight help file for more information." % mem) return exported.get_manager("highlight").addHighlight(ses, style, text) if not quiet: exported.write_message("highlight: {%s} {%s} added." % (style, text), ses)
def grep_cmd(ses, args, input): """ Similar to the unix grep command, this allows you to extract information from the session's data buffer using regular expressions. It prints matching lines in their entirety. examples: #grep {says:} 1000 Greps the last 1000 lines of the databuffer for lines that have "says:" in them. category: commands """ if ses.getName() == "common": exported.write_error("grep cannot be applied to common session.", ses) return pattern = args["pattern"] size = args["size"] context = args["context"] buffer = ses.getDataBuffer() ret = [] cpattern = re.compile(pattern) for i in range(max(len(buffer) - size, 0), len(buffer)): mem = buffer[i] if cpattern.search(mem): if context > 0: mem = [] if i > 0: bound = i - context if bound < 0: bound = 0 for j in range(bound, i): mem.append(" " + buffer[j]) mem.append("+ " + buffer[i]) if i < len(buffer): bound = i + context + 1 if bound > len(buffer) - 1: bound = len(buffer) - 1 for j in range(i + 1, bound): mem.append(" " + buffer[j]) mem = "".join(mem) ret.append(mem) if context == 0: splitter = "" else: splitter = "---\n" exported.write_message("grep %s results:\n%s" % (pattern, splitter.join(ret)), ses)
def grep_cmd(ses, args, input): """ Similar to the unix grep command, this allows you to extract information from the session's data buffer using regular expressions. It prints matching lines in their entirety. examples: #grep {says:} 1000 Greps the last 1000 lines of the databuffer for lines that have "says:" in them. category: commands """ if (ses.getName() == "common"): exported.write_error("grep cannot be applied to common session.", ses) return pattern = args["pattern"] size = args["size"] context = args["context"] buffer = ses.getDataBuffer() ret = [] cpattern = re.compile(pattern) for i in range(max(len(buffer) - size, 0), len(buffer)): mem = buffer[i] if cpattern.search(mem): if context > 0: mem = [] if i > 0: bound = i - context if bound < 0: bound = 0 for j in range(bound, i): mem.append(" " + buffer[j]) mem.append("+ " + buffer[i]) if i < len(buffer): bound = i + context + 1 if bound > len(buffer) - 1: bound = len(buffer) - 1 for j in range(i + 1, bound): mem.append(" " + buffer[j]) mem = "".join(mem) ret.append(mem) if context == 0: splitter = "" else: splitter = "---\n" exported.write_message( "grep %s results:\n%s" % (pattern, splitter.join(ret)), ses)
def raw_cmd(ses, args, input): """ Sends input straight to the mud. category: commands """ if (ses.getName() == "common"): exported.write_error("raw: cannot send raw data to the common session.", ses) return ses.writeSocket(args["input"] + "\n")
def raw_cmd(ses, args, input): """ Sends input straight to the mud. category: commands """ if (ses.getName() == "common"): exported.write_error( "raw: cannot send raw data to the common session.", ses) return ses.writeSocket(args["input"] + "\n")
def loop_cmd(ses, args, input): """ Executes a given command replacing %0 in the command with the range of numbers specified in <from> and <to>. example: #loop {1,4} {reclaim %0.corpse} will execute: reclaim 1.corpse reclaim 2.corpse reclaim 3.corpse reclaim 4.corpse A better way to execute a command a number of times without regard to an index, would be: #4 {reclaim corpse} which will send "reclaim corpse" to the mud 5 times. category: commands """ loop = args["fromto"] command = args["comm"] # split it into parts looprange = loop.split(',') if len(looprange) != 2: exported.write_error("syntax: #loop <from,to> <command>", ses) return # remove trailing and leading whitespace and convert to ints # so we can use them in a range function ifrom = int(looprange[0].strip()) ito = int(looprange[1].strip()) # we need to handle backwards and forwards using the step # and need to adjust ito so the range is correctly bounded. if ifrom > ito: step = -1 else: step = 1 if ito > 0: ito = ito + step else: ito = ito - step for i in range(ifrom, ito, step): loopcommand = command.replace("%0", repr(i)) exported.lyntin_command(loopcommand, internal=1, session=ses)
def turnonecho(self): """ Turns on echo if termios module is present.""" if self._tio == 0 or self._rline == 1: return fd = self._stdin.fileno() new = termios.tcgetattr(fd) new[3] = self._onecho_attr try: termios.tcsetattr(fd, termios.TCSADRAIN, new) self._echo = 1 except Exception, e: exported.write_error("textui: unable to turn on echo: %s" % e)
def variable_cmd(ses, args, input): """ Creates a variable for that session of said name with said value. Variables can then pretty much be used anywhere. examples: #variable {hps} {100} #action {HP: %0/%1 } {#variable {hps} {%0}} Variables can later be accessed via the variable character (which defaults to $) and the variable name. In the case of the above, the variable name would be $hps. We also handle braced closures for denoting variables like ${hps}. If you have a variable hps and a variable hpset, you can explicitly specify which one using { }. There are also system variables $HOME, $TIMESTAMP, $LOGTIMESTAMP, and $DATADIR (must be upper-cased) and global variables. To set a global variable which can be used in all sessions, it must be preceded by a _. examples: #variable {_fun} {happy fun ball} #showme $_fun #showme $TIMESTAMP #showme ${TIMESTAMP} category: commands """ var = args["var"] expansion = args["expansion"] quiet = args["quiet"] vm = exported.get_manager("variable") if not expansion: data = vm.getInfo(ses, var) if not data: data = ["variable: no variables defined."] exported.write_message("variables:\n" + "\n".join(data), ses) return try: vm.addVariable(ses, var, expansion) if not quiet: exported.write_message( "variable: {%s}={%s} added." % (var, expansion), ses) except Exception, e: exported.write_error("variable: cannot be set. %s" % e, ses)
def tallyError(self): """ Adds one to the error count. If we see more than 20 errors, we shutdown. """ self._errorcount = self._errorcount + 1 exported.write_error("WARNING: Unhandled error encountered (%d out of %d)." % (self._errorcount, 20)) exported.hook_spam("error_occurred_hook", {"count": self._errorcount}) if self._errorcount > 20: exported.hook_spam("too_many_errors_hook", {}) exported.write_error("Error count exceeded--shutting down.") sys.exit(0)
def variable_cmd(ses, args, input): """ Creates a variable for that session of said name with said value. Variables can then pretty much be used anywhere. examples: #variable {hps} {100} #action {HP: %0/%1 } {#variable {hps} {%0}} Variables can later be accessed via the variable character (which defaults to $) and the variable name. In the case of the above, the variable name would be $hps. We also handle braced closures for denoting variables like ${hps}. If you have a variable hps and a variable hpset, you can explicitly specify which one using { }. There are also system variables $HOME, $TIMESTAMP, $LOGTIMESTAMP, and $DATADIR (must be upper-cased) and global variables. To set a global variable which can be used in all sessions, it must be preceded by a _. examples: #variable {_fun} {happy fun ball} #showme $_fun #showme $TIMESTAMP #showme ${TIMESTAMP} category: commands """ var = args["var"] expansion = args["expansion"] quiet = args["quiet"] vm = exported.get_manager("variable") if not expansion: data = vm.getInfo(ses, var) if not data: data = ["variable: no variables defined."] exported.write_message("variables:\n" + "\n".join(data), ses) return try: vm.addVariable(ses, var, expansion) if not quiet: exported.write_message("variable: {%s}={%s} added." % (var, expansion), ses) except Exception, e: exported.write_error("variable: cannot be set. %s" % e, ses)
def alias_cmd(ses, args, input): """ With no arguments, prints all aliases. With one argument, prints all aliases which match the arg. With multiple arguments, creates an alias. You can use pattern variables which look like % and a number. %0 will be all the arguments passed in. Ranges can be used by using python colon-syntax, specifying a half-open slice of the input items, so %0:3 is the alias name, first, and second arguments of the input. Negative numbers count back from the end of the list. So %-1 is the last item in the list, %:-1 is everything but the last item in the list. examples: #alias {k*} - prints out aliases that start with k #alias {k} {kill %1} - builds a new alias #alias {gg} {put %1: in chest} - builds a new alias category: commands """ name = args["alias"] command = args["expansion"] quiet = args["quiet"] am = exported.get_manager("alias") ad = am.getAliasData(ses) # they typed '#alias' or '#alias x' so we print the relevant aliases if not command: data = ad.getInfo(name) if not data: data = ["alias: no aliases defined."] exported.write_message("aliases:\n" + "\n".join(data), ses) return # they're creating an alias try: ad.addAlias(name, command) except ValueError as e: exported.write_error("alias: %s" % e, ses) if not quiet: exported.write_message("alias: {%s} {%s} added." % (name, command), ses)
def read_cmd(ses, args, input): """ Reads in a file running each line as a Lyntin command. This is the opposite of #write which allows you to save session settings and restore them using #read. You can also read in via the commandline when you start Lyntin: lyntin --read 3k And read can handle HTTP urls: lyntin --read http://lyntin.sourceforge.net/lyntinrc #read http://lyntin.sourceforge.net/lyntinrc Note: the first non-whitespace char is used to set the Lyntin command character. If you use non Lyntin commands in your file, make sure the first one is a command char. If not, use #nop . It will skip blank lines. If you don't specify a directory, Lyntin will look for the file in your datadir. category: commands """ filename = args["filename"] import os if os.sep not in filename and not filename.startswith("http://"): filename = config.options["datadir"] + filename if filename.startswith("~"): filename = os.path.expanduser(filename) try: # http reading contributed by Sebastian John if filename.startswith("http://"): f = utils.http_get(filename) contents = f.readlines() else: f = open(filename, "r") contents = f.readlines() f.close() except Exception, e: exported.write_error( "read: file %s cannot be opened.\n%s" % (filename, e), ses) return
def swdir_cmd(ses, args, input): """ This adds speedwalking aliases and tells you the current speedwalking dirs already registered. examples: #swdir {n} {north} #swdir {s} {south} #swdir {e} {east} #swdir {w} {west} #swdir {NE} {northeast} #swdir {l} {look} ... This allows you to string characters together to speedwalk: 4e2sNE which using the above swdirs gets expanded to "east;east;east;east;south;south;northeast" and who wants to type all that? see also: swexclude category: commands """ # originally written by Sebastian John alias = args["alias"] dir = args["dir"] quiet = args["quiet"] # they typed '#swdir dd*' and are looking for matching speedwalking dirs if not dir: data = exported.get_manager("speedwalk").getDirsInfo(ses, alias) if not data: data = ["swdir: no speedwalking dirs defined."] exported.write_message("swdirs:\n" + "\n".join(data), ses) return try: exported.get_manager("speedwalk").addDir(ses, alias, dir) if not quiet: exported.write_message("swdir: {%s} {%s} added." % (alias, dir), ses) except ValueError, e: exported.write_error("swdir: cannot add alias '%s': %s." % (alias, e), ses)
def read_cmd(ses, args, input): """ Reads in a file running each line as a Lyntin command. This is the opposite of #write which allows you to save session settings and restore them using #read. You can also read in via the commandline when you start Lyntin: lyntin --read 3k And read can handle HTTP urls: lyntin --read http://lyntin.sourceforge.net/lyntinrc #read http://lyntin.sourceforge.net/lyntinrc Note: the first non-whitespace char is used to set the Lyntin command character. If you use non Lyntin commands in your file, make sure the first one is a command char. If not, use #nop . It will skip blank lines. If you don't specify a directory, Lyntin will look for the file in your datadir. category: commands """ filename = args["filename"] import os if os.sep not in filename and not filename.startswith("http://"): filename = config.options["datadir"] + filename if filename.startswith("~"): filename = os.path.expanduser(filename) try: # http reading contributed by Sebastian John if filename.startswith("http://"): f = utils.http_get(filename) contents = f.readlines() else: f = open(filename, "r") contents = f.readlines() f.close() except Exception, e: exported.write_error("read: file %s cannot be opened.\n%s" % (filename, e), ses) return
def alias_cmd(ses, args, input): """ With no arguments, prints all aliases. With one argument, prints all aliases which match the arg. With multiple arguments, creates an alias. You can use pattern variables which look like % and a number. %0 will be all the arguments passed in. Ranges can be used by using python colon-syntax, specifying a half-open slice of the input items, so %0:3 is the alias name, first, and second arguments of the input. Negative numbers count back from the end of the list. So %-1 is the last item in the list, %:-1 is everything but the last item in the list. examples: #alias {k*} - prints out aliases that start with k #alias {k} {kill %1} - builds a new alias #alias {gg} {put %1: in chest} - builds a new alias category: commands """ name = args["alias"] command = args["expansion"] quiet = args["quiet"] am = exported.get_manager("alias") ad = am.getAliasData(ses) # they typed '#alias' or '#alias x' so we print the relevant aliases if not command: data = ad.getInfo(name) if not data: data = ["alias: no aliases defined."] exported.write_message("aliases:\n" + "\n".join(data), ses) return # they're creating an alias try: ad.addAlias(name, command) except ValueError, e: exported.write_error("alias: %s" % e, ses)
def deed_cmd(ses, args, input): """ Deeds serve as a kind of notebook - whatever you don't want to forget, store it in a deed. examples:: #deed -- prints all the deeds for that session #deed {$TIMESTAMP Joe healed me} -- adds a new deed to the list #deed 10 -- prints the last 10 deeds Before a deed is stored, variables are expanded--this allows you to use system, global, and session variables in your deeds like $TIMESTAMP which will mark when the deed was created. category: commands """ # original deed_cmd code contributied by Sebastian John if (ses.getName() == "common"): exported.write_error("deed cannot be applied to common session.", ses) return deedtext = args["text"] quiet = args["quiet"] if not deedtext: data = exported.get_manager("deed").getInfo(ses) if data == "": data = "deed: no deeds defined." exported.write_message(data, ses) return if deedtext.isdigit(): data = exported.get_manager("deed").getInfo(ses, deedtext) if data == "": data = "deed: no deeds defined." exported.write_message(data, ses) return exported.get_manager("deed").getDeedData(ses).addDeed(deedtext) if not quiet: exported.write_message("deed: {%s} added." % deedtext, ses)
def test_for_conflicts(name, module): """ Tests a module we just imported with the name the path the module should have. This allows us to test Lyntin modules we just dynamically loaded to verify it's the one we intended to load. Right now we don't really do anything except kick up an error to the user. Let them deal with the issue. @param name: the full name of the module we wanted to load @type name: string @param module: the actual module we loaded @type module: module instance """ if module.__file__ != name + "c" and module.__file__ != name: exported.write_error("possible name conflict: '%s' and '%s'" % (name, module.__file__))
def zap_cmd(ses, args, input): """ This disconnects from the mud and closes the session. If no session is specified, it will close the current session. category: commands """ sesname = args["session"] if sesname: ses = exported.myengine.getSession(sesname) if ses == None: exported.write_error("zap: session %s does not exist." % sesname) return if exported.myengine.closeSession(ses): exported.write_message("zap: session %s zapped!" % ses.getName()) else: exported.write_message("zap: session %s cannot be zapped!" % ses.getName())
def unregisterSession(self, ses): """ Unregisters a session from the engine. @param ses: the session to unregister @type ses: session.Session instance """ if not self._sessions.has_key(ses.getName()): raise ValueError("No session of that name.") if ses == self._current_session: self.changeSession() for mem in self._managers.values(): try: mem.removeSession(ses) except Exception, e: exported.write_error("Exception with removing session %s." % e)
def showme_cmd(ses, args, input): """ Will display {text} on your screen. Doesn't get sent to the mud-- just your screen. examples: #action {^%0 annihilates you!} {#showme {EJECT! EJECT! EJECT!}} category: commands """ input = args["input"] if not input: exported.write_error("syntax: requires a message.", ses) return input = input.replace("\\;", ";") input = input.replace("\\$", "$") input = input.replace("\\%", "%") exported.write_message(input, ses)
def startAutotyper(self, tkevent): """ This will start the autotyper. It will be called if you type <Ctrl>+<t>. There can be only one autotyper at a time. The autotyper cannot be started for the common session. """ if self._autotyper != None: exported.write_error("cannot start autotyper: already started.") return session = exported.get_current_session() if session.getName() == "common": exported.write_error("autotyper cannot be applied to common session.") return self._autotyper = Autotyper(self._partk._tk, self.autotyperDone) self._autotyper_ses = session exported.write_message("autotyper: started.")
def closeSession(self, ses=None): """ Closes down a session. @param ses: the name of the session to close @type ses: string @return: 1 if successful; 0 if not @rtype: boolean """ if ses == None: ses = self._current_session if ses.getName() == "common": exported.write_error("Can't close the common session.") return 0 ses.shutdown((1,)) self.unregisterSession(ses) exported.hook_unregister("shutdown_hook", ses.shutdown) return 1
def closeSession(self, ses=None): """ Closes down a session. @param ses: the name of the session to close @type ses: string @return: 1 if successful; 0 if not @rtype: boolean """ if ses == None: ses = self._current_session if ses.getName() == "common": exported.write_error("Can't close the common session.") return 0 ses.shutdown((1, )) self.unregisterSession(ses) exported.hook_unregister("shutdown_hook", ses.shutdown) return 1
def unload_cmd(ses, args, input): """ Unloads a module from Lyntin by calling the module's "unload" function and then removing references to it in the Python environment. examples: #unload wbgscheduler #unload modules.alias category: commands """ mod = args["modulename"] if sys.modules.has_key(mod): _module = sys.modules[mod] if _module.__dict__.has_key("lyntin_import"): if _module.__dict__.has_key("unload"): try: _module.unload() except: exported.write_traceback("unload: module %s didn't unload properly." % mod) else: exported.write_error("unload: module %s doesn't have an unload function." % mod) del sys.modules[mod] exported.write_message("unload: module %s unloaded." % mod) config.lyntinmodules.remove(mod) return else: exported.write_error("unload: module %s cannot be unloaded." % mod) return exported.write_error("unload: module %s is not loaded." % mod)
def textin_cmd(ses, args, input): """ Takes the contents of the file and outputs it directly to the mud without processing it (like #read does). If you don't specify a directory, Lyntin will look for the file in the datadir. category: commands """ if (ses.getName() == "common"): exported.write_error("textin cannot be applied to common session.", ses) return filename = args["file"] if os.sep not in filename: filename = config.options["datadir"] + filename try: f = open(filename, "r") contents = f.readlines() f.close() for mem in contents: mem = utils.chomp(mem) ses.getSocketCommunicator().write(mem + "\n") exported.write_message("textin: file %s read and sent to mud." % filename, ses) except IOError: exported.write_error("textin: file %s is not readable." % filename, ses) except Exception, e: exported.write_error("textin: exception thrown %s." % e, ses)
def log_cmd(ses, args, input): """ Will start or stop logging to a given filename for that session. Each session can have its own logfile. If USERPREFIX is set, then every line from the user will be prepended with this prefix and immediately written into log file. If USERPREFIX is omitted, then the user input will be attached to mud prompts before logging. category: commands """ logfile = args["logfile"] databuffer = args["databuffer"] stripansi = args["stripansi"] userprefix = args["userprefix"] if not ses.isConnected(): exported.write_error("log: You must have a session to log.", ses) return lm = exported.get_manager("logger") loggerdata = lm.getLogData(ses) if not logfile: exported.write_message(loggerdata.getStatus(), ses) return # handle stopping logging if loggerdata.isLogging() == 1: try: logname = loggerdata._logfile.name loggerdata.closeLogFile() exported.write_message("log: stopped logging to '%s'." % logname, ses) except Exception as e: exported.write_error("log: logfile cannot be closed (%s)." % (e), ses) return # handle starting logging try: if os.sep not in logfile: logfile = config.options["datadir"] + logfile if databuffer: f = open(logfile, "w") buffer = "".join(ses.getDataBuffer()) f.write(buffer) exported.write_message("log: dumped %d lines of databuffer to logfile" % buffer.count("\n"), ses) loggerdata.setLogFile(f, stripansi, userprefix) else: loggerdata.openLogFile(logfile, stripansi, userprefix) if stripansi: stripansimessage = " stripping ansi" else: stripansimessage = "" exported.write_message("log: starting logging to '%s'%s." % (logfile, stripansimessage), ses) except Exception as e: exported.write_error("log: logfile cannot be opened for appending. %s" % (e), ses)
def textin_cmd(ses, args, input): """ Takes the contents of the file and outputs it directly to the mud without processing it (like #read does). If you don't specify a directory, Lyntin will look for the file in the datadir. category: commands """ if (ses.getName() == "common"): exported.write_error("textin cannot be applied to common session.", ses) return filename = args["file"] if os.sep not in filename: filename = config.options["datadir"] + filename try: f = open(filename, "r") contents = f.readlines() f.close() for mem in contents: mem = utils.chomp(mem) ses.getSocketCommunicator().write(mem + "\n") exported.write_message( "textin: file %s read and sent to mud." % filename, ses) except IOError: exported.write_error("textin: file %s is not readable." % filename, ses) except Exception, e: exported.write_error("textin: exception thrown %s." % e, ses)
def tickwarnsize_cmd(ses, args, input): """ Sets and displays the number of seconds you get warned before a Tick actually happens. examples: #tickwarnsize #tickwarnsize 6 #tickwarnsize 0 see also: tick, tickon, tickoff, ticksize, tickwarnsize category: commands """ if not hasattr(ses, "_ticker"): ses._ticker = DEFAULT_TICKER.copy() size = args["size"] if size == 0: exported.write_message( "tickwarnsize: tickwarnsize is %d seconds." % ses._ticker["warn_len"], ses) return if size > ses._ticker["len"]: exported.write_error( "tickwarnsize: tickwarn length cannot be >= " + "to ticksize.\nCurrent ticksize is %s." % ses._ticker["len"], ses) return ses._ticker["warn_len"] = size ret = _removetickevents(ses) if ret: _addtickevents(ses) exported.write_message( "tickwarnsize: tickwarn length set to %s." % str(size), ses)
def tickwarnsize_cmd(ses, args, input): """ Sets and displays the number of seconds you get warned before a Tick actually happens. examples: #tickwarnsize #tickwarnsize 6 #tickwarnsize 0 see also: tick, tickon, tickoff, ticksize, tickwarnsize category: commands """ if not hasattr(ses, "_ticker"): ses._ticker = DEFAULT_TICKER.copy() size = args["size"] if size == 0: exported.write_message("tickwarnsize: tickwarnsize is %d seconds." % ses._ticker["warn_len"], ses) return if size > ses._ticker["len"]: exported.write_error("tickwarnsize: tickwarn length cannot be >= " + "to ticksize.\nCurrent ticksize is %s." % ses._ticker["len"], ses) return ses._ticker["warn_len"] = size ret = _removetickevents(ses) if ret: _addtickevents(ses) exported.write_message("tickwarnsize: tickwarn length set to %s." % str(size), ses)
def math_cmd(ses, args, input): """ Implements the #math command which allows you to manipulate variables above and beyond setting them. examples: #math {hps} {$hps + 5} category: commands """ var = args["var"] ops = args["operation"] quiet = args["quiet"] try: rvalue = eval(ops) varman = exported.get_manager("variable") if varman: varman.addVariable(ses,var, str(rvalue)) if not quiet: exported.write_message("math: %s = %s = %s." % (var, ops, str(rvalue)), ses) except Exception, e: exported.write_error("math: exception: %s\n%s" % (ops, e), ses)
def if_cmd(ses, args, input): """ Allows you to do some boolean logic based on Lyntin variables or any Python expression. If this expression returns a non-false value, then the action will be performed otherwise the elseaction (if there is one) will be peformed. examples: #if {$myhpvar < 100} {#showme PANIC!} #if {$myhpvar < 100 && $myspvar < 100} {#showme PANIC!} #if {'$name' == 'Joe'} {#showme That joe is a jerk.} When you're comparing variable values with other strings, make sure to put them in quotes becuase variable expansion happens before the if command is evaluated. examples: WRONG: #if {$name == Joe} {#showme Joe is a jerk.} RIGHT: #if {'$name' == 'Joe'} {#showme Joe is a jerk.} category: commands """ # original if_cmd code contributed by Sebastian John expr = args["expr"] action = args["action"] elseaction = args["elseaction"] try: if eval(expr): exported.lyntin_command(action, 1, ses) elif elseaction: exported.lyntin_command(elseaction, 1, ses) except SyntaxError: exported.write_error("if: invalid syntax / syntax error.", ses) except Exception, e: exported.write_error("if: exception: %s" % e, ses)
def log_cmd(ses, args, input): """ Will start or stop logging to a given filename for that session. Each session can have its own logfile. If USERPREFIX is set, then every line from the user will be prepended with this prefix and immediately written into log file. If USERPREFIX is omitted, then the user input will be attached to mud prompts before logging. category: commands """ logfile = args["logfile"] databuffer = args["databuffer"] stripansi = args["stripansi"] userprefix = args["userprefix"] if not ses.isConnected(): exported.write_error("log: You must have a session to log.", ses) return lm = exported.get_manager("logger") loggerdata = lm.getLogData(ses) if not logfile: exported.write_message(loggerdata.getStatus(), ses) return # handle stopping logging if loggerdata.isLogging() == 1: try: logname = loggerdata._logfile.name loggerdata.closeLogFile() exported.write_message("log: stopped logging to '%s'." % logname, ses) except Exception, e: exported.write_error("log: logfile cannot be closed (%s)." % (e), ses) return
def if_cmd(ses, args, input): """ Allows you to do some boolean logic based on Lyntin variables or any Python expression. If this expression returns a non-false value, then the action will be performed otherwise the elseaction (if there is one) will be peformed. examples: #if {$myhpvar < 100} {#showme PANIC!} #if {$myhpvar < 100 and $myspvar < 100} {#showme PANIC!} #if {'$name' == 'Joe'} {#showme That joe is a jerk.} When you're comparing variable values with other strings, make sure to put them in quotes becuase variable expansion happens before the if command is evaluated. examples: WRONG: #if {$name == Joe} {#showme Joe is a jerk.} RIGHT: #if {'$name' == 'Joe'} {#showme Joe is a jerk.} category: commands """ # original if_cmd code contributed by Sebastian John expr = args["expr"] action = args["action"] elseaction = args["elseaction"] try: if eval(expr): exported.lyntin_command(action, 1, ses) elif elseaction: exported.lyntin_command(elseaction, 1, ses) except SyntaxError: exported.write_error("if: invalid syntax / syntax error.", ses) except Exception, e: exported.write_error("if: exception: %s" % e, ses)
def math_cmd(ses, args, input): """ Implements the #math command which allows you to manipulate variables above and beyond setting them. examples: #math {hps} {$hps + 5} category: commands """ var = args["var"] ops = args["operation"] quiet = args["quiet"] try: rvalue = eval(ops) varman = exported.get_manager("variable") if varman: varman.addVariable(ses, var, str(rvalue)) if not quiet: exported.write_message( "math: %s = %s = %s." % (var, ops, str(rvalue)), ses) except Exception, e: exported.write_error("math: exception: %s\n%s" % (ops, e), ses)
def runui(self): global HELP_TEXT exported.add_help("textui", HELP_TEXT) exported.write_message("For textui help, type \"#help textui\".") # termios is the module that allows us to change echo for a terminal # but only if the module is present try: import termios except ImportError: self._tio = 0 else: self._tio = 1 echonew = termios.tcgetattr(self._stdin.fileno()) self._onecho_attr = echonew[3] self._offecho_attr = echonew[3] & ~termios.ECHO if config.options.has_key("readline"): try: import readline except ImportError: self._rline = 0 exported.write_error("Readline not available for your system.") else: self._rline = 1 # we do some stuff to grab the readlinerc file if they have one # so the user can set some readline oriented things which makes # things a little nicer for the user. d = exported.get_config("datadir") try: readline.read_init_file(d + "readlinerc") except: exported.write_error( "Note: No readlinerc file available in %s." % d) exported.write_message("Readline enabled.") if self._tio == 0 or self._rline == 1: exported.write_error("Warming: echo off is unavailable. " + "Your password will be visible.") # go into the main loop self.run()
def runui(self): global HELP_TEXT exported.add_help("textui", HELP_TEXT) exported.write_message("For textui help, type \"#help textui\".") # termios is the module that allows us to change echo for a terminal # but only if the module is present try: import termios except ImportError: self._tio = 0 else: self._tio = 1 echonew = termios.tcgetattr(self._stdin.fileno()) self._onecho_attr = echonew[3] self._offecho_attr = echonew[3] & ~termios.ECHO if config.options.has_key("readline"): try: import readline except ImportError: self._rline = 0 exported.write_error("Readline not available for your system.") else: self._rline = 1 # we do some stuff to grab the readlinerc file if they have one # so the user can set some readline oriented things which makes # things a little nicer for the user. d = exported.get_config("datadir") try: readline.read_init_file(d + "readlinerc") except: exported.write_error("Note: No readlinerc file available in %s." % d) exported.write_message("Readline enabled.") if self._tio == 0 or self._rline == 1: exported.write_error("Warming: echo off is unavailable. " + "Your password will be visible.") # go into the main loop self.run()