1d912c1b by Barry

Created zone support / subdir support for rooms and basic GMCP protocol

1 parent 021a4bc9
...@@ -41,7 +41,7 @@ class CommandHandler(object): ...@@ -41,7 +41,7 @@ class CommandHandler(object):
41 41
42 locals()['next_command'] = None 42 locals()['next_command'] = None
43 try: 43 try:
44 if cmd in utils.load_object_from_file('rooms/' + players[id]["room"] + '.json').get('exits'): 44 if cmd in (exit.lower() for exit in utils.load_object_from_file('rooms/' + players[id]["room"] + '.json').get('exits')):
45 params = cmd + " " + params.lower().strip() 45 params = cmd + " " + params.lower().strip()
46 cmd = "go" 46 cmd = "go"
47 if cmd in players[id]["sp"]: 47 if cmd in players[id]["sp"]:
......
1 def go(id, params, players, mud, tokens, command): 1 def go(id, params, players, mud, tokens, command):
2 # store the exit name 2 # store the exit name
3 if params == '': 3 if params == '':
4 params = command.strip() 4 params = command.strip().lower()
5 else: 5 else:
6 params = params.strip() 6 params = params.strip().lower()
7 7
8 room_data = utils.load_object_from_file('rooms/' + players[id]["room"] + '.json') 8 room_data = utils.load_object_from_file('rooms/' + players[id]["room"] + '.json')
9 exits = room_data['exits'] 9 tmp_exits = room_data['exits']
10 # if the specified exit is found in the room's exits list 10 # if the specified exit is found in the room's exits list
11 exits = {}
12 for exit, value in tmp_exits.items():
13 exits[exit.lower()] = value
11 14
15 print(exits)
12 if params in exits: 16 if params in exits:
13 # go through all the players in the game 17 # go through all the players in the game
14 for pid, pl in players.items(): 18 for pid, pl in players.items():
...@@ -23,7 +27,7 @@ def go(id, params, players, mud, tokens, command): ...@@ -23,7 +27,7 @@ def go(id, params, players, mud, tokens, command):
23 27
24 # update the player's current room to the one the exit leads to 28 # update the player's current room to the one the exit leads to
25 29
26 if room_data['exits'][params] == None: 30 if exits[params] == None:
27 mud.send_message(id, "An invisible force prevents you from going in that direction.") 31 mud.send_message(id, "An invisible force prevents you from going in that direction.")
28 return None 32 return None
29 else: 33 else:
...@@ -33,6 +37,7 @@ def go(id, params, players, mud, tokens, command): ...@@ -33,6 +37,7 @@ def go(id, params, players, mud, tokens, command):
33 return None 37 return None
34 else: 38 else:
35 players[id]["room"] = exits[params] 39 players[id]["room"] = exits[params]
40 utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
36 mud.send_message(id, "You arrive at '{}'".format(new_room['title'])) 41 mud.send_message(id, "You arrive at '{}'".format(new_room['title']))
37 42
38 # go through all the players in the game 43 # go through all the players in the game
......
...@@ -10,6 +10,7 @@ def look(id, mud, players, tokens): ...@@ -10,6 +10,7 @@ def look(id, mud, players, tokens):
10 del tokens[0] 10 del tokens[0]
11 container = True 11 container = True
12 if len(tokens) == 0: 12 if len(tokens) == 0:
13 mud.send_room(id, room_data.get('title'), room_data.get('description'), 'exits')
13 mud.send_message(id, room_data.get('title'), color=['bold', 'green']) 14 mud.send_message(id, room_data.get('title'), color=['bold', 'green'])
14 mud.send_message(id, room_data.get('description'), line_ending='\r\n\r\n', color='green') 15 mud.send_message(id, room_data.get('description'), line_ending='\r\n\r\n', color='green')
15 else: 16 else:
......
...@@ -254,7 +254,7 @@ while True: ...@@ -254,7 +254,7 @@ while True:
254 loaded_player = load_object_from_file("players/{}.json".format(players[pid]["name"])) 254 loaded_player = load_object_from_file("players/{}.json".format(players[pid]["name"]))
255 if loaded_player is None: 255 if loaded_player is None:
256 players[id]["password"] = password_hash(players[pid]["name"], command) 256 players[id]["password"] = password_hash(players[pid]["name"], command)
257 players[id]["room"] = "Tavern" 257 players[id]["room"] = "town/tavern"
258 else: 258 else:
259 if loaded_player["password"] == password_hash(players[pid]["name"], command): 259 if loaded_player["password"] == password_hash(players[pid]["name"], command):
260 players[id] = loaded_player 260 players[id] = loaded_player
......
...@@ -124,7 +124,7 @@ class MudServer(object): ...@@ -124,7 +124,7 @@ class MudServer(object):
124 # this requires root permissions, so we use a higher arbitrary port 124 # this requires root permissions, so we use a higher arbitrary port
125 # number instead: 1234. Address 0.0.0.0 means that we will bind to all 125 # number instead: 1234. Address 0.0.0.0 means that we will bind to all
126 # of the available network interfaces 126 # of the available network interfaces
127 self._listen_socket.bind(("0.0.0.0", 3333)) 127 self._listen_socket.bind(("0.0.0.0", 4000))
128 128
129 # set to non-blocking mode. This means that when we call 'accept', it 129 # set to non-blocking mode. This means that when we call 'accept', it
130 # will return immediately without waiting for a connection 130 # will return immediately without waiting for a connection
...@@ -241,6 +241,30 @@ class MudServer(object): ...@@ -241,6 +241,30 @@ class MudServer(object):
241 # stop listening for new clients 241 # stop listening for new clients
242 self._listen_socket.close() 242 self._listen_socket.close()
243 243
244 def send_room(self, clid, name, description, exits):
245 if self._clients[clid].MXP_ENABLED:
246 self.mxp_secure(clid, name, 10)
247
248 # def send_description(self, clid, description, command=''):
249 # if self._clients[clid].MXP_ENABLED:
250 # output = ""
251 # for idx, item in enumerate(list_items):
252 # if idx > 0:
253 # output += ", "
254 # parts = item.split(' ')
255 # mod_item = item
256 # if len(parts) > 1:
257 # try:
258 # num = int(parts[0])
259 # mod_item = ' '.join(parts[1:])[:-1]
260 # except ValueError:
261 # pass
262
263 # output += "<send \"{} {}\">{}</send>".format(command, mod_item, item)
264 # self.mxp_secure(clid, output)
265 # else:
266 # self.send_message(clid, ', '.join(list_items))
267
244 def send_list(self, clid, list_items, command=''): 268 def send_list(self, clid, list_items, command=''):
245 if self._clients[clid].MXP_ENABLED: 269 if self._clients[clid].MXP_ENABLED:
246 output = "" 270 output = ""
...@@ -261,8 +285,8 @@ class MudServer(object): ...@@ -261,8 +285,8 @@ class MudServer(object):
261 else: 285 else:
262 self.send_message(clid, ', '.join(list_items)) 286 self.send_message(clid, ', '.join(list_items))
263 287
264 def mxp_secure(self, clid, message): 288 def mxp_secure(self, clid, message, mxp_code="1"):
265 bytes_to_send = bytearray("\x1b[1z{}\x1b[6z\r\n".format(message), 'utf-8') 289 bytes_to_send = bytearray("\x1b[{}z{}\x1b[3z\r\n".format(mxp_code, message), 'utf-8')
266 client_socket = self._clients[clid].socket 290 client_socket = self._clients[clid].socket
267 client_socket.sendall(bytes_to_send) 291 client_socket.sendall(bytes_to_send)
268 292
...@@ -431,8 +455,11 @@ class MudServer(object): ...@@ -431,8 +455,11 @@ class MudServer(object):
431 bytes_to_send = bytearray([self._TN_IAC, self._TN_WONT, self._ECHO]) 455 bytes_to_send = bytearray([self._TN_IAC, self._TN_WONT, self._ECHO])
432 else: 456 else:
433 bytes_to_send = bytearray([self._TN_IAC, self._TN_WILL, self._ECHO]) 457 bytes_to_send = bytearray([self._TN_IAC, self._TN_WILL, self._ECHO])
434 client_socket = self._clients[clid].socket 458 try:
435 client_socket.sendall(bytes_to_send) 459 client_socket = self._clients[clid].socket
460 client_socket.sendall(bytes_to_send)
461 except:
462 pass
436 463
437 def _send_mssp(self, client): 464 def _send_mssp(self, client):
438 byte_data = bytearray([self._TN_IAC, self._TN_SUB_START, self._MSSP, self._MSSP_VAR]) 465 byte_data = bytearray([self._TN_IAC, self._TN_SUB_START, self._MSSP, self._MSSP_VAR])
......
1 {"look_items": {"tavern": "A roughly constructed building."}, "description": "You are standing outside of a simple tavern made of pressed clay and shale roof. The door becons you to come in and have a drink.", "inventory": {}, "exits": {"tavern": "Tavern"}, "title": "Outside the Tavern"}
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "look_items": {
3 "tavern": "A roughly constructed building."
4 },
5 "description": "You are standing outside of a simple tavern made of pressed clay and shale roof. The door becons you to come in and have a drink.",
6 "inventory": {},
7 "exits": {
8 "Tavern": "town/tavern"
9 },
10 "title": "Outside the Tavern"
11 }
...\ No newline at end of file ...\ No newline at end of file
......
1 {"look_items": {"wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks.", "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.", "bar": "The bar is a long wooden plank thrown over roughly hewn barrels."}, "description": "The back of the bar gives a full view of the tavern. The bar top is a large wooden plank thrown across some barrels.", "inventory": {"candle": [{"age": 0}]}, "exits": {"tavern": "Tavern"}, "title": "Behind the bar"}
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "look_items": {
3 "wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks.",
4 "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.",
5 "bar": "The bar is a long wooden plank thrown over roughly hewn barrels."
6 },
7 "description": "The back of the bar gives a full view of the tavern. The bar top is a large wooden plank thrown across some barrels.",
8 "inventory": {
9 "candle": [{
10 "age": 0
11 }]
12 },
13 "exits": {
14 "Tavern": "town/tavern"
15 },
16 "title": "Behind the bar"
17 }
...\ No newline at end of file ...\ No newline at end of file
......
1 {"look_items": {"wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks.", "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.", "bar": "The bar is a long wooden plank thrown over roughly hewn barrels.", "fire": "The fire crackles quietly in the corner providing a small amount of light and heat."}, "description": "You're in a cozy tavern warmed by an open fire.", "inventory": {"candle": [{"age": 0}, {"age": 0}], "sword": [{"expries": 0}]}, "exits": {"behind": "Room001", "dark": "Dark", "outside": "Outside"}, "title": "Tavern"}
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "look_items": {
3 "wooden,oak,plank": "An old solid oak plank that has a large number of chips and drink marks.",
4 "barrel,barrels": "The old barrels bands are thick with oxidation and stained with the purple of spilled wine.",
5 "bar": "The bar is a long wooden plank thrown over roughly hewn barrels.",
6 "fire": "The fire crackles quietly in the corner providing a small amount of light and heat."
7 },
8 "description": "You're in a cozy tavern warmed by an open fire.",
9 "inventory": {
10 "candle": [{
11 "age": 0
12 }, {
13 "age": 0
14 }],
15 "sword": [{
16 "expries": 0
17 }]
18 },
19 "exits": {
20 "behind": "Room001",
21 "dark": "Dark",
22 "outside": "Outside"
23 },
24 "title": "Tavern",
25 "zone":"town"
26 }
...\ No newline at end of file ...\ No newline at end of file