Exemple #1
0
        /// <summary>
        /// Link
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="resPaths">resource paths</param>
        /// <param name="baseDir"></param>
        /// <param name="order">how to arrange images</param>
        /// <param name="isExternal">Whether this is an external texture PSB</param>
        public static void Link(this PSB psb, IList <string> resPaths, string baseDir = null,
                                PsbLinkOrderBy order = PsbLinkOrderBy.Convention, bool isExternal = false)
        {
            if (isExternal)
            {
                psb.MotionResourceInstrument();
            }
            var resList = psb.CollectResources();
            var context = FreeMount.CreateContext();

            if (order == PsbLinkOrderBy.Order)
            {
                for (int i = 0; i < resList.Count; i++)
                {
                    var    resMd    = resList[i];
                    var    fullPath = Path.Combine(baseDir ?? "", resPaths[i]);
                    byte[] data     = LoadImageBytes(fullPath, resMd, context);
                    resMd.Resource.Data = data;
                }
                return;
            }

            if (order == PsbLinkOrderBy.Name)
            {
                if (psb.Platform == PsbSpec.krkr)
                {
                    throw new InvalidOperationException(
                              $"Can not link by file name for krkr PSB. Please consider using {PsbLinkOrderBy.Convention}");
                }

                resList.Sort((md1, md2) => (int)(md1.TextureIndex ?? 0) - (int)(md2.TextureIndex ?? 0));
            }

            for (var i = 0; i < resPaths.Count; i++)
            {
                var resPath = resPaths[i];
                var resName = Path.GetFileNameWithoutExtension(resPath);
                //var resMd = uint.TryParse(resName, out uint rid)
                //    ? resList.FirstOrDefault(r => r.Index == rid)
                //    : resList.FirstOrDefault(r =>
                //        resName == $"{r.Part}{PsbResCollector.ResourceNameDelimiter}{r.Name}");

                //Scan for Resource
                ResourceMetadata resMd = null;
                if (order == PsbLinkOrderBy.Name)
                {
                    if (resName == null)
                    {
                        continue;
                    }

                    if (resList.Count == 1 && resPaths.Count == 1)
                    {
                        //If there is only one resource and one texture, we won't care about file name.
                        resMd = resList[0];
                    }
                    else
                    {
                        var texIdx = ResourceMetadata.GetTextureIndex(resName);

                        if (texIdx == null)
                        {
                            Console.WriteLine($"[WARN]{resPath} is not used since the file name cannot be recognized.");
                            continue;
                        }

                        if (resList.Count <= texIdx.Value)
                        {
                            Console.WriteLine($"[WARN]{resPath} is not used since the tex No. is too large.");
                            continue;
                        }

                        resMd = resList[(int)texIdx.Value];
                    }
                }
                else //if (order == PsbLinkOrderBy.Convention)
                {
                    resMd = resList.FirstOrDefault(r =>
                                                   resName == $"{r.Part}{PsbResCollector.ResourceNameDelimiter}{r.Name}");
                    if (resMd == null && uint.TryParse(resName, out uint rid))
                    {
                        resMd = resList.FirstOrDefault(r => r.Index == rid);
                    }

                    if (resMd == null && psb.Type == PsbType.Pimg)
                    {
                        resMd = resList.FirstOrDefault(r => resName == Path.GetFileNameWithoutExtension(r.Name));
                    }
                }


                if (resMd == null)
                {
                    Console.WriteLine($"[WARN]{resPath} is not used.");
                    continue;
                }

                var    fullPath = Path.Combine(baseDir ?? "", resPath.Replace('/', '\\'));
                byte[] data     = LoadImageBytes(fullPath, resMd, context);
                resMd.Resource.Data = data;
            }
        }