home · contact · privacy
Refactor player session code.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 19 Nov 2020 19:28:27 +0000 (20:28 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 19 Nov 2020 19:28:27 +0000 (20:28 +0100)
plomrogue/commands.py
plomrogue/game.py

index 249e1ab5e91d50a91a51ff940ba572936baf1cef..603e0d32414c5eb8fa756633123d2434f014f499 100644 (file)
@@ -41,14 +41,14 @@ def cmd_ALL(game, msg, connection_id):
             lowered_msg += c
         return lowered_msg
 
-    if not connection_id in game.sessions:
+    speaker = game.get_player(connection_id)
+    if not speaker:
         raise GameError('need to be logged in for this')
-    speaker = game.get_thing(game.sessions[connection_id])
     largest_audible_distance = 20
     dijkstra_map = DijkstraMap(game.maps, speaker.position,
                                largest_audible_distance, game.get_map)
     for c_id in game.sessions:
-        listener = game.get_thing(game.sessions[c_id])
+        listener = game.get_player(c_id)
         target_yx = dijkstra_map.target_yx(*listener.position, True)
         if not target_yx:
             continue
@@ -68,14 +68,14 @@ cmd_ALL.argtypes = 'string'
 def cmd_LOGIN(game, nick, connection_id):
     for t in [t for t in game.things if t.type_ == 'Player' and t.name == nick]:
         raise GameError('name already in use')
-    if connection_id in game.sessions:
+    if game.get_player(connection_id):
         raise GameError('cannot log in twice')
     t = game.thing_types['Player'](game)
     t.position = (YX(0,0),
                   YX(game.map_geometry.size.y // 2, game.map_geometry.size.x // 2))
     game.things += [t]  # TODO refactor into Thing.__init__?
     t.player_char = game.get_next_player_char()
-    game.sessions[connection_id] = t.id_
+    game.sessions[connection_id] = {'thing_id': t.id_}
     game.io.send('LOGIN_OK', connection_id)
     t.name = nick
     game.io.send('CHAT ' + quote(t.name + ' entered the map.'))
@@ -86,10 +86,9 @@ cmd_LOGIN.argtypes = 'string'
 def cmd_NICK(game, nick, connection_id):
     for t in [t for t in game.things if t.type_ == 'Player' and t.name == nick]:
         raise GameError('name already in use')
-    if not connection_id in game.sessions:
+    t = game.get_player(connection_id)
+    if not t:
         raise GameError('can only rename when already logged in')
-    t_id = game.sessions[connection_id]
-    t = game.get_thing(t_id)
     old_nick = t.name
     t.name = nick
     game.io.send('CHAT ' + quote(old_nick + ' renamed themselves to ' + nick))
@@ -124,7 +123,7 @@ def cmd_TURN(game, n):
 cmd_TURN.argtypes = 'int:nonneg'
 
 def cmd_ANNOTATE(game, yx, msg, pw, connection_id):
-    player = game.get_thing(game.sessions[connection_id])
+    player = game.get_player(connection_id)
     big_yx, little_yx = player.fov_stencil.source_yxyx(yx)
     if not player.fov_test(big_yx, little_yx):
         raise GameError('cannot annotate tile outside field of view')
@@ -142,7 +141,7 @@ def cmd_ANNOTATE(game, yx, msg, pw, connection_id):
 cmd_ANNOTATE.argtypes = 'yx_tuple:nonneg string string'
 
 def cmd_PORTAL(game, yx, msg, pw, connection_id):
-    player = game.get_thing(game.sessions[connection_id])
+    player = game.get_player(connection_id)
     big_yx, little_yx = player.fov_stencil.source_yxyx(yx)
     if not player.fov_test(big_yx, little_yx):
         raise GameError('cannot edit portal on tile outside field of view')
@@ -174,7 +173,7 @@ def cmd_GOD_PORTAL(game, big_yx, little_yx, msg):
 cmd_GOD_PORTAL.argtypes = 'yx_tuple yx_tuple:nonneg string'
 
 def cmd_GET_ANNOTATION(game, yx, connection_id):
-    player = game.get_thing(game.sessions[connection_id])
+    player = game.get_player(connection_id)
     big_yx, little_yx = player.fov_stencil.source_yxyx(yx)
     annotation = '(unknown)';
     if player.fov_test(big_yx, little_yx):
index 84bebb98c2d4a45f0a1f68619681790f07ce5d99..23a0d7bbc21cd7763e9c58e7f2e7c49da584c3a9 100755 (executable)
@@ -119,12 +119,18 @@ class Game(GameBase):
     def get_map_geometry_shape(self):
         return self.map_geometry.__class__.__name__[len('MapGeometry'):]
 
+    def get_player(self, connection_id):
+        if not connection_id in self.sessions:
+            return None
+        player = self.get_thing(self.sessions[connection_id]['thing_id'])
+        return player
+
     def send_gamestate(self, connection_id=None):
         """Send out game state data relevant to clients."""
 
         self.io.send('TURN ' + str(self.turn))
         for c_id in self.sessions:
-            player = self.get_thing(self.sessions[c_id])
+            player = self.get_player(c_id)
             visible_terrain = player.fov_stencil_map()
             self.io.send('FOV %s' % quote(player.fov_stencil.terrain), c_id)
             self.io.send('MAP %s %s %s' % (self.get_map_geometry_shape(),
@@ -163,7 +169,7 @@ class Game(GameBase):
                     connection_id_found = True
                     break
             if not connection_id_found:
-                t = self.get_thing(self.sessions[connection_id])
+                t = self.get_player(connection_id)
                 if hasattr(t, 'name'):
                     self.io.send('CHAT ' + quote(t.name + ' left the map.'))
                 self.things.remove(t)
@@ -177,11 +183,11 @@ class Game(GameBase):
                     t.proceed()
                 except GameError as e:
                     for connection_id in [c_id for c_id in self.sessions
-                                          if self.sessions[c_id] == t.id_]:
+                                          if self.sessions[c_id]['thing_id'] == t.id_]:
                         self.io.send('GAME_ERROR ' + quote(str(e)), connection_id)
                 except PlayError as e:
                     for connection_id in [c_id for c_id in self.sessions
-                                          if self.sessions[c_id] == t.id_]:
+                                          if self.sessions[c_id]['thing_id'] == t.id_]:
                         self.io.send('PLAY_ERROR ' + quote(str(e)), connection_id)
         if self.changed:
             self.turn += 1
@@ -198,9 +204,9 @@ class Game(GameBase):
             return p
 
         def cmd_TASK_colon(task_name, game, *args, connection_id):
-            if connection_id not in game.sessions:
+            t = self.get_player(connection_id)
+            if not t:
                 raise GameError('Not registered as player.')
-            t = game.get_thing(game.sessions[connection_id])
             t.set_next_task(task_name, args)
 
         def task_prefixed(command_name, task_prefix, task_command):