From: Jeremy Stanley Date: Wed, 28 Sep 2005 23:14:53 +0000 (+0000) Subject: Imported from archive. X-Git-Tag: 0.0.1~330 X-Git-Url: https://mudpy.org/gitweb?p=mudpy.git;a=commitdiff_plain;h=89ff278697fb215e01b34bebe85b18d8db3af44d Imported from archive. * command (command:look), mudpy.py (command_look): New command allowing avatars to view the description and contents of their location. * mudpy.conf (internal:directions), mudpy.py (Element.move_direction, Element.portals): Made direction vectors for actor movement configurable. * mudpy.conf (internal:logging), mudpy.py (log): Made logging configurable to write to a particular file, toggle printing to stdout, and added the ability to specify a syslog tag. * mudpy.py (Element.go_home, Element.move_direction): Added a feedback message to notify the user when their avatar moves between locations, and inform other users when actors depart from or arrive at their location. (User.send): Avoid unnecessarily duplicating prompts following unsolicited/notification messages. --- diff --git a/command b/command index 5319735..6d4509a 100644 --- a/command +++ b/command @@ -30,6 +30,11 @@ action = command_help(user, parameters) description = List commands or get help on one. help = This will list all comand words available to you along with a brief description or, alternatively, give you detailed information on one command. +[command:look] +action = command_look(user, parameters) +description = Look around. +help = With the look command, you can see where you are. + [command:move] action = command_move(user, parameters) description = Move in a specific direction. diff --git a/mudpy.conf b/mudpy.conf index fdacfe1..280368a 100644 --- a/mudpy.conf +++ b/mudpy.conf @@ -18,6 +18,11 @@ punctuation_say = . max_avatars = 7 password_tries = 3 +[internal:logging] +#file = mudpy.log +stdout = yes +#syslog = mudpy + [internal:network] host = port = 6669 @@ -34,3 +39,11 @@ frequency_log = 6000 frequency_save = 600 increment = 0.1 +[internal:directions] +down = { "vector": (0,0,-1), "exit": "downward", "enter": "above" } +east = { "vector": (1,0,0), "exit": "to the east", "enter": "the west" } +north = { "vector": (0,1,0), "exit": "to the north", "enter": "the south" } +south = { "vector": (0,-1,0), "exit": "to the south", "enter": "the north" } +up = { "vector": (0,0,1), "exit": "upward", "enter": "below" } +west = { "vector": (-1,0,0), "exit": "to the west", "enter": "the east" } + diff --git a/mudpy.py b/mudpy.py index 4c3cdf5..7e23d23 100644 --- a/mudpy.py +++ b/mudpy.py @@ -139,7 +139,7 @@ class Element: def go_to(self, location): """Relocate the element to a specific location.""" current = self.get("location") - if current and current in universe.contents[current].contents: + if current and self.key in universe.contents[current].contents: del universe.contents[current].contents[self.key] if location in universe.contents: self.set("location", location) universe.contents[location].contents[self.key] = self @@ -147,9 +147,13 @@ class Element: def go_home(self): """Relocate the element to its default location.""" self.go_to(self.get("default_location")) + self.echo_to_location("You suddenly realize that " + self.get("name") + " is here.") def move_direction(self, direction): """Relocate the element in a specified direction.""" + self.echo_to_location(self.get("name") + " exits " + universe.categories["internal"]["directions"].getdict(direction)["exit"] + ".") + self.send("You exit " + universe.categories["internal"]["directions"].getdict(direction)["exit"] + ".") self.go_to(universe.contents[self.get("location")].link_neighbor(direction)) + self.echo_to_location(self.get("name") + " arrives from " + universe.categories["internal"]["directions"].getdict(direction)["enter"] + ".") def look_at(self, key): """Show an element to another element.""" if self.owner: @@ -172,14 +176,8 @@ class Element: portals = {} if match("""^location:-?\d+,-?\d+,-?\d+$""", self.key): coordinates = [(int(x)) for x in self.key.split(":")[1].split(",")] - offsets = { - "down": (0,0,-1), - "east": (1,0,0), - "north": (0,1,0), - "south": (0,-1,0), - "up": (0,0,1), - "west": (-1,0,0) - } + directions = universe.categories["internal"]["directions"] + offsets = dict([(x, directions.getdict(x)["vector"]) for x in directions.facets()]) for portal in self.getlist("gridlinks"): adjacent = map(lambda c,o: c+o, coordinates, offsets[portal]) neighbor = "location:" + ",".join([(str(x)) for x in adjacent]) @@ -337,6 +335,7 @@ class User: self.output_queue = [] self.partial_input = "" self.echoing = True + self.received_newline = True self.terminator = IAC+GA self.negotiation_pause = 0 self.avatar = None @@ -377,6 +376,7 @@ class User: "output_queue", "partial_input", "echoing", + "received_newline", "terminator", "negotiation_pause", "avatar", @@ -451,7 +451,7 @@ class User: """Remove a user from the list of connected users.""" universe.userlist.remove(self) - def send(self, output, eol="$(eol)", raw=False, flush=False, add_prompt=True): + def send(self, output, eol="$(eol)", raw=False, flush=False, add_prompt=True, just_prompt=False): """Send arbitrary text to a connected user.""" # unless raw mode is on, clean it up all nice and pretty @@ -470,10 +470,13 @@ class User: # start with a newline, append the message, then end # with the optional eol string passed to this function # and the ansi escape to return to normal text - output = "$(eol)" + output + eol + chr(27) + "[0m" + if not just_prompt: output = "$(eol)$(eol)" + output + output += eol + chr(27) + "[0m" # tack on a prompt if active - if self.state == "active" and add_prompt: output += "$(eol)> " + if self.state == "active": + if not just_prompt: output += "$(eol)" + if add_prompt: output += "> " # find and replace macros in the output output = replace_macros(self, output) @@ -521,6 +524,10 @@ class User: def flush(self): """Try to send the last item in the queue and remove it.""" if self.output_queue: + if self.received_newline: + self.received_newline = False + if self.output_queue[0].startswith("\r\n"): + self.output_queue[0] = self.output_queue[0][2:] try: self.connection.send(self.output_queue[0]) del self.output_queue[0] @@ -697,6 +704,7 @@ class User: if self.avatar: current = self.avatar.get("location") self.avatar.set("default_location", current) + self.avatar.echo_to_location("You suddenly wonder where " + self.avatar.get("name") + " went.") del universe.contents[current].contents[self.avatar.key] self.avatar.remove_facet("location") self.avatar.owner = None @@ -722,9 +730,9 @@ def makedict(value): elif value.find(":") > 0: return eval("{" + value + "}") else: return { value: None } -def broadcast(message): +def broadcast(message, add_prompt=True): """Send a message to all connected users.""" - for each_user in universe.userlist: each_user.send("$(eol)" + message) + for each_user in universe.userlist: each_user.send("$(eol)" + message, add_prompt=add_prompt) def log(message): """Log a message.""" @@ -732,13 +740,23 @@ def log(message): # the time in posix log timestamp format timestamp = asctime()[4:19] + file_name = universe.categories["internal"]["logging"].get("file") + if file_name: + file_descriptor = file(file_name, "a") + file_descriptor.write(timestamp + " " + message + "\n") + file_descriptor.flush() + file_descriptor.close() + # send the timestamp and message to standard output - print(timestamp + " " + message) + if universe.categories["internal"]["logging"].getboolean("stdout"): + print(timestamp + " " + message) # send the message to the system log - openlog("mudpy", LOG_PID, LOG_INFO | LOG_DAEMON) - syslog(message) - closelog() + syslog_name = universe.categories["internal"]["logging"].get("syslog") + if syslog_name: + openlog(syslog_name, LOG_PID, LOG_INFO | LOG_DAEMON) + syslog(message) + closelog() def wrap_ansi_text(text, width): """Wrap text with arbitrary width while ignoring ANSI colors.""" @@ -1157,7 +1175,7 @@ def handle_user_input(user): user.menu_seen = False # if the user's client echo is off, send a blank line for aesthetics - if not user.echoing: user.send("", "") + if user.echoing: user.received_newline = True def generic_menu_handler(user): """A generic menu choice handler.""" @@ -1287,27 +1305,33 @@ def handler_active(user): # get the next waiting line of input input_data = user.input_queue.pop(0) - # split out the command (first word) and parameters (everything else) - if input_data.find(" ") > 0: - command_name, parameters = input_data.split(" ", 1) - else: - command_name = input_data - parameters = "" + # is there input? + if input_data: - # lowercase the command - command_name = command_name.lower() + # split out the command (first word) and parameters (everything else) + if input_data.find(" ") > 0: + command_name, parameters = input_data.split(" ", 1) + else: + command_name = input_data + parameters = "" - # the command matches a command word for which we have data - if command_name in universe.categories["command"]: - command = universe.categories["command"][command_name] - else: command = None + # lowercase the command + command_name = command_name.lower() - # if it's allowed, do it - if user.can_run(command): exec(command.get("action")) + # the command matches a command word for which we have data + if command_name in universe.categories["command"]: + command = universe.categories["command"][command_name] + else: command = None + + # if it's allowed, do it + if user.can_run(command): exec(command.get("action")) - # otherwise, give an error - elif command_name: command_error(user, input_data) + # otherwise, give an error + elif command_name: command_error(user, input_data) + # if no input, just idle back with a prompt + else: user.send("", just_prompt=True) + def command_halt(user, parameters): """Halt the world.""" @@ -1316,7 +1340,7 @@ def command_halt(user, parameters): else: message = "User " + user.account.get("name") + " halted the world." # let everyone know - broadcast(message) + broadcast(message, add_prompt=False) log(message) # set a flag to terminate the world @@ -1396,6 +1420,11 @@ def command_move(user, parameters): user.avatar.move_direction(parameters) else: user.send("You cannot go that way.") +def command_look(user, parameters): + """Look around.""" + if parameters: user.send("You look at or in anything yet.") + else: user.avatar.look_at(user.avatar.get("location")) + def command_say(user, parameters): """Speak to others in the same room."""