public void Dispose() { refs?.Dispose(); AssetReport.instance?.Dispose(); failedAssets.Clear(); instance = null; refs = null; failedAssets = null; }
internal static UsedAssets Create() { if (instance == null) { instance = new UsedAssets(); instance.LookupUsed(); } return(instance); }
/// <summary> /// Checks if the savegame needs any assets or prefabs not currently in memory. /// </summary> bool AnyMissingAssets() { try { return(UsedAssets.Create().AnyMissing(knownToFail)); } catch (Exception e) { UnityEngine.Debug.LogException(e); } return(true); }
/// <summary> /// Checks if the game has all required assets currently in memory. /// </summary> bool AllAssetsAvailable() { try { return(UsedAssets.Create().AllAssetsAvailable(knownFailedAssets)); } catch (Exception e) { UnityEngine.Debug.LogException(e); } return(true); }
internal void Save() { try { w = new StreamWriter(Util.GetFileName(AssetLoader.AssetName(LevelLoader.instance.cityName) + "-AssetsReport", "htm")); w.WriteLine(@"<!DOCTYPE html><html><head><meta charset=""UTF-8""><title>Assets Report</title><style>"); w.WriteLine(@"* {font-family: sans-serif;}"); w.WriteLine(@".my {display: -webkit-flex; display: flex;}"); w.WriteLine(@".my div {min-width: 30%; margin: 4px 4px 4px 20px;}"); w.WriteLine(@"</style></head><body>"); H1(AssetLoader.AssetName(LevelLoader.instance.cityName)); Para("To stop saving these files, disable the option \"Save assets report\" in Loading Screen Mod."); Para("You can safely delete this file. No-one reads it except you."); Save("Assets that failed to load", failed); Save("Assets that were not found", notFound); if (Settings.settings.loadUsed) { H1("The following custom assets were used in this city when it was saved"); UsedAssets refs = AssetLoader.instance.refs; Save("Buildings", new List <string>(refs.Buildings)); Save("Props", new List <string>(refs.Props)); Save("Trees", new List <string>(refs.Trees)); Save("Vehicles", new List <string>(refs.Vehicles)); } else { Para("Enable the option \"Load used assets\" to track missing assets."); H1("Used assets"); Para("To also list the custom assets used in this city, enable the option \"Load used assets\" in Loading Screen Mod."); } w.WriteLine(@"</body></html>"); } catch (Exception e) { UnityEngine.Debug.LogException(e); } finally { w?.Dispose(); w = null; } }
public IEnumerator LoadCustomContent() { LoadingManager.instance.m_loadingProfilerMain.BeginLoading("LoadCustomContent"); LoadingManager.instance.m_loadingProfilerCustomContent.Reset(); LoadingManager.instance.m_loadingProfilerCustomAsset.Reset(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); hasStarted = true; int i, j; DistrictStyle districtStyle; DistrictStyleMetaData districtStyleMetaData; List <DistrictStyle> districtStyles = new List <DistrictStyle>(); HashSet <string> styleBuildings = new HashSet <string>(); FastList <DistrictStyleMetaData> districtStyleMetaDatas = new FastList <DistrictStyleMetaData>(); FastList <Package> districtStylePackages = new FastList <Package>(); Package.Asset europeanStyles = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanStyleName); if (europeanStyles != null && europeanStyles.isEnabled) { districtStyle = new DistrictStyle(DistrictStyle.kEuropeanStyleName, true); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style new"), districtStyle, false); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style others"), districtStyle, true); districtStyles.Add(districtStyle); } if ((bool)typeof(LoadingManager).GetMethod("DLC", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(LoadingManager.instance, new object[] { 715190u })) { Package.Asset asset = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanSuburbiaStyleName); if (asset != null && asset.isEnabled) { districtStyle = new DistrictStyle(DistrictStyle.kEuropeanSuburbiaStyleName, true); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("Modder Pack 3"), districtStyle, false); districtStyles.Add(districtStyle); } } foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.DistrictStyleMetaData)) { try { if (asset != null && asset.isEnabled) { 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 })); } } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); if (Settings.settings.loadUsed) { UsedAssets.Create(); } lastMillis = Profiling.Millis; LoadingScreen.instance.DualSource.Add("Custom Assets"); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Calculating asset load order"); Package.Asset[] queue = GetLoadQueue(styleBuildings); Util.DebugPrint("LoadQueue", queue.Length, Profiling.Millis); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Loading Custom Assets"); Sharing.instance.Start(queue); beginMillis = Profiling.Millis; for (i = 0; i < queue.Length; i++) { Package.Asset assetRef = queue[i]; if ((i & 63) == 0) { PrintMem(i); } Sharing.instance.WaitForWorkers(); try { stack.Clear(); LoadImpl(assetRef); } catch (Exception e) { AssetFailed(assetRef.fullName, e); } Sharing.instance.ManageLoadQueue(i); if (Profiling.Millis - lastMillis > yieldInterval) { lastMillis = Profiling.Millis; progress = 0.15f + (i + 1) * 0.7f / queue.Length; LoadingScreen.instance.SetProgress(progress, progress, assetCount, assetCount - i - 1 + queue.Length, beginMillis, lastMillis); yield return(null); } } lastMillis = Profiling.Millis; LoadingScreen.instance.SetProgress(0.85f, 1f, assetCount, assetCount, beginMillis, lastMillis); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); Util.DebugPrint("Custom assets loaded in", lastMillis - beginMillis); PrintMem(); queue = null; stack.Clear(); Report(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Finalizing District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); for (i = 0; i < districtStyleMetaDatas.m_size; i++) { try { districtStyleMetaData = districtStyleMetaDatas.m_buffer[i]; districtStyle = new DistrictStyle(districtStyleMetaData.name, false); if (districtStylePackages.m_buffer[i].GetPublishedFileID() != PublishedFileId.invalid) { districtStyle.PackageName = districtStylePackages.m_buffer[i].packageName; } if (districtStyleMetaData.assets != null) { for (j = 0; j < districtStyleMetaData.assets.Length; j++) { BuildingInfo bi = CustomDeserializer.FindLoaded <BuildingInfo>(districtStyleMetaData.assets[j] + "_Data"); if (bi != null) { districtStyle.Add(bi); if (districtStyleMetaData.builtin) // this is always false { bi.m_dontSpawnNormally = !districtStyleMetaData.assetRef.isEnabled; } } else { CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Warning: Missing asset (" + districtStyleMetaData.assets[j] + ") in style " + districtStyleMetaData.name); } } districtStyles.Add(districtStyle); } } catch (Exception ex) { CODebugBase <LogChannel> .Warn(LogChannel.Modding, ex.GetType() + ": Loading district style failed\n" + ex.Message); } } Singleton <DistrictManager> .instance.m_Styles = districtStyles.ToArray(); if (Singleton <BuildingManager> .exists) { Singleton <BuildingManager> .instance.InitializeStyleArray(districtStyles.Count); } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); LoadingManager.instance.m_loadingProfilerMain.EndLoading(); hasFinished = true; }
public IEnumerator LoadCustomContent() { LoadingManager.instance.m_loadingProfilerMain.BeginLoading("LoadCustomContent"); LoadingManager.instance.m_loadingProfilerCustomContent.Reset(); LoadingManager.instance.m_loadingProfilerCustomAsset.Reset(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); hasStarted = true; int i, j; DistrictStyle districtStyle; DistrictStyleMetaData districtStyleMetaData; List <DistrictStyle> districtStyles = new List <DistrictStyle>(); HashSet <string> styleBuildings = new HashSet <string>(); FastList <DistrictStyleMetaData> districtStyleMetaDatas = new FastList <DistrictStyleMetaData>(); FastList <Package> districtStylePackages = new FastList <Package>(); Package.Asset europeanStyles = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanStyleName); if (europeanStyles != null && europeanStyles.isEnabled) { districtStyle = new DistrictStyle(DistrictStyle.kEuropeanStyleName, true); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style new"), districtStyle, false); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style others"), districtStyle, true); districtStyles.Add(districtStyle); } foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.DistrictStyleMetaData)) { try { if (asset != null && asset.isEnabled) { 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 })); } } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); if (loadUsed) { //while (!Profiling.SimulationPaused()) // yield return null; refs = new UsedAssets(); refs.Setup(); } LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Loading Assets First Pass"); notMask = ~SteamHelper.GetOwnedDLCMask(); lastMillis = Profiling.Millis; // Load custom assets: props, trees, trailers foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.CustomAssetMetaData)) { if (asset != null && PropTreeTrailer(asset) && Profiling.Millis - lastMillis > yieldInterval) { lastMillis = Profiling.Millis; yield return(null); } } LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Loading Assets Second Pass"); // Load custom assets: buildings and vehicles foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.CustomAssetMetaData)) { if (asset != null && BuildingVehicle(asset, styleBuildings.Contains(asset.fullName)) && Profiling.Millis - lastMillis > yieldInterval) { lastMillis = Profiling.Millis; yield return(null); } } if (loadUsed) { refs.ReportMissingAssets(); } if (reportAssets) { AssetReport.instance.Save(); } LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Finalizing District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); for (i = 0; i < districtStyleMetaDatas.m_size; i++) { try { districtStyleMetaData = districtStyleMetaDatas.m_buffer[i]; districtStyle = new DistrictStyle(districtStyleMetaData.name, false); if (districtStylePackages.m_buffer[i].GetPublishedFileID() != PublishedFileId.invalid) { districtStyle.PackageName = districtStylePackages.m_buffer[i].packageName; } if (districtStyleMetaData.assets != null) { for (j = 0; j < districtStyleMetaData.assets.Length; j++) { BuildingInfo bi = PrefabCollection <BuildingInfo> .FindLoaded(districtStyleMetaData.assets[j] + "_Data"); if (bi != null) { districtStyle.Add(bi); if (districtStyleMetaData.builtin) // this is always false { bi.m_dontSpawnNormally = !districtStyleMetaData.assetRef.isEnabled; } } else { CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Warning: Missing asset (" + districtStyleMetaData.assets[i] + ") in style " + districtStyleMetaData.name); } } districtStyles.Add(districtStyle); } } catch (Exception ex) { CODebugBase <LogChannel> .Warn(LogChannel.Modding, ex.GetType() + ": Loading district style failed\n" + ex.Message); } } Singleton <DistrictManager> .instance.m_Styles = districtStyles.ToArray(); if (Singleton <BuildingManager> .exists) { Singleton <BuildingManager> .instance.InitializeStyleArray(districtStyles.Count); } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); if (Singleton <TelemetryManager> .exists) { Singleton <TelemetryManager> .instance.CustomContentInfo(buildingsCount, propsCount, treeCount, vehicleCount); } LoadingManager.instance.m_loadingProfilerMain.EndLoading(); hasFinished = true; }
internal void Dispose() { allPackages.Clear(); buildingAssets.Clear(); propAssets.Clear(); treeAssets.Clear(); vehicleAssets.Clear(); indirectProps.Clear(); indirectTrees.Clear(); buildingPrefabs.Clear(); allPackages = null; buildingAssets = null; propAssets = null; treeAssets = null; vehicleAssets = null; indirectProps = null; indirectTrees = null; buildingPrefabs = null; instance = null; assets = null; defaultHandler = null; }
IEnumerator Skip(IEnumerator action) { try { string name = nameField.GetValue(action) as string; BuildingInfo[] prefabs = prefabsField.GetValue(action) as BuildingInfo[]; string[] replaces = replacesField.GetValue(action) as string[]; if (replaces == null) { replaces = new string[0]; } List <BuildingInfo> keptPrefabs = null; List <string> keptReplaces = null; UsedAssets.Create(); for (int i = 0; i < prefabs.Length; i++) { BuildingInfo info = prefabs[i]; string replace = i < replaces.Length ? replaces[i] : null; if (Skip(info, replace)) { skippedPrefabs.Add(info.gameObject.name); if (keptPrefabs == null) { keptPrefabs = prefabs.ToList(i); if (i < replaces.Length) { keptReplaces = replaces.ToList(i); } } } else if (keptPrefabs != null) { keptPrefabs.Add(info); if (keptReplaces != null) { keptReplaces.Add(replace); } } } if (keptPrefabs != null) { BuildingInfo[] p = keptPrefabs.ToArray(); prefabsField.SetValue(action, p); prefabsField2.SetValue(action, p); BuildingCollection bc = GameObject.Find(name)?.GetComponent <BuildingCollection>(); // In the presence of the European Buildings Unlocker mod, bc is usually null. // Obviously caused by the Destroy() invokes in that mod. if (bc != null) { bc.m_prefabs = p; } if (keptReplaces != null) { string[] r = keptReplaces.ToArray(); replacesField.SetValue(action, r); replacesField2.SetValue(action, r); if (bc != null) { bc.m_replacedNames = r; } } if (p.Length == 0) { return(null); } } } catch (Exception e) { UnityEngine.Debug.LogException(e); } return(action); }
public IEnumerator LoadCustomContent() { LoadingManager.instance.m_loadingProfilerMain.BeginLoading("LoadCustomContent"); LoadingManager.instance.m_loadingProfilerCustomContent.Reset(); LoadingManager.instance.m_loadingProfilerCustomAsset.Reset(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); hasStarted = true; int i, j; DistrictStyle districtStyle; DistrictStyleMetaData districtStyleMetaData; List <DistrictStyle> districtStyles = new List <DistrictStyle>(); HashSet <string> styleBuildings = new HashSet <string>(); FastList <DistrictStyleMetaData> districtStyleMetaDatas = new FastList <DistrictStyleMetaData>(); FastList <Package> districtStylePackages = new FastList <Package>(); Package.Asset europeanStyles = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanStyleName); if (europeanStyles != null && europeanStyles.isEnabled) { districtStyle = new DistrictStyle(DistrictStyle.kEuropeanStyleName, true); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style new"), districtStyle, false); Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style others"), districtStyle, true); // If skipping of standard prefabs is enabled, we must ensure that there are no skipped prefabs in the default district syle. if (Settings.settings.SkipAny) { RemoveSkipped(districtStyle); } districtStyles.Add(districtStyle); } foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.DistrictStyleMetaData)) { try { if (asset != null && asset.isEnabled) { 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 })); } } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); if (loadUsed) { UsedAssets.Create().Hook(); } LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Calculating asset load order"); List <Package.Asset>[] queues = GetLoadQueues(styleBuildings); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); lastMillis = Profiling.Millis; Sharing.instance?.Start(); // Load custom assets. for (i = 0; i < queues.Length; i++) { LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Loading Custom Assets Pass " + i); foreach (Package.Asset asset in queues[i]) { Load(asset); if (Profiling.Millis - lastMillis > yieldInterval) { lastMillis = Profiling.Millis; yield return(null); } } LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); } stack.Clear(); Report(); LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Finalizing District Styles"); LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading(); for (i = 0; i < districtStyleMetaDatas.m_size; i++) { try { districtStyleMetaData = districtStyleMetaDatas.m_buffer[i]; districtStyle = new DistrictStyle(districtStyleMetaData.name, false); if (districtStylePackages.m_buffer[i].GetPublishedFileID() != PublishedFileId.invalid) { districtStyle.PackageName = districtStylePackages.m_buffer[i].packageName; } if (districtStyleMetaData.assets != null) { for (j = 0; j < districtStyleMetaData.assets.Length; j++) { BuildingInfo bi = PrefabCollection <BuildingInfo> .FindLoaded(districtStyleMetaData.assets[j] + "_Data"); if (bi != null) { districtStyle.Add(bi); if (districtStyleMetaData.builtin) // this is always false { bi.m_dontSpawnNormally = !districtStyleMetaData.assetRef.isEnabled; } } else { CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Warning: Missing asset (" + districtStyleMetaData.assets[i] + ") in style " + districtStyleMetaData.name); } } districtStyles.Add(districtStyle); } } catch (Exception ex) { CODebugBase <LogChannel> .Warn(LogChannel.Modding, ex.GetType() + ": Loading district style failed\n" + ex.Message); } } Singleton <DistrictManager> .instance.m_Styles = districtStyles.ToArray(); if (Singleton <BuildingManager> .exists) { Singleton <BuildingManager> .instance.InitializeStyleArray(districtStyles.Count); } LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading(); LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading(); if (Singleton <TelemetryManager> .exists) { Singleton <TelemetryManager> .instance.CustomContentInfo(buildingCount, propCount, treeCount, vehicleCount); } LoadingManager.instance.m_loadingProfilerMain.EndLoading(); hasFinished = true; }