示例#1
0
    def load(filename, book=None, req_book=None):
        """
        Static method to load a savename file.  This will open the file once and
        read in a bit of data to determine whether this is a Book 1 character file or
        a Book 2 character file, and then call the appropriate constructor and
        return the object.  The individual Book constructors expect to be passed in
        an 
        """
        df = Savefile(filename)

        # First figure out what format to load, if needed
        if book is None:
            try:
                df.open_r()
                name = df.readstr()
                date = df.readstr()
                time = df.readstr()
                map_or_version = df.readstr()
                df.close()
            except (IOError, struct.error), e:
                raise LoadException(str(e))

            if map_or_version.startswith('book3'):
                book = 3
            elif map_or_version in B1Constants.maps:
                book = 1
            else:
                book = 2
示例#2
0
    def load(filename, book=None, req_book=None):
        """
        Static method to load a savename file.  This will open the file once and
        read in a bit of data to determine whether this is a Book 1 character file or
        a Book 2 character file, and then call the appropriate constructor and
        return the object.  The individual Book constructors expect to be passed in
        an 
        """
        df = Savefile(filename)

        # First figure out what format to load, if needed
        if book is None:
            try:
                df.open_r()
                name = df.readstr()
                date = df.readstr()
                time = df.readstr()
                map_or_version = df.readstr()
                df.close()
            except (IOError, struct.error), e:
                raise LoadException(str(e))

            if map_or_version.startswith('book3'):
                book = 3
            elif map_or_version in B1Constants.maps:
                book = 1
            else:
                book = 2
示例#3
0
    def load_charname(self, book=None) -> None:
        """
        Read our character name; this is a bit dependant on the book number,
        which is why we pass it in here.  If the book number is not passed
        in, we will scan for map files and then use the first map's book
        number.  If there are no maps in the slot, then we'll raise a
        LoadException
        """

        # First figure out which book number we are, if we don't have it yet
        if not book:
            if not self.maps_loaded:
                self.load_maps()
            if len(self.maps) > 0:
                book = self.maps[0].book
            else:
                raise LoadException(
                    'Could not auto-detect which book version to use for charname')

        # Now do the actual loading
        if not os.path.exists(self.char_loc):
            raise LoadException(f'"char" file not found in {self.char_loc}')
        df = Savefile(self.char_loc)
        df.open_r()
        if book == 1:
            df.readint()
        else:
            df.readuchar()
        self.charname = df.readstr().decode('UTF-8')
        self.char_loaded = True
        df.close()
示例#4
0
    def load(filename, book=None, req_book=None):
        """
        Static method to load a map file.  This will open the file once
        and read in a bit of data to determine whether this is a Book 1 map file
        or a Book 1 map file, and then call the appropriate constructor and
        return the object.
        """
        df = Savefile(filename)

        # Book 1 files start with 10 strings, Book 2 with 9, and Book 3 with
        # more.  To see what kind of file we have, read 11 strings and check
        # whether the last two are ASCII-only
        if book is None:
            try:
                df.open_r()
                strings = []
                for i in range(11):
                    strings.append(df.readstr())
                df.close()
            except (IOError, struct.error), e:
                raise LoadException(str(e))

            if not Map.is_ascii(strings[9]):
                book = 2
            elif not Map.is_ascii(strings[10]):
                book = 1
            else:
                book = 3
示例#5
0
    def load_charname(self, book=None):
        """
        Read our character name; this is a bit dependant on the book number,
        which is why we pass it in here.  If the book number is not passed
        in, we will scan for map files and then use the first map's book
        number.  If there are no maps in the slot, then we'll raise a
        LoadException
        """

        # First figure out which book number we are, if we don't have it yet
        if not book:
            if not self.maps_loaded:
                self.load_maps()
            if len(self.maps) > 0:
                book = self.maps[0].book
            else:
                raise LoadException(
                    'Could not auto-detect which book version to use for charname'
                )

        # Now do the actual loading
        if not os.path.exists(self.char_loc):
            raise LoadException('"char" file not found in %s' % (directory))
        df = Savefile(self.char_loc)
        df.open_r()
        if book == 1:
            df.readint()
        else:
            df.readuchar()
        self.charname = df.readstr()
        self.char_loaded = True
        df.close()
示例#6
0
    def load(filename, book=None, req_book=None):
        """
        Static method to load a savename file.  This will open the file once and
        read in a bit of data to determine whether this is a Book 1 character file or
        a Book 2 character file, and then call the appropriate constructor and
        return the object.  The individual Book constructors expect to be passed in
        an 
        """
        df = Savefile(filename)

        # First figure out what format to load, if needed
        if book is None:
            try:
                df.open_r()
                name = df.readstr().decode('UTF-8')
                date = df.readstr().decode('UTF-8')
                time = df.readstr().decode('UTF-8')
                map_or_version = df.readstr().decode('UTF-8')
                df.close()
            except (IOError, struct.error) as e:
                LOG.error("Failed to load book", exc_info=True)
                raise LoadException(e) from e

            if map_or_version.startswith(b'book3'):
                book = 3
            elif map_or_version in B1Constants.maps:
                book = 1
            else:
                book = 2

        # See if we're required to conform to a specific book
        if (req_book is not None and book != req_book):
            raise LoadException(
                'This utility can only load Book %d Character files; this file is from Book %d' % (req_book, book))

        # Now actually return the object
        if book == 1:
            c.switch_to_book(1)
            return B1Savename(df)
        elif book == 2:
            c.switch_to_book(2)
            return B2Savename(df)
        else:
            c.switch_to_book(3)
            return B3Savename(df)
示例#7
0
    def get_mapinfo(filename=None, map_df=None):
        """
        Given a filename or a passed filehandle, loads the first few bits of
        information from a map file, and will return a tuple containing the
        Eschalon Book the map belongs to, the internal "map name" of the map,
        and a Savefile object pointing to the map.  Will raise a LoadException
        if it encounters errors.

        Book 1 files start with 10 strings
        Book 2 files start with 9 strings, followed by a uchar whose value
          will always be 1 (the "loadhook" var, presumably)
        Book 3 files start with 12 strings, the first of which is a version,
          which so far is always 0.992.

        So, to figure out dynamically what kind of file we're loading:
          1) Read 9 strings, remember the first one
          2) Read the next uchar - if it's 1, then we're editing Book 2
          3) If the first string is "0.992", then we're editing Book 3
          4) Otherwise, we're editing Book 1

        Theoretically, that way this works even if a Book 2 map happens
        to use a mapname of 0.992, in an effort to be cheeky.
        """
        if filename is not None:
            df = Savefile(filename)
        elif map_df is not None:
            df = map_df
        else:
            raise LoadException('One of filename or map_df must be passed in')
        stringlist = []
        try:
            df.open_r()
            for i in range(9):
                stringlist.append(df.readstr())
            nextbyte = df.readuchar()
            df.close()
        except (IOError, struct.error) as e:
            raise LoadException(str(e))

        if nextbyte == 1:
            detected_book = 2
            detected_mapname = stringlist[0]
        # TODO: We're checking for a blank string here to cover up
        # for some invalid data that older versions of the unofficial
        # pre-1.0.0 builds.  By the time 1.1.0 rolls around, or so,
        # we should get rid of that.
        elif stringlist[0] == '0.992' or stringlist[0] == '':
            detected_book = 3
            detected_mapname = stringlist[1]
        else:
            detected_book = 1
            detected_mapname = stringlist[1]

        return detected_book, detected_mapname, df
示例#8
0
    def get_mapinfo(filename=None, map_df=None):
        """
        Given a filename or a passed filehandle, loads the first few bits of
        information from a map file, and will return a tuple containing the
        Eschalon Book the map belongs to, the internal "map name" of the map,
        and a Savefile object pointing to the map.  Will raise a LoadException
        if it encounters errors.

        Book 1 files start with 10 strings
        Book 2 files start with 9 strings, followed by a uchar whose value
          will always be 1 (the "loadhook" var, presumably)
        Book 3 files start with 12 strings, the first of which is a version,
          which so far is always 0.992.
        
        So, to figure out dynamically what kind of file we're loading:
          1) Read 9 strings, remember the first one
          2) Read the next uchar - if it's 1, then we're editing Book 2
          3) If the first string is "0.992", then we're editing Book 3
          4) Otherwise, we're editing Book 1
        
        Theoretically, that way this works even if a Book 2 map happens
        to use a mapname of 0.992, in an effort to be cheeky.
        """
        if filename is not None:
            df = Savefile(filename)
        elif map_df is not None:
            df = map_df
        else:
            raise LoadException('One of filename or map_df must be passed in')
        stringlist = []
        try:
            df.open_r()
            for i in range(9):
                stringlist.append(df.readstr())
            nextbyte = df.readuchar()
            df.close()
        except (IOError, struct.error), e:
            raise LoadException(str(e))
示例#9
0
    def get_mapinfo(filename=None, map_df=None):
        """
        Given a filename or a passed filehandle, loads the first few bits of
        information from a map file, and will return a tuple containing the
        Eschalon Book the map belongs to, the internal "map name" of the map,
        and a Savefile object pointing to the map.  Will raise a LoadException
        if it encounters errors.

        Book 1 files start with 10 strings
        Book 2 files start with 9 strings, followed by a uchar whose value
          will always be 1 (the "loadhook" var, presumably)
        Book 3 files start with 12 strings, the first of which is a version,
          which so far is always 0.992.
        
        So, to figure out dynamically what kind of file we're loading:
          1) Read 9 strings, remember the first one
          2) Read the next uchar - if it's 1, then we're editing Book 2
          3) If the first string is "0.992", then we're editing Book 3
          4) Otherwise, we're editing Book 1
        
        Theoretically, that way this works even if a Book 2 map happens
        to use a mapname of 0.992, in an effort to be cheeky.
        """
        if filename is not None:
            df = Savefile(filename)
        elif map_df is not None:
            df = map_df
        else:
            raise LoadException('One of filename or map_df must be passed in')
        stringlist = []
        try:
            df.open_r()
            for i in range(9):
                stringlist.append(df.readstr())
            nextbyte = df.readuchar()
            df.close()
        except (IOError, struct.error), e:
            raise LoadException(str(e))