commandhandler.py 7.7 KB
import utils
from roomloader import RoomLoader


global_aliases = {
    'n': 'north',
    's': 'south',
    'e': 'east',
    'w': 'west',
    'u': 'up',
    'd': 'down',
    'l': 'look',
    '\'': 'say',
}

roomloader = RoomLoader('rooms')

class CommandHandler(object):


  def alias(self, command):
    if command in global_aliases:
        return global_aliases[command]
    if 'aliases' not in self.players[self.id]:
        self.players[self.id]["aliases"] = {}
    if command in self.players[self.id]["aliases"]:
        return self.players[self.id]["aliases"][command]
    return command

  def tokenize_params(self):
    cleaned = self.params.lower().strip()
    tokens = []
    for token in cleaned.split(' '):
        token = token.strip()
        if len(token) > 0:
            tokens.append(token)
    self.tokens = tokens

  def look(self):
    room_name = self.players[self.id]["room"]
    self.mud.send_message(self.id, "")
    if len(self.tokens) > 0 and self.tokens[0] == 'at':
        del self.tokens[0]
    if len(self.tokens) == 0:
        self.mud.send_message(self.id, roomloader.get_description(room_name))
    else:
        subject = self.tokens[0]
        items = roomloader.get_look_items(room_name)
        for item in items:
            if subject in item:
                self.mud.send_message(self.id, items[item])
                return True
        self.mud.send_message(self.id, "That doesn't seem to be here.")

    playershere = []
    # go through every player in the game
    for pid, pl in self.players.items():
        # if they're in the same room as the player
        if self.players[pid]["room"] == self.players[self.id]["room"]:
            # ... and they have a name to be shown
            if self.players[pid]["name"] is not None:
                # add their name to the list
                playershere.append(self.players[pid]["name"])

    # send player a message containing the list of players in the room
    self.mud.send_message(self.id, "Players here: {}".format(
                                            ", ".join(playershere)))

    # send player a message containing the list of exits from this room
    self.mud.send_message(self.id, "Exits are: {}".format(
                                  ", ".join(roomloader.get_exits(room_name))))

    return True

  def who(self):
    self.mud.send_message(self.id, "")
    self.mud.send_message(self.id, "-------- {} Players Currently Online --------".format(len(self.players)))
    for pid, player in self.players.items():
        self.mud.send_message(self.id, "   " + player["name"])
    self.mud.send_message(self.id, "---------------------------------------------".format(len(self.players)))
    self.mud.send_message(self.id, "")
    return True

  def go(self):
    # store the exit name
    ex = self.params.lower().strip()

    exits = roomloader.get_exits(self.players[self.id]["room"])
    # if the specified exit is found in the room's exits list
    if ex in exits:
        # go through all the players in the game
        for pid, pl in self.players.items():
            # if player is in the same room and isn't the player
            # sending the command
            if self.players[pid]["room"] == self.players[self.id]["room"] \
                    and pid != self.id:
                # send them a message telling them that the player
                # left the room
                self.mud.send_message(pid, "{} left via exit '{}'".format(
                                              self.players[self.id]["name"], ex))

        # update the player's current room to the one the exit leads to
        
        if roomloader.get_title(exits[ex]) == None:
            self.mud.send_message(self.id, "An invisible force prevents you from going in that direction.")
            return True
        else:
            self.players[self.id]["room"] = exits[ex]
            self.room = ex

        # go through all the players in the game
        for pid, pl in self.players.items():
            # if player is in the same (new) room and isn't the player
            # sending the command
            if self.players[pid]["room"] == self.players[self.id]["room"] \
                    and pid != self.id:
                # send them a message telling them that the player
                # entered the room
                self.mud.send_message(pid,
                                 "{} arrived via exit '{}'".format(
                                              self.players[self.id]["name"], ex))

        # send the player a message telling them where they are now
        self.mud.send_message(self.id, "You arrive at '{}'".format(roomloader.get_title(self.players[self.id]["room"])))
        self.tokens = []
        return self.look()
    # the specified exit wasn't found in the current room
    else:
        # send back an 'unknown exit' message
        self.mud.send_message(self.id, "Unknown exit '{}'".format(ex))
    return True


  def prompt(self):
    if len(self.tokens) == 0:
        self.mud.send_message(self.id, 'No prompt provided, no changes will be made.\r\nEx: prompt %hp>')

    self.players[self.id]['prompt'] = self.params + ' '
    utils.save_object_to_file(self.players[self.id], "players/{}.json".format(self.players[self.id]["name"]))

    return True

  def help(self):
    if len(self.tokens) > 0:
        filename = 'help/' + self.tokens[0] + '.txt'
    else:
        filename = 'help/help.txt'
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            for line in f:
                self.mud.send_message(self.id, line, '\r')
            self.mud.send_message(self.id, '')
    except:
        self.mud.send_message(self.id, 'No help topics available for \"{}\". A list\r\n of all commands is available at: help index'.format(self.tokens[0]))

  def say(self):
    # go through every player in the game
    for pid, pl in self.players.items():
        # if they're in the same room as the player
        if self.players[pid]["room"] == self.players[self.id]["room"]:
            # send them a message telling them what the player said
            self.mud.send_message(pid, "{} says: {}".format(
                                        self.players[self.id]["name"], self.params))
    return True

  def whisper(self):
    # go through every player in the game
    for pid, pl in self.players.items():
        # if they're in the same room as the player
        if self.players[pid]["name"] == self.tokens[0]:
            # send them a message telling them what the player said
            self.mud.send_message(pid, "{} whispers: {}".format(
                                        self.players[self.id]["name"], ' '.join(self.tokens[1:])))
    return True

  def quit(self):
    # send the player back the list of possible commands
    self.mud.send_message(id, "Saving...")
    utils.save_object_to_file(self.players[self.id], "players/{}.json".format(self.players[self.id]["name"]))
    self.mud.disconnect_player(self.id)
    return True

  def save(self):
    # send the player back the list of possible commands
    self.mud.send_message(self.id, "Saving...")
    utils.save_object_to_file(self.players[self.id], "players/{}.json".format(self.players[self.id]["name"]))
    self.mud.send_message(self.id, "Save complete")
    return True



  def parse(self, id, cmd, params, mud, players):
    self.id = id
    self.params = params
    self.tokenize_params()
    self.mud = mud
    self.players = players
    self.cmd = self.alias(cmd)
    try:
        if self.cmd in roomloader.get_exits(self.players[id]["room"]):
            self.params = self.cmd + " " + self.params
            self.cmd = "go"
        method = getattr(self, self.cmd)
        return method()
    except AttributeError as e:
        print(e)
        mud.send_message(id, "Unknown command '{}'".format(self.cmd))
        return False