def load(filename, book=None, req_book=None): """ Static method to load a character 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: # The initial "zero" padding in Book 1 is four bytes, and only one byte in # Book 2. Since the next bit of data is the character name, as a string, # if the second byte of the file is 00, we'll assume that it's a Book 1 file, # and Book 2 otherwise. try: df.open_r() initital = df.readuchar() second = df.readuchar() df.close() except (IOError, struct.error), e: raise LoadException(str(e)) if second == 0: book = 1 else: book = 2
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()
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()
def load(filename, book=None, req_book=None): """ Static method to load a character 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: # The initial "zero" padding in Book 1 is four bytes, and only one byte in # Book 2. Since the next bit of data is the character name, as a string, # if the second byte of the file is 00, we'll assume that it's a Book 1 file, # and Book 2 otherwise. try: df.open_r() initital = df.readuchar() second = df.readuchar() df.close() except (IOError, struct.error), e: raise LoadException(str(e)) if second == 0: book = 1 else: book = 2
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
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))
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))