def _Setup () -> None: for mod in Mods.GetAllMods(): # type: Mods.Mod modLoader = _Loader(mod) # type: _Loader modLoader.GetInformation() registeredMods = "" # type: str for mod in Mods.GetAllMods(): # type: Mods.Mod if not mod.ReadInformation: continue if registeredMods != "": registeredMods += "\n" versionString = str(mod.Version) if versionString == mod.VersionDisplay: registeredMods += "%s, v%s" % (mod.Namespace, versionString) else: registeredMods += "%s, v%s (%s)" % (mod.Namespace, versionString, mod.VersionDisplay) Debug.Log("Registered mods:\n" + registeredMods, This.Mod.Namespace, Debug.LogLevels.Info, group = This.Mod.Namespace, owner = __name__) _CheckInstallation() LoadingEvents.ModLoadedEvent += _ModLoadedCallback atexit.register(_OnExitCallback) _PatchOnLoadingScreenAnimationFinished()
def CanShow(self, shownPromotions: typing.List[str]) -> bool: if self.Text is None: return False if self.TargetsType == _FilterTypes.Whitelist: validGame = False # type: bool for promotionTarget in self.Targets: # type: str if promotionTarget.lower() == "s4": validGame = True if not validGame: return False else: for promotionTarget in self.Targets: # type: str if promotionTarget.lower() == "s4": return False if self.ModsType == _FilterTypes.Whitelist: validMods = True # type: bool for promotionMod in self.Mods: # type: str if not Mods.IsInstalled(promotionMod): validMods = False if not validMods: return False else: for promotionMod in self.Mods: # type: str if Mods.IsInstalled(promotionMod): return False if self.Rating == Mods.Rating.NSFW: validRating = False for mod in Mods.GetAllMods(): # type: Mods.Mod if mod.Rating == Mods.Rating.NSFW: validRating = True if not validRating: return False identifierLower = self.Identifier.lower() # type: str for shownPromotion in shownPromotions: # type: str if identifierLower == shownPromotion.lower(): return False return True
def _UpdateDistribution (self, informationDictionary: dict) -> bool: informationKey = "Distribution" # type: str try: distributionData = informationDictionary.get(informationKey, None) # type: typing.Optional[typing.Dict[str, dict]] if distributionData is None: return True if not isinstance(distributionData, dict) and distributionData is not None: raise Exceptions.IncorrectTypeException(distributionData, "Root[%s]" % informationKey, (dict, None)) def GetStringValue (targetKey: str) -> typing.Optional[str]: targetValue = distributionData.get(targetKey, None) # type: typing.Optional[str] if not isinstance(targetValue, str) and targetValue is not None: raise Exceptions.IncorrectTypeException(targetValue, "Root[%s][%s]" % (informationKey, targetKey), (str, None)) return targetValue updatesController = GetStringValue("UpdatesController") # type: typing.Optional[str] updatesFileURL = GetStringValue("UpdatesFileURL") # type: typing.Optional[str] downloadURL = GetStringValue("DownloadURL") # type: typing.Optional[str] previewDownloadURL = GetStringValue("PreviewDownloadURL") # type: typing.Optional[str] self.Mod.Distribution = Mods.Distribution(updatesController, updatesFileURL, downloadURL, previewDownloadURL) return True except Exception: Debug.Log("Failed to read mod information file value '%s' for '%s'." % (informationKey, self.Mod.Namespace), This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__) return False
def PatchedOnLoadingScreenAnimationFinished (*args, **kwargs): global _failedLoadingMods, _invalidSetupMods, _cascadeFailureMods, _showedNotLoadedFailureNotification originalFunction(*args, **kwargs) from sims4 import log try: if len(_failedLoadingMods) != 0: _WarnOfLoadingFailure() _failedLoadingMods = list() if len(_invalidSetupMods) != 0: _WarnOfInvalidSetup() _invalidSetupMods = list() if len(_cascadeFailureMods) != 0: _WarnOfCascadeFailure() _cascadeFailureMods = list() if not _showedNotLoadedFailureNotification: for mod in Mods.GetAllMods(): if not mod.IsLoaded() and mod.IsLoadable(This.Mod.Namespace): _WarnOfNotLoadedFailure() _showedNotLoadedFailureNotification = True break except Exception as e: log.exception(This.Mod.Namespace, "Failed to show loading failure dialogs.", exc = e, owner = __name__)
def OnLoadingScreenAnimationFinished(cls, zoneReference: zone.Zone) -> None: global _updatesTicker, _promotionsTicker if not Mods.IsInstalled("NeonOcean.Main") and not Mods.IsInstalled( "NeonOcean.S4.Main"): if _updatesTicker is None: startUpdatesDistributionTimer = Timer.Timer( 15, _StartUpdatesDistributionThread) # type: Timer.Timer startUpdatesDistributionTimer.start() if _promotionsTicker is None: startPromotionsDistributionTimer = Timer.Timer( 20, _StartPromotionsDistributionThread) # type: Timer.Timer startPromotionsDistributionTimer.start()
def _UpdateCompatibility (self, informationDictionary: dict) -> bool: informationKey = "Compatibility" # type: str compatibilityLowestVersionKey = "LowestVersion" # type: str compatibilityHighestVersionKey = "HighestVersion" # type: str try: compatibility = informationDictionary.get(informationKey, dict()) # type: typing.Dict[str, dict] if not isinstance(compatibility, dict): raise Exceptions.IncorrectTypeException(compatibility, "Root[%s]" % informationKey, (dict,)) for namespace, modDictionary in compatibility.items(): # type: str, typing.Dict[str, str] if not isinstance(namespace, str): raise Exceptions.IncorrectTypeException(namespace, "Root[%s]<Key>" % informationKey, (str,)) if namespace == self.Mod.Namespace: raise Exception("A mod cannot have compatibility information for its self.") if not isinstance(modDictionary, dict): raise Exceptions.IncorrectTypeException(modDictionary, "Root[%s][%s]" % (informationKey, namespace), (dict,)) if not compatibilityLowestVersionKey in modDictionary: lowestVersion = None else: lowestVersion = modDictionary[compatibilityLowestVersionKey] if not isinstance(lowestVersion, str) and lowestVersion is not None: raise Exceptions.IncorrectTypeException(lowestVersion, "Root[%s][%s][%s]" % (informationKey, namespace, compatibilityLowestVersionKey), (str, "None")) if not compatibilityHighestVersionKey in modDictionary: highestVersion = None else: highestVersion = modDictionary[compatibilityHighestVersionKey] if not isinstance(highestVersion, str) and highestVersion is not None: raise Exceptions.IncorrectTypeException(highestVersion, "Root[%s][%s][%s]" % (informationKey, namespace, compatibilityHighestVersionKey), (str, "None")) lowestVersionObject = Version.Version(versionString = lowestVersion) if lowestVersion is not None else None # type: typing.Optional[Version.Version] highestVersionObject = Version.Version(versionString = highestVersion) if highestVersion is not None else None # type: typing.Optional[Version.Version] self.Mod.Compatibility.append(Mods.Compatibility(namespace, lowestVersionObject, highestVersionObject)) return True except Exception: Debug.Log("Failed to read mod information file value '%s' for '%s'." % (informationKey, self.Mod.Namespace), This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__) return False
def _ResetInformation (self) -> None: self.Mod.Author = "" self.Mod.Version = Version.Version() self.Mod.VersionDisplay = "0.0.0" self.Mod.Distribution = Mods.Distribution(None, None, None, None) self.Mod.Rating = Mods.Rating.Normal self.Mod.ScriptPaths = list() self.Mod.Modules = list() self.Mod.RequiredMods = set() self.Mod.IncompatibleMods = set() self.Mod.LoadAfter = set() self.Mod.LoadBefore = set() self.Mod.Compatibility = list() self.Mod.BuildDate = None self.Mod.BuildGameVersion = None self.Mod.Additional = dict()
def _WarnOfNotLoadedFailure () -> None: badMods = "" for mod in Mods.GetAllMods(): # type: Mods.Mod if not mod.IsLoaded() and mod.IsLoadable(This.Mod.Namespace): if badMods != "": badMods += "\n" if mod.ReadInformation: badMods += mod.Namespace + ": v" + str(mod.Version) else: badMods += mod.Namespace Debug.Log("The following mods have not been loaded, even though they should have been.\n" + badMods, This.Mod.Namespace, Debug.LogLevels.Error, group = This.Mod.Namespace, owner = __name__) notificationArguments = { "title": NotLoadedFailureNotificationTitle.GetCallableLocalizationString(), "text": NotLoadedFailureNotificationText.GetCallableLocalizationString(badMods), "expand_behavior": ui_dialog_notification.UiDialogNotification.UiDialogNotificationExpandBehavior.FORCE_EXPAND, "urgency": ui_dialog_notification.UiDialogNotification.UiDialogNotificationUrgency.URGENT } # type: typing.Dict[str, ...] Notifications.ShowNotification(queue = True, **notificationArguments)
def _WarnOfCascadeFailure () -> None: badMods = "" for modNamespace in _cascadeFailureMods: # type: str mod = Mods.GetMod(modNamespace) # type: Mods.Mod if badMods != "": badMods += "\n" if mod.ReadInformation: badMods += mod.Namespace + ": v" + str(mod.Version) else: badMods += mod.Namespace Debug.Log("The following mods could not be loaded due to failures in a mod they require.\n" + badMods, This.Mod.Namespace, Debug.LogLevels.Error, group = This.Mod.Namespace, owner = __name__) notificationArguments = { "title": CascadeFailureNotificationTitle.GetCallableLocalizationString(), "text": CascadeFailureNotificationText.GetCallableLocalizationString(badMods), "expand_behavior": ui_dialog_notification.UiDialogNotification.UiDialogNotificationExpandBehavior.FORCE_EXPAND, "urgency": ui_dialog_notification.UiDialogNotification.UiDialogNotificationUrgency.URGENT } # type: typing.Dict[str, ...] Notifications.ShowNotification(queue = True, **notificationArguments)
from __future__ import annotations from __future__ import annotations from NeonOcean.S4.Order import Mods try: Mod = Mods.GetMod("NeonOcean.S4.Order") # type: Mods.Mod except Exception as e: raise Exception("Cannot find self in mod list.") from e
def _CheckUpdates() -> None: previewAvailableMods = list( ) # type: typing.List[typing.Tuple[Mods.Mod, Version.Version]] releaseAvailableMods = list( ) # type: typing.List[typing.Tuple[Mods.Mod, Version.Version]] distributeUpdates = Settings.CheckForUpdates.Get() # type: bool distributePreviewUpdates = Settings.CheckForPreviewUpdates.Get( ) # type: bool if not distributeUpdates: return latestURL = _distributionURL + "/mods/latest.json" # type: str try: latestDictionary = _ReadVersionFile( latestURL ) # type: typing.Dict[str, typing.Dict[str, Version.Version]] except Exception: Debug.Log("Failed to get mod versions.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) return for mod in Mods.GetAllMods(): # type: Mods.Mod if not mod.ReadInformation: continue if mod.Distribution.UpdatesController is None: continue if mod.Distribution.UpdatesController != Information.RootNamespace: continue modShownReleaseVersions = _shownReleaseVersions.get(mod) # type: list if modShownReleaseVersions is None: modShownReleaseVersions = list() _shownReleaseVersions[mod] = modShownReleaseVersions modShownPreviewVersions = _shownPreviewVersions.get(mod) # type: list if modShownPreviewVersions is None: modShownPreviewVersions = list() _shownPreviewVersions[mod] = modShownPreviewVersions try: modVersions = latestDictionary.get(mod.Namespace) # type: Version if modVersions is None: Debug.Log("Missing version data for '" + mod.Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) continue releaseVersion = modVersions.get( "Release") # type: Version.Version if releaseVersion is None: Debug.Log("Missing release version for '" + mod.Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) releaseVersion = Version.Version() if distributePreviewUpdates: previewVersion = modVersions.get( "Preview") # type: Version.Version if previewVersion is None: Debug.Log("Missing preview version for '" + mod.Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) previewVersion = Version.Version() if previewVersion <= releaseVersion: if not releaseVersion in modShownReleaseVersions: if mod.Version < releaseVersion: releaseAvailableMods.append((mod, releaseVersion)) continue else: if not previewVersion in modShownPreviewVersions: if mod.Version < previewVersion: previewAvailableMods.append((mod, previewVersion)) continue else: if not releaseVersion in modShownReleaseVersions: if mod.Version < releaseVersion: releaseAvailableMods.append((mod, releaseVersion)) continue except Exception: Debug.Log("Failed to get update information for '" + mod.Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) for releaseTuple in releaseAvailableMods: # type: typing.Tuple[Mods.Mod, Version.Version] try: _ShowReleaseUpdateNotification(releaseTuple[0], releaseTuple[1]) except Exception: Debug.Log("Failed to show release update notification for '" + releaseTuple[0].Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__) for previewTuple in previewAvailableMods: # type: typing.Tuple[Mods.Mod, Version.Version] try: _ShowPreviewUpdateNotification(previewTuple[0], previewTuple[1]) except Exception: Debug.Log("Failed to show release update notification for '" + previewTuple[0].Namespace + "'.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__)