817c7517 by Barry

Initial commit

0 parents
class CommandHandler(object):
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):
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, self.room.get_description())
else:
subject = self.tokens[0]
items = self.room.get_look_items()
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(self.room.get_exits())))
return True
def parse(self, id, cmd, params, room, mud, players):
self.id = id
self.cmd = cmd
self.params = params
self.tokenize_params()
self.room = room
self.mud = mud
self.players = players
try:
method = getattr(self, cmd)
return method()
except AttributeError:
return False
Commands:
say <message> - Says something out loud, e.g. 'say Hello'
look - Examines the surroundings, e.g. 'look'
go <exit> - Moves through the exit specified, e.g. 'go outside'
save - Saves your character
quit - Saves your character then closes the connection
\ No newline at end of file
#!/usr/bin/env python
"""A simple Multi-User Dungeon (MUD) game. Players can talk to each
other, examine their surroundings and move between rooms.
Some ideas for things to try adding:
* More rooms to explore
* An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
out loud'
* A 'whisper' command for talking to individual players
* A 'shout' command for yelling to players in all rooms
* Items to look at in rooms e.g. 'look fireplace' -> 'You see a
roaring, glowing fire'
* Items to pick up e.g. 'take rock' -> 'You pick up the rock'
* Monsters to fight
* Loot to collect
* Saving players accounts between sessions
* A password login
* A shop from which to buy items
author: Mark Frimston - mfrimston@gmail.com
"""
import time
# import datetime
#import io
import json
# import the MUD server class
from mudserver import MudServer
from commands import CommandHandler
print('STARTING MUD\r\n\r\n\r\n')
rooms = {}
# stores the players in the game
players = {}
# start the server
mud = MudServer()
cmd_handler = CommandHandler()
def load_room(room_name):
print("Loading room:" + room_name)
try:
if room_name in rooms:
return rooms[room_name]
module = __import__('rooms.' + room_name.lower())
room_module = getattr(module, room_name.lower())
room_class = getattr(room_module, room_name)
instance = room_class()
rooms[room_name] = instance
return instance
except Exception as e:
print(e)
return None
def save_object_to_file(obj, filename):
with open(filename, 'w', encoding='utf-8') as f:
f.write(json.dumps(obj, ensure_ascii=False))
def load_object_from_file(filename):
try:
with open(filename, 'r', encoding='utf-8') as f:
return json.loads(f.read())
except Exception:
return None
def prompt(pid):
if "prompt" not in players[pid]:
players[pid]["prompt"] = "> "
mud.send_message(pid, "\r\n" + players[pid]["prompt"], '')
# main game loop. We loop forever (i.e. until the program is terminated)
while True:
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time.sleep(0.001)
# TODO: Add some cache removal if older than X
# now = datetime.datetime.now()
# delta = now - datetime.timedelta(minutes = 2)
# for room in rooms:
# if room.created < delta:
# del rooms[room]
# 'update' must be called in the loop to keep the game running and give
# us up-to-date information
mud.update()
# go through any newly connected players
for id in mud.get_new_players():
# add the new player to the dictionary, noting that they've not been
# named yet.
# The dictionary key is the player's id number. We set their room to
# None initially until they have entered a name
# Try adding more player stats - level, gold, inventory, etc
players[id] = {
"name": None,
"room": None,
"inventory": None,
"prompt": "> ",
}
# send the new player a prompt for their name
mud.send_message(id, "What is your name?")
# go through any recently disconnected players
for id in mud.get_disconnected_players():
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players:
continue
# go through all the players in the game
for pid, pl in players.items():
# send each player a message to tell them about the diconnected
# player
mud.send_message(pid, "{} quit the game".format(
players[id]["name"]))
# remove the player's entry in the player dictionary
del(players[id])
# go through any new commands sent from players
for id, command, params in mud.get_commands():
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players:
continue
if players[id]["room"]:
rm = load_room(players[id]["room"])
# if the player hasn't given their name yet, use this first command as
# their name and move them to the starting room.
if players[id]["name"] is None:
loaded_player = load_object_from_file("players/{}.json".format(command))
if loaded_player is None:
players[id]["name"] = command
players[id]["room"] = "Tavern"
else:
players[id] = loaded_player
# go through all the players in the game
for pid, pl in players.items():
# send each player a message to tell them about the new player
mud.send_message(pid, "{} entered the game".format(
players[id]["name"]))
# send the new player a welcome message
mud.send_message(id, "\r\n\r\nWelcome to the game, {}. ".format(
players[id]["name"])
+ "\r\nType 'help' for a list of commands. Have fun!\r\n\r\n")
# send the new player the description of their current room
mud.send_message(id, load_room(players[id]["room"]).get_description())
# each of the possible commands is handled below. Try adding new
# commands to the game!
# 'help' command
elif command == "help":
with open('help/help.txt', 'r', encoding='utf-8') as f:
for line in f:
mud.send_message(id, line, '\r')
mud.send_message(id, '')
# 'help' command
elif command == "quit":
# send the player back the list of possible commands
mud.send_message(id, "Saving...")
save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
mud.disconnect_player(id)
# 'help' command
elif command == "save":
# send the player back the list of possible commands
mud.send_message(id, "Saving...")
save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
mud.send_message(id, "Save complete")
# 'say' command
elif command == "say":
# go through every player in the game
for pid, pl in players.items():
# if they're in the same room as the player
if players[pid]["room"] == players[id]["room"]:
# send them a message telling them what the player said
mud.send_message(pid, "{} says: {}".format(
players[id]["name"], params))
# 'look' command
elif cmd_handler.parse(id, command, params, rm, mud, players):
pass
# 'go' command
elif command == "go":
# store the exit name
ex = params.lower()
# store the player's current room
rm = load_room(players[id]["room"])
# if the specified exit is found in the room's exits list
if ex in rm.get_exits():
# go through all the players in the game
for pid, pl in players.items():
# if player is in the same room and isn't the player
# sending the command
if players[pid]["room"] == players[id]["room"] \
and pid != id:
# send them a message telling them that the player
# left the room
mud.send_message(pid, "{} left via exit '{}'".format(
players[id]["name"], ex))
# update the player's current room to the one the exit leads to
loaded = load_room(rm.get_exits()[ex])
if loaded == None:
mud.send_message(id, "An invisible force prevents you from going in that direction.")
continue
else:
players[id]["room"] = rm.get_exits()[ex]
rm = loaded
# go through all the players in the game
for pid, pl in players.items():
# if player is in the same (new) room and isn't the player
# sending the command
if players[pid]["room"] == players[id]["room"] \
and pid != id:
# send them a message telling them that the player
# entered the room
mud.send_message(pid,
"{} arrived via exit '{}'".format(
players[id]["name"], ex))
# send the player a message telling them where they are now
mud.send_message(id, "You arrive at '{}'".format(rm.get_title()))
# the specified exit wasn't found in the current room
else:
# send back an 'unknown exit' message
mud.send_message(id, "Unknown exit '{}'".format(ex))
# some other, unrecognised command
else:
# send back an 'unknown command' message
mud.send_message(id, "Unknown command '{}'".format(command))
prompt(id)
This diff is collapsed. Click to expand it.
{"name": "test", "room": "Room001", "inventory": null, "prompt": "> "}
\ No newline at end of file
File mode changed
# import datetime
class BaseRoom(object):
def __init__(self, title, description, exits, look_items):
self.title = title
self.description = description
self.exits = exits
self.look_items = look_items
# self.created = datetime.datetime.now()
def get_title(self):
return self.title
def get_description(self):
return self.description
def get_exits(self):
return self.exits
def get_look_items(self):
return self.look_items
from .baseroom import BaseRoom
class Room001(BaseRoom):
def __init__(self):
title = "Behind the bar"
description = "The back of the bar gives a full view of the tavern. The bar\r\n top is a large wooden plank thrown across some barrels."
exits = {"tavern": "Tavern"}
look_items = {
"bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
"barrel,barrels": "The old barrels bands are thick with oxidation and stained\r\n with the purple of spilled wine.",
"wooden,oak,plank": "An old solid oak plank that has a large number of chips\r\n and drink marks."
}
super(Room001, self).__init__(title, description, exits, look_items)
from .baseroom import BaseRoom
class Tavern(BaseRoom):
def __init__(self):
title = "Tavern"
description = "You're in a cozy tavern warmed by an open fire."
exits = {"outside": "Outside", "behind bar": "Room001"}
look_items = {
"bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
"barrel,barrels": "The old barrels bands are thick with oxidation and stained\r\n with the purple of spilled wine.",
"wooden,oak,plank": "An old solid oak plank that has a large number of chips\r\n and drink marks.",
"fire": "The fire crackles quietly in the corner providing a small amount of light and heat."
}
super(Tavern, self).__init__(title, description, exits, look_items)
#!/usr/bin/env python
"""A simple Multi-User Dungeon (MUD) game. Players can talk to each
other, examine their surroundings and move between rooms.
Some ideas for things to try adding:
* More rooms to explore
* An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
out loud'
* A 'whisper' command for talking to individual players
* A 'shout' command for yelling to players in all rooms
* Items to look at in rooms e.g. 'look fireplace' -> 'You see a
roaring, glowing fire'
* Items to pick up e.g. 'take rock' -> 'You pick up the rock'
* Monsters to fight
* Loot to collect
* Saving players accounts between sessions
* A password login
* A shop from which to buy items
author: Mark Frimston - mfrimston@gmail.com
"""
import time
# import the MUD server class
from mudserver import MudServer
# structure defining the rooms in the game. Try adding more rooms to the game!
rooms = {
"Tavern": {
"description": "You're in a cozy tavern warmed by an open fire.",
"exits": {"outside": "Outside"},
},
"Outside": {
"description": "You're standing outside a tavern. It's raining.",
"exits": {"inside": "Tavern"},
}
}
# stores the players in the game
players = {}
# start the server
mud = MudServer()
# main game loop. We loop forever (i.e. until the program is terminated)
while True:
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time.sleep(0.2)
# 'update' must be called in the loop to keep the game running and give
# us up-to-date information
mud.update()
# go through any newly connected players
for id in mud.get_new_players():
# add the new player to the dictionary, noting that they've not been
# named yet.
# The dictionary key is the player's id number. We set their room to
# None initially until they have entered a name
# Try adding more player stats - level, gold, inventory, etc
players[id] = {
"name": None,
"room": None,
}
# send the new player a prompt for their name
mud.send_message(id, "What is your name?")
# go through any recently disconnected players
for id in mud.get_disconnected_players():
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players:
continue
# go through all the players in the game
for pid, pl in players.items():
# send each player a message to tell them about the diconnected
# player
mud.send_message(pid, "{} quit the game".format(
players[id]["name"]))
# remove the player's entry in the player dictionary
del(players[id])
# go through any new commands sent from players
for id, command, params in mud.get_commands():
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players:
continue
# if the player hasn't given their name yet, use this first command as
# their name and move them to the starting room.
if players[id]["name"] is None:
players[id]["name"] = command
players[id]["room"] = "Tavern"
# go through all the players in the game
for pid, pl in players.items():
# send each player a message to tell them about the new player
mud.send_message(pid, "{} entered the game".format(
players[id]["name"]))
# send the new player a welcome message
mud.send_message(id, "Welcome to the game, {}. ".format(
players[id]["name"])
+ "Type 'help' for a list of commands. Have fun!")
# send the new player the description of their current room
mud.send_message(id, rooms[players[id]["room"]]["description"])
# each of the possible commands is handled below. Try adding new
# commands to the game!
# 'help' command
elif command == "help":
# send the player back the list of possible commands
mud.send_message(id, "Commands:")
mud.send_message(id, " say <message> - Says something out loud, "
+ "e.g. 'say Hello'")
mud.send_message(id, " look - Examines the "
+ "surroundings, e.g. 'look'")
mud.send_message(id, " go <exit> - Moves through the exit "
+ "specified, e.g. 'go outside'")
# 'say' command
elif command == "say":
# go through every player in the game
for pid, pl in players.items():
# if they're in the same room as the player
if players[pid]["room"] == players[id]["room"]:
# send them a message telling them what the player said
mud.send_message(pid, "{} says: {}".format(
players[id]["name"], params))
# 'look' command
elif command == "look":
# store the player's current room
rm = rooms[players[id]["room"]]
# send the player back the description of their current room
mud.send_message(id, rm["description"])
playershere = []
# go through every player in the game
for pid, pl in players.items():
# if they're in the same room as the player
if players[pid]["room"] == players[id]["room"]:
# ... and they have a name to be shown
if players[pid]["name"] is not None:
# add their name to the list
playershere.append(players[pid]["name"])
# send player a message containing the list of players in the room
mud.send_message(id, "Players here: {}".format(
", ".join(playershere)))
# send player a message containing the list of exits from this room
mud.send_message(id, "Exits are: {}".format(
", ".join(rm["exits"])))
# 'go' command
elif command == "go":
# store the exit name
ex = params.lower()
# store the player's current room
rm = rooms[players[id]["room"]]
# if the specified exit is found in the room's exits list
if ex in rm["exits"]:
# go through all the players in the game
for pid, pl in players.items():
# if player is in the same room and isn't the player
# sending the command
if players[pid]["room"] == players[id]["room"] \
and pid != id:
# send them a message telling them that the player
# left the room
mud.send_message(pid, "{} left via exit '{}'".format(
players[id]["name"], ex))
# update the player's current room to the one the exit leads to
players[id]["room"] = rm["exits"][ex]
rm = rooms[players[id]["room"]]
# go through all the players in the game
for pid, pl in players.items():
# if player is in the same (new) room and isn't the player
# sending the command
if players[pid]["room"] == players[id]["room"] \
and pid != id:
# send them a message telling them that the player
# entered the room
mud.send_message(pid,
"{} arrived via exit '{}'".format(
players[id]["name"], ex))
# send the player a message telling them where they are now
mud.send_message(id, "You arrive at '{}'".format(
players[id]["room"]))
# the specified exit wasn't found in the current room
else:
# send back an 'unknown exit' message
mud.send_message(id, "Unknown exit '{}'".format(ex))
# some other, unrecognised command
else:
# send back an 'unknown command' message
mud.send_message(id, "Unknown command '{}'".format(command))
{"test": "value"}
\ No newline at end of file