Ejemplo n.º 1
0
        public static void getShaderNameFromFile(string fileName)
        {
            try
            {
                Console.WriteLine("Reading: " + fileName);
                UnityParser unityParser = new UnityParser(fileName);
                int         count       = unityParser.Cabinet.Components.Count;
                string      text        = fileName.Substring(fileName.IndexOf("abdata") + 7);
                for (int i = 0; i < count; i++)
                {
                    try
                    {
                        switch (unityParser.Cabinet.Components[i].classID())
                        {
                        case UnityClassID.MeshRenderer:
                        case UnityClassID.ParticleRenderer:
                        case UnityClassID.TrailRenderer:
                        case UnityClassID.LineRenderer:
                        case UnityClassID.SkinnedMeshRenderer:
                        case UnityClassID.ParticleSystemRenderer:
                            foreach (dynamic item in unityParser.Cabinet.LoadComponent(unityParser.Cabinet.Components[i].pathID).m_Materials)
                            {
                                Material  material  = (Material)((PPtr <Material>)item).asset;
                                Component component = material.m_Shader.asset;
                                try
                                {
                                    string shader_name = "";
                                    //Note: Make sure the main Shader discovery process is all within FileID == 0
                                    //      Which means it is in the same abdata and not relying on external files.
                                    //      HPI will never be able to handle manifests & external files properly
                                    //      for HS1 items.
                                    // if (material.m_Shader.m_FileID == 0)
                                    if (material.m_Shader.m_FileID == 0 && material.m_Shader.m_PathID != 0)
                                    {
                                        //shader_name = ((component is NotLoaded) ?
                                        //                  ((NotLoaded)component).Name :
                                        //                  ((component.file.VersionNumber < AssetCabinet.VERSION_5_5_0) ?
                                        //                      ((Shader)component).m_Name :
                                        //                      ((Shader)component).m_ParsedForm.m_Name)
                                        //              );
                                        //long _dummy_ = 0;
                                        ////Note: Not only we want to avoid empty shader names, but some modder strangely
                                        ////      renames shaders into random numbers. We don't want those either.
                                        //if ((shader_name.Equals("") || long.TryParse(shader_name, out _dummy_)) &&
                                        //    material.m_Shader.m_PathID != 0)
                                        //{
                                        //    component = unityParser.Cabinet.LoadComponent(material.m_Shader.m_PathID);
                                        //    Shader shader = (Shader)component;
                                        //    if (shader != null)
                                        //    {
                                        //        string shader_script = shader.m_Script;
                                        //        if (shader_script != null && shader_script.Length > 0)
                                        //        {
                                        //            shader_script = shader_script.Substring(shader_script.IndexOf("\"") + 1);
                                        //            shader_name = shader_script.Substring(0, shader_script.IndexOf("\""));
                                        //        }
                                        //    }
                                        //    //Shader.m_Script seem to start with [[Shader "name"...]], so we just grab the string in between
                                        //    //the first quote and the second quote? That easy?
                                        //}
                                        if (component.file.VersionNumber < AssetCabinet.VERSION_5_5_0)
                                        {
                                            Shader shader = (Shader)unityParser.Cabinet.LoadComponent(material.m_Shader.m_PathID);
                                            if (shader != null)
                                            {
                                                string shader_script = shader.m_Script;
                                                if (shader_script != null && shader_script.Length > 0)
                                                {
                                                    shader_script = shader_script.Substring(shader_script.IndexOf("\"") + 1);
                                                    shader_name   = shader_script.Substring(0, shader_script.IndexOf("\""));
                                                }
                                            }
                                            //Shader.m_Script seem to start with [[Shader "name"...]], so we just grab the string in between
                                            //the first quote and the second quote. But this seems to be also true for Unity 5.3 shaders.
                                        }
                                        //If trying to get the Unity 5.3 shader.m_Script somehow fails, try the basic m_Name.
                                        if (shader_name.Equals(""))
                                        {
                                            shader_name = ((component is NotLoaded) ?
                                                           ((NotLoaded)component).Name :
                                                           ((component.file.VersionNumber < AssetCabinet.VERSION_5_5_0) ?
                                                            ((Shader)component).m_Name :
                                                            ((Shader)component).m_ParsedForm.m_Name)
                                                           );
                                        }
                                        //The last resort is still the PathID, as long as the PathID isn't 0.
                                        if (shader_name.Equals(""))
                                        {
                                            shader_name = material.m_Shader.m_PathID.ToString();
                                        }
                                    }
                                    else
                                    {
                                        switch (material.m_Shader.m_PathID)
                                        {
                                        case                    6: shader_name = "Normal-VertexLit"; break;

                                        case                    7: shader_name = "Normal-Diffuse"; break;

                                        case -9046184444883282072: shader_name = "Shader Forge/PBRsp_texture_alpha_culloff"; break;

                                        default:                   shader_name = "Standard"; break;
                                        }
                                        //Note: For certain objects relying on unity_builtin_extra's shaders,
                                        //      Usually they are just for Diffuse or VertexLit, which are just
                                        //      Standard since Unity 5.
                                        //      There will be other mod packs with expectation of a manifest,
                                        //      for such mods, they could use whatever shaders that HPI will never
                                        //      be able to identify within the scope of the same abdata
                                        //      so that has to be ruled out as impossible for the foreseeable future.
                                    }
                                    Console.WriteLine(text + " - " + material.m_Name + " - " + shader_name + " - " + material.m_CustomRenderQueue);
                                    ret[text.Replace("\\", "/") + "|" + material.m_Name] = shader_name + "," + material.m_CustomRenderQueue;
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.ToString());
                                    Console.WriteLine(ex.StackTrace);
                                }
                            }
                            break;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
                unityParser.Dispose();
            }
            catch (Exception ex3)
            {
                Console.WriteLine(ex3.ToString());
                Console.WriteLine(ex3.StackTrace);
            }
        }