7 def __init__(self, game, save_file='savefile'):
8 from plomrogue.parser import Parser
10 self.parser = Parser(game)
12 self.save_file = save_file
15 """Handle commands coming through queue q, run game, send results back."""
18 command, connection_id = q.get(timeout=0.001)
19 self.handle_input(connection_id, command)
23 def run_loop_with_server(self, port, server_class):
24 """Run connection of server talking to clients and game IO loop.
26 We have a server of self.server_class and we have the game IO loop,
27 a thread running self.loop. Both communicate with each other via a
28 queue.Queue. While the server may spawn parallel threads to many
29 clients, the IO loop works sequentially through game commands
30 received from the server's client connections. A processed command
31 may trigger messages to the commanding client or to all clients,
32 delivered from the IO loop to the server via the queue.
37 c = threading.Thread(target=self.loop, daemon=True, args=(q,))
39 self.server = server_class(q, port)
41 self.server.serve_forever()
42 except KeyboardInterrupt:
45 print('Killing server')
46 self.server.server_close()
48 def handle_input(self, input_, connection_id=None, god_mode=False):
49 """Process input_ to command grammar, call command handler if found.
51 Command handlers that have no connectin_i argument in their
52 signature will only be called if god_mode is set.
55 from inspect import signature
56 from plomrogue.errors import GameError, ArgError, PlayError
57 from plomrogue.misc import quote
59 def answer(connection_id, msg):
61 self.send(msg, connection_id)
66 command, args = self.parser.parse(input_)
68 answer(connection_id, 'UNHANDLED_INPUT')
70 if 'connection_id' in list(signature(command).parameters):
71 command(*args, connection_id=connection_id)
74 #if store and not hasattr(command, 'dont_save'):
75 # with open(self.game_file_name, 'a') as f:
76 # f.write(input_ + '\n')
78 answer(connection_id, 'ARGUMENT_ERROR ' + quote(str(e)))
79 except PlayError as e:
80 answer(connection_id, 'PLAY_ERROR ' + quote(str(e)))
81 except GameError as e:
82 answer(connection_id, 'GAME_ERROR ' + quote(str(e)))
84 def send(self, msg, connection_id=None):
85 """Send message msg to server's client(s).
87 If a specific client is identified by connection_id, only
88 sends msg to that one. Else, sends it to all clients.
92 self.server.clients[connection_id].put(msg)
94 for c in self.server.clients.values():