Files
sbox-public/engine/Sandbox.Engine/Resources/Textures/Loader/HttpImageLoader.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

78 lines
1.8 KiB
C#

using System.IO;
using System.Net.Http;
namespace Sandbox.TextureLoader;
internal static class ImageUrl
{
/// <summary>
/// For textures loaded from the web we want to keep them around a bit longer
/// </summary>
static CaseInsensitiveDictionary<Texture> 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<Texture> 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;
}
}