static void AddRef(PrefabInfo info, string fullName, CustomAssetMetaData.Type type) { if (info == null) { if (type == CustomAssetMetaData.Type.Prop && instance.skipProps && SkippedProps.Contains(fullName)) { return; } // The referenced asset is missing. Package.Asset container = FindContainer(); if (container != null) { AssetReport.instance.AddReference(container, fullName, type); } } else if (info.m_isCustomContent) { string r = info.name; Package.Asset container = FindContainer(); if (!string.IsNullOrEmpty(r) && container != null) { string packageName = container.package.packageName; int i = r.IndexOf('.'); string r2; if (i >= 0 && (i != packageName.Length || !r.StartsWith(packageName)) && (r2 = FindMain(r)) != null) { AssetReport.instance.AddReference(container, r2, type); } } } }
// For sub-buildings, name may be package.assetname. static T Get <T>(Package package, string fullName, string name, bool tryName) where T : PrefabInfo { T info = FindLoaded <T>(fullName); if (tryName && info == null) { info = FindLoaded <T>(name); } if (info == null) { Package.Asset data = package.Find(name); if (tryName && data == null) { data = FindAsset(name); // yes, name } if (data != null) { fullName = data.fullName; } else if (name.IndexOf('.') >= 0) { fullName = name; } if (Load(ref fullName, data)) { info = FindLoaded <T>(fullName); } } return(info); }
static bool Load(ref string fullName, Package.Asset data) { if (data != null) { try { fullName = data.fullName; // There is at least one asset (411236307) on the workshop that wants to include itself. Asset Editor quite // certainly no longer accepts that but in the early days, it was possible. if (fullName != AssetLoader.instance.Current.fullName && !AssetLoader.instance.HasFailed(fullName)) { AssetLoader.instance.LoadImpl(data); return(true); } } catch (Exception e) { AssetLoader.instance.AssetFailed(fullName, e); } } else { AssetLoader.instance.NotFound(fullName); } return(false); }
void AddToQueue(List <Package.Asset>[] queues, CustomAssetMetaData meta, int offset, bool dontSpawn) { Package.Asset assetRef = meta.assetRef; if (assetRef == null) { Util.DebugPrint(meta.name, " Warning : NULL asset"); return; } CustomAssetMetaData.Type type = meta.type; Package package = assetRef.package; string fullName = type < CustomAssetMetaData.Type.RoadElevation ? assetRef.fullName : PillarOrElevationName(package.packageName, assetRef.name); if (!IsDuplicate(fullName, allLoads[(int)type], package)) { queues[loadQueueIndex[(int)type] + offset].Add(assetRef); metaTypes[assetRef.fullName] = type; if (dontSpawn) { dontSpawnNormally.Add(fullName); } if (type == CustomAssetMetaData.Type.Citizen) { citizenMetaDatas[fullName] = meta; } } }
internal void NotFound(string fullName) { if (fullName != null) { if (reportAssets) { Package.Asset refBy = Current; if (refBy != null) { AssetReport.instance.NotFound(fullName, refBy.fullName); } else { AssetReport.instance.NotFound(fullName); } } if (failedAssets.Add(fullName)) { Util.DebugPrint("Asset not found:", fullName); DualProfilerSource profiler = LoadingScreen.instance.DualSource; profiler?.CustomAssetNotFound(ShorterAssetName(fullName)); } } }
public static void LoadTemplateAsset(GameObject gameObject, Package.Asset asset) { if (gameObject.GetComponent <MarkingInfo>() is not MarkingInfo markingInfo) { return; } Mod.Logger.Debug($"Start load template asset \"{asset.fullName}\" from {asset.package.packagePath}"); try { var templateConfig = XmlExtension.Parse(markingInfo.data); if (TemplateAsset.FromPackage(templateConfig, asset, out TemplateAsset templateAsset)) { templateAsset.Template.Manager.AddTemplate(templateAsset.Template); Mod.Logger.Debug($"Template asset loaded: {templateAsset} ({templateAsset.Flags})"); } else { Mod.Logger.Error($"Could not load template asset"); } } catch (Exception error) { Mod.Logger.Error($"Could not load template asset", error); } }
public void LoadSavedGame2(Package.Asset savedGame) { LogCalled(); AssertNotNull(savedGame, "could not find save"); var metaData = savedGame?.Instantiate <SaveGameMetaData>(); AssertNotNull(metaData, "metadata"); AssertNotNull(metaData.assetRef, "assetRef"); var package = savedGame.package ?? metaData.assetRef.package; AssertNotNull(package, "package"); PrintModsInfo(metaData.mods); SimulationMetaData ngs = new SimulationMetaData { m_CityName = metaData.cityName, m_updateMode = SimulationManager.UpdateMode.LoadGame, }; if (package.GetPublishedFileID() != PublishedFileId.invalid) { ngs.m_disableAchievements = MetaBool.True; } UpdateTheme(metaData.mapThemeRef, ngs); Log.Info($"Loading new game from " + $"map:{ngs.m_CityName} " + $"assetName:{savedGame.name} " + $"filePath:{package.packagePath}) " + $"theme={(ngs.m_MapThemeMetaData?.name).ToSTR()} " + $"LHT:{ngs.m_invertTraffic}", true); LoadGame(metaData, ngs); }
/// <summary> /// Load the world byte array sent by the server /// </summary> public static void LoadLevel(byte[] world) { Log.Info($"Preparing to load world (of size {world.Length})..."); // Load the package Package package = new Package(SYNC_NAME, world); // Ensure that the LoadingManager is ready. // Don't know if thats really necessary but doesn't hurt either. - root#0042 Singleton <LoadingManager> .Ensure(); // Get the meta data Package.Asset asset = package.Find(package.packageMainAsset); SaveGameMetaData metaData = asset.Instantiate <SaveGameMetaData>(); // Build the simulation SimulationMetaData simulation = new SimulationMetaData() { m_CityName = metaData.cityName, m_updateMode = SimulationManager.UpdateMode.LoadGame, m_environment = UIView.GetAView().panelsLibrary.Get <LoadPanel>("LoadPanel").m_forceEnvironment }; // Load the level Log.Info("Telling the loading manager to load the level"); Singleton <LoadingManager> .instance.LoadLevel(metaData.assetRef, "Game", "InGame", simulation, false); }
public void LoadLut(string lut) { if (string.IsNullOrEmpty(lut)) { return; } Texture3DWrapper wrapper = BuiltInLuts.FirstOrDefault(t3d => t3d.name == lut); int index = wrapper != null?Array.IndexOf(BuiltInLuts, wrapper) : -1; if (index != -1) { ColorCorrectionManager.instance.currentSelection = index + 1; return; } var userLuts = UserLuts; Package.Asset asset = userLuts.Find(l => l.name == lut); index = asset != null?UserLuts.IndexOf(asset) : -1; if (index != -1) { ColorCorrectionManager.instance.currentSelection = index + BuiltInLuts.Length + 1; } OptionsGraphicsPanel ogp = FindObjectOfType <OptionsGraphicsPanel>(); if (ogp == null) { return; } ogp.SendMessage("RefreshColorCorrectionLUTs"); }
UserAssetData GetUserAssetData(Package.Asset assetRef, out string name) { if (!metaDatas.TryGetValue(assetRef.fullName, out SomeMetaData some)) { ReadMetaData(assetRef.package); metaDatas.TryGetValue(assetRef.fullName, out some); } if (some.userDataRef != null) { try { UserAssetData uad = AssetDeserializer.Instantiate(some.userDataRef) as UserAssetData; if (uad == null) { uad = new UserAssetData(); } name = some.name; return(uad); } catch (Exception) { Util.DebugPrint("!Cannot resolve UserAssetData for", assetRef.fullName); } } name = string.Empty; return(null); }
internal void AssetFailed(Package.Asset assetRef, Package p, Exception e) { string fullName = assetRef?.fullName; if (fullName == null) { assetRef = FindMainAssetRef(p); fullName = assetRef?.fullName; } if (fullName != null && LevelLoader.instance.AddFailed(fullName)) { if (reportAssets) { AssetReport.instance.AssetFailed(assetRef); } Util.DebugPrint("Asset failed:", fullName); DualProfilerSource profiler = LoadingScreen.instance.DualSource; profiler?.CustomAssetFailed(ShortAssetName(fullName)); } if (e != null) { UnityEngine.Debug.LogException(e); } }
void AddToQueue(List <Package.Asset>[] queues, CustomAssetMetaData meta, CustomAssetMetaData.Type type, int offset, bool dontSpawn) { Package.Asset assetRef = meta.assetRef; if (assetRef == null) { Util.DebugPrint(meta.name, " Error : NULL asset"); return; } if (assetRef.fullName == null) { Util.DebugPrint(meta.name, " Warning : NULL asset name"); } Package package = assetRef.package; string fullName = type < CustomAssetMetaData.Type.RoadElevation ? assetRef.fullName : PillarOrElevationName(package.packageName, assetRef.name); if (!IsDuplicate(assetRef, type, queues)) { int index = Math.Max(loadQueueIndex[(int)type] + offset, 0); queues[index].Add(assetRef); metaDatas[assetRef.fullName] = new SomeMetaData(meta.userDataRef, meta.name, type); if (dontSpawn) { dontSpawnNormally.Add(fullName); } if (type == CustomAssetMetaData.Type.Citizen) { citizenMetaDatas[fullName] = meta; } } }
internal void PropTreeTrailerImpl(string packageName, Package.Asset data) { try { string name = AssetName(data.name); LoadingManager.instance.m_loadingProfilerCustomAsset.BeginLoading(name); // CODebugBase<LogChannel>.Log(LogChannel.Modding, string.Concat("Loading custom asset ", assetMetaData.name, " from ", asset)); GameObject go = data.Instantiate <GameObject>(); go.name = packageName + "." + go.name; go.SetActive(false); PrefabInfo info = go.GetComponent <PrefabInfo>(); info.m_isCustomContent = true; if (info.m_Atlas != null && info.m_InfoTooltipThumbnail != null && info.m_InfoTooltipThumbnail != string.Empty && info.m_Atlas[info.m_InfoTooltipThumbnail] != null) { info.m_InfoTooltipAtlas = info.m_Atlas; } PropInfo pi = go.GetComponent <PropInfo>(); if (pi != null) { if (pi.m_lodObject != null) { pi.m_lodObject.SetActive(false); } PrefabCollection <PropInfo> .InitializePrefabs("Custom Assets", pi, null); propsCount++; } TreeInfo ti = go.GetComponent <TreeInfo>(); if (ti != null) { PrefabCollection <TreeInfo> .InitializePrefabs("Custom Assets", ti, null); treeCount++; } // Trailers, this way. VehicleInfo vi = go.GetComponent <VehicleInfo>(); if (vi != null) { PrefabCollection <VehicleInfo> .InitializePrefabs("Custom Assets", vi, null); if (vi.m_lodObject != null) { vi.m_lodObject.SetActive(false); } } } finally { LoadingManager.instance.m_loadingProfilerCustomAsset.EndLoading(); } }
bool PropTreeTrailer(Package.Asset asset) { CustomAssetMetaData assetMetaData = null; try { bool wantBecauseEnabled = loadEnabled && IsEnabled(asset); if (!wantBecauseEnabled && !(loadUsed && refs.GotPropTreeTrailerPackage(asset.package.packageName))) { return(false); } assetMetaData = asset.Instantiate <CustomAssetMetaData>(); if (assetMetaData.type == CustomAssetMetaData.Type.Building || assetMetaData.type == CustomAssetMetaData.Type.Vehicle || assetMetaData.type == CustomAssetMetaData.Type.Unknown || (AssetImporterAssetTemplate.GetAssetDLCMask(assetMetaData) & notMask) != 0) { return(false); } if (wantBecauseEnabled || loadUsed && refs.GotPropTreeAsset(assetMetaData.assetRef.fullName) || loadUsed && assetMetaData.type == CustomAssetMetaData.Type.Trailer && refs.GotTrailerAsset(assetMetaData.assetRef.fullName)) { PropTreeTrailerImpl(asset.package.packageName, assetMetaData.assetRef); } } catch (Exception ex) { Failed(assetMetaData?.assetRef, ex); // CODebugBase<LogChannel>.Warn(LogChannel.Modding, string.Concat(new object[] { ex.GetType(), ": Loading custom asset failed[", asset, "]\n", ex.Message })); } return(true); }
void DeserializeTextObj(Package.Asset asset, byte[] bytes, int index) { TextObj to; using (MemStream stream = new MemStream(bytes, 0)) using (MemReader reader = new MemReader(stream)) { Type t = DeserializeHeader(reader); if (t != typeof(Texture2D) && t != typeof(Image)) { throw new IOException("Asset " + asset.fullName + " should be Texture2D or Image"); } string name = reader.ReadString(); bool linear = reader.ReadBoolean(); int anisoLevel = asset.package.version >= 6 ? reader.ReadInt32() : 1; int count = reader.ReadInt32(); Image image = new Image(reader.ReadBytes(count)); byte[] pix = image.GetAllPixels(); to = new TextObj { name = name, pixels = pix, width = image.width, height = image.height, anisoLevel = anisoLevel, format = image.format, mipmap = image.mipmapCount > 1, linear = linear }; // image.Clear(); TODO test image = null; } lock (mutex) { data[asset.checksum] = new KeyValuePair <int, object>(index, to); } }
public static void ScanPrefabsFolders <T>(Dictionary <string, Action <FileStream, T> > actions) where T : PrefabInfo { var list = new List <string>(); ForEachLoadedPrefab <T>((loaded) => { Package.Asset asset = PackageManager.FindAssetByName(loaded.name); if (!(asset == null) && !(asset.package == null)) { string packagePath = asset.package.packagePath; if (packagePath != null) { foreach (string filenameToSearch in actions.Keys) { string filePath = Path.Combine(Path.GetDirectoryName(packagePath), filenameToSearch); if (!list.Contains(filePath)) { list.Add(filePath); if (File.Exists(filePath)) { using FileStream stream = File.OpenRead(filePath); actions[filenameToSearch](stream, loaded); } } } } } }); }
public void OnLoad() { if ((!SavePanel.isSaving && Singleton <LoadingManager> .exists) && !Singleton <LoadingManager> .instance.m_currentlyLoading) { ServerSettings.Name = m_serverNameTextbox.text; ServerSettings.Port = int.Parse(m_serverPortTextbox.text); ServerSettings.Private = m_serverPrivateCheckbox.isChecked; ServerSettings.IsHosting = true; base.CloseEverything(); m_LastSaveName = base.GetListingName(this.m_SaveList.selectedIndex); SavePanel.lastLoadedName = m_LastSaveName; SaveGameMetaData listingMetaData = base.GetListingMetaData(this.m_SaveList.selectedIndex); base.PrintModsInfo(listingMetaData); Package.Asset listingData = base.GetListingData(this.m_SaveList.selectedIndex); SavePanel.lastCloudSetting = (listingData.package != null) && PackageManager.IsSteamCloudPath(listingData.package.packagePath); SimulationMetaData ngs = new SimulationMetaData { m_CityName = listingMetaData.cityName, m_updateMode = SimulationManager.UpdateMode.LoadGame, m_environment = this.m_forceEnvironment }; if ((Singleton <PluginManager> .instance.enabledModCount > 0) || ((listingData.package != null) && (listingData.package.GetPublishedFileID() != PublishedFileId.invalid))) { ngs.m_disableAchievements = SimulationMetaData.MetaBool.True; } Singleton <LoadingManager> .instance.LoadLevel(listingData, "Game", "InGame", ngs); UIView.library.Hide(base.GetType().Name, 1); Debug.Log("menuid " + listingData.package.GetPublishedFileID()); } }
public static void ScanPrefabsFoldersDirectory <T>(string directoryToFind, Action <string, T> action) where T : PrefabInfo { var list = new List <string>(); ForEachLoadedPrefab <T>((loaded) => { Package.Asset asset = PackageManager.FindAssetByName(loaded.name); if (!(asset == null) && !(asset.package == null)) { string packagePath = asset.package.packagePath; if (packagePath != null) { string filePath = Path.Combine(Path.GetDirectoryName(packagePath), directoryToFind); if (!list.Contains(filePath)) { list.Add(filePath); LogUtils.DoLog("DIRECTORY TO FIND: " + filePath); if (Directory.Exists(filePath)) { action(filePath, loaded); } } } } }); }
bool Used(string fullName, HashSet <string> packagePaths) { Package.Asset asset = CustomDeserializer.FindAsset(fullName); string path = asset?.package.packagePath; return(path != null && packagePaths.Contains(path)); }
private void StartNewGameRoutine() { //begin mod var m_MapName = this.Find <UITextField>("MapName"); var m_FileList = this.Find <UIListBox>("MapList"); //end mod SimulationMetaData ngs = new SimulationMetaData() { m_CityName = m_MapName.text, m_gameInstanceIdentifier = Guid.NewGuid().ToString(), m_invertTraffic = !this.Find <UICheckBox>("InvertTraffic").isChecked ? SimulationMetaData.MetaBool.False : SimulationMetaData.MetaBool.True, m_disableAchievements = Singleton <PluginManager> .instance.enabledModCount <= 0 ? SimulationMetaData.MetaBool.False : SimulationMetaData.MetaBool.True, m_currentDateTime = DateTime.Now, m_newGameAppVersion = 159507472, m_updateMode = SimulationManager.UpdateMode.NewGameFromMap }; //begin mod ngs.m_environment = m_forceEnvironment; //end mod MapMetaData listingMetaData = this.GetListingMetaData(m_FileList.selectedIndex); if (listingMetaData.mapThemeRef != null) { Package.Asset assetByName = PackageManager.FindAssetByName(listingMetaData.mapThemeRef); if (assetByName != (Package.Asset)null) { ngs.m_MapThemeMetaData = assetByName.Instantiate <MapThemeMetaData>(); ngs.m_MapThemeMetaData.SetSelfRef(assetByName); } } Singleton <LoadingManager> .instance.LoadLevel(this.GetListingData(m_FileList.selectedIndex), "Game", "InGame", ngs); UIView.library.Hide(this.GetType().Name, 1); }
public void LoadAssetEditor(bool load = true, bool lht = false, bool lsm = true) { LogCalled(); //Patches.ForceLSMPatch.ForceLSM = lsm; var mode = load ? SimulationManager.UpdateMode.LoadAsset : SimulationManager.UpdateMode.NewAsset; Package.Asset theme = GetDefaultTheme(); AssertNotNull(theme, "theme not found"); var themeMetaData = theme.Instantiate <SystemMapMetaData>(); AssertNotNull(themeMetaData, "themeMetaData"); SimulationMetaData ngs = new SimulationMetaData { m_gameInstanceIdentifier = Guid.NewGuid().ToString(), m_WorkshopPublishedFileId = PublishedFileId.invalid, m_updateMode = mode, //m_MapThemeMetaData = themeMetaData, m_invertTraffic = lht ? MetaBool.True : MetaBool.False, }; Singleton <LoadingManager> .instance.LoadLevel(themeMetaData.assetRef, "AssetEditor", "InAssetEditor", ngs, false); }
public static void Postfix(Package.Asset __instance, ref object __result) { if (!Mod.IsInGame) { return; } if (!(__result is GameObject) || __instance.package == null) { return; } var prefab = ((GameObject)__result).GetComponent <BuildingInfo>(); if (prefab == null || prefab.name == null) { return; } var replacementPrefab = AssetAnimationLoader.instance.ProcessBuildingAsset(__instance.package, prefab); if (replacementPrefab != null) { __result = replacementPrefab.gameObject; } }
internal CustomAssetMetaData.Type GetMetaType(Package.Asset assetRef) { if (metaTypes.TryGetValue(assetRef.fullName, out CustomAssetMetaData.Type type)) { return(type); } try { foreach (Package.Asset asset in assetRef.package.FilterAssets(UserAssetType.CustomAssetMetaData)) { CustomAssetMetaData meta = AssetDeserializer.Instantiate(asset) as CustomAssetMetaData; if (meta?.assetRef != null) { metaTypes[meta.assetRef.fullName] = meta.type; } } if (metaTypes.TryGetValue(assetRef.fullName, out type)) { return(type); } } catch (Exception) { } Util.DebugPrint("Cannot resolve metatype:", assetRef.fullName); return(CustomAssetMetaData.Type.Unknown); }
// For sub-buildings, name may be package.assetname. static T Get <T>(Package package, string fullName, string name, bool tryName) where T : PrefabInfo { T info = PrefabCollection <T> .FindLoaded(fullName); if (info == null && tryName) { info = PrefabCollection <T> .FindLoaded(name); } if (info == null) { Package.Asset data = package.Find(name); if (data == null && tryName) { data = UsedAssets.FindAsset(name); // yes, name } if (data != null) { fullName = data.fullName; } else if (name.Contains(".")) { fullName = name; } if (AssetLoader.instance.LoadAsset(fullName, data)) { info = PrefabCollection <T> .FindLoaded(fullName); } } return(info); }
// For nets and pillars, the reference can be to a custom asset (dotted) or a built-in asset. static T Get <T>(Package package, string name) where T : PrefabInfo { if (string.IsNullOrEmpty(name)) { return(null); } string stripName = PackageHelper.StripName(name); T info = FindLoaded <T>(package.packageName + "." + stripName); if (info == null) { Package.Asset data = package.Find(stripName); if (data != null) { string fullName = data.fullName; if (Load(ref fullName, data)) { info = FindLoaded <T>(fullName); } } else { info = Get <T>(name); } } return(info); }
public static void UpdateItemPrefix(Package.Asset ___m_TargetAsset, string ___m_ContentPath, ref string[] ___m_Tags) { if (___m_TargetAsset.type == UserAssetType.CustomAssetMetaData) { var animationBundlePath = Path.Combine(___m_ContentPath, AssetAnimationLoader.AnimationBundleFileName); if (File.Exists(animationBundlePath)) { if (!___m_Tags.Contains(AssetWorkshopTag)) { var tagList = new List <string>(___m_Tags); tagList.Add(AssetWorkshopTag); ___m_Tags = tagList.ToArray(); } } else { if (___m_Tags.Contains(AssetWorkshopTag)) { var tagList = new List <string>(___m_Tags); tagList.Remove(AssetWorkshopTag); ___m_Tags = tagList.ToArray(); } } } }
/// <summary> /// Given packagename.assetname, find the asset. Works with (fullName = asset name), too. /// </summary> internal static Package.Asset FindAsset(string fullName) { int j = fullName.IndexOf('.'); if (j > 0 && j < fullName.Length - 1) { // The fast path. Package.Asset asset = instance.FindByName(fullName.Substring(0, j), fullName.Substring(j + 1)); if (asset != null) { return(asset); } } // Fast fail. if (AssetLoader.instance.HasFailed(fullName)) { return(null); } Package.Asset[] a = Assets; // We also try the old (early 2015) naming that does not contain the package name. FindLoaded does this, too. for (int i = 0; i < a.Length; i++) { if (fullName == a[i].fullName || fullName == a[i].name) { return(a[i]); } } return(null); }
byte[] LoadAsset(FileStream fs, Package.Asset asset) { int remaining = asset.size; if (remaining > 222444000 || remaining < 0) { throw new IOException("Asset " + asset.fullName + " size: " + remaining); } fs.Position = asset.offset; byte[] bytes = new byte[remaining]; int got = 0; while (remaining > 0) { int n = fs.Read(bytes, got, remaining); if (n == 0) { throw new IOException("Unexpected end of file: " + asset.fullName); } got += n; remaining -= n; } return(bytes); }
static Package.Asset[] FilterAssets(Package.AssetType assetType) { List <Package.Asset> enabled = new List <Package.Asset>(64), notEnabled = new List <Package.Asset>(64); foreach (Package.Asset asset in PackageManager.FilterAssets(assetType)) { if (asset != null) { if (asset.isEnabled) { enabled.Add(asset); } else { notEnabled.Add(asset); } } } // Why enabled assets first? Because in duplicate name situations, I want the enabled one to get through. Package.Asset[] ret = new Package.Asset[enabled.Count + notEnabled.Count]; enabled.CopyTo(ret); notEnabled.CopyTo(ret, enabled.Count); enabled.Clear(); notEnabled.Clear(); return(ret); }
void SetupAssetDistrictStyle(Package.Asset asset) { int i; try { if (asset != null && asset.isEnabled) { DistrictStyleMetaData districtStyleMetaData = asset.Instantiate <DistrictStyleMetaData>(); if (districtStyleMetaData != null && !districtStyleMetaData.builtin) { districtStyleMetaDatas.Add(districtStyleMetaData); districtStylePackages.Add(asset.package); if (districtStyleMetaData.assets != null) { for (i = 0; i < districtStyleMetaData.assets.Length; i++) { styleBuildings.Add(districtStyleMetaData.assets[i]); } } } } } catch (Exception ex) { CODebugBase <LogChannel> .Warn(LogChannel.Modding, string.Concat(new object[] { ex.GetType(), ": Loading custom district style failed[", asset, "]\n", ex.Message })); } }