2023-08-21 10:58:17 -04:00
using System ;
2023-07-03 23:24:35 -04:00
using System.Collections.Generic ;
2024-03-20 23:18:34 -04:00
using System.Diagnostics.CodeAnalysis ;
2023-08-21 10:58:17 -04:00
using System.IO ;
2023-07-03 23:24:35 -04:00
using System.Linq ;
2024-03-20 23:18:34 -04:00
using System.Net.Http ;
using System.Text.Json ;
2023-10-01 13:12:27 -04:00
using System.Text.Json.Serialization ;
2024-03-20 23:18:34 -04:00
using System.Text.Json.Serialization.Metadata ;
using System.Threading ;
2023-08-21 10:58:17 -04:00
using System.Threading.Tasks ;
2023-07-10 07:35:05 -04:00
using Luski.net.Enums ;
2024-03-20 23:18:34 -04:00
using Luski.Shared.PublicServers.V1.Enums ;
using Luski.Shared.PublicServers.V1.ServerToClient.HTTP ;
2023-07-03 23:24:35 -04:00
namespace Luski.net ;
public class API
{
2023-10-01 13:12:27 -04:00
[JsonIgnore]
2023-07-08 09:06:13 -04:00
public MainServer MainServer { get ; internal set ; }
2023-10-01 12:28:10 -04:00
public bool IsAnyServerLoggedin { get ; internal set ; }
2024-03-20 23:18:34 -04:00
public const string DefaultVersion = "v1" ;
internal List < string > Versions = new ( )
{
DefaultVersion
} ;
public IReadOnlyList < string > SupportedVersions = > Versions . AsReadOnly ( ) ;
2023-07-08 09:06:13 -04:00
internal List < PublicServer > InternalServers { get ; } = new ( ) ;
public IReadOnlyList < PublicServer > LoadedServers = > InternalServers . AsReadOnly ( ) ;
2024-03-20 23:18:34 -04:00
2024-08-27 10:57:22 -04:00
internal List < PublicServer > InternalFailedServers { get ; } = new ( ) ;
public IReadOnlyList < PublicServer > FailedServers = > InternalFailedServers . AsReadOnly ( ) ;
2024-03-20 23:18:34 -04:00
private static HttpResponseMessage GetFromServer ( string Domain , string ApiVersion , bool Secure , string Path , CancellationToken CancellationToken , params KeyValuePair < string , string? > [ ] Headers )
{
using HttpClient web = new ( ) ;
web . Timeout = TimeSpan . FromSeconds ( 10 ) ;
if ( Headers is not null & & Headers . Length > 0 ) foreach ( KeyValuePair < string , string? > header in Headers ) web . DefaultRequestHeaders . Add ( header . Key , header . Value ) ;
return web . GetAsync ( $"{(Secure ? " https " : " http " )}://{Domain}/{ApiVersion}/{Path}" , cancellationToken : CancellationToken ) . Result ;
}
private static Task < Tresult > GetFromServer < Tresult > ( string Domain , string ApiVersion , bool Secure , string Path , JsonTypeInfo < Tresult > Type , CancellationToken CancellationToken , params KeyValuePair < string , string? > [ ] Headers ) where Tresult : STC , new ( )
{
HttpResponseMessage ServerResponce = GetFromServer ( Domain , ApiVersion , Secure , Path , CancellationToken , Headers ) ;
Tresult temp = new ( ) ;
string raw = ServerResponce . Content . ReadAsStringAsync ( CancellationToken ) . Result ;
try
{
temp = JsonSerializer . Deserialize ( raw , Type ) ! ;
}
catch ( Exception e )
{
Console . WriteLine ( "JSON parse failed for the following data as type {0}\n{1}" , temp . GetType ( ) , raw ) ;
}
if ( temp is null ) return Task . FromResult ( new Tresult ( ) { StatusCode = ServerResponce . StatusCode , Error = ErrorCode . ServerError , ErrorMessage = $"Server responded with empty data" } ) ;
return Task . FromResult ( temp ) ;
}
public Task < ServerInfoSTC > GetServerInfo ( string Domain , string Version = DefaultVersion ,
bool Secure = true )
{
ServerInfoSTC ? si = GetFromServer ( Domain , Version , Secure , "socketserver" , ServerInfoSTCContext . Default . ServerInfoSTC , CancellationToken . None ) . Result ;
if ( si is null ) throw new Exception ( "Bad Response" ) ;
return Task . FromResult ( si ) ;
}
2023-10-01 12:28:10 -04:00
2024-03-20 23:18:34 -04:00
public Task < bool > TryGetServerInfo ( [ NotNullWhen ( true ) ] out ServerInfoSTC ? si , string Domain , string Version = DefaultVersion ,
2023-10-01 12:28:10 -04:00
bool Secure = true )
{
2024-03-20 23:18:34 -04:00
2023-10-01 12:28:10 -04:00
try
{
2024-03-20 23:18:34 -04:00
si = GetServerInfo ( Domain , Version , Secure ) . Result ;
return Task . FromResult ( true ) ;
}
catch ( Exception e )
{
si = null ;
return Task . FromResult ( false ) ;
}
}
public Task < bool > TryGetPublicServer ( out PublicServer Server , string Domain , string Version = DefaultVersion ,
bool Secure = true , bool GenerateEncryption = true , bool LogConsole = false )
{
try
{
Task < PublicServer > result = GetPublicServer ( Domain , Version , Secure , GenerateEncryption , LogConsole ) ;
2023-10-01 12:28:10 -04:00
Task . WaitAll ( result ) ;
Server = result . Result ;
return Task . FromResult ( true ) ;
}
catch ( Exception e )
{
2024-03-20 23:18:34 -04:00
if ( ! e . Message . Contains ( "Connection refused" ) ) Console . WriteLine ( e ) ;
2023-10-01 12:28:10 -04:00
Server = null ! ;
return Task . FromResult ( false ) ;
}
}
2023-07-03 23:24:35 -04:00
2024-03-20 23:18:34 -04:00
public async Task < PublicServer > GetPublicServer ( string Domain , string Version = DefaultVersion , bool Secure = true , bool GenerateEncryption = true , bool LogConsole = false )
2023-07-03 23:24:35 -04:00
{
2023-08-21 10:58:17 -04:00
PublicServer s ;
try
2023-07-03 23:24:35 -04:00
{
2023-08-21 10:58:17 -04:00
IEnumerable < PublicServer > isl = InternalServers . Where ( a = > ( a . Domain = = Domain & & a . ApiVersion = = Version ) ) ;
if ( isl . Any ( ) ) return isl . First ( ) ;
2024-08-27 10:57:22 -04:00
s = await PublicServer . GetServer ( InternalFailedServers , Domain , Version , Secure , GenerateEncryption , LogConsole ) ;
2023-08-21 10:58:17 -04:00
}
catch ( Exception e )
{
2023-08-25 12:07:36 -04:00
Console . WriteLine ( "Failed to connect to public server '{0}' using API {1}. No alternate server was found." , Domain , Version ) ;
2023-08-21 10:58:17 -04:00
throw ;
}
2023-08-25 12:07:36 -04:00
2023-08-21 10:58:17 -04:00
string? f = s . Storage . GetStorageDirectory ( StorageDirectory . StorageInfo ) + "token" ;
if ( File . Exists ( f ) )
{
f = File . ReadAllText ( f ) ;
}
else f = null ;
try
{
if ( f is not null )
{
bool b = await s . LoginViaToken ( f ) ;
2023-10-01 12:28:10 -04:00
if ( b )
{
IsAnyServerLoggedin = true ;
}
2023-08-21 10:58:17 -04:00
else
{
s . Token = null ;
s . Error = null ;
}
}
}
catch
{
}
2023-07-03 23:24:35 -04:00
InternalServers . Add ( s ) ;
return s ;
}
2024-03-20 23:18:34 -04:00
public MainServer GetMainServer ( string Domain , string Version = DefaultVersion )
2023-07-03 23:24:35 -04:00
{
2023-08-21 10:58:17 -04:00
DateTime dt = DateTime . UtcNow ;
Console . WriteLine ( "Conecting to main server '{0}' using API {1}." , Domain , Version ) ;
2023-10-01 13:12:27 -04:00
MainServer = new ( Domain , Version )
2023-07-03 23:24:35 -04:00
{
2023-07-10 07:35:05 -04:00
ServerType = ServerType . Main
2023-07-03 23:24:35 -04:00
} ;
2023-08-21 10:58:17 -04:00
Console . WriteLine ( "Connected to main server '{0}' using API {1} in {2}." , Domain , Version , DateTime . UtcNow . Subtract ( dt ) . ToString ( "g" ) ) ;
2023-07-03 23:24:35 -04:00
return MainServer ;
}
}