Can read ship coordinates (ShipXY)
2 files changed, 32 insertions(+), 6 deletions(-)

M player.py
M result.py
M player.py +29 -5
@@ 3,7 3,7 @@ Classes for reading player data such as 
 """
 
 # Disable pylint warnings caused by fields not being explicity defined
-# pylint: disable=W0201
+# pylint: disable=W0201,E0203
 
 import struct
 from common import PlanetsData

          
@@ 132,6 132,26 @@ class Ship(PlanetsData):
               'intercept_id',
               'credits')
 
+class ShipXY(PlanetsData):
+    """List of ship coordinates"""
+    # No FILENAME, byt typically: SHIPXYx.DAT (x=player)
+    COUNT = 500 # Not compatible with host999
+    PACK_LENGTH = 8
+    PACK_FORMAT = '< h h h h'
+    FIELDS = ('x',
+              'y',
+              'owner',
+              'mass')
+    
+    @classmethod
+    def load(cls, data, count=None):
+        result = super(ShipXY, cls).load(data, count)
+        # Remove empty objects from result (mass = 0 and owner = 0)
+        for key in result.keys():
+            if not result[key].mass and not result[key].owner:
+                del result[key]
+        return result
+
 class Target(PlanetsData):
     """List of of visual enemy ships (contacts)"""
     # No FILENAME, but typically: TARGETx.DAT (x=player)

          
@@ 146,6 166,13 @@ class Target(PlanetsData):
               'hull',
               'heading',
               'name')
+    
+    def decrypt(self):
+        """Decrypts ship names in extra enemy contact data in RST files"""
+        name = ''
+        for i in range(0, len(self.name)):
+            name += chr(ord(self.name[i]) ^ (154 - i))
+        self.name = name
 
     @classmethod
     def read_result(cls, f, extra_offset=None):

          
@@ 161,10 188,7 @@ class Target(PlanetsData):
             extra = cls.load(data, count)
             # Extra data has encrypted ship name
             for k in extra.keys():
-                name = ''
-                for i in range(0, len(extra[k].name)):
-                    name += chr(ord(extra[k].name[i]) ^ (154 - i))
-                extra[k].name = name
+                extra[k].decrypt()
             # Merge results
             result = dict(result.items() + extra.items())
         # Run fix() on returned objects

          
M result.py +3 -1
@@ 3,7 3,7 @@ Functions for reading and parsing RST (r
 """
 
 import struct
-from player import Base, Planet, Ship, Target, read_messages
+from player import Base, Planet, Ship, ShipXY, Target, read_messages
 
 class InvalidResultFile(Exception):
     """Exception raised when the RST file is invalid or corrupt"""

          
@@ 27,6 27,8 @@ def read(f, filesize):
     result['bases'] = Base.read(f, has_count=True)
     f.seek(pointers['messages'])
     result['messages'] = read_messages(f)
+    f.seek(pointers['shipxy'])
+    result['shipxy'] = ShipXY.read(f)
     return result
     
 def _valid_pointer(pointer, filesize, datasize):