MatrixRoomUtils

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | LICENSE

IHomeServer.cs (5255B)


      1 using System.Net.Http.Json;
      2 using System.Text.Json;
      3 using MatrixRoomUtils.Core.Extensions;
      4 using MatrixRoomUtils.Core.Responses;
      5 
      6 namespace MatrixRoomUtils.Core.Interfaces;
      7 
      8 public class IHomeServer
      9 {
     10     private Dictionary<string, ProfileResponse?> _profileCache = new();
     11     public string HomeServerDomain { get; set; }
     12     public string FullHomeServerDomain { get; set; }
     13 
     14     private protected HttpClient _httpClient { get; set; } = new();
     15 
     16     public async Task<string> ResolveHomeserverFromWellKnown(string homeserver)
     17     {
     18         var res = await _resolveHomeserverFromWellKnown(homeserver);
     19         if(!res.StartsWith("http")) res = "https://" + res;
     20         if(res.EndsWith(":443")) res = res.Substring(0, res.Length - 4);
     21         return res;
     22     }
     23     private async Task<string> _resolveHomeserverFromWellKnown(string homeserver)
     24     {
     25         if (RuntimeCache.HomeserverResolutionCache.Count == 0)
     26         {
     27             Console.WriteLine("No cached homeservers, resolving...");
     28             await Task.Delay(Random.Shared.Next(1000, 5000));
     29         } 
     30         if (RuntimeCache.HomeserverResolutionCache.ContainsKey(homeserver))
     31         {
     32             if (RuntimeCache.HomeserverResolutionCache[homeserver].ResolutionTime < DateTime.Now.AddHours(1))
     33             {
     34                 Console.WriteLine($"Found cached homeserver: {RuntimeCache.HomeserverResolutionCache[homeserver].Result}");
     35                 return RuntimeCache.HomeserverResolutionCache[homeserver].Result;
     36             }
     37             Console.WriteLine($"Cached homeserver expired, removing: {RuntimeCache.HomeserverResolutionCache[homeserver].Result}");
     38             RuntimeCache.HomeserverResolutionCache.Remove(homeserver);
     39         }
     40         //throw new NotImplementedException();
     41 
     42         string result = null;
     43         Console.WriteLine($"Resolving homeserver: {homeserver}");
     44         if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver;
     45         if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client"))
     46         {
     47             Console.WriteLine($"Got successful response for client well-known...");
     48             var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/client");
     49             Console.WriteLine($"Response: {resp.ToString()}");
     50             var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString();
     51             result = hs;
     52         }
     53         else
     54         {
     55             Console.WriteLine($"No client well-known...");
     56             if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server"))
     57             {
     58                 var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/server");
     59                 var hs = resp.GetProperty("m.server").GetString();
     60                 result = hs;
     61             }
     62             else
     63             {
     64                 Console.WriteLine($"No server well-known...");
     65                 if (await _httpClient.CheckSuccessStatus($"{homeserver}/_matrix/client/versions")) result = homeserver;
     66                 else
     67                 {
     68                     Console.WriteLine("No homeserver on shortname...");
     69                     if (await _httpClient.CheckSuccessStatus($"{homeserver.Replace("//", "//matrix.")}/_matrix/client/versions")) result = homeserver.Replace("//", "//matrix.");
     70                     else Console.WriteLine($"Failed to resolve homeserver, not on {homeserver}, nor do client or server well-knowns exist!");
     71                 }
     72             }
     73         }
     74 
     75         if (result != null)
     76         {
     77             Console.WriteLine($"Resolved homeserver: {homeserver} -> {result}");
     78             RuntimeCache.HomeserverResolutionCache.TryAdd(homeserver, new()
     79             {
     80                 Result = result,
     81                 ResolutionTime = DateTime.Now
     82             });
     83             return result;
     84         }
     85         throw new InvalidDataException($"Failed to resolve homeserver, not on {homeserver}, nor do client or server well-knowns exist!");
     86     }
     87     public async Task<ProfileResponse> GetProfile(string mxid, bool debounce = false, bool cache = true)
     88     {
     89         if (cache)
     90         {
     91             if(debounce) await Task.Delay(Random.Shared.Next(100, 500));
     92             if (_profileCache.ContainsKey(mxid))
     93             {
     94                 while (_profileCache[mxid] == null)
     95                 {
     96                     Console.WriteLine($"Waiting for profile cache for {mxid}, currently {_profileCache[mxid]?.ToJson() ?? "null"} within {_profileCache.Count} profiles...");
     97                     await Task.Delay(Random.Shared.Next(50, 500));
     98                 }
     99                 return _profileCache[mxid];
    100             }
    101         }
    102 
    103         _profileCache.Add(mxid, null);
    104         var resp = await _httpClient.GetAsync($"/_matrix/client/r0/profile/{mxid}");
    105         var data = await resp.Content.ReadFromJsonAsync<JsonElement>();
    106         if(!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data.ToString());
    107         var profile = data.Deserialize<ProfileResponse>();
    108         _profileCache[mxid] = profile;
    109         return profile;
    110     }
    111     public string ResolveMediaUri(string mxc)
    112     {
    113         return mxc.Replace("mxc://", $"{FullHomeServerDomain}/_matrix/media/r0/download/");
    114     }
    115 }