2023-07-08 09:06:13 -04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2023-07-10 14:19:03 -04:00
using System.Net ;
using System.Text ;
2023-07-08 09:06:13 -04:00
using System.Text.Json.Serialization.Metadata ;
using System.Threading ;
using System.Threading.Tasks ;
2023-07-10 14:19:03 -04:00
using JacobTechEncryption ;
2023-07-10 07:35:05 -04:00
using Luski.net.Enums.Main ;
2023-07-08 09:06:13 -04:00
using Luski.net.Interfaces ;
2023-07-10 14:19:03 -04:00
using Luski.net.JsonTypes ;
2023-07-08 09:06:13 -04:00
using Luski.net.JsonTypes.HTTP ;
using Luski.net.Structures.Main ;
2024-03-20 23:18:34 -04:00
using Luski.Shared.PublicServers.V1.ClientToServer.HTTP ;
using Luski.Shared.PublicServers.V1.Enums ;
using Luski.Shared.PublicServers.V1.ServerToClient.HTTP ;
using ChannelType = Luski . net . Enums . Main . ChannelType ;
2023-07-08 09:06:13 -04:00
namespace Luski.net ;
public partial class MainServer : Server
{
2023-10-01 13:12:27 -04:00
internal MainServer ( string Domain , string API_Version ) :
base ( Domain , API_Version )
2023-07-10 14:19:03 -04:00
{
}
2023-07-08 09:06:13 -04:00
public MainSocketAppUser User { get ; internal set ; } = default ! ;
2023-08-21 10:58:17 -04:00
public List < MainSocketChannel > chans { get ; } = new ( ) ;
2023-07-10 14:19:03 -04:00
public async Task < MainSocketRemoteUser > SendFriendResult ( long user , bool answer , CancellationToken CancellationToken )
{
FriendRequestResult json = await SendServer ( "FriendRequestResult" ,
new FriendRequestResultOut ( )
{
Id = user ,
Result = answer
} ,
FriendRequestResultOutContext . Default . FriendRequestResultOut ,
FriendRequestResultContext . Default . FriendRequestResult ,
CancellationToken ) ;
if ( json is not null & & json . Error is null & & json . ErrorMessage is null & & answer & & json . Channel is not null )
{
MainSocketDMChannel chan = await GetChannel ( ( long ) json . Channel , MainSocketDMChannelContext . Default . MainSocketDMChannel , CancellationToken ) ;
_ = chan . StartKeyProcessAsync ( CancellationToken ) ;
chans . Add ( chan ) ;
}
else
{
throw new Exception ( json ? . Error . ToString ( ) ) ;
}
return GetUser ( user , MainSocketRemoteUserContext . Default . MainSocketRemoteUser , CancellationToken ) . Result ;
}
public async Task < MainSocketRemoteUser > SendFriendRequest ( long code , CancellationToken CancellationToken )
{
string ccode = Convert . ToBase64String ( Encryption . Hashing . SHA256 ( Encoding . Unicode . GetBytes ( code . ToString ( ) ) ) ) ;
FriendRequestResult ? json = await SendServer ( "FriendRequest" , new FriendRequest ( ) { code = ccode } , FriendRequestContext . Default . FriendRequest , FriendRequestResultContext . Default . FriendRequestResult , CancellationToken ) ;
if ( json . StatusCode ! = HttpStatusCode . Accepted )
{
if ( json is not null & & json . Error is not null )
{
switch ( ( ErrorCode ) ( int ) json . Error )
{
case ErrorCode . InvalidToken :
throw new Exception ( "Your current token is no longer valid" ) ;
case ErrorCode . ServerError :
throw new Exception ( $"Error from server: {json.ErrorMessage}" ) ;
case ErrorCode . InvalidPostData :
throw new Exception ( "The post data dent to the server is not the correct format. This may be because you app is couropt or you are using the wron API version" ) ;
case ErrorCode . Forbidden :
throw new Exception ( "You already have an outgoing request or the persone is not real" ) ;
}
}
if ( json is not null & & json . Channel is not null )
{
MainSocketDMChannel chan = await GetChannel ( ( long ) json . Channel , MainSocketDMChannelContext . Default . MainSocketDMChannel , CancellationToken ) ;
_ = chan . StartKeyProcessAsync ( CancellationToken ) ;
chans . Add ( chan ) ;
}
}
MainSocketRemoteUser b = await GetUser ( code , MainSocketRemoteUserContext . Default . MainSocketRemoteUser , CancellationToken ) ;
if ( json . Channel is not null )
b . FriendStatus = FriendStatus . Friends ;
else
b . FriendStatus = FriendStatus . PendingOut ;
return b ;
}
2023-07-08 09:06:13 -04:00
public async Task < TChannel > GetChannel < TChannel > ( long Channel , CancellationToken CancellationToken ) where TChannel : MainSocketChannel , new ( )
{
TChannel Return = new ( ) ;
switch ( Return )
{
case MainSocketDMChannel :
Return = ( await GetChannel ( Channel , MainSocketDMChannelContext . Default . MainSocketDMChannel , CancellationToken ) as TChannel ) ! ;
break ;
case MainSocketGroupChannel :
Return = ( await GetChannel ( Channel , MainSocketGroupChannelContext . Default . MainSocketGroupChannel , CancellationToken ) as TChannel ) ! ;
break ;
case MainSocketTextChannel :
Return = ( await GetChannel ( Channel , MainSocketTextChannelContext . Default . MainSocketTextChannel , CancellationToken ) as TChannel ) ! ;
break ;
case MainSocketChannel :
Return = ( await GetChannel ( Channel , MainSocketChannelContext . Default . MainSocketChannel , CancellationToken ) as TChannel ) ! ;
break ;
case null :
throw new NullReferenceException ( nameof ( TChannel ) ) ;
default :
throw new Exception ( "Unknown channel type" ) ;
}
return Return ;
}
internal async Task < TChannel > GetChannel < TChannel > ( long id , JsonTypeInfo < TChannel > Json , CancellationToken CancellationToken ) where TChannel : MainSocketChannel , new ( )
{
TChannel request ;
if ( chans . Count > 0 & & chans . Any ( s = > s . Id = = id ) )
{
2023-08-21 10:58:17 -04:00
return ( chans . Where ( s = > s is TChannel & & s . Id = = id ) . First ( ) as TChannel ) ! ;
2023-07-08 09:06:13 -04:00
}
while ( true )
{
if ( CanRequest )
{
request = await GetFromServer ( $"SocketChannel/Get/{id}" , Json , CancellationToken ) ;
break ;
}
}
if ( request is null ) throw new Exception ( "Something was wrong with the server responce" ) ;
if ( request . Error is null )
{
if ( chans . Count > 0 & & chans . Any ( s = > s . Id = = request . Id ) )
{
foreach ( MainSocketChannel ? p in chans . Where ( s = > s . Id = = request . Id ) )
{
chans . Remove ( p ) ;
}
}
2023-07-10 07:35:05 -04:00
request . Server = this ;
2023-07-08 09:06:13 -04:00
chans . Add ( request ) ;
return request ;
}
throw request . Error switch
{
ErrorCode . InvalidToken = > new Exception ( "Your current token is no longer valid" ) ,
ErrorCode . Forbidden = > new Exception ( "The server rejected your request" ) ,
ErrorCode . ServerError = > new Exception ( "Error from server: " + request . ErrorMessage ) ,
ErrorCode . InvalidURL or ErrorCode . MissingHeader = > new Exception ( request . ErrorMessage ) ,
_ = > new Exception ( $"Unknown data: '{request.ErrorMessage}'" ) ,
} ;
}
public Task < Tuser > GetUser < Tuser > ( long UserID , CancellationToken CancellationToken ) where Tuser : MainSocketUserBase , new ( )
{
Tuser user = new ( ) ;
switch ( user )
{
case MainSocketAppUser :
user = ( GetUser ( UserID , MainSocketAppUserContext . Default . MainSocketAppUser , CancellationToken ) . Result as Tuser ) ! ;
break ;
2023-07-10 07:35:05 -04:00
case MainSocketRemoteUser :
user = ( GetUser ( UserID , MainSocketRemoteUserContext . Default . MainSocketRemoteUser , CancellationToken ) . Result as Tuser ) ! ;
break ;
2023-07-08 09:06:13 -04:00
case MainSocketUserBase :
user = ( GetUser ( UserID , MainSocketUserBaseContext . Default . MainSocketUserBase , CancellationToken ) . Result as Tuser ) ! ;
break ;
case null :
throw new NullReferenceException ( nameof ( Tuser ) ) ;
default :
throw new Exception ( "Unknown channel type" ) ;
}
return Task . FromResult ( user ) ;
}
public async Task < MainSocketMessage > GetMessage ( long id , CancellationToken CancellationToken )
{
MainSocketMessage message ;
while ( true )
{
if ( CanRequest )
{
message = await GetFromServer ( "socketmessage" ,
MainSocketMessageContext . Default . MainSocketMessage ,
CancellationToken ,
2023-07-10 07:35:05 -04:00
new KeyValuePair < string , string? > ( "msg_id" , id . ToString ( ) ) ) ;
2023-07-08 09:06:13 -04:00
break ;
}
}
2023-07-10 07:35:05 -04:00
if ( message is not null )
{
message . Server = this ;
return message ;
}
2023-07-08 09:06:13 -04:00
throw new Exception ( "Server did not return a message" ) ;
}
/// <summary>
/// Sends the server a request to update the <paramref name="Status"/> of you account
/// </summary>
/// <param name="Status">The <see cref="UserStatus"/> you want to set your status to</param>
/// <exception cref="Exception"></exception>
public async Task < Task > UpdateStatus ( UserStatus Status , CancellationToken CancellationToken )
{
2024-03-20 23:18:34 -04:00
STC ? data = await SendServer ( "SocketUserProfile/Status" , new StatusUpdateCTS ( ) { Status = Status } , StatusUpdateCTSContext . Default . StatusUpdateCTS , STCContext . Default . STC , CancellationToken ) ;
2023-07-08 09:06:13 -04:00
if ( data . Error is not null & & ( ( int ) data . StatusCode < 200 | | ( int ) data . StatusCode > 299 ) )
{
if ( data ? . ErrorMessage is not null ) throw new Exception ( data . ErrorMessage ) ;
if ( data ? . Error is not null ) throw new Exception ( ( ( int ) data . Error ) . ToString ( ) ) ;
else throw new Exception ( "Something went worng" ) ;
}
User . Status = Status ;
return Task . CompletedTask ;
}
internal async Task < Tuser > GetUser < Tuser > ( long UserId , JsonTypeInfo < Tuser > Json , CancellationToken CancellationToken ) where Tuser : MainSocketUserBase , new ( )
{
Tuser user ;
if ( poeople . Count > 0 & & poeople . Any ( s = > s . Id = = UserId ) )
{
Tuser temp = poeople . Where ( s = > s is Tuser & & s . Id = = UserId ) . Cast < Tuser > ( ) . FirstOrDefault ( ) ! ;
2023-07-10 07:35:05 -04:00
if ( temp is MainSocketRemoteUser & & ( temp as MainSocketRemoteUser ) ! . Channel = = null )
{
foreach ( MainSocketDMChannel chan in chans . Where ( s = > s is MainSocketDMChannel ) . Cast < MainSocketDMChannel > ( ) )
{
if ( chan . Type = = ChannelType . DM & & chan . Id ! = 0 & & chan . MemberIdList is not null )
{
if ( chan . MemberIdList . Any ( s = > s = = UserId ) ) ( temp as MainSocketRemoteUser ) ! . Channel = chan ;
}
}
}
2023-07-08 09:06:13 -04:00
return temp ;
}
while ( true )
{
if ( CanRequest )
{
user = await GetFromServer ( "socketuser" ,
Json ,
CancellationToken ,
new KeyValuePair < string , string? > ( "id" , UserId . ToString ( ) ) ) ;
break ;
}
}
if ( user is null ) throw new Exception ( "Server did not return a user" ) ;
if ( poeople . Count > 0 & & poeople . Any ( s = > s . Id = = UserId ) )
{
foreach ( IUser ? p in poeople . Where ( s = > s . Id = = UserId ) )
{
poeople . Remove ( p ) ;
}
}
2023-07-10 07:35:05 -04:00
user . Server = this ;
if ( user is MainSocketRemoteUser & & ( user as MainSocketRemoteUser ) ! . Channel = = null )
{
foreach ( MainSocketDMChannel chan in chans . Where ( s = > s is MainSocketDMChannel ) . Cast < MainSocketDMChannel > ( ) )
{
if ( chan . Type = = ChannelType . DM & & chan . Id ! = 0 & & chan . MemberIdList is not null )
{
if ( chan . MemberIdList . Any ( s = > s = = UserId ) ) ( user as MainSocketRemoteUser ) ! . Channel = chan ;
}
}
}
2023-07-08 09:06:13 -04:00
poeople . Add ( user ) ;
return user ;
}
}