817c7517 by Barry

Initial commit

0 parents
1
2 class CommandHandler(object):
3
4 def tokenize_params(self):
5 cleaned = self.params.lower().strip()
6 tokens = []
7 for token in cleaned.split(' '):
8 token = token.strip()
9 if len(token) > 0:
10 tokens.append(token)
11 self.tokens = tokens
12
13 def look(self):
14 self.mud.send_message(self.id, "")
15 if len(self.tokens) > 0 and self.tokens[0] == 'at':
16 del self.tokens[0]
17 if len(self.tokens) == 0:
18 self.mud.send_message(self.id, self.room.get_description())
19 else:
20 subject = self.tokens[0]
21 items = self.room.get_look_items()
22 for item in items:
23 if subject in item:
24 self.mud.send_message(self.id, items[item])
25 return True
26 self.mud.send_message(self.id, "That doesn't seem to be here.")
27
28 playershere = []
29 # go through every player in the game
30 for pid, pl in self.players.items():
31 # if they're in the same room as the player
32 if self.players[pid]["room"] == self.players[self.id]["room"]:
33 # ... and they have a name to be shown
34 if self.players[pid]["name"] is not None:
35 # add their name to the list
36 playershere.append(self.players[pid]["name"])
37
38 # send player a message containing the list of players in the room
39 self.mud.send_message(self.id, "Players here: {}".format(
40 ", ".join(playershere)))
41
42 # send player a message containing the list of exits from this room
43 self.mud.send_message(self.id, "Exits are: {}".format(
44 ", ".join(self.room.get_exits())))
45
46 return True
47
48 def parse(self, id, cmd, params, room, mud, players):
49 self.id = id
50 self.cmd = cmd
51 self.params = params
52 self.tokenize_params()
53 self.room = room
54 self.mud = mud
55 self.players = players
56
57 try:
58 method = getattr(self, cmd)
59 return method()
60 except AttributeError:
61 return False
62
1 Commands:
2 say <message> - Says something out loud, e.g. 'say Hello'
3 look - Examines the surroundings, e.g. 'look'
4 go <exit> - Moves through the exit specified, e.g. 'go outside'
5 save - Saves your character
6 quit - Saves your character then closes the connection
...\ No newline at end of file ...\ No newline at end of file
1 #!/usr/bin/env python
2
3 """A simple Multi-User Dungeon (MUD) game. Players can talk to each
4 other, examine their surroundings and move between rooms.
5
6 Some ideas for things to try adding:
7 * More rooms to explore
8 * An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
9 out loud'
10 * A 'whisper' command for talking to individual players
11 * A 'shout' command for yelling to players in all rooms
12 * Items to look at in rooms e.g. 'look fireplace' -> 'You see a
13 roaring, glowing fire'
14 * Items to pick up e.g. 'take rock' -> 'You pick up the rock'
15 * Monsters to fight
16 * Loot to collect
17 * Saving players accounts between sessions
18 * A password login
19 * A shop from which to buy items
20
21 author: Mark Frimston - mfrimston@gmail.com
22 """
23
24 import time
25 # import datetime
26 #import io
27 import json
28
29 # import the MUD server class
30 from mudserver import MudServer
31 from commands import CommandHandler
32
33 print('STARTING MUD\r\n\r\n\r\n')
34
35 rooms = {}
36
37 # stores the players in the game
38 players = {}
39
40 # start the server
41 mud = MudServer()
42
43 cmd_handler = CommandHandler()
44
45 def load_room(room_name):
46 print("Loading room:" + room_name)
47 try:
48 if room_name in rooms:
49 return rooms[room_name]
50
51
52 module = __import__('rooms.' + room_name.lower())
53 room_module = getattr(module, room_name.lower())
54 room_class = getattr(room_module, room_name)
55 instance = room_class()
56 rooms[room_name] = instance
57
58 return instance
59 except Exception as e:
60 print(e)
61 return None
62
63 def save_object_to_file(obj, filename):
64 with open(filename, 'w', encoding='utf-8') as f:
65 f.write(json.dumps(obj, ensure_ascii=False))
66
67 def load_object_from_file(filename):
68 try:
69 with open(filename, 'r', encoding='utf-8') as f:
70 return json.loads(f.read())
71 except Exception:
72 return None
73
74 def prompt(pid):
75 if "prompt" not in players[pid]:
76 players[pid]["prompt"] = "> "
77 mud.send_message(pid, "\r\n" + players[pid]["prompt"], '')
78
79 # main game loop. We loop forever (i.e. until the program is terminated)
80 while True:
81
82 # pause for 1/5 of a second on each loop, so that we don't constantly
83 # use 100% CPU time
84 time.sleep(0.001)
85
86 # TODO: Add some cache removal if older than X
87 # now = datetime.datetime.now()
88 # delta = now - datetime.timedelta(minutes = 2)
89 # for room in rooms:
90 # if room.created < delta:
91 # del rooms[room]
92
93 # 'update' must be called in the loop to keep the game running and give
94 # us up-to-date information
95 mud.update()
96
97 # go through any newly connected players
98 for id in mud.get_new_players():
99
100 # add the new player to the dictionary, noting that they've not been
101 # named yet.
102 # The dictionary key is the player's id number. We set their room to
103 # None initially until they have entered a name
104 # Try adding more player stats - level, gold, inventory, etc
105 players[id] = {
106 "name": None,
107 "room": None,
108 "inventory": None,
109 "prompt": "> ",
110 }
111
112 # send the new player a prompt for their name
113 mud.send_message(id, "What is your name?")
114
115 # go through any recently disconnected players
116 for id in mud.get_disconnected_players():
117
118 # if for any reason the player isn't in the player map, skip them and
119 # move on to the next one
120 if id not in players:
121 continue
122
123 # go through all the players in the game
124 for pid, pl in players.items():
125 # send each player a message to tell them about the diconnected
126 # player
127 mud.send_message(pid, "{} quit the game".format(
128 players[id]["name"]))
129
130 # remove the player's entry in the player dictionary
131 del(players[id])
132
133 # go through any new commands sent from players
134 for id, command, params in mud.get_commands():
135
136 # if for any reason the player isn't in the player map, skip them and
137 # move on to the next one
138 if id not in players:
139 continue
140
141 if players[id]["room"]:
142 rm = load_room(players[id]["room"])
143 # if the player hasn't given their name yet, use this first command as
144 # their name and move them to the starting room.
145 if players[id]["name"] is None:
146
147 loaded_player = load_object_from_file("players/{}.json".format(command))
148 if loaded_player is None:
149 players[id]["name"] = command
150 players[id]["room"] = "Tavern"
151 else:
152 players[id] = loaded_player
153
154 # go through all the players in the game
155 for pid, pl in players.items():
156 # send each player a message to tell them about the new player
157 mud.send_message(pid, "{} entered the game".format(
158 players[id]["name"]))
159
160 # send the new player a welcome message
161 mud.send_message(id, "\r\n\r\nWelcome to the game, {}. ".format(
162 players[id]["name"])
163 + "\r\nType 'help' for a list of commands. Have fun!\r\n\r\n")
164
165 # send the new player the description of their current room
166 mud.send_message(id, load_room(players[id]["room"]).get_description())
167
168 # each of the possible commands is handled below. Try adding new
169 # commands to the game!
170
171 # 'help' command
172 elif command == "help":
173
174 with open('help/help.txt', 'r', encoding='utf-8') as f:
175 for line in f:
176 mud.send_message(id, line, '\r')
177 mud.send_message(id, '')
178
179 # 'help' command
180 elif command == "quit":
181
182 # send the player back the list of possible commands
183 mud.send_message(id, "Saving...")
184 save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
185 mud.disconnect_player(id)
186
187 # 'help' command
188 elif command == "save":
189
190 # send the player back the list of possible commands
191 mud.send_message(id, "Saving...")
192 save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
193 mud.send_message(id, "Save complete")
194
195 # 'say' command
196 elif command == "say":
197
198 # go through every player in the game
199 for pid, pl in players.items():
200 # if they're in the same room as the player
201 if players[pid]["room"] == players[id]["room"]:
202 # send them a message telling them what the player said
203 mud.send_message(pid, "{} says: {}".format(
204 players[id]["name"], params))
205
206 # 'look' command
207 elif cmd_handler.parse(id, command, params, rm, mud, players):
208
209 pass
210
211 # 'go' command
212 elif command == "go":
213
214 # store the exit name
215 ex = params.lower()
216
217 # store the player's current room
218 rm = load_room(players[id]["room"])
219
220 # if the specified exit is found in the room's exits list
221 if ex in rm.get_exits():
222
223 # go through all the players in the game
224 for pid, pl in players.items():
225 # if player is in the same room and isn't the player
226 # sending the command
227 if players[pid]["room"] == players[id]["room"] \
228 and pid != id:
229 # send them a message telling them that the player
230 # left the room
231 mud.send_message(pid, "{} left via exit '{}'".format(
232 players[id]["name"], ex))
233
234 # update the player's current room to the one the exit leads to
235 loaded = load_room(rm.get_exits()[ex])
236 if loaded == None:
237 mud.send_message(id, "An invisible force prevents you from going in that direction.")
238 continue
239 else:
240 players[id]["room"] = rm.get_exits()[ex]
241 rm = loaded
242
243 # go through all the players in the game
244 for pid, pl in players.items():
245 # if player is in the same (new) room and isn't the player
246 # sending the command
247 if players[pid]["room"] == players[id]["room"] \
248 and pid != id:
249 # send them a message telling them that the player
250 # entered the room
251 mud.send_message(pid,
252 "{} arrived via exit '{}'".format(
253 players[id]["name"], ex))
254
255 # send the player a message telling them where they are now
256 mud.send_message(id, "You arrive at '{}'".format(rm.get_title()))
257
258 # the specified exit wasn't found in the current room
259 else:
260 # send back an 'unknown exit' message
261 mud.send_message(id, "Unknown exit '{}'".format(ex))
262
263
264 # some other, unrecognised command
265 else:
266 # send back an 'unknown command' message
267 mud.send_message(id, "Unknown command '{}'".format(command))
268 prompt(id)
This diff is collapsed. Click to expand it.
1 {"name": "test", "room": "Room001", "inventory": null, "prompt": "> "}
...\ No newline at end of file ...\ No newline at end of file
File mode changed
1
2 # import datetime
3
4 class BaseRoom(object):
5
6 def __init__(self, title, description, exits, look_items):
7 self.title = title
8 self.description = description
9 self.exits = exits
10 self.look_items = look_items
11 # self.created = datetime.datetime.now()
12
13 def get_title(self):
14 return self.title
15
16 def get_description(self):
17 return self.description
18
19 def get_exits(self):
20 return self.exits
21
22 def get_look_items(self):
23 return self.look_items
1 from .baseroom import BaseRoom
2
3 class Room001(BaseRoom):
4
5 def __init__(self):
6
7 title = "Behind the bar"
8 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."
9 exits = {"tavern": "Tavern"}
10 look_items = {
11 "bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
12 "barrel,barrels": "The old barrels bands are thick with oxidation and stained\r\n with the purple of spilled wine.",
13 "wooden,oak,plank": "An old solid oak plank that has a large number of chips\r\n and drink marks."
14 }
15
16 super(Room001, self).__init__(title, description, exits, look_items)
1 from .baseroom import BaseRoom
2
3 class Tavern(BaseRoom):
4
5 def __init__(self):
6
7 title = "Tavern"
8 description = "You're in a cozy tavern warmed by an open fire."
9 exits = {"outside": "Outside", "behind bar": "Room001"}
10 look_items = {
11 "bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
12 "barrel,barrels": "The old barrels bands are thick with oxidation and stained\r\n with the purple of spilled wine.",
13 "wooden,oak,plank": "An old solid oak plank that has a large number of chips\r\n and drink marks.",
14 "fire": "The fire crackles quietly in the corner providing a small amount of light and heat."
15 }
16
17 super(Tavern, self).__init__(title, description, exits, look_items)
1 #!/usr/bin/env python
2
3 """A simple Multi-User Dungeon (MUD) game. Players can talk to each
4 other, examine their surroundings and move between rooms.
5
6 Some ideas for things to try adding:
7 * More rooms to explore
8 * An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
9 out loud'
10 * A 'whisper' command for talking to individual players
11 * A 'shout' command for yelling to players in all rooms
12 * Items to look at in rooms e.g. 'look fireplace' -> 'You see a
13 roaring, glowing fire'
14 * Items to pick up e.g. 'take rock' -> 'You pick up the rock'
15 * Monsters to fight
16 * Loot to collect
17 * Saving players accounts between sessions
18 * A password login
19 * A shop from which to buy items
20
21 author: Mark Frimston - mfrimston@gmail.com
22 """
23
24 import time
25
26 # import the MUD server class
27 from mudserver import MudServer
28
29
30 # structure defining the rooms in the game. Try adding more rooms to the game!
31 rooms = {
32 "Tavern": {
33 "description": "You're in a cozy tavern warmed by an open fire.",
34 "exits": {"outside": "Outside"},
35 },
36 "Outside": {
37 "description": "You're standing outside a tavern. It's raining.",
38 "exits": {"inside": "Tavern"},
39 }
40 }
41
42 # stores the players in the game
43 players = {}
44
45 # start the server
46 mud = MudServer()
47
48 # main game loop. We loop forever (i.e. until the program is terminated)
49 while True:
50
51 # pause for 1/5 of a second on each loop, so that we don't constantly
52 # use 100% CPU time
53 time.sleep(0.2)
54
55 # 'update' must be called in the loop to keep the game running and give
56 # us up-to-date information
57 mud.update()
58
59 # go through any newly connected players
60 for id in mud.get_new_players():
61
62 # add the new player to the dictionary, noting that they've not been
63 # named yet.
64 # The dictionary key is the player's id number. We set their room to
65 # None initially until they have entered a name
66 # Try adding more player stats - level, gold, inventory, etc
67 players[id] = {
68 "name": None,
69 "room": None,
70 }
71
72 # send the new player a prompt for their name
73 mud.send_message(id, "What is your name?")
74
75 # go through any recently disconnected players
76 for id in mud.get_disconnected_players():
77
78 # if for any reason the player isn't in the player map, skip them and
79 # move on to the next one
80 if id not in players:
81 continue
82
83 # go through all the players in the game
84 for pid, pl in players.items():
85 # send each player a message to tell them about the diconnected
86 # player
87 mud.send_message(pid, "{} quit the game".format(
88 players[id]["name"]))
89
90 # remove the player's entry in the player dictionary
91 del(players[id])
92
93 # go through any new commands sent from players
94 for id, command, params in mud.get_commands():
95
96 # if for any reason the player isn't in the player map, skip them and
97 # move on to the next one
98 if id not in players:
99 continue
100
101 # if the player hasn't given their name yet, use this first command as
102 # their name and move them to the starting room.
103 if players[id]["name"] is None:
104
105 players[id]["name"] = command
106 players[id]["room"] = "Tavern"
107
108 # go through all the players in the game
109 for pid, pl in players.items():
110 # send each player a message to tell them about the new player
111 mud.send_message(pid, "{} entered the game".format(
112 players[id]["name"]))
113
114 # send the new player a welcome message
115 mud.send_message(id, "Welcome to the game, {}. ".format(
116 players[id]["name"])
117 + "Type 'help' for a list of commands. Have fun!")
118
119 # send the new player the description of their current room
120 mud.send_message(id, rooms[players[id]["room"]]["description"])
121
122 # each of the possible commands is handled below. Try adding new
123 # commands to the game!
124
125 # 'help' command
126 elif command == "help":
127
128 # send the player back the list of possible commands
129 mud.send_message(id, "Commands:")
130 mud.send_message(id, " say <message> - Says something out loud, "
131 + "e.g. 'say Hello'")
132 mud.send_message(id, " look - Examines the "
133 + "surroundings, e.g. 'look'")
134 mud.send_message(id, " go <exit> - Moves through the exit "
135 + "specified, e.g. 'go outside'")
136
137 # 'say' command
138 elif command == "say":
139
140 # go through every player in the game
141 for pid, pl in players.items():
142 # if they're in the same room as the player
143 if players[pid]["room"] == players[id]["room"]:
144 # send them a message telling them what the player said
145 mud.send_message(pid, "{} says: {}".format(
146 players[id]["name"], params))
147
148 # 'look' command
149 elif command == "look":
150
151 # store the player's current room
152 rm = rooms[players[id]["room"]]
153
154 # send the player back the description of their current room
155 mud.send_message(id, rm["description"])
156
157 playershere = []
158 # go through every player in the game
159 for pid, pl in players.items():
160 # if they're in the same room as the player
161 if players[pid]["room"] == players[id]["room"]:
162 # ... and they have a name to be shown
163 if players[pid]["name"] is not None:
164 # add their name to the list
165 playershere.append(players[pid]["name"])
166
167 # send player a message containing the list of players in the room
168 mud.send_message(id, "Players here: {}".format(
169 ", ".join(playershere)))
170
171 # send player a message containing the list of exits from this room
172 mud.send_message(id, "Exits are: {}".format(
173 ", ".join(rm["exits"])))
174
175 # 'go' command
176 elif command == "go":
177
178 # store the exit name
179 ex = params.lower()
180
181 # store the player's current room
182 rm = rooms[players[id]["room"]]
183
184 # if the specified exit is found in the room's exits list
185 if ex in rm["exits"]:
186
187 # go through all the players in the game
188 for pid, pl in players.items():
189 # if player is in the same room and isn't the player
190 # sending the command
191 if players[pid]["room"] == players[id]["room"] \
192 and pid != id:
193 # send them a message telling them that the player
194 # left the room
195 mud.send_message(pid, "{} left via exit '{}'".format(
196 players[id]["name"], ex))
197
198 # update the player's current room to the one the exit leads to
199 players[id]["room"] = rm["exits"][ex]
200 rm = rooms[players[id]["room"]]
201
202 # go through all the players in the game
203 for pid, pl in players.items():
204 # if player is in the same (new) room and isn't the player
205 # sending the command
206 if players[pid]["room"] == players[id]["room"] \
207 and pid != id:
208 # send them a message telling them that the player
209 # entered the room
210 mud.send_message(pid,
211 "{} arrived via exit '{}'".format(
212 players[id]["name"], ex))
213
214 # send the player a message telling them where they are now
215 mud.send_message(id, "You arrive at '{}'".format(
216 players[id]["room"]))
217
218 # the specified exit wasn't found in the current room
219 else:
220 # send back an 'unknown exit' message
221 mud.send_message(id, "Unknown exit '{}'".format(ex))
222
223 # some other, unrecognised command
224 else:
225 # send back an 'unknown command' message
226 mud.send_message(id, "Unknown command '{}'".format(command))
1 {"test": "value"}
...\ No newline at end of file ...\ No newline at end of file