using System.IO; using System.Net.Http; namespace Sandbox.TextureLoader; internal static class ImageUrl { /// /// For textures loaded from the web we want to keep them around a bit longer /// static CaseInsensitiveDictionary Loaded = new(); internal static bool IsAppropriate( string url ) { return url.StartsWith( "https://" ) || url.StartsWith( "http://" ); } internal static Texture Load( string filename, bool warnOnMissing ) { if ( Loaded.TryGetValue( filename, out var cachedTexture ) ) { return cachedTexture; } try { // // Create a 1x1 placeholder texture // var placeholder = Texture.Create( 1, 1 ).WithName( "httpimg-placeholder" ).WithData( new byte[4] { 0, 0, 0, 0 } ).Finish(); _ = placeholder.ReplacementAsync( LoadFromUrl( filename ) ); Loaded[filename] = placeholder; return placeholder; } catch ( System.Exception e ) { Log.Warning( $"Couldn't Load from Url {filename} ({e.Message})" ); return null; } } static HttpClient HttpClient; internal static async Task LoadFromUrl( string url ) { HttpClient ??= new HttpClient(); var filename = url; try { // I'd love to retry this multiple times, if it's a weird error that seems recoverable var bytes = await HttpClient.GetByteArrayAsync( url ); Texture texture = null; // decode in a thread await Task.Run( () => { using var ms = new MemoryStream( bytes ); texture = Image.Load( ms, url ); } ); return texture; } catch ( System.Security.Authentication.AuthenticationException ) { Log.Warning( $"AuthenticationException when downloading {url}" ); } catch ( HttpRequestException e ) { Log.Warning( e, $"HttpRequestException when downloading {url}" ); } return default; } }