fix: load images for main repo plugins from main repo, json for third-party

This commit is contained in:
goat 2021-08-23 15:46:13 +02:00
parent 80f2990d8f
commit 4ff74f9c33
No known key found for this signature in database
GPG key ID: F18F057873895461

View file

@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Numerics; using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -37,6 +38,10 @@ namespace Dalamud.Interface.Internal.Windows
private const int PluginIconWidth = 512; private const int PluginIconWidth = 512;
private const int PluginIconHeight = 512; private const int PluginIconHeight = 512;
// TODO: Change back to master after release
private const string MainRepoImageUrl =
"https://raw.githubusercontent.com/goatcorp/DalamudPlugins/api4/{0}/{1}/images/{2}";
private static readonly ModuleLog Log = new("PLUGINW"); private static readonly ModuleLog Log = new("PLUGINW");
private readonly TextureWrap defaultIcon; private readonly TextureWrap defaultIcon;
@ -56,7 +61,7 @@ namespace Dalamud.Interface.Internal.Windows
private bool hasDevPlugins = false; private bool hasDevPlugins = false;
private bool downloadingIcons = false; private bool downloadingIcons = false;
private Dictionary<string, (bool IsDownloaded, TextureWrap[] Textures)> pluginImagesMap = new(); private Dictionary<string, (bool IsDownloaded, TextureWrap?[]? Textures)> pluginImagesMap = new();
private Dictionary<string, (bool IsDownloaded, TextureWrap? Texture)> pluginIconMap = new(); private Dictionary<string, (bool IsDownloaded, TextureWrap? Texture)> pluginIconMap = new();
private string searchText = string.Empty; private string searchText = string.Empty;
@ -177,13 +182,26 @@ namespace Dalamud.Interface.Internal.Windows
private static Vector2 GetButtonSize(string text) => ImGui.CalcTextSize(text) + (ImGui.GetStyle().FramePadding * 2); private static Vector2 GetButtonSize(string text) => ImGui.CalcTextSize(text) + (ImGui.GetStyle().FramePadding * 2);
// TODO: This is a stopgap solution, ideally will be rewritten with something better in mind soon private static string? GetPluginIconUrl(PluginManifest manifest, bool isThirdParty, bool isTesting)
private static bool IsSafeUrl(string url)
{ {
return url.StartsWith("https://raw.githubusercontent.com/goatcorp/DalamudPlugins/"); if (isThirdParty)
// || url.StartsWith("https://cdn.discordapp.com/") return manifest.IconUrl;
// || url.StartsWith("https://i.imgur.com/")
// || url.StartsWith("https://git.sr.ht/"); return MainRepoImageUrl.Format(isTesting ? "testing" : "plugins", manifest.InternalName, "icon.png");
}
private static List<string>? GetPluginImageUrls(PluginManifest manifest, bool isThirdParty, bool isTesting)
{
if (isThirdParty)
return manifest.ImageUrls;
var output = new List<string>();
for (var i = 1; i <= 5; i++)
{
output.Add(MainRepoImageUrl.Format(isTesting ? "testing" : "plugins", manifest.InternalName, $"image{i}.png"));
}
return output;
} }
private void DrawHeader() private void DrawHeader()
@ -1279,6 +1297,8 @@ namespace Dalamud.Interface.Internal.Windows
{ {
var popupId = $"plugin{index}image{i}"; var popupId = $"plugin{index}image{i}";
var image = images.Textures[i]; var image = images.Textures[i];
if (image == null)
continue;
ImGui.PushStyleVar(ImGuiStyleVar.PopupBorderSize, 0); ImGui.PushStyleVar(ImGuiStyleVar.PopupBorderSize, 0);
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
@ -1452,6 +1472,8 @@ namespace Dalamud.Interface.Internal.Windows
this.downloadingIcons = true; this.downloadingIcons = true;
var pluginManager = Service<PluginManager>.Get();
Log.Verbose("Start downloading plugin icons..."); Log.Verbose("Start downloading plugin icons...");
Task.Run(async () => Task.Run(async () =>
@ -1460,8 +1482,10 @@ namespace Dalamud.Interface.Internal.Windows
foreach (var pluginManifest in plugins) foreach (var pluginManifest in plugins)
{ {
var useTesting = pluginManager.UseTesting(pluginManifest);
if (!this.pluginIconMap.ContainsKey(pluginManifest.InternalName)) if (!this.pluginIconMap.ContainsKey(pluginManifest.InternalName))
await this.DownloadPluginIconAsync(pluginManifest); await this.DownloadPluginIconAsync(pluginManifest, useTesting);
} }
}).ContinueWith(t => }).ContinueWith(t =>
{ {
@ -1470,24 +1494,25 @@ namespace Dalamud.Interface.Internal.Windows
}); });
} }
private async Task DownloadPluginIconAsync(RemotePluginManifest manifest) private async Task DownloadPluginIconAsync(RemotePluginManifest manifest, bool isTesting)
{ {
var interfaceManager = Service<InterfaceManager>.Get(); var interfaceManager = Service<InterfaceManager>.Get();
Log.Verbose($"Downloading icon for {manifest.InternalName}"); Log.Verbose($"Downloading icon for {manifest.InternalName}");
this.pluginIconMap.Add(manifest.InternalName, (false, null)); this.pluginIconMap.Add(manifest.InternalName, (false, null));
var url = GetPluginIconUrl(manifest, manifest.SourceRepo.IsThirdParty, isTesting);
Log.Verbose($"Icon from {url}");
var client = new HttpClient(); var client = new HttpClient();
if (manifest.IconUrl != null) if (url != null)
{ {
if (!IsSafeUrl(manifest.IconUrl) && !manifest.SourceRepo.IsThirdParty) var data = await client.GetAsync(url);
{ if (data.StatusCode == HttpStatusCode.NotFound)
Log.Error($"Icon at {manifest.IconUrl} is not on a whitelisted host.");
return; return;
}
var data = await client.GetAsync(manifest.IconUrl);
data.EnsureSuccessStatusCode(); data.EnsureSuccessStatusCode();
var icon = interfaceManager.LoadImage(await data.Content.ReadAsByteArrayAsync()); var icon = interfaceManager.LoadImage(await data.Content.ReadAsByteArrayAsync());
@ -1513,6 +1538,7 @@ namespace Dalamud.Interface.Internal.Windows
private async Task DownloadPluginImagesAsync(PluginManifest manifest, bool isThirdParty) private async Task DownloadPluginImagesAsync(PluginManifest manifest, bool isThirdParty)
{ {
var interfaceManager = Service<InterfaceManager>.Get(); var interfaceManager = Service<InterfaceManager>.Get();
var pluginManager = Service<PluginManager>.Get();
Log.Verbose($"Downloading images for {manifest.InternalName}"); Log.Verbose($"Downloading images for {manifest.InternalName}");
@ -1520,24 +1546,27 @@ namespace Dalamud.Interface.Internal.Windows
var client = new HttpClient(); var client = new HttpClient();
if (manifest.ImageUrls != null) var urls = GetPluginImageUrls(manifest, isThirdParty, pluginManager.UseTesting(manifest));
var didAny = false;
if (urls != null)
{ {
if (manifest.ImageUrls.Count > 5) if (urls.Count > 5)
{ {
Log.Error($"Plugin {manifest.InternalName} has too many images."); Log.Error($"Plugin {manifest.InternalName} has too many images.");
return; return;
} }
var pluginImages = new TextureWrap[manifest.ImageUrls.Count]; var pluginImages = new TextureWrap[urls.Count];
for (var i = 0; i < manifest.ImageUrls.Count; i++) for (var i = 0; i < urls.Count; i++)
{ {
if (!IsSafeUrl(manifest.ImageUrls[i]) && !isThirdParty) var data = await client.GetAsync(urls[i]);
{
Log.Error($"Icon at {manifest.IconUrl} is not on a whitelisted host."); Serilog.Log.Information($"Download from {urls[i]}");
return;
} if (data.StatusCode == HttpStatusCode.NotFound)
continue;
var data = await client.GetAsync(manifest.ImageUrls[i]);
data.EnsureSuccessStatusCode(); data.EnsureSuccessStatusCode();
var image = interfaceManager.LoadImage(await data.Content.ReadAsByteArrayAsync()); var image = interfaceManager.LoadImage(await data.Content.ReadAsByteArrayAsync());
@ -1548,14 +1577,19 @@ namespace Dalamud.Interface.Internal.Windows
if (image.Height != PluginImageHeight || image.Width != PluginImageWidth) if (image.Height != PluginImageHeight || image.Width != PluginImageWidth)
{ {
Log.Error($"Image at {manifest.ImageUrls[i]} was not of the correct resolution."); Log.Error($"Image at {urls[i]} was not of the correct resolution.");
return; return;
} }
didAny = true;
pluginImages[i] = image; pluginImages[i] = image;
} }
this.pluginImagesMap[manifest.InternalName] = (true, pluginImages); if (didAny)
{
this.pluginImagesMap[manifest.InternalName] = (true, pluginImages);
}
} }
Log.Verbose($"Plugin images for {manifest.InternalName} downloaded"); Log.Verbose($"Plugin images for {manifest.InternalName} downloaded");