コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        internal Material GetMaterial(string checksum, Package package, bool isMain)
        {
            MaterialData mat;
            KeyValuePair <int, object> kvp;

            lock (mutex)
            {
                if (isMain && materialsMain.TryGetValue(checksum, out mat))
                {
                    mathit++;
                    texhit += mat.textureCount;
                    return(mat.material);
                }
                else if (!isMain && (materialsLod.TryGetValue(checksum, out mat) || materialsMain.TryGetValue(checksum, out mat)))
                {
                    matpre++;
                    return(new Material(mat.material));
                }

                data.TryGetValue(checksum, out kvp);
            }

            byte[] bytes = kvp.Value as byte[];

            if (bytes != null)
            {
                mat = (MaterialData)AssetDeserializer.Instantiate(package, bytes, isMain);
                matpre++;
            }
            else
            {
                Package.Asset asset = package.FindByChecksum(checksum);
                mat = (MaterialData)AssetDeserializer.Instantiate(asset, isMain);
                matload++;
            }

            if (shareMaterials)
            {
                lock (mutex)
                {
                    if (isMain)
                    {
                        materialsMain[checksum] = mat;
                    }
                    else
                    {
                        materialsLod[checksum] = mat;
                    }

                    if (data.Remove(checksum))
                    {
                        removedCount++;
                    }
                }
            }

            return(mat.material);
        }
コード例 #4
0
 void ReadMetaData(Package package)
 {
     foreach (Package.Asset asset in package.FilterAssets(UserAssetType.CustomAssetMetaData))
     {
         try
         {
             CustomAssetMetaData meta = AssetDeserializer.Instantiate(asset) as CustomAssetMetaData;
             metaDatas[meta.assetRef.fullName] = new SomeMetaData(meta.userDataRef, meta.name, meta.type);
         }
         catch (Exception)
         {
             Util.DebugPrint("!Cannot read metadata from", package.packageName);
         }
     }
 }
コード例 #5
0
        internal static object CustomDeserialize(Package p, Type t, PackageReader r)
        {
            // Props and trees in buildings and parks.
            if (t == typeof(BuildingInfo.Prop))
            {
                PropInfo pi = Get <PropInfo>(r.ReadString()); // old name format (without package name) is possible
                TreeInfo ti = Get <TreeInfo>(r.ReadString()); // old name format (without package name) is possible

                if (instance.report && UsedAssets.instance.GotAnyContainer())
                {
                    if (pi != null)
                    {
                        string n = pi.gameObject.name;

                        if (!string.IsNullOrEmpty(n) && n.IndexOf('.') >= 0)
                        {
                            UsedAssets.instance.IndirectProps.Add(n);
                        }
                    }

                    if (ti != null)
                    {
                        string n = ti.gameObject.name;

                        if (!string.IsNullOrEmpty(n) && n.IndexOf('.') >= 0)
                        {
                            UsedAssets.instance.IndirectTrees.Add(n);
                        }
                    }
                }

                return(new BuildingInfo.Prop
                {
                    m_prop = pi,
                    m_tree = ti,
                    m_position = r.ReadVector3(),
                    m_angle = r.ReadSingle(),
                    m_probability = r.ReadInt32(),
                    m_fixedHeight = r.ReadBoolean()
                });
            }

            // Paths (nets) in buildings.
            if (t == typeof(BuildingInfo.PathInfo))
            {
                string  fullName           = r.ReadString();
                NetInfo ni                 = Get <NetInfo>(fullName);
                BuildingInfo.PathInfo path = new BuildingInfo.PathInfo();
                path.m_netInfo         = ni;
                path.m_nodes           = r.ReadVector3Array();
                path.m_curveTargets    = r.ReadVector3Array();
                path.m_invertSegments  = r.ReadBoolean();
                path.m_maxSnapDistance = r.ReadSingle();

                if (p.version >= 5)
                {
                    path.m_forbidLaneConnection = r.ReadBooleanArray();
                    path.m_trafficLights        = (BuildingInfo.TrafficLights[])(object) r.ReadInt32Array();
                    path.m_yieldSigns           = r.ReadBooleanArray();
                }

                return(path);
            }

            if (t == typeof(Package.Asset))
            {
                return(r.ReadAsset(p));
            }

            // It seems that trailers are listed in the save game so this is not necessary. Better to be safe however
            // because a missing trailer reference is fatal for the simulation thread.
            if (t == typeof(VehicleInfo.VehicleTrailer))
            {
                string      name     = r.ReadString();
                string      fullName = p.packageName + "." + name;
                VehicleInfo vi       = Get <VehicleInfo>(p, fullName, name, false);

                VehicleInfo.VehicleTrailer trailer;
                trailer.m_info              = vi;
                trailer.m_probability       = r.ReadInt32();
                trailer.m_invertProbability = r.ReadInt32();
                return(trailer);
            }

            if (t == typeof(NetInfo.Lane))
            {
                return(new NetInfo.Lane
                {
                    m_position = r.ReadSingle(),
                    m_width = r.ReadSingle(),
                    m_verticalOffset = r.ReadSingle(),
                    m_stopOffset = r.ReadSingle(),
                    m_speedLimit = r.ReadSingle(),
                    m_direction = (NetInfo.Direction)r.ReadInt32(),
                    m_laneType = (NetInfo.LaneType)r.ReadInt32(),
                    m_vehicleType = (VehicleInfo.VehicleType)r.ReadInt32(),
                    m_stopType = (VehicleInfo.VehicleType)r.ReadInt32(),
                    m_laneProps = GetNetLaneProps(p, r),
                    m_allowConnect = r.ReadBoolean(),
                    m_useTerrainHeight = r.ReadBoolean(),
                    m_centerPlatform = r.ReadBoolean(),
                    m_elevated = r.ReadBoolean()
                });
            }

            if (t == typeof(NetInfo.Segment))
            {
                NetInfo.Segment segment  = new NetInfo.Segment();
                string          checksum = r.ReadString();
                segment.m_mesh              = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, true);
                checksum                    = r.ReadString();
                segment.m_material          = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, true);
                checksum                    = r.ReadString();
                segment.m_lodMesh           = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, false);
                checksum                    = r.ReadString();
                segment.m_lodMaterial       = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, false);
                segment.m_forwardRequired   = (NetSegment.Flags)r.ReadInt32();
                segment.m_forwardForbidden  = (NetSegment.Flags)r.ReadInt32();
                segment.m_backwardRequired  = (NetSegment.Flags)r.ReadInt32();
                segment.m_backwardForbidden = (NetSegment.Flags)r.ReadInt32();
                segment.m_emptyTransparent  = r.ReadBoolean();
                segment.m_disableBendNodes  = r.ReadBoolean();
                return(segment);
            }

            if (t == typeof(NetInfo.Node))
            {
                NetInfo.Node node     = new NetInfo.Node();
                string       checksum = r.ReadString();
                node.m_mesh             = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, true);
                checksum                = r.ReadString();
                node.m_material         = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, true);
                checksum                = r.ReadString();
                node.m_lodMesh          = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, false);
                checksum                = r.ReadString();
                node.m_lodMaterial      = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, false);
                node.m_flagsRequired    = (NetNode.Flags)r.ReadInt32();
                node.m_flagsForbidden   = (NetNode.Flags)r.ReadInt32();
                node.m_connectGroup     = (NetInfo.ConnectGroup)r.ReadInt32();
                node.m_directConnect    = r.ReadBoolean();
                node.m_emptyTransparent = r.ReadBoolean();
                return(node);
            }

            if (t == typeof(NetInfo))
            {
                string name = r.ReadString();
                CustomAssetMetaData.Type type = AssetLoader.instance.GetMetaType(AssetLoader.instance.Current);

                if (type == CustomAssetMetaData.Type.Road || type == CustomAssetMetaData.Type.RoadElevation)
                {
                    return(Get <NetInfo>(p, name));
                }
                else
                {
                    return(Get <NetInfo>(name));
                }
            }

            if (t == typeof(BuildingInfo))
            {
                string name = r.ReadString();
                CustomAssetMetaData.Type type = AssetLoader.instance.GetMetaType(AssetLoader.instance.Current);

                if (type == CustomAssetMetaData.Type.Road || type == CustomAssetMetaData.Type.RoadElevation)
                {
                    return(Get <BuildingInfo>(p, name));
                }
                else
                {
                    return(Get <BuildingInfo>(name));
                }
            }

            // Sub-buildings in buildings.
            if (t == typeof(BuildingInfo.SubInfo))
            {
                string       name     = r.ReadString();
                string       fullName = p.packageName + "." + name;
                BuildingInfo bi       = null;

                if (fullName == AssetLoader.instance.Current.fullName || name == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a sub-building for itself");
                }
                else
                {
                    bi = Get <BuildingInfo>(p, fullName, name, true);
                }

                BuildingInfo.SubInfo subInfo = new BuildingInfo.SubInfo();
                subInfo.m_buildingInfo = bi;
                subInfo.m_position     = r.ReadVector3();
                subInfo.m_angle        = r.ReadSingle();
                subInfo.m_fixedHeight  = r.ReadBoolean();
                return(subInfo);
            }

            // Prop variations in props.
            if (t == typeof(PropInfo.Variation))
            {
                string   name     = r.ReadString();
                string   fullName = p.packageName + "." + name;
                PropInfo pi       = null;

                if (fullName == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a prop variation for itself");
                }
                else
                {
                    pi = Get <PropInfo>(p, fullName, name, false);
                }

                return(new PropInfo.Variation
                {
                    m_prop = pi,
                    m_probability = r.ReadInt32()
                });
            }

            // Tree variations in trees.
            if (t == typeof(TreeInfo.Variation))
            {
                string   name     = r.ReadString();
                string   fullName = p.packageName + "." + name;
                TreeInfo ti       = null;

                if (fullName == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a tree variation for itself");
                }
                else
                {
                    ti = Get <TreeInfo>(p, fullName, name, false);
                }

                return(new TreeInfo.Variation
                {
                    m_tree = ti,
                    m_probability = r.ReadInt32()
                });
            }

            if (t == typeof(VehicleInfo.MeshInfo))
            {
                VehicleInfo.MeshInfo meshinfo = new VehicleInfo.MeshInfo();
                string checksum = r.ReadString();

                if (!string.IsNullOrEmpty(checksum))
                {
                    Package.Asset asset = p.FindByChecksum(checksum);
                    GameObject    go    = AssetDeserializer.Instantiate(asset) as GameObject;
                    meshinfo.m_subInfo = go.GetComponent <VehicleInfoBase>();
                    go.SetActive(false);

                    if (meshinfo.m_subInfo.m_lodObject != null)
                    {
                        meshinfo.m_subInfo.m_lodObject.SetActive(false);
                    }
                }
                else
                {
                    meshinfo.m_subInfo = null;
                }

                meshinfo.m_vehicleFlagsForbidden = (Vehicle.Flags)r.ReadInt32();
                meshinfo.m_vehicleFlagsRequired  = (Vehicle.Flags)r.ReadInt32();
                meshinfo.m_parkedFlagsForbidden  = (VehicleParked.Flags)r.ReadInt32();
                meshinfo.m_parkedFlagsRequired   = (VehicleParked.Flags)r.ReadInt32();
                return(meshinfo);
            }

            return(PackageHelper.CustomDeserialize(p, t, r));
        }
コード例 #6
0
        Package.Asset[] GetLoadQueue(HashSet <string> styleBuildings)
        {
            Package[] packages = PackageManager.allPackages.ToArray();
            Array.Sort(packages, (a, b) => string.Compare(a.packageName, b.packageName));
            List <Package.Asset>       assets = new List <Package.Asset>(8);
            List <CustomAssetMetaData> metas  = new List <CustomAssetMetaData>(8);

            // Why this load order? By having related and identical assets close to each other, we get more loader cache hits (of meshes and textures)
            // in Sharing. We also get faster disk reads.
            // [0] propvar and prop, citizen  [1] prop, tree  [2] pillar and elevation and road  [3] road
            // [4] sub-building and building  [5] building    [6] trailer and vehicle            [7] vehicle
            List <Package.Asset>[] queues = { new List <Package.Asset>(4), new List <Package.Asset>(64), new List <Package.Asset>(4),  new List <Package.Asset>(4),
                                              new List <Package.Asset>(4), new List <Package.Asset>(64), new List <Package.Asset>(32), new List <Package.Asset>(32) };

            SteamHelper.DLC_BitMask notMask = ~SteamHelper.GetOwnedDLCMask();
            bool loadEnabled = Settings.settings.loadEnabled, loadUsed = Settings.settings.loadUsed, report = loadUsed && Settings.settings.reportAssets;

            //PrintPackages(packages);

            foreach (Package p in packages)
            {
                CustomAssetMetaData meta = null;

                try
                {
                    assets.Clear();
                    assets.AddRange(p.FilterAssets(UserAssetType.CustomAssetMetaData));

                    if (assets.Count == 0)
                    {
                        continue;
                    }

                    if (report)
                    {
                        AssetReport.instance.AddPackage(p);
                    }

                    bool enabled = loadEnabled && IsEnabled(p);

                    if (assets.Count == 1) // the common case
                    {
                        bool want = enabled || styleBuildings.Contains(assets[0].fullName);

                        // Fast exit.
                        if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                        {
                            continue;
                        }

                        meta = AssetDeserializer.Instantiate(assets[0]) as CustomAssetMetaData;
                        bool used = loadUsed && UsedAssets.instance.IsUsed(meta);

                        if (used || want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0)
                        {
                            CustomAssetMetaData.Type type = meta.type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            AddToQueue(queues, meta, offset, !(enabled | used));
                        }
                    }
                    else
                    {
                        bool want = enabled;

                        // Fast exit.
                        if (!want)
                        {
                            for (int i = 0; i < assets.Count; i++)
                            {
                                want = want || styleBuildings.Contains(assets[i].fullName);
                            }

                            if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                            {
                                continue;
                            }
                        }

                        metas.Clear();
                        bool used = false;

                        for (int i = 0; i < assets.Count; i++)
                        {
                            meta = AssetDeserializer.Instantiate(assets[i]) as CustomAssetMetaData;
                            metas.Add(meta);
                            want = want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0;
                            used = used || loadUsed && UsedAssets.instance.IsUsed(meta);
                        }

                        if (want | used)
                        {
                            metas.Sort((a, b) => b.type - a.type); // prop variation, sub-building, trailer, elevation, pillar before main asset
                            CustomAssetMetaData.Type type = metas[0].type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            bool dontSpawn = !(enabled | used);

                            for (int i = 0; i < metas.Count; i++)
                            {
                                AddToQueue(queues, metas[i], offset, dontSpawn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    AssetFailed(meta?.assetRef?.fullName ?? p.packageName + "." + p.packageMainAsset, e);
                }
            }

            Package.Asset[] queue = new Package.Asset[queues.Select(lst => lst.Count).Sum()];

            for (int i = 0, k = 0; i < queues.Length; k += queues[i].Count, i++)
            {
                queues[i].CopyTo(queue, k);
            }

            return(queue);
        }
コード例 #7
0
        internal void LoadImpl(Package.Asset assetRef)
        {
            try
            {
                stack.Push(assetRef);
                LoadingManager.instance.m_loadingProfilerCustomAsset.BeginLoading(AssetName(assetRef.name));
                GameObject go = AssetDeserializer.Instantiate(assetRef) as GameObject;
                CustomAssetMetaData.Type type = GetMetaType(assetRef);
                string packageName            = assetRef.package.packageName;
                string fullName = type < CustomAssetMetaData.Type.RoadElevation ? packageName + "." + go.name : PillarOrElevationName(packageName, go.name);
                go.name = fullName;
                go.SetActive(false);
                PrefabInfo info = go.GetComponent <PrefabInfo>();
                info.m_isCustomContent = true;

                if (info.m_Atlas != null && !string.IsNullOrEmpty(info.m_InfoTooltipThumbnail) && 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);
                    }

                    Initialize(pi);
                    loadedProps.Add(fullName);
                }

                TreeInfo ti = go.GetComponent <TreeInfo>();

                if (ti != null)
                {
                    Initialize(ti);
                    loadedTrees.Add(fullName);
                }

                BuildingInfo bi = go.GetComponent <BuildingInfo>();

                if (bi != null)
                {
                    if (bi.m_lodObject != null)
                    {
                        bi.m_lodObject.SetActive(false);
                    }

                    bi.m_dontSpawnNormally = dontSpawnNormally.Remove(fullName);
                    Initialize(bi);
                    loadedBuildings.Add(fullName);

                    if (bi.GetAI() is IntersectionAI)
                    {
                        loadedIntersections.Add(fullName);
                    }
                }

                VehicleInfo vi = go.GetComponent <VehicleInfo>();

                if (vi != null)
                {
                    if (vi.m_lodObject != null)
                    {
                        vi.m_lodObject.SetActive(false);
                    }

                    Initialize(vi);
                    loadedVehicles.Add(fullName);
                }

                CitizenInfo ci = go.GetComponent <CitizenInfo>();

                if (ci != null)
                {
                    if (ci.m_lodObject != null)
                    {
                        ci.m_lodObject.SetActive(false);
                    }

                    if (ci.InitializeCustomPrefab(citizenMetaDatas[assetRef.fullName]))
                    {
                        citizenMetaDatas.Remove(assetRef.fullName);
                        ci.gameObject.SetActive(true);
                        Initialize(ci);
                        loadedCitizens.Add(fullName);
                    }
                    else
                    {
                        CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Custom citizen [" + assetRef.fullName + "] template not available in selected theme. Asset not added in game.");
                    }
                }

                NetInfo ni = go.GetComponent <NetInfo>();

                if (ni != null)
                {
                    loadedNets.Add(fullName);
                    Initialize(ni);
                }
            }
            finally
            {
                stack.Pop();
                assetCount++;
                LoadingManager.instance.m_loadingProfilerCustomAsset.EndLoading();
            }
        }
コード例 #8
0
        internal Texture2D GetTexture(string checksum, Package package, bool isMain)
        {
            Texture2D texture2D;
            KeyValuePair <int, object> kvp;

            lock (mutex)
            {
                if (isMain && texturesMain.TryGetValue(checksum, out texture2D))
                {
                    texhit++;
                    return(texture2D);
                }
                else if (!isMain && (texturesLod.TryGetValue(checksum, out texture2D) || texturesMain.TryGetValue(checksum, out texture2D)))
                {
                    texpre++;
                    return(UnityEngine.Object.Instantiate(texture2D));
                }

                data.TryGetValue(checksum, out kvp);
            }

            TextObj to = kvp.Value as TextObj;

            byte[] bytes;

            if (to != null)
            {
                texture2D = new Texture2D(to.width, to.height, to.format, to.mipmap, to.linear);
                texture2D.LoadRawTextureData(to.pixels);
                texture2D.Apply();
                texture2D.name       = to.name;
                texture2D.anisoLevel = to.anisoLevel;
                texpre++;
            }
            else if ((bytes = kvp.Value as byte[]) != null)
            {
                texture2D = AssetDeserializer.Instantiate(package, bytes, isMain) as Texture2D;
                texpre++;
            }
            else
            {
                Package.Asset asset = package.FindByChecksum(checksum);
                texture2D = AssetDeserializer.Instantiate(asset, isMain) as Texture2D;
                texload++;
            }

            if (shareTextures)
            {
                lock (mutex)
                {
                    if (isMain)
                    {
                        texturesMain[checksum] = texture2D;
                    }
                    else
                    {
                        texturesLod[checksum] = texture2D;
                    }

                    if (data.Remove(checksum))
                    {
                        removedCount++;
                    }
                }
            }

            return(texture2D);
        }
コード例 #9
0
        internal Mesh GetMesh(string checksum, Package package, bool isMain)
        {
            Mesh mesh;
            KeyValuePair <int, object> kvp;

            lock (mutex)
            {
                if (meshes.TryGetValue(checksum, out mesh))
                {
                    meshit++;
                    return(mesh);
                }

                data.TryGetValue(checksum, out kvp);
            }

            MeshObj mo = kvp.Value as MeshObj;

            byte[] bytes;

            if (mo != null)
            {
                mesh             = new Mesh();
                mesh.name        = mo.name;
                mesh.vertices    = mo.vertices;
                mesh.colors      = mo.colors;
                mesh.uv          = mo.uv;
                mesh.normals     = mo.normals;
                mesh.tangents    = mo.tangents;
                mesh.boneWeights = mo.boneWeights;
                mesh.bindposes   = mo.bindposes;

                for (int i = 0; i < mo.triangles.Length; i++)
                {
                    mesh.SetTriangles(mo.triangles[i], i);
                }

                mespre++;
            }
            else if ((bytes = kvp.Value as byte[]) != null)
            {
                mesh = AssetDeserializer.Instantiate(package, bytes, isMain) as Mesh;
                mespre++;
            }
            else
            {
                Package.Asset asset = package.FindByChecksum(checksum);
                mesh = AssetDeserializer.Instantiate(asset, isMain) as Mesh;
                mesload++;
            }

            if (shareMeshes)
            {
                lock (mutex)
                {
                    meshes[checksum] = mesh;

                    if (data.Remove(checksum))
                    {
                        removedCount++;
                    }
                }
            }

            return(mesh);
        }
コード例 #10
0
        Package.Asset[] GetLoadQueue(HashSet <string> styleBuildings)
        {
            Package.AssetType[] customAssets = { UserAssetType.CustomAssetMetaData };
            Package[]           packages     = { };

            try
            {
                packages = PackageManager.allPackages.Where(p => p.FilterAssets(customAssets).Any()).ToArray();
                Array.Sort(packages, PackageComparison);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogException(e);
            }

            List <Package.Asset>       assets = new List <Package.Asset>(8);
            List <CustomAssetMetaData> metas  = new List <CustomAssetMetaData>(8);

            // Why this load order? By having related and identical assets close to each other, we get more loader cache hits (of meshes and textures)
            // in Sharing. We also get faster disk reads.
            // [0] propvar and prop, tree, citizen  [1] prop      [2] pillar and elevation and road  [3] road
            // [4] sub-building and building        [5] building  [6] trailer and vehicle            [7] vehicle
            List <Package.Asset>[] queues = { new List <Package.Asset>(32), new List <Package.Asset>(64), new List <Package.Asset>(4),  new List <Package.Asset>(4),
                                              new List <Package.Asset>(16), new List <Package.Asset>(64), new List <Package.Asset>(32), new List <Package.Asset>(32) };

            SteamHelper.DLC_BitMask notMask = ~SteamHelper.GetOwnedDLCMask();
            bool loadEnabled = Settings.settings.loadEnabled, loadUsed = Settings.settings.loadUsed;

            //PrintPackages(packages);

            foreach (Package p in packages)
            {
                CustomAssetMetaData meta = null;

                try
                {
                    assets.Clear();
                    assets.AddRange(p.FilterAssets(customAssets));
                    int count = assets.Count;

                    CustomDeserializer.instance.AddPackage(p);
                    bool enabled = loadEnabled && IsEnabled(p);

                    if (count == 1) // the common case
                    {
                        bool want = enabled || styleBuildings.Contains(assets[0].fullName);

                        // Fast exit.
                        if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                        {
                            continue;
                        }

                        meta = AssetDeserializer.Instantiate(assets[0]) as CustomAssetMetaData;
                        bool used = loadUsed && UsedAssets.instance.IsUsed(meta);

                        if (used || want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0)
                        {
                            if (reportAssets)
                            {
                                AssetReport.instance.AddPackage(p, meta, want, used);
                            }

                            CustomAssetMetaData.Type type = meta.type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;

                            AddToQueue(queues, meta, type, offset, !(enabled | used));
                        }
                    }
                    else
                    {
                        bool want = enabled;

                        // Fast exit.
                        if (!want)
                        {
                            for (int i = 0; i < count; i++)
                            {
                                want = want || styleBuildings.Contains(assets[i].fullName);
                            }

                            if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                            {
                                continue;
                            }
                        }

                        metas.Clear();
                        bool used = false;

                        for (int i = 0; i < count; i++)
                        {
                            meta = AssetDeserializer.Instantiate(assets[i]) as CustomAssetMetaData;
                            metas.Add(meta);
                            want = want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0;
                            used = used || loadUsed && UsedAssets.instance.IsUsed(meta);
                        }

                        if (want | used)
                        {
                            metas.Sort((a, b) => b.type - a.type); // prop variation, sub-building, trailer, elevation, pillar before main asset
                            CustomAssetMetaData lastmeta = metas[count - 1];

                            if (reportAssets)
                            {
                                AssetReport.instance.AddPackage(p, lastmeta, want, used);
                            }

                            CustomAssetMetaData.Type type = metas[0].type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            bool treeVariations = lastmeta.type == CustomAssetMetaData.Type.Tree, dontSpawn = !(enabled | used);

                            for (int i = 0; i < count; i++)
                            {
                                CustomAssetMetaData      m = metas[i];
                                CustomAssetMetaData.Type t = m.type;

                                if (treeVariations && t == CustomAssetMetaData.Type.PropVariation)
                                {
                                    t = CustomAssetMetaData.Type.Tree;
                                }

                                AddToQueue(queues, m, t, offset, dontSpawn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    AssetFailed(meta?.assetRef, p, e);
                }
            }

            CheckSuspects();

            for (int i = 0; i < queuedLoads.Length; i++)
            {
                queuedLoads[i].Clear();
                queuedLoads[i] = null;
            }

            queuedLoads = null;
            Package.Asset[] queue = new Package.Asset[queues.Sum(lst => lst.Count)];

            for (int i = 0, k = 0; i < queues.Length; i++)
            {
                queues[i].CopyTo(queue, k);
                k += queues[i].Count;
                queues[i].Clear(); queues[i] = null;
            }

            return(queue);
        }
コード例 #11
0
        internal void LoadImpl(Package.Asset assetRef)
        {
            try
            {
                stack.Push(assetRef);
                LoadingManager.instance.m_loadingProfilerCustomAsset.BeginLoading(ShortName(assetRef.name));
                CustomAssetMetaData.Type type = GetMetaType(assetRef);

                GameObject go          = AssetDeserializer.Instantiate(assetRef) as GameObject;
                string     packageName = assetRef.package.packageName;
                string     fullName    = type < CustomAssetMetaData.Type.RoadElevation ? packageName + "." + go.name : PillarOrElevationName(packageName, go.name);
                go.name = fullName;
                go.SetActive(false);
                PrefabInfo info = go.GetComponent <PrefabInfo>();
                info.m_isCustomContent = true;

                if (info.m_Atlas != null && !string.IsNullOrEmpty(info.m_InfoTooltipThumbnail) && info.m_Atlas[info.m_InfoTooltipThumbnail] != null)
                {
                    info.m_InfoTooltipAtlas = info.m_Atlas;
                }

                PropInfo     pi;
                TreeInfo     ti;
                BuildingInfo bi;
                VehicleInfo  vi;
                CitizenInfo  ci;
                NetInfo      ni;

                if ((pi = go.GetComponent <PropInfo>()) != null)
                {
                    if (pi.m_lodObject != null)
                    {
                        pi.m_lodObject.SetActive(false);
                    }

                    Initialize(pi);
                }
                else if ((ti = go.GetComponent <TreeInfo>()) != null)
                {
                    Initialize(ti);
                }
                else if ((bi = go.GetComponent <BuildingInfo>()) != null)
                {
                    if (bi.m_lodObject != null)
                    {
                        bi.m_lodObject.SetActive(false);
                    }

                    bi.m_dontSpawnNormally = dontSpawnNormally.Remove(fullName);
                    Initialize(bi);

                    if (bi.GetAI() is IntersectionAI)
                    {
                        loadedIntersections.Add(fullName);
                    }
                }
                else if ((vi = go.GetComponent <VehicleInfo>()) != null)
                {
                    if (vi.m_lodObject != null)
                    {
                        vi.m_lodObject.SetActive(false);
                    }

                    Initialize(vi);
                }
                else if ((ci = go.GetComponent <CitizenInfo>()) != null)
                {
                    if (ci.m_lodObject != null)
                    {
                        ci.m_lodObject.SetActive(false);
                    }

                    if (ci.InitializeCustomPrefab(citizenMetaDatas[assetRef.fullName]))
                    {
                        citizenMetaDatas.Remove(assetRef.fullName);
                        ci.gameObject.SetActive(true);
                        Initialize(ci);
                    }
                    else
                    {
                        info = null;
                        CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Custom citizen [" + assetRef.fullName + "] template not available in selected theme. Asset not added in game.");
                    }
                }
                else if ((ni = go.GetComponent <NetInfo>()) != null)
                {
                    Initialize(ni);
                }
                else
                {
                    info = null;
                }

                if (info != null)
                {
                    string path = Path.GetDirectoryName(assetRef.package.packagePath);

                    if (!string.IsNullOrEmpty(path) && plugins.TryGetValue(path, out PluginInfo plugin))
                    {
                        IAssetDataExtension[] extensions = plugin.GetInstances <IAssetDataExtension>();

                        if (extensions.Length > 0)
                        {
                            UserAssetData uad = GetUserAssetData(assetRef, out string name);

                            if (uad != null)
                            {
                                for (int i = 0; i < extensions.Length; i++)
                                {
                                    try
                                    {
                                        extensions[i].OnAssetLoaded(name, info, uad.Data);
                                    }
                                    catch (Exception e)
                                    {
                                        ModException ex = new ModException("The Mod " + plugin.ToString() + " has caused an error when loading " + fullName, e);
                                        UIView.ForwardException(ex);
                                        Debug.LogException(ex);
                                    }
                                }
                            }
                            else
                            {
                                Util.DebugPrint("UserAssetData is null for", fullName);
                            }
                        }
                    }
                }
            }
            finally
            {
                stack.Pop();
                assetCount++;
                LoadingManager.instance.m_loadingProfilerCustomAsset.EndLoading();
            }
        }