Пример #1
0
        /// <summary>Get update check info about a mod.</summary>
        /// <param name="id">The mod ID.</param>
        public async Task <IModPage> GetModData(string id)
        {
            var page = new GenericModPage(this.SiteKey, id);

            if (!long.TryParse(id, out long parsedId))
            {
                return(page.SetError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid ModDrop mod ID, must be an integer ID."));
            }

            // get raw data
            ModListModel response = await this.Client
                                    .PostAsync("")
                                    .WithBody(new
            {
                ModIDs = new[] { parsedId },
                Files  = true,
                Mods   = true
            })
                                    .As <ModListModel>();

            ModModel mod = response.Mods[parsedId];

            if (mod.Mod?.Title == null || mod.Mod.ErrorCode.HasValue)
            {
                return(null);
            }

            // get files
            var downloads = new List <IModDownload>();

            foreach (FileDataModel file in mod.Files)
            {
                if (file.IsOld || file.IsDeleted || file.IsHidden)
                {
                    continue;
                }

                downloads.Add(
                    new GenericModDownload(file.Name, file.Description, file.Version)
                    );
            }

            // return info
            string name = mod.Mod?.Title;
            string url  = string.Format(this.ModUrlFormat, id);

            return(page.SetInfo(name: name, version: null, url: url, downloads: downloads));
        }
Пример #2
0
        /*********
        ** Private methods
        *********/
        /// <summary>Asynchronously fetch mod metadata from the wiki.</summary>
        public async Task <ModListModel> FetchDataAsync()
        {
            return(await this.Cache.GetOrCreateAsync($"{nameof(ModsController)}_mod_list", async entry =>
            {
                WikiModList data = await new ModToolkit().GetWikiCompatibilityListAsync();
                ModListModel model = new ModListModel(
                    stableVersion: data.StableVersion,
                    betaVersion: data.BetaVersion,
                    mods: data
                    .Mods
                    .Select(mod => new ModModel(mod))
                    .OrderBy(p => Regex.Replace(p.Name.ToLower(), "[^a-z0-9]", ""))     // ignore case, spaces, and special characters when sorting
                    );

                entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.SuccessCacheMinutes);
                return model;
            }));
        }
Пример #3
0
        public ModListModel ParseEntry(JsonEntry entry)
        {
            ModListModel mlm = new ModListModel();
            string       race, map, part, type;

            if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/"))
            {
                race = Strings.All;
            }
            else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman"))
            {
                race = Strings.Monster;
            }
            else
            {
                race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/'));

                if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11))
                {
                    race = race.Substring(race.LastIndexOf("--c") + 3, 4);
                }
                else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.LastIndexOf("/c") + 2, 4);
                }
                else if (entry.fullPath.Contains("_c_"))
                {
                    race = race.Substring(race.IndexOf("_c") + 2, 4);
                }
                else
                {
                    race = race.Substring(race.LastIndexOf('c') + 1, 4);
                }
                race = Info.IDRace[race];
            }

            mlm.Race = race;


            if (entry.fullPath.Contains("_d."))
            {
                map = Strings.Diffuse;
            }
            else if (entry.fullPath.Contains("_n."))
            {
                map = Strings.Normal;
            }
            else if (entry.fullPath.Contains("_s."))
            {
                map = Strings.Specular;
            }
            else if (entry.fullPath.Contains("material"))
            {
                map = Strings.ColorSet;
            }
            else if (entry.fullPath.Contains("model"))
            {
                map = "3D";
            }
            else if (entry.fullPath.Contains("ui/"))
            {
                map = "UI";
            }
            else
            {
                map = Strings.Mask;
            }

            mlm.Map = map;


            if (entry.fullPath.Contains("_b_"))
            {
                part = "b";
            }
            else if (entry.fullPath.Contains("_c_"))
            {
                part = "c";
            }
            else if (entry.fullPath.Contains("_d_"))
            {
                part = "d";
            }
            else if (entry.fullPath.Contains("decal"))
            {
                part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1));
            }
            else
            {
                part = "a";
            }

            mlm.Part = part;


            if (entry.fullPath.Contains("_iri_"))
            {
                type = "Iris";
            }
            else if (entry.fullPath.Contains("_etc_"))
            {
                type = "Etc.";
            }
            else if (entry.fullPath.Contains("_fac_"))
            {
                type = "Face";
            }
            else if (entry.fullPath.Contains("_hir_"))
            {
                type = "Hair";
            }
            else if (entry.fullPath.Contains("_acc_"))
            {
                type = "Accessory";
            }
            else if (entry.fullPath.Contains("demihuman"))
            {
                type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3);
                type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key;
            }
            else
            {
                type = "-";
            }

            mlm.Type = type;

            if (entry.fullPath.Contains("material"))
            {
                var info = MTRL.GetMTRLInfo(entry.modOffset, false);

                var bitmap = TEX.TextureToBitmap(info.ColorData, 9312, 4, 16);

                mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }
            else if (entry.fullPath.Contains("model"))
            {
                mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png"));
            }
            else
            {
                TEXData texData;

                if (entry.fullPath.Contains("vfx"))
                {
                    texData = TEX.GetVFX(entry.modOffset, entry.datFile);
                }
                else
                {
                    if (entry.fullPath.Contains("icon"))
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                    else
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                }

                mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }

            var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile);

            if (offset == entry.modOffset)
            {
                mlm.ActiveBorder  = Brushes.Green;
                mlm.Active        = Brushes.Transparent;
                mlm.ActiveOpacity = 1;
            }
            else if (offset == entry.originalOffset)
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Gray;
                mlm.ActiveOpacity = 0.5f;
            }
            else
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Red;
                mlm.ActiveOpacity = 1;
            }

            mlm.Entry = entry;

            return(mlm);
        }
Пример #4
0
        public ModListModel ParseEntry(JsonEntry entry)
        {
            ModListModel mlm = new ModListModel();
            string       race, map, part, type;

            if (entry.fullPath.Contains("mt_"))
            {
                Debug.WriteLine(entry.fullPath);
            }

            if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/"))
            {
                race = Strings.All;
            }
            else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman"))
            {
                race = Strings.Monster;
            }
            else
            {
                race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/'));
                if (entry.fullPath.Contains("mt_") && entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.IndexOf("_") + 2, 4);
                }
                else if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11))
                {
                    race = race.Substring(race.LastIndexOf("--c") + 3, 4);
                }
                else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.LastIndexOf("/c") + 2, 4);
                }
                else if (entry.fullPath.Contains("_c_"))
                {
                    race = race.Substring(race.IndexOf("_c") + 2, 4);
                }
                else
                {
                    if (entry.fullPath.Contains(".mdl") && entry.fullPath.Contains("_fac"))
                    {
                        race = race.Substring(race.IndexOf('c') + 1, 4);
                    }
                    else
                    {
                        race = race.Substring(race.LastIndexOf('c') + 1, 4);
                    }
                }

                if (entry.fullPath.Contains("mt_"))
                {
                    Debug.WriteLine(race + "\n");
                }

                race = Info.IDRace[race];
            }

            mlm.Race = race;


            if (entry.fullPath.Contains("_d."))
            {
                map = Strings.Diffuse;
            }
            else if (entry.fullPath.Contains("_n."))
            {
                map = Strings.Normal;
            }
            else if (entry.fullPath.Contains("_s."))
            {
                map = Strings.Specular;
            }
            else if (entry.fullPath.Contains("material"))
            {
                map = Strings.ColorSet;
            }
            else if (entry.fullPath.Contains("model"))
            {
                map = "3D";
            }
            else if (entry.fullPath.Contains("ui/"))
            {
                map = "UI";
            }
            else
            {
                map = Strings.Mask;
            }

            mlm.Map = map;


            if (entry.fullPath.Contains("_b_"))
            {
                part = "b";
            }
            else if (entry.fullPath.Contains("_c_"))
            {
                part = "c";
            }
            else if (entry.fullPath.Contains("_d_"))
            {
                part = "d";
            }
            else if (entry.fullPath.Contains("decal"))
            {
                part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1));
            }
            else
            {
                part = "a";
            }

            mlm.Part = part;


            if (entry.fullPath.Contains("_iri_"))
            {
                type = "Iris";
            }
            else if (entry.fullPath.Contains("_etc_"))
            {
                type = "Etc.";
            }
            else if (entry.fullPath.Contains("_fac_"))
            {
                type = "Face";
            }
            else if (entry.fullPath.Contains("_hir_"))
            {
                type = "Hair";
            }
            else if (entry.fullPath.Contains("_acc_"))
            {
                type = "Accessory";
            }
            else if (entry.fullPath.Contains("demihuman"))
            {
                type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3);
                type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key;
            }
            else
            {
                type = "-";
            }

            mlm.Type = type;

            if (entry.fullPath.Contains("material"))
            {
                var info = MTRL.GetMTRLInfo(entry.modOffset, false);

                using (var bitmap = TEX.ColorSetToBitmap(info.ColorData))
                    mlm.BMP = TexHelper.CreateBitmapSource(bitmap);
                mlm.BMP.Freeze();
            }
            else if (entry.fullPath.Contains("model"))
            {
                mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png"));
            }
            else
            {
                TEXData texData;

                if (entry.fullPath.Contains("vfx"))
                {
                    texData = TEX.GetVFX(entry.modOffset, entry.datFile);
                }
                else
                {
                    if (entry.fullPath.Contains("icon"))
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                    else
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                }

                var scale = 1;

                if (texData.Width >= 4096 || texData.Height >= 4096)
                {
                    scale = 16;
                }
                else if (texData.Width >= 2048 || texData.Height >= 2048)
                {
                    scale = 8;
                }
                else if (texData.Width >= 1024 || texData.Height >= 1024)
                {
                    scale = 4;
                }

                var nWidth  = texData.Width / scale;
                var nHeight = texData.Height / scale;

                var resizedImage = TexHelper.CreateResizedImage(texData.BMPSouceNoAlpha, nWidth, nHeight);
                mlm.BMP = (BitmapSource)resizedImage;
                mlm.BMP.Freeze();
            }

            var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile);

            if (offset == entry.modOffset)
            {
                mlm.ActiveBorder  = Brushes.Green;
                mlm.Active        = Brushes.Transparent;
                mlm.ActiveOpacity = 1;
            }
            else if (offset == entry.originalOffset)
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Gray;
                mlm.ActiveOpacity = 0.5f;
            }
            else
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Red;
                mlm.ActiveOpacity = 1;
            }

            mlm.Entry = entry;

            return(mlm);
        }
Пример #5
0
        /// <summary>Get metadata about a mod.</summary>
        /// <param name="id">The ModDrop mod ID.</param>
        /// <returns>Returns the mod info if found, else <c>null</c>.</returns>
        public async Task <ModDropMod> GetModAsync(long id)
        {
            // get raw data
            ModListModel response = await this.Client
                                    .PostAsync("")
                                    .WithBody(new
            {
                ModIDs = new[] { id },
                Files  = true,
                Mods   = true
            })
                                    .As <ModListModel>();

            ModModel mod = response.Mods[id];

            if (mod.Mod?.Title == null || mod.Mod.ErrorCode.HasValue)
            {
                return(null);
            }

            // get latest versions
            ISemanticVersion latest   = null;
            ISemanticVersion optional = null;

            foreach (FileDataModel file in mod.Files)
            {
                if (file.IsOld || file.IsDeleted || file.IsHidden)
                {
                    continue;
                }

                if (!SemanticVersion.TryParse(file.Version, out ISemanticVersion version))
                {
                    continue;
                }

                if (file.IsDefault)
                {
                    if (latest == null || version.IsNewerThan(latest))
                    {
                        latest = version;
                    }
                }
                else if (optional == null || version.IsNewerThan(optional))
                {
                    optional = version;
                }
            }
            if (latest == null)
            {
                latest   = optional;
                optional = null;
            }
            if (optional != null && latest.IsNewerThan(optional))
            {
                optional = null;
            }

            // generate result
            return(new ModDropMod
            {
                Name = mod.Mod?.Title,
                LatestDefaultVersion = latest,
                LatestOptionalVersion = optional,
                Url = string.Format(this.ModUrlFormat, id)
            });
        }