def __init__(self, info: Mapping[str, Any], platform_config: 'PlatformConfig'): super().__init__(platform_config) self.info = info self.is_on_cd: bool = info.get('is_on_cd', False) self.path: str = info['path'] #Could be a host path (e.g. DOS) or could be some special path particular to that platform (e.g. Mac using PathInsideHFS, DOS using paths inside CDs when is_on_cd) self.args = info.get('args', []) self.cd_path: Optional[Path] = None self.other_cd_paths: Collection[PurePath] = set() #Could be None I guess, if cd_path not in info if 'cd_path' in info: _cd_paths = info['cd_path'] if isinstance(info['cd_path'], list) else [info['cd_path']] cd_paths = tuple(self.base_folder.joinpath(cd_path) if self.base_folder and not cd_path.startswith('/') else cd_path for cd_path in _cd_paths) self.cd_path = Path(cd_paths[0]) self.other_cd_paths = cd_paths[1:] elif self.is_on_cd: raise KeyError('cd_path is mandatory if is_on_cd is true') self._name = info.get('name', fix_name(self.fallback_name))
def make_launcher(self, task: GOGTask): emulator_name, params = self.get_launcher_params(task) if not params: return if not task.path: #It already won't be, just satisfying automated code checkers return task_metadata = copy.deepcopy(self.metadata) if task.category == 'tool': task_metadata.categories = ('Applications', ) task_metadata.emulator_name = emulator_name if task.compatibility_flags: task_metadata.specific_info[ 'Compatibility Flags'] = task.compatibility_flags if task.is_dosbox and emulator_name != 'DOSBox': task_metadata.specific_info['Wrapper'] = 'DOSBox' if task.is_scummvm and emulator_name != 'ScummVM': task_metadata.specific_info['Wrapper'] = 'ScummVM' if task.is_residualvm and emulator_name != 'ScummVM': task_metadata.specific_info['Wrapper'] = 'ResidualVM' executable_name = os.path.basename(task.path) task_metadata.specific_info['Executable Name'] = executable_name if os.path.extsep in executable_name: task_metadata.specific_info['Extension'] = executable_name.rsplit( os.path.extsep, 1)[-1].lower() if not (task.is_dosbox or task.is_scummvm or task.is_residualvm): exe_path = _find_subpath_case_insensitive(self.folder, task.path) exe_icon = pc_common_metadata.get_icon_inside_exe(str(exe_path)) if exe_icon: task_metadata.images['Icon'] = exe_icon pc_common_metadata.add_metadata_for_raw_exe( str(exe_path), task_metadata) name = self.name if task.name: if task.is_probably_subtask: if task.name.startswith(self.original_name): name = task.name.replace(self.original_name, self.name) else: name += ' ({0})'.format(task.name) else: name = name_utils.fix_name(task.name) make_launcher(params, name, task_metadata, 'GOG', str(self.folder))
def parse_param_sfo_kv(rompath: str, metadata: 'Metadata', key: str, value: SFOValueType): #rompath is just there for warning messages if key == 'DISC_ID': if value != 'UCJS10041': #That one's used by all the PSP homebrews metadata.product_code = cast(str, value) elif key == 'TITLE_ID': #PS3 uses this instead I guess metadata.product_code = cast(str, value) elif key == 'DISC_NUMBER': metadata.disc_number = cast(int, value) elif key == 'DISC_TOTAL': metadata.disc_total = cast(int, value) elif key == 'TITLE': metadata.add_alternate_name( fix_name(cast(str, value).replace('\n', ' - ')), 'Banner Title') elif len(key) == 8 and key[:5] == 'TITLE' and key[-2:].isdigit(): lang_id = int(key[-2:]) prefix = title_languages.get(lang_id) name_name = 'Banner Title' if prefix: name_name = prefix + name_name metadata.add_alternate_name( fix_name(cast(str, value).replace('\n', ' - ')), name_name) elif key == 'PARENTAL_LEVEL': #Seems this doesn't actually mean anything by itself, and is Sony's own rating system, so don't try and think about it too much metadata.specific_info['Parental Level'] = value elif key == 'CATEGORY': #This is a two letter code which generally means something like "Memory stick game" "Update" "PS1 Classics", see ROMniscience notes cat = categories.get(cast(str, value)) if cat: metadata.specific_info['PlayStation Category'] = cat.cat if cat.metadata_category is not None: if not metadata.categories or (len(metadata.categories) == 1 and metadata.categories[0] == metadata.platform): metadata.categories = [cat.metadata_category] else: metadata.specific_info['Bootable?'] = False else: if main_config.debug: print(rompath, 'has unknown category', value) elif key in {'DISC_VERSION', 'APP_VER'}: if cast(str, value)[0] != 'v': value = 'v' + cast(str, value) metadata.specific_info['Version'] = value elif key == 'VERSION': metadata.specific_info['Revision'] = value elif key == 'LICENSE': metadata.descriptions['License'] = cast(str, value) elif key == 'BOOTABLE': if value == 0: metadata.specific_info['Bootable?'] = False #Does not seem to ever be set to anything?? elif key == 'CONTENT_ID': metadata.specific_info['Content ID'] = value elif key == 'USE_USB': metadata.specific_info['Uses USB?'] = value != 0 elif key in {'PSP_SYSTEM_VER', 'PS3_SYSTEM_VER'}: metadata.specific_info['Required Firmware'] = value elif key == 'ATTRIBUTE': if value: try: flags = AttributeFlags(value) if flags & AttributeFlags.MoveControllerEnabled: metadata.specific_info['Uses Move Controller?'] = True #metadata.specific_info['Attribute Flags'] = flags except ValueError: #metadata.specific_info['Attribute Flags'] = hex(value) if main_config.debug: print(rompath, 'has funny attributes flag', hex(cast(int, value))) elif key == 'RESOLUTION': try: metadata.specific_info['Display Resolution'] = { res[1:] for res in str(Resolutions(value))[12:].split('|') } except ValueError: if main_config.debug: print(rompath, 'has funny resolution flag', hex(cast(int, value))) elif key == 'SOUND_FORMAT': try: metadata.specific_info['Supported Sound Formats'] = { res.lstrip('_').replace('_', '.') for res in str(SoundFormats(value))[13:].split('|') } except ValueError: if main_config.debug: print(rompath, 'has funny sound format flag', hex(cast(int, value))) elif key in {'MEMSIZE', 'REGION', 'HRKGMP_VER', 'NP_COMMUNICATION_ID'}: #These are known, but not necessarily useful to us or we just don't feel like putting it in the metadata or otherwise doing anything with it at this point #MEMSIZE: PSP, 1 if game uses extra RAM? #REGION: Seems to always be 32768 (is anything region locked?) and also only on PSP?? #HRKGMP_VER = ??? (19) #NP_COMMUNICATION_ID = PS3, ID used for online features I guess, also the subdirectory of TROPDIR containing TROPHY.TRP #print('ooo', rom.path, key, value) pass else: if main_config.debug: print(rompath, 'has unknown param.sfo value', key, value)
def _add_metadata_from_receipt(self) -> None: if not self.receipt: return game = self.receipt['game'] upload = self.receipt['upload'] #build, files, installerName probably not needed title = game.get('title') if title: self._name = fix_name(title) self.metadata.specific_info['Game ID'] = game.get('id') self.metadata.documents['Homepage'] = game.get('url') description = game.get('shortText') if description: self.metadata.descriptions['Description'] = description self.game_type = game.get( 'type', 'default') #Default, flash, unity, java, html self.category = game.get( 'classification', 'game' ) #game, tool, assets, game_mod, physical_game, soundtrack, other, comic, book created_at = game.get('createdAt') published_at = game.get('publishedAt') if created_at: creation_date = datetime.date.fromisoformat(created_at[:10]) self.metadata.specific_info['Creation Date'] = Date( creation_date.year, creation_date.month, creation_date.day) if published_at: release_date = datetime.date.fromisoformat(published_at[:10]) self.metadata.release_date = Date(release_date.year, release_date.month, release_date.day) #coverUrl, stillCoverUrl might be useful? I dunno #platforms is what platforms the game _can_ be available for, but it doesn't tell us about this exe #minPrice, canBeBought, sale aren't so useful here as this receipt is generated at the time this game is downloaded I think which might be out of date user = game.get('user') if user: user_name = user.get('displayName') #not using the second param of .get here because we also don't want it to be an empty string if not user_name: user_name = user.get('username') if user_name: self.metadata.developer = self.metadata.publisher = user_name #developer and pressUser here just indicate if this user (who has uploaded the game) has ticked a box saying they are a developer or press, which doesn't seem to matter self.metadata.documents['Developer Homepage'] = user.get('url') if upload: build_name = upload.get('displayName') if not build_name: build_name = upload.get('filename') self.metadata.specific_info['Build Name'] = build_name self.is_demo = upload.get('demo') if self.is_demo and not 'demo' in self.name.lower(): self._name += ' (Demo)' self.metadata.specific_info['Upload Type'] = upload.get( 'type', 'default' ) #default, flash, unity, java, html, soundtrack, book, video, documentation, mod, audio_assets, graphical_assets, sourcecode, other self.platforms = tuple(upload.get( 'platforms', {}).keys()) #I think the values show if it's x86/x64 but eh #Not sure what channelName or preorder does upload_created_at = upload.get('createdAt') upload_updated_at = upload.get('updatedAt') if upload_created_at: upload_creation_date = datetime.date.fromisoformat( upload_created_at[:10]) self.metadata.specific_info['Upload Creation Date'] = Date( upload_creation_date.year, upload_creation_date.month, upload_creation_date.day) if upload_updated_at: upload_date = datetime.date.fromisoformat( upload_updated_at[:10]) self.metadata.specific_info['Upload Date'] = Date( upload_date.year, upload_date.month, upload_date.day)
def name(self) -> str: name = self.app_state.get('name') if not name: name = f'<unknown game {self.appid}>' name = fix_name(name) return name
def name(self) -> str: return name_utils.fix_name(self.original_name)
def name(self) -> str: return name_utils.fix_name(self.info.name)