def _common_testing_show_ui_response_dialog(_connection: int = None): output = CheatOutput(_connection) output('Showing test ui response dialog.') def _on_chosen(_: CommonUiResponseDialog): response_value = _.get_response_value() output('Chosen value {}'.format(response_value if response_value is not None else 'No value chosen.')) try: responses: Tuple[CommonUiDialogResponse] = (CommonUiDialogResponse( 0, 'one', text='Button one'), CommonUiDialogResponse( 1, 'two', text='Button two')) title = CommonLocalizationUtils.create_localized_string( CommonStringId.TESTING_TEST_TEXT_WITH_STRING_TOKEN, tokens=(CommonLocalizationUtils.create_localized_string( CommonStringId.TESTING_SOME_TEXT_FOR_TESTING, text_color=CommonLocalizedStringColor.GREEN), )) description = CommonLocalizationUtils.create_localized_string( CommonStringId.TESTING_TEST_TEXT_WITH_STRING_TOKEN, tokens=(CommonLocalizationUtils.create_localized_string( CommonStringId.TESTING_TEST_TEXT_WITH_SIM_FIRST_AND_LAST_NAME, tokens=(CommonSimUtils.get_active_sim_info(), ), text_color=CommonLocalizedStringColor.BLUE), )) active_sim_info = CommonSimUtils.get_active_sim_info() dialog = CommonUiResponseDialog.TunableFactory().default( active_sim_info, responses, # Having a value of 0 means that we want to display the Close button with no other dialog options. dialog_options=0, text=lambda *_, **__: description, title=lambda *_, **__: title) dialog.add_listener(_on_chosen) dialog.show_dialog() except Exception as ex: CommonExceptionHandler.log_exception(ModInfo.get_identity(), 'Failed to show button dialog.', exception=ex) output('Done')
def write_to_file(file_path: str, data: str, buffering: int = 1, encoding: str = 'utf-8', ignore_errors: bool = False) -> bool: """write_to_file(file_path, data, buffering=1, encoding='utf-8', ignore_errors=False) Write string data to a file. :param file_path: The file to write to. :type file_path: str :param data: The data to write. :type data: str :param buffering: See the built-in python :func:`~open` function documentation for more details. :type buffering: int, optional :param encoding: See the built-in python :func:`~open` function documentation for more details. :type encoding: str, optional :param ignore_errors: If True, any exceptions thrown will be ignored (Useful in preventing infinite loops) :type ignore_errors: bool, optional :return: True if successful. False if not. :rtype: bool """ if file_path is None or data is None: return False try: with open(file_path, mode='a', buffering=buffering, encoding=encoding) as opened_file: opened_file.write(data) opened_file.flush() opened_file.close() except Exception as ex: if ignore_errors: return False from sims4communitylib.exceptions.common_exceptions_handler import CommonExceptionHandler CommonExceptionHandler.log_exception( ModInfo.get_identity(), 'Error occurred while writing to file \'{}\''.format( file_path), exception=ex) return False return True
def _create_dialog( self, picker_type: UiObjectPicker. UiObjectPickerObjectPickerType = UiObjectPicker. UiObjectPickerObjectPickerType.OBJECT, sim_info: SimInfo = None) -> Union[UiObjectPicker, None]: try: return UiObjectPicker.TunableFactory().default( sim_info or CommonSimUtils.get_active_sim_info(), text=lambda *_, **__: self.description, title=lambda *_, **__: self.title, min_selectable=1, max_selectable=1, picker_type=picker_type) except Exception as ex: CommonExceptionHandler.log_exception(self.mod_identity.name, '_create_dialog', exception=ex) return None
def _constraint_gen( cls, inst: Interaction, sim: Sim, target: Any, participant_type: ParticipantType = ParticipantType.Actor, **kwargs) -> Constraint: interaction_instance = inst if inst is not None else cls try: yield cls.on_constraint_gen(interaction_instance, sim or interaction_instance.sim, target or interaction_instance.target) except Exception as ex: CommonExceptionHandler.log_exception( ModInfo.get_identity().name, 'Error occurred while running interaction \'{}\' on_constraint_gen.' .format(cls.__name__), exception=ex) return None
def _wrapped_function(*args, **kwargs) -> Any: try: if type(original_function) is property: return new_function(original_function.fget, *args, **kwargs) return new_function(original_function, *args, **kwargs) except Exception as ex: # noinspection PyBroadException try: from sims4communitylib.exceptions.common_exceptions_handler import CommonExceptionHandler CommonExceptionHandler.log_exception( mod_identity, 'Error occurred while injecting into function \'{}\' of class' .format(new_function.__name__, target_object.__name__), exception=ex) except Exception: pass return original_function(*args, **kwargs)
def _common_testing_show_choose_sim_dialog(_connection: int=None): output = sims4.commands.CheatOutput(_connection) output('Showing test choose sim dialog.') def _on_chosen(choice: Union[SimInfo, None], outcome: CommonChoiceOutcome): output('Chose {} with result: {}.'.format(CommonSimNameUtils.get_full_name(choice), pformat(outcome))) try: # LocalizedStrings within other LocalizedStrings title_tokens = (CommonLocalizationUtils.create_localized_string(CommonStringId.TESTING_SOME_TEXT_FOR_TESTING, text_color=CommonLocalizedStringColor.GREEN),) description_tokens = (CommonLocalizationUtils.create_localized_string(CommonStringId.TESTING_TEST_TEXT_WITH_SIM_FIRST_AND_LAST_NAME, tokens=(CommonSimUtils.get_active_sim_info(),), text_color=CommonLocalizedStringColor.BLUE),) from sims4communitylib.utils.common_icon_utils import CommonIconUtils current_count = 0 count = 25 options = [] for sim_info in CommonSimUtils.get_sim_info_for_all_sims_generator(): if current_count >= count: break sim_id = CommonSimUtils.get_sim_id(sim_info) should_select = random.choice((True, False)) is_enabled = random.choice((True, False)) options.append( SimPickerRow( sim_id, select_default=should_select, tag=sim_info, is_enable=is_enabled ) ) current_count += 1 dialog = CommonChooseSimDialog( CommonStringId.TESTING_TEST_TEXT_WITH_STRING_TOKEN, CommonStringId.TESTING_TEST_TEXT_WITH_STRING_TOKEN, tuple(options), title_tokens=title_tokens, description_tokens=description_tokens ) dialog.show(on_chosen=_on_chosen, column_count=5) except Exception as ex: CommonExceptionHandler.log_exception(ModInfo.get_identity().name, 'Failed to show dialog', exception=ex) output('Failed to show dialog, please locate your exception log file and upload it to the appropriate thread.') output('Done showing.')
def _test(cls, target: Any, context: InteractionContext, **kwargs) -> TestResult: try: test_result = cls.on_test(context.sim, target, context, **kwargs) except Exception as ex: try: if hasattr(cls, 'mod_identity'): mod_identity = cls.mod_identity else: mod_identity = ModInfo.get_identity() except Exception as ex1: mod_identity = ModInfo.get_identity() CommonExceptionHandler.log_exception( mod_identity.name, 'Error occurred attempting to retrieve mod info for interaction {}.' .format(cls.__name__), exception=ex1) CommonExceptionHandler.log_exception( mod_identity.name, 'Error occurred while running interaction \'{}\' on_test.'. format(cls.__name__), exception=ex) return TestResult.NONE if test_result is None: return super()._test(target, context, **kwargs) if not isinstance(test_result, TestResult): raise RuntimeError( 'Interaction on_test did not result in a TestResult, instead got {}. {}' .format(pformat(test_result), cls.__name__)) if test_result.result is False: if test_result.tooltip is not None: tooltip = CommonLocalizationUtils.create_localized_tooltip( test_result.tooltip) elif test_result.reason is not None: tooltip = CommonLocalizationUtils.create_localized_tooltip( test_result.reason) else: tooltip = None return cls.create_test_result(test_result.result, test_result.reason, tooltip=tooltip) return super()._test(target, context, **kwargs)
def remove_buff(cls, sim_info: SimInfo, *buff_ids: int) -> bool: """ Remove the specified buffs from a sim. :param sim_info: The sim to remove the specified buffs from. :param buff_ids: The decimal identifiers of buffs to remove. :return: True if all of the specified buffs were successfully removed. """ if sim_info is None: CommonExceptionHandler.log_exception(ModInfo.get_identity().name, 'Argument sim_info was \'None\' for {} of class {}'.format(CommonBuffUtils.remove_buff.__name__, CommonBuffUtils.__name__)) return False if not CommonComponentUtils.has_component(sim_info, CommonComponentType.BUFF): return False success = True for buff_identifier in buff_ids: buff_instance = CommonBuffUtils._load_buff_instance(buff_identifier) if buff_instance is None: continue if not sim_info.remove_buff_by_type(buff_instance): success = False return success
def get_name(cls, inst: Interaction, target: Any = None, context: InteractionContext = None, *args, **kwargs) -> Union[LocalizedString, None]: try: inst_or_cls = context or inst or cls return cls._create_display_name(inst_or_cls.sim, target or inst_or_cls.target, interaction=inst, interaction_context=context, *args, **kwargs) except Exception as ex: CommonExceptionHandler.log_exception( cls.get_mod_identity(), 'An error occurred while running get_name of interaction {}'. format(cls.__name__), exception=ex)
def _on_interaction_run(self, interaction_queue: InteractionQueue, timeline: Timeline, interaction: Interaction, *_, **__) -> Union[bool, None]: if interaction is None or interaction.sim is None: return None try: return CommonEventRegistry.get().dispatch( S4CLInteractionRunEvent(interaction, interaction_queue)) except Exception as ex: CommonExceptionHandler.log_exception( ModInfo.get_identity(), 'Error occurred while running _on_interaction_run for interaction {} with short name {} and display name {}' .format( pformat(interaction), CommonInteractionUtils.get_interaction_short_name( interaction), CommonInteractionUtils.get_interaction_display_name( interaction)), exception=ex) return False
def has_buff(cls, sim_info: SimInfo, *buff_ids: int) -> bool: """ Determine if any of the specified buffs are currently active on a sim. :param sim_info: The sim being checked. :param buff_ids: The decimal identifiers of the Buffs being located. :return: True if the sim has any of the specified buffs. """ if sim_info is None: CommonExceptionHandler.log_exception(ModInfo.get_identity().name, 'argument sim_info was \'None\' for {} of class {}'.format(CommonBuffUtils.has_buff.__name__, CommonBuffUtils.__name__)) return False if not CommonComponentUtils.has_component(sim_info, CommonComponentType.BUFF): return False if not buff_ids: return False sim_buffs = CommonBuffUtils.get_buffs(sim_info) for buff in sim_buffs: buff_id = getattr(buff, 'guid64', None) if buff_id in buff_ids: return True return False
def resend_outfits(sim_info: SimInfo) -> bool: """resend_outfits(sim_info) Resend outfit data to a Sim to refresh their outfits. :param sim_info: The Sim to resend the outfit for. :type sim_info: SimInfo :return: True, if outfits were resent successfully. False, if not. :rtype: bool """ try: sim_info.resend_outfits() return True except Exception as ex: CommonExceptionHandler.log_exception( ModInfo.get_identity().name, 'Problem occurred running function \'{}\'.'.format( CommonOutfitUtils.resend_outfits.__name__), exception=ex) return False
def _on_interaction_outcome(self, interaction: Interaction, outcome: InteractionOutcome, result: OutcomeResult) -> Union[bool, Any]: if interaction.sim is None: return False try: return CommonEventRegistry.get().dispatch( S4CLInteractionOutcomeEvent(interaction, outcome, result)) except Exception as ex: CommonExceptionHandler.log_exception( ModInfo.get_identity(), 'Error occurred while running _on_interaction_outcome for interaction {} with short name {} and display name {}' .format( pformat(interaction), CommonInteractionUtils.get_interaction_short_name( interaction), CommonInteractionUtils.get_interaction_display_name( interaction)), exception=ex) return False
def apply_posture_state( self, posture_state: PostureState, participant_type: ParticipantType = ParticipantType.Actor, sim: Sim = DEFAULT): try: (new_posture_state, new_participant_type, new_sim) = self.modify_posture_state( posture_state, participant_type=participant_type, sim=sim) except Exception as ex: CommonExceptionHandler.log_exception( self.mod_identity.name, 'Error occurred while running interaction \'{}\' modify_posture_state.' .format(self.__class__.__name__), exception=ex) return None, None, None return super().apply_posture_state( new_posture_state, participant_type=new_participant_type, sim=new_sim)
def build_dialog( self, *_: Any, on_submit: Callable[[Tuple[DialogOptionValueType]], Any]=CommonFunctionUtils.noop, min_selectable: int=1, max_selectable: int=1, **__: Any ) -> Union[UiDialogBase, None]: """build_dialog(\ *_,\ on_submit=CommonFunctionUtils.noop,\ min_selectable=1,\ max_selectable=1,\ **__\ ) Build the dialog. .. note:: Override this function to provide your own arguments. :param on_submit: When the dialog is submitted, this callback will be invoked with the chosen options. :type on_submit: Callable[[Tuple[DialogOptionValueType]], Any], optional :param min_selectable: The minimum number of options that can be chosen. :type min_selectable: int, optional :param max_selectable: The maximum number of options that can be chosen. :type max_selectable: int, optional :return: The built dialog or None if a problem occurs. :rtype: Union[UiDialogBase, None] """ try: return self._internal_dialog.build_dialog( *_, on_chosen=self._on_submit(on_submit), min_selectable=min_selectable, max_selectable=max_selectable, **__ ) except Exception as ex: CommonExceptionHandler.log_exception(self.mod_identity, 'choose_options.build_dialog', exception=ex) return None
def on_add(self, from_load: bool = False, apply_buff_loot: bool = True): """on_add(from_load=False, apply_buff_loot=True) A function that occurs upon a Buff being added to a Sim. :param from_load: True, if the Buff is being added from a load. Default is False. :type from_load: bool, optional :param apply_buff_loot: If True, Loot will be applied when the Buff is added. Default is True. :type apply_buff_loot: bool, optional """ super().on_add(from_load=from_load, apply_buff_loot=apply_buff_loot) try: self.on_added(self.sim, from_load=from_load, apply_buff_loot=apply_buff_loot) except Exception as ex: CommonExceptionHandler.log_exception( self.mod_identity, 'Error occurred while running buff \'{}\' on_added.'.format( self.__class__.__name__), exception=ex)
def _log_message(self, message_type: str, message: str): from sims4communitylib.utils.common_date_utils import CommonRealDateUtils from pprint import pformat from sims4communitylib.exceptions.common_exceptions_handler import CommonExceptionHandler current_date_time = CommonRealDateUtils.get_current_date_string() new_message = '{} [{}] {}: [{}]: {}\n'.format(current_date_time, self.mod_name, str(message_type), self.name, message) try: from sims4communitylib.utils.common_io_utils import CommonIOUtils file_path = CommonLogUtils.get_message_file_path(self.mod_name) CommonIOUtils.write_to_file(file_path, new_message, ignore_errors=True) except Exception as ex: CommonExceptionHandler.log_exception( self.mod_name, 'Error occurred while attempting to log message: {}'.format( pformat(message)), exception=ex)
def _log_message(self, message_type: CommonMessageType, message: str): from sims4communitylib.utils.common_date_utils import CommonRealDateUtils from sims4communitylib.exceptions.common_exceptions_handler import CommonExceptionHandler current_date_time = CommonRealDateUtils.get_current_date_string() new_message = '{} {}: [{}]: {}\n'.format(current_date_time, message_type.name, self.name, message) try: from sims4communitylib.utils.common_io_utils import CommonIOUtils file_path = self.messages_file_path os.makedirs(os.path.dirname(file_path), exist_ok=True) CommonIOUtils.write_to_file(file_path, new_message, ignore_errors=True) except Exception as ex: CommonExceptionHandler.log_exception( self.mod_name, 'Error occurred while attempting to log message: {}'.format( pformat(message)), exception=ex, custom_file_path=self._custom_file_path)
def generate_outfit(sim_info: SimInfo, outfit_category_and_index: Tuple[OutfitCategory, int]) -> bool: """generate_outfit(sim_info, outfit_category_and_index) Generate an outfit for a Sim for the specified OutfitCategory and Index. .. note:: If an outfit exists in the specified OutfitCategory and Index, already, it will be overridden. :param sim_info: The Sim to generate an outfit for. :type sim_info: SimInfo :param outfit_category_and_index: The OutfitCategory and Index of the outfit to generate. :type outfit_category_and_index: Tuple[OutfitCategory, int] :return: True, if an outfit was generated successfully. False, if not. :rtype: bool """ try: sim_info.on_outfit_generated(sim_info, CommonOutfitUtils.get_current_outfit(sim_info)) sim_info.generate_outfit(*outfit_category_and_index) return True except Exception as ex: CommonExceptionHandler.log_exception(ModInfo.get_identity(), 'Problem occurred running function \'{}\'.'.format(CommonOutfitUtils.generate_outfit.__name__), exception=ex) return False
def show(self, *_, **__): """Show the dialog. .. note:: Override this function and provide your own arguments. """ try: def _on_chosen(chosen_option: CommonDialogOption, outcome: CommonChoiceOutcome) -> bool: if chosen_option is None or CommonChoiceOutcome.is_error_or_cancel( outcome): self.close() return False return chosen_option.choose() self._internal_dialog.show(*_, on_chosen=_on_chosen, **__) except Exception as ex: CommonExceptionHandler.log_exception(self.mod_identity.name, 'show', exception=ex)
def _test(cls, target: Any, context: InteractionContext, *args, **kwargs) -> TestResult: try: if context.sim is target: return TestResult( False, 'Social Mixer Interactions cannot target self!') if context.pick is not None: pick_target = context.pick.target if context.source == context.SOURCE_PIE_MENU else None if context.sim is pick_target: return TestResult( False, 'Social Mixer Interactions cannot target self!') test_result = cls.on_test(context.sim, target, context, *args, **kwargs) except Exception as ex: mod_identity = cls.get_mod_identity() CommonExceptionHandler.log_exception( mod_identity, 'Error occurred while running interaction \'{}\' on_test.'. format(cls.__name__), exception=ex) return TestResult.NONE if test_result is None: return super()._test(target, context, *args, **kwargs) if not isinstance(test_result, TestResult): raise RuntimeError( 'Interaction on_test did not result in a TestResult, instead got {}. {}' .format(pformat(test_result), cls.__name__)) if test_result.result is False: if test_result.tooltip is not None: tooltip = CommonLocalizationUtils.create_localized_tooltip( test_result.tooltip) elif test_result.reason is not None: tooltip = CommonLocalizationUtils.create_localized_tooltip( test_result.reason) else: tooltip = None return cls.create_test_result(test_result.result, test_result.reason, tooltip=tooltip) return super()._test(target, context, *args, **kwargs)
def _create_dialog( self, picker_type: UiObjectPicker.UiObjectPickerObjectPickerType=UiObjectPicker.UiObjectPickerObjectPickerType.OBJECT, sim_info: SimInfo=None, categories: Iterator[CommonDialogObjectOptionCategory]=(), min_selectable: int=1, max_selectable: int=1 ) -> Union[UiObjectPicker, None]: try: from collections import namedtuple object_category_type = namedtuple('object_category_type', ('object_category', 'icon', 'category_name')) object_categories = list() for category in tuple(categories): object_categories.append(object_category_type(category.object_category, lambda *_, **__: IconInfoData(icon_resource=CommonIconUtils._load_icon(category.icon)), CommonLocalizationUtils.create_localized_string(category.category_name))) if len(object_categories) > 0: self.log.debug('Building dialog with categories.') return CommonUiObjectCategoryPicker.TunableFactory().default( sim_info or CommonSimUtils.get_active_sim_info(), text=lambda *_, **__: self.description, title=lambda *_, **__: self.title, picker_type=picker_type, use_dropdown_filter=True, object_categories=tuple(object_categories), min_selectable=min_selectable, max_selectable=max_selectable ) else: self.log.debug('Building dialog without categories.') return UiObjectPicker.TunableFactory().default( sim_info or CommonSimUtils.get_active_sim_info(), text=lambda *_, **__: self.description, title=lambda *_, **__: self.title, picker_type=picker_type, min_selectable=min_selectable, max_selectable=max_selectable ) except Exception as ex: CommonExceptionHandler.log_exception(self.mod_identity, '_create_dialog', exception=ex) return None
def add_buff( sim_info: SimInfo, *buff_ids: Union[int, CommonBuffId], buff_reason: Union[int, str, LocalizedString, CommonStringId] = None ) -> bool: """add_buff(sim_info, *buff_ids, buff_reason=None) Add the specified buffs to a sim. :param sim_info: The sim to add the specified buffs to. :type sim_info: SimInfo :param buff_ids: The decimal identifiers of buffs to add. :type buff_ids: int :param buff_reason: The text that will display when the player hovers over the buffs. What caused the buffs to be added. :type buff_reason: Union[int, str, LocalizedString, CommonStringId], optional :return: True, if all of the specified buffs were successfully added. False, if not. :rtype: bool """ if sim_info is None: CommonExceptionHandler.log_exception( ModInfo.get_identity(), 'Argument \'sim_info\' was \'None\' for \'{}\' of class \'{}\'' .format(CommonBuffUtils.add_buff.__name__, CommonBuffUtils.__name__)) return False if not CommonComponentUtils.has_component(sim_info, CommonComponentType.BUFF): return False localized_buff_reason = CommonLocalizationUtils.create_localized_string( buff_reason) success = True for buff_identifier in buff_ids: buff_instance = CommonBuffUtils._load_buff_instance( buff_identifier) if buff_instance is None: continue if not sim_info.add_buff_from_op( buff_instance, buff_reason=localized_buff_reason): success = False return success
def _common_broadcaster_apply(original, self: Broadcaster, *_, **__) -> None: try: return original(self, *_, **__) except Exception as ex: if self.interaction is not None: interaction = self.interaction # noinspection PyTypeChecker CommonExceptionHandler.log_exception( None, 'Error occurred while running apply_broadcaster_effect for broadcaster {} for interaction {} with short name {} and display name {}' .format( pformat(self), pformat(interaction), CommonInteractionUtils.get_interaction_short_name( interaction), CommonInteractionUtils.get_interaction_display_name( interaction)), exception=ex) elif self.broadcasting_object is not None: broadcasting_object = self.broadcasting_object # noinspection PyTypeChecker CommonExceptionHandler.log_exception( None, 'Error occurred while running apply_broadcaster_effect for broadcaster {} from object {}' .format(pformat(self), pformat(broadcasting_object)), exception=ex) else: # noinspection PyTypeChecker CommonExceptionHandler.log_exception( None, 'Error occurred while running apply_broadcaster_effect for broadcaster {}' .format(pformat(self)), exception=ex) return None
def show( self, on_chosen: Callable[[Any, CommonChoiceOutcome], Any]=CommonFunctionUtils.noop, sim_info: SimInfo=None, should_show_names: bool=True, hide_row_descriptions: bool=False, column_count: int=3 ): """show(\ on_chosen=CommonFunctionUtils.noop,\ sim_info=None,\ should_show_names=True,\ hide_row_descriptions=False,\ column_count=3\ ) Show the dialog and invoke the callbacks upon the player making a choice. :param on_chosen: A callback invoked upon the player choosing a Sim from the list. Cannot be None. :type on_chosen: Callable[[Any, CommonChoiceOutcome], Any], optional :param sim_info: The SimInfo of the Sim that will appear in the dialog image. The default Sim is the active Sim. :type sim_info: SimInfo, optional :param should_show_names: If True, then the names of the Sims will display in the dialog. :type should_show_names: bool, optional :param hide_row_descriptions: A flag to hide the row descriptions. :type hide_row_descriptions: bool, optional :param column_count: The number of columns to display Sims in. Minimum: 3, Maximum: 8 :type column_count: int, optional :exception AssertionError: when something is wrong with the arguments or no rows were added to the dialog. """ try: return self._show( on_chosen=on_chosen, sim_info=sim_info, should_show_names=should_show_names, hide_row_descriptions=hide_row_descriptions, column_count=column_count ) except Exception as ex: CommonExceptionHandler.log_exception(self.mod_identity.name, 'show', exception=ex)
def setup_asm_default(self, asm: NativeAsm, *args, **kwargs) -> bool: """setup_asm_default(asm, *args, **kwargs) A function that occurs when setting up the Animation State Machine. :param asm: An instance of the Animation State Machine :type asm: NativeAsm :return: True, if the ASM was setup properly. False, if not. :rtype: bool """ try: result = self._setup_asm_default(self.sim, self.target, asm, *args, **kwargs) if result is not None: return result except Exception as ex: CommonExceptionHandler.log_exception( self.mod_identity.name, 'Error occurred while running interaction \'{}\' setup_asm_default.' .format(self.__class__.__name__), exception=ex) return super().setup_asm_default(asm, *args, **kwargs)
def safe_run(mod_identity: CommonModIdentity, primary_function: Callable[..., Any], fallback_function: Callable[..., Any], *args: Any, **kwargs: Any) -> Any: """safe_run(mod_identity, primary_function, fallback_function, *args, **kwargs) Safely run a function, if the primary function throws an exception, the fallback function will be run instead. :param mod_identity: The identity of the mod running a function safely. :type mod_identity: CommonModIdentity :param primary_function: The primary function to safely run. :type primary_function: Callable[..., Any] :param fallback_function: A function called when the primary function throws an exception. :type fallback_function: Callable[..., Any] :param args: Arguments to pass to both the primary function and fallback function. :type args: Any :param kwargs: Keyword Arguments to pass to both the primary function and fallback function. :type kwargs: Any :return: The result of either the primary function or the fallback function if the primary threw an exception. :rtype: Any """ try: if primary_function is None: if fallback_function is None: return return fallback_function(*args, **kwargs) return primary_function(*args, **kwargs) except Exception as ex: # noinspection PyBroadException try: from sims4communitylib.exceptions.common_exceptions_handler import CommonExceptionHandler CommonExceptionHandler.log_exception(mod_identity, 'Error occurred while running \'{}\'' .format(primary_function.__name__), exception=ex) except Exception: pass # noinspection PyBroadException try: if fallback_function is None: return return fallback_function(*args, **kwargs) except: pass
def load_from_file(file_path: str, buffering: int=1, encoding: str= 'utf-8') -> Union[Any, None]: """load_from_file(file_path, buffering=1, encoding='utf-8') Deserialize an object from a JSON file. :param file_path: The file to read from. :type: file_path: str :param buffering: See the built-in python :func:`~open` function documentation for more details. :type buffering: int, optional :param encoding: See the built-in python :func:`~open` function documentation for more details. :type encoding: str, optional :return: The contents of the file as an object or None if an error occurred. :rtype: Union[Any, None] """ file_contents: str = CommonIOUtils.load_from_file(file_path, buffering=buffering, encoding=encoding) if file_contents is None: return None try: return json.loads(file_contents) except Exception as ex: CommonExceptionHandler.log_exception(ModInfo.get_identity().name, 'Error occurred while reading JSON from file \'{}\''.format(file_path), exception=ex) return None
def _common_remove_trait(trait_id: int=None, target_sim_id: int=None, _connection: int=None): output = CheatOutput(_connection) if trait_id is None: output('Missing trait_id') return if target_sim_id is None: output('No Target specified, using the Active Sim.') target_sim_info = CommonSimUtils.get_active_sim_info() else: target_sim_info = CommonSimUtils.get_sim_info(target_sim_id) if target_sim_info is None: output('No target Sim found with id {}'.format(target_sim_id)) return try: output('Attempting to remove trait {} from Sim {}'.format(trait_id, CommonSimNameUtils.get_full_name(target_sim_info))) if CommonTraitUtils.remove_trait(target_sim_info, trait_id): output('Successfully removed trait.') else: output('Failed to remove trait.') except Exception as ex: CommonExceptionHandler.log_exception(ModInfo.get_identity(), 'Failed to remove trait {} from Sim {}'.format(trait_id, CommonSimNameUtils.get_full_name(target_sim_info)), exception=ex) output('Done')
def spawn_sim(sim_info: SimInfo, location: Vector3) -> bool: """spawn_sim(sim_info, location) Spawn a Sim. :param sim_info: The Sim to Spawn. :type sim_info: SimInfo :param location: The location to spawn the Sim at. :type location: Vector3 :return: True, if the Sim was spawned successfully. False, if not. :rtype: bool """ try: SimSpawner.spawn_sim(sim_info, sim_location=location) except Exception as ex: CommonExceptionHandler.log_exception( ModInfo.get_identity(), 'Failed to spawn Sim with SimInfo \'{}\' at location \'{}\'.'. format(sim_info, location), exception=ex) return False return True