2023-08-21 10:58:17 -04:00
using System ;
using System.Collections.Generic ;
2024-08-27 10:57:22 -04:00
using System.IO ;
2023-08-21 10:58:17 -04:00
using System.Linq ;
2023-08-25 12:07:36 -04:00
using System.Net.Http ;
2023-08-21 10:58:17 -04:00
using System.Text ;
using System.Threading ;
using System.Threading.Tasks ;
using JacobTechEncryption ;
using JacobTechEncryption.Enums ;
using Luski.net.Enums ;
using Luski.net.Interfaces ;
using Luski.net.JsonTypes ;
using Luski.net.JsonTypes.HTTP ;
using Luski.net.Structures ;
using Luski.net.Structures.Public ;
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 Luski.Shared.PublicServers.V1.Shared ;
2023-08-21 10:58:17 -04:00
using Role = Luski . net . Structures . Public . Role ;
using SocketUser = Luski . net . Structures . Public . SocketUser ;
2023-07-08 09:06:13 -04:00
namespace Luski.net ;
2023-08-21 10:58:17 -04:00
public partial class PublicServer : Server
2023-07-08 09:06:13 -04:00
{
2024-03-20 23:18:34 -04:00
public event Func < SocketMessage , Task > ? MessageReceived ;
2024-08-27 10:57:22 -04:00
public event Func < UserStatus , SocketUser , Task > ? StatusUpdate ;
public event Func < bool , Role , Task > ? RoleEvent ;
public event Func < Role , Task > ? RoleDeleted ;
public event Func < Role , IUser [ ] , IUser [ ] , Task > ? RoleMemberEvent ;
public PictureType PictureType { get ; private set ; }
2023-08-21 10:58:17 -04:00
public List < SocketChannel > chans { get ; } = new ( ) ;
public List < SocketCategory > cats { get ; } = new ( ) ;
public List < Role > roles { get ; } = new ( ) ;
2024-03-31 23:57:12 -04:00
public List < RoleOverride > roleso { get ; } = new ( ) ;
2023-08-21 10:58:17 -04:00
public SocketAppUser User { get ; private set ; } = null ! ;
2023-08-25 12:07:36 -04:00
2023-10-01 13:12:27 -04:00
private PublicServer ( string Domain , string API_Version , bool Secure = true ) :
base ( Domain , API_Version , Secure )
2023-08-25 12:07:36 -04:00
{ }
2024-08-27 10:57:22 -04:00
internal static async Task < PublicServer > GetServer ( List < PublicServer > Failed , string Domain , string API_Version , bool Secure = true , bool GenerateEncryption = true , bool LogConsole = false )
2023-08-21 10:58:17 -04:00
{
2023-08-25 12:07:36 -04:00
DateTime dt = DateTime . UtcNow ;
Console . WriteLine ( "Connecting to public server '{0}' using API {1}." , Domain , API_Version ) ;
2023-10-01 13:12:27 -04:00
PublicServer s = new ( Domain , API_Version , Secure ) ;
2024-03-20 23:18:34 -04:00
s . PrintServerMessages = LogConsole ;
if ( GenerateEncryption )
{
Thread t = new ( _ = >
{
s . EncryptionHandler . GenerateKeys ( ) ;
} ) ;
t . Start ( ) ;
}
ServerInfoSTC ? si = null ;
2023-08-25 12:07:36 -04:00
try
{
2024-03-20 23:18:34 -04:00
si = await s . GetFromServer ( "socketserver" , ServerInfoSTCContext . Default . ServerInfoSTC , CancellationToken . None ) ;
2023-08-25 12:07:36 -04:00
s . EncryptionHandler . ServerPublicKey = await ( await new HttpClient ( )
. GetAsync ( $"{(s.Secure ? " https " : " http ")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey" ) )
. Content
. ReadAsStringAsync ( ) ;
}
catch ( Exception e )
{
2024-08-27 10:57:22 -04:00
LocalServerInfo ServerListing = s . Storage . GetJson ( StorageDirectory . ServerInfo , "server.json" , true ,
2023-08-25 12:07:36 -04:00
LocalServerInfoContext . Default . LocalServerInfo ) ;
2024-08-27 10:57:22 -04:00
s . Name = ServerListing . Name ;
s . Description = ServerListing . Description ;
s . PictureType = ServerListing . PictureType ;
2023-08-25 12:07:36 -04:00
if ( ServerListing . AlternateServers . Length > 0 )
{
Console . WriteLine ( "Failed to connect to public server '{0}' using API {1}. Attempting to connect to alternate servers." , Domain , API_Version ) ;
foreach ( ServerData Server in ServerListing . AlternateServers )
{
s . Secure = Server . Secure ;
s . Domain = Server . DomainAndPort ;
try
{
2024-03-20 23:18:34 -04:00
si = await s . GetFromServer ( "socketserver" , ServerInfoSTCContext . Default . ServerInfoSTC , CancellationToken . None ) ;
2023-08-25 12:07:36 -04:00
s . EncryptionHandler . ServerPublicKey = await ( await new HttpClient ( )
. GetAsync ( $"{(s.Secure ? " https " : " http ")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey" ) )
. Content
. ReadAsStringAsync ( ) ;
Console . WriteLine ( "Public server '{0}' connection restored by alternate server '{1}' using API {2}." , Domain , s . Domain , API_Version ) ;
break ;
}
catch
{
// ignored
}
}
}
2024-08-27 10:57:22 -04:00
if ( si is null )
{
Failed . Add ( s ) ;
2024-11-18 23:24:23 -05:00
s . ConnectionStatus = ConnectionStatus . FailedToConnect ;
2024-08-27 10:57:22 -04:00
throw ;
}
2023-08-25 12:07:36 -04:00
}
2024-11-18 23:24:23 -05:00
s . ConnectionStatus = ConnectionStatus . ConnectedNotLoggedIn ;
2024-08-27 10:57:22 -04:00
s . Storage . SetJson ( StorageDirectory . ServerInfo , "server.json" , new ( )
{
AlternateServers = Array . Empty < ServerData > ( ) ,
PictureType = si . PictureType ,
Name = si . Name ,
Description = si . Description
} ,
LocalServerInfoContext . Default . LocalServerInfo ) ;
2024-03-20 23:18:34 -04:00
s . Name = si . Name ;
2024-08-27 10:57:22 -04:00
s . PictureType = si . PictureType ;
2024-03-20 23:18:34 -04:00
s . Description = si . Description ;
s . wssurl = si . WSSv4Address ;
2023-08-25 12:07:36 -04:00
s . ServerType = ServerType . Public ;
2024-03-20 23:18:34 -04:00
s . OwnerID = si . Owner ;
2023-08-25 12:07:36 -04:00
Console . WriteLine ( "Connected to public server '{0}' using API {1} in {4}.\nServer Name: {2}\nServer Description: {3}" , Domain , API_Version , s . Name , s . Description , DateTime . UtcNow . Subtract ( dt ) . ToString ( "g" ) ) ;
return s ;
2023-08-21 10:58:17 -04:00
}
2024-03-20 23:18:34 -04:00
public long OwnerID { get ; private set ; } = 0 ;
2023-08-21 10:58:17 -04:00
public async Task < TCategory > GetCategory < TCategory > ( long id , CancellationToken CancellationToken ) where TCategory : SocketCategory , new ( )
{
2024-03-20 23:18:34 -04:00
CategorySTC request ;
2023-08-21 10:58:17 -04:00
if ( cats . Count > 0 & & cats . Any ( s = > s . ID = = id ) )
{
return ( cats . Where ( s = > s is TCategory & & s . ID = = id ) . First ( ) as TCategory ) ! ;
}
while ( true )
{
if ( CanRequest )
{
2024-03-20 23:18:34 -04:00
request = await GetFromServer ( $"SocketCategory" , CategorySTCContext . Default . CategorySTC , CancellationToken , new KeyValuePair < string , string? > ( "id" , id . ToString ( ) ) ) ;
2023-08-21 10:58:17 -04:00
break ;
}
}
if ( request is null ) throw new Exception ( "Something was wrong with the server responce" ) ;
if ( request . Error is null )
{
if ( cats . Count > 0 & & cats . Any ( s = > s . ID = = request . ID ) )
{
foreach ( SocketCategory ? p in cats . Where ( s = > s . ID = = request . ID ) )
{
cats . Remove ( p ) ;
}
}
2024-03-20 23:18:34 -04:00
LocalKeyInfo deckey ;
if ( request . DescriptionEncryptionKey ! = 0 )
deckey = EncryptionHandler . GetKey ( request . DescriptionEncryptionKey ) ;
else deckey = new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ;
2023-08-21 10:58:17 -04:00
string dec = deckey . EncryptionType switch
{
EncryptionType . RSA = > Encryption . RSA . Decrypt ( Convert . FromBase64String ( request . Description ) , deckey . Key , request . DescriptionEncoderType ) ,
EncryptionType . AES = > Encryption . Generic . Encoders [ ( short ) request . DescriptionEncoderType ] . GetString (
Encryption . AES . Decrypt ( Convert . FromBase64String ( request . Description ) , deckey . Key ) ) ,
_ = > Encryption . Generic . Encoders [ ( short ) request . DescriptionEncoderType ] . GetString ( Convert . FromBase64String ( request . Description ) )
} ;
2024-03-20 23:18:34 -04:00
LocalKeyInfo nkey ;
if ( request . TitleEncryptionKey ! = 0 )
nkey = EncryptionHandler . GetKey ( request . TitleEncryptionKey ) ;
else nkey = new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ;
2023-08-21 10:58:17 -04:00
string n = nkey . EncryptionType switch
{
EncryptionType . RSA = > Encryption . RSA . Decrypt ( Convert . FromBase64String ( request . Name ) , nkey . Key , request . TitleEncoderType ) ,
EncryptionType . AES = > Encryption . Generic . Encoders [ ( short ) request . TitleEncoderType ] . GetString (
Encryption . AES . Decrypt ( Convert . FromBase64String ( request . Name ) , nkey . Key ) ) ,
_ = > Encryption . Generic . Encoders [ ( short ) request . TitleEncoderType ] . GetString ( Convert . FromBase64String ( request . Name ) )
} ;
TCategory bob = new ( )
{
ID = request . ID ,
ParentID = request . Parent ,
Description = dec ,
DescriptionEncoderType = request . DescriptionEncoderType ,
DescriptionEncryptionKey = request . DescriptionEncryptionKey ,
Channels = request . Channels ,
Categories = request . InnerCategories ,
Name = n ,
2024-03-20 23:18:34 -04:00
RoleOverides = request . RoleOverrides ,
UserOverides = request . UserOverrides ,
2023-08-21 10:58:17 -04:00
TitleEncoderType = request . TitleEncoderType ,
TitleEncryptionKey = request . TitleEncryptionKey ,
2024-11-18 23:24:23 -05:00
Server = this
2023-08-21 10:58:17 -04:00
} ;
cats . Add ( bob ) ;
return bob ;
}
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}'" ) ,
} ;
}
2024-03-20 23:18:34 -04:00
2023-08-21 10:58:17 -04:00
public async Task < Role > GetRole ( long id )
{
Role [ ] r = roles . Where ( s = > s . ID = = id ) . ToArray ( ) ;
if ( r . Length > 0 ) return r [ 0 ] ;
2024-03-20 23:18:34 -04:00
RoleSTC s = await GetFromServer ( "SocketRole?id=" + id . ToString ( ) , RoleSTCContext . Default . RoleSTC , CancellationToken . None ) ;
2023-08-21 10:58:17 -04:00
2024-08-27 10:57:22 -04:00
List < Color > cols = new ( ) ;
if ( s . ColorType = = ColorType . Full )
{
Color nc = new ( s . Color ) ;
cols . Add ( nc ) ;
}
else
{
for ( int i = 0 ; i < s . Color . Length - 7 ; i + = 8 )
{
cols . Add ( new ( s . Color [ i . . ( i + 8 ) ] ) ) ;
}
}
2023-08-21 10:58:17 -04:00
Role role = new ( )
{
Server = this ,
2024-03-20 23:18:34 -04:00
ID = s . ID ,
2024-08-27 10:57:22 -04:00
ColorType = s . ColorType ,
Colors = cols . ToArray ( ) ,
2024-03-20 23:18:34 -04:00
Description = s . Description ,
DisplayName = s . DisplayName ,
MembersListID = s . Members ,
Index = s . Index ,
ServerPermissions = s . ServerPermissions
2023-08-21 10:58:17 -04:00
} ;
roles . Add ( role ) ;
return role ;
}
2024-03-31 23:57:12 -04:00
public async Task < Role [ ] > GetRoles ( )
{
RolesSTC s = await GetFromServer ( "SocketRole/GetAll" , RolesSTCContext . Default . RolesSTC , CancellationToken . None ) ;
roles . Clear ( ) ;
foreach ( var ServerRole in s . Roles )
{
2024-08-27 10:57:22 -04:00
List < Color > cols = new ( ) ;
if ( ServerRole . ColorType = = ColorType . Full )
{
Color nc = new ( ServerRole . Color ) ;
cols . Add ( nc ) ;
}
else
{
for ( int i = 0 ; i < ServerRole . Color . Length - 7 ; i + = 8 )
{
cols . Add ( new ( ServerRole . Color [ i . . ( i + 8 ) ] ) ) ;
}
}
2024-03-31 23:57:12 -04:00
roles . Add ( new Role ( )
{
Server = this ,
ID = ServerRole . ID ,
2024-08-27 10:57:22 -04:00
ColorType = ServerRole . ColorType ,
Colors = cols . ToArray ( ) ,
2024-03-31 23:57:12 -04:00
Description = ServerRole . Description ,
DisplayName = ServerRole . DisplayName ,
MembersListID = ServerRole . Members ,
Index = ServerRole . Index ,
ServerPermissions = ServerRole . ServerPermissions
} ) ;
}
return roles . ToArray ( ) ;
}
2024-03-20 23:18:34 -04:00
public async Task < SocketMessage > SendMessage < TChannel > ( TChannel channel , string msg , SocketMessage ? ReplyTo = null ,
2024-08-27 10:57:22 -04:00
ServerProfile ? FakeProfile = null , params string [ ] files ) where TChannel : SocketChannel , new ( )
{
List < SocketFile > lll = new ( ) ;
foreach ( var f in files )
{
lll . Add ( await UploadFile ( f ) ) ;
}
return await SendMessage ( channel , msg , ReplyTo , FakeProfile , lll . ToArray ( ) ) ;
}
public async Task < SocketFile > UploadFile ( string File )
{
FileInfo FI = new FileInfo ( File ) ;
ServerFileInfoSTC res = await SendServer ( "SocketFile" , File , ServerFileInfoSTCContext . Default . ServerFileInfoSTC ,
CancellationToken . None ,
new ( "name_encoder" , "0" ) ,
new ( "encoder" , "0" ) ,
new ( "name_encryption" , "0" ) ,
new ( "encryption" , "0" ) ,
new ( "name" , Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( FI . Name ) ) ) ) ;
if ( res . ErrorMessage is not null | | res . Error is not null )
{
Console . WriteLine ( "Error {0}: {1}" , ( res . Error is null ? "Unknown" : res . Error . Value ) , res . ErrorMessage ) ;
}
return new SocketFile ( )
{
ID = res . ID ,
Encoder = EncoderType . UTF8 ,
Key = 0 ,
Name = FI . Name ,
NameEncoder = EncoderType . UTF8 ,
NameKey = 0 ,
Server = this ,
Size = FI . Length
} ;
}
public async Task < SocketMessage > SendMessage < TChannel > ( TChannel channel , string msg , SocketMessage ? ReplyTo = null ,
ServerProfile ? FakeProfile = null , params SocketFile [ ] files ) where TChannel : SocketChannel , new ( )
2024-03-20 23:18:34 -04:00
{
string bc = "" ;
if ( channel . EncryptionKeys [ 0 ] = = 0 )
{
if ( ! string . IsNullOrEmpty ( msg ) )
bc = Convert . ToBase64String ( Encryption . Generic . Encoders [ ( int ) channel . EncoderTypes [ 0 ] ] . GetBytes ( msg ) ) ;
}
else
{
LocalKeyInfo key = channel . Server . EncryptionHandler . GetKey ( channel . EncryptionKeys [ 0 ] ) ;
bc = Convert . ToBase64String ( key . EncryptionType switch
{
EncryptionType . RSA = > Encryption . RSA . Encrypt ( msg , key . Key , channel . EncoderTypes [ 0 ] ) ,
_ = > Encryption . AES . Encrypt ( Encryption . Generic . Encoders [ ( int ) channel . EncoderTypes [ 0 ] ] . GetBytes ( msg ) , key . Key )
} ) ;
}
2024-08-27 10:57:22 -04:00
List < long > lll = new ( ) ;
foreach ( var f in files )
{
lll . Add ( f . ID ) ;
}
2024-03-20 23:18:34 -04:00
MessageCTS pcsm = new ( )
{
2024-08-27 10:57:22 -04:00
Files = lll . ToArray ( ) ,
2024-03-20 23:18:34 -04:00
ChannelID = channel . ID ,
EncryptionKey = channel . EncryptionKeys [ 0 ] ,
Encoding = channel . EncoderTypes [ 0 ] ,
2024-08-27 10:57:22 -04:00
Base64Context = bc ,
2024-03-20 23:18:34 -04:00
} ;
if ( FakeProfile is not null )
{
2024-08-27 10:57:22 -04:00
pcsm . Profile = FakeProfile . ID ;
2024-03-20 23:18:34 -04:00
}
MessageSTC smsg = await channel . Server . SendServer ( "socketmessage" , pcsm ,
MessageCTSContext . Default . MessageCTS , MessageSTCContext . Default . MessageSTC ,
CancellationToken . None ) ;
List < long > fl = new ( ) ;
foreach ( var VARIABLE in smsg . Files )
{
fl . Add ( VARIABLE . ID ) ;
}
SocketMessage sm = new ( )
{
ID = smsg . ID ,
AuthorID = smsg . AuthorID ,
2024-08-27 10:57:22 -04:00
ProfileID = smsg . ProfileID ,
2024-03-20 23:18:34 -04:00
ChannelID = channel . ID ,
2024-08-27 10:57:22 -04:00
TimeStamp = smsg . Timestamp ,
2024-03-20 23:18:34 -04:00
Context = msg ,
EncoderType = smsg . EncoderType ,
EncryptionKey = smsg . EncryptionKey ,
FileIDs = fl . ToArray ( ) ,
Server = channel . Server ,
2024-08-27 10:57:22 -04:00
_Files = files . ToList ( )
2024-03-20 23:18:34 -04:00
} ;
return sm ;
}
2024-08-27 10:57:22 -04:00
public async Task < Role > CreateRole ( RolePostCTS Req )
{
RoleSTC res = await SendServer ( "SocketRole" ,
Req ,
RolePostCTSContext . Default . RolePostCTS ,
RoleSTCContext . Default . RoleSTC ,
CancellationToken . None ) ;
List < Color > cols = new ( ) ;
if ( res . ColorType = = ColorType . Full )
{
Color nc = new ( res . Color ) ;
cols . Add ( nc ) ;
}
else
{
for ( int i = 0 ; i < res . Color . Length - 7 ; i + = 8 )
{
cols . Add ( new ( res . Color [ i . . ( i + 8 ) ] ) ) ;
}
}
Role role = new Role ( )
{
DisplayName = res . DisplayName ,
ServerPermissions = res . ServerPermissions ,
Description = res . Description ,
Index = res . Index ,
MembersListID = res . Members ,
ColorType = res . ColorType ,
Colors = cols . ToArray ( ) ,
Server = this ,
ID = res . ID
} ;
roles . Add ( role ) ;
return role ;
}
public async Task < Role > EditRole ( Role role , string? Name = null , string? Description = null , int? Index = null , ServerPermission ? Permissions = null , string? Color = null , ColorType ? colorType = null )
{
RoleSTC res = await SendServerPatch ( "SocketRole" ,
new ( )
{
ID = role . ID ,
Description = Description ,
DisplayName = Name ,
Index = Index ,
ColorType = colorType ,
Color = Color ,
ServerPermissions = Permissions
} ,
RolePatchCTSContext . Default . RolePatchCTS ,
RoleSTCContext . Default . RoleSTC ,
CancellationToken . None ) ;
if ( Permissions is not null ) role . ServerPermissions = res . ServerPermissions ;
if ( Description is not null ) role . Description = res . Description ;
if ( Index is not null ) role . Index = res . Index ;
if ( Name is not null ) role . DisplayName = res . DisplayName ;
if ( Color is not null ) role . Colors = new [ ] { new Color ( res . Color ) } ;
if ( colorType is not null ) role . ColorType = res . ColorType ;
return role ;
}
public async Task < Role > EditRoleMembers ( Role r )
{
return r ;
}
2023-08-21 10:58:17 -04:00
public async Task < TChannel > GetChannel < TChannel > ( long id , CancellationToken CancellationToken ) where TChannel : SocketChannel , new ( )
{
2024-03-20 23:18:34 -04:00
ChannelSTC request ;
2023-08-21 10:58:17 -04:00
if ( chans . Count > 0 & & chans . Any ( s = > s . ID = = id ) )
{
return ( chans . Where ( s = > s is TChannel & & s . ID = = id ) . First ( ) as TChannel ) ! ;
}
while ( true )
{
if ( CanRequest )
{
2024-03-20 23:18:34 -04:00
request = await GetFromServer ( $"SocketChannel" , ChannelSTCContext . Default . ChannelSTC , CancellationToken , new KeyValuePair < string , string? > ( "id" , id . ToString ( ) ) ) ;
2023-08-21 10:58:17 -04:00
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 ( SocketChannel ? p in chans . Where ( s = > s . ID = = request . ID ) )
{
chans . Remove ( p ) ;
}
}
2024-03-20 23:18:34 -04:00
LocalKeyInfo deckey ;
if ( request . DescriptionEncryptionKey ! = 0 )
deckey = EncryptionHandler . GetKey ( request . DescriptionEncryptionKey ) ;
else deckey = new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ;
2023-08-21 10:58:17 -04:00
string dec = deckey . EncryptionType switch
{
EncryptionType . RSA = > Encryption . RSA . Decrypt ( Convert . FromBase64String ( request . Description ) , deckey . Key , request . DescriptionEncoderType ) ,
EncryptionType . AES = > Encryption . Generic . Encoders [ ( short ) request . DescriptionEncoderType ] . GetString (
Encryption . AES . Decrypt ( Convert . FromBase64String ( request . Description ) , deckey . Key ) ) ,
_ = > Encryption . Generic . Encoders [ ( short ) request . DescriptionEncoderType ] . GetString ( Convert . FromBase64String ( request . Description ) )
} ;
2024-03-20 23:18:34 -04:00
LocalKeyInfo nkey ;
if ( request . TitleEncryptionKey ! = 0 )
nkey = EncryptionHandler . GetKey ( request . TitleEncryptionKey ) ;
else nkey = new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ;
2023-08-21 10:58:17 -04:00
string n = nkey . EncryptionType switch
{
EncryptionType . RSA = > Encryption . RSA . Decrypt ( Convert . FromBase64String ( request . Name ) , nkey . Key , request . TitleEncoderType ) ,
EncryptionType . AES = > Encryption . Generic . Encoders [ ( short ) request . TitleEncoderType ] . GetString (
Encryption . AES . Decrypt ( Convert . FromBase64String ( request . Name ) , nkey . Key ) ) ,
_ = > Encryption . Generic . Encoders [ ( short ) request . TitleEncoderType ] . GetString ( Convert . FromBase64String ( request . Name ) )
} ;
TChannel bob = new ( )
{
ID = request . ID ,
CategoryID = request . Parent ,
Description = dec ,
DescriptionEncoderType = request . DescriptionEncoderType ,
DescriptionEncryptionKey = request . DescriptionEncryptionKey ,
EncoderTypes = request . EncoderTypes ,
EncryptionKeys = request . EncryptionKeys ,
Epoch = request . Epoch ,
Name = n ,
2024-03-20 23:18:34 -04:00
RoleOverrides = request . RoleOverrides ,
UserOverrides = request . UserOverrides ,
2023-08-21 10:58:17 -04:00
Type = request . Type ,
TitleEncoderType = request . TitleEncoderType ,
TitleEncryptionKey = request . TitleEncryptionKey ,
PictureType = request . PictureType ,
Server = this ,
} ;
2024-03-31 23:57:12 -04:00
2023-08-21 10:58:17 -04:00
chans . Add ( bob ) ;
return bob ;
}
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}'" ) ,
} ;
}
2024-03-20 23:18:34 -04:00
public async Task < SocketChannel > MakeChannel ( SocketCategory parent , string Name , string Decription )
{
ChannelSTC res = await SendServer (
"SocketChannel" ,
new ChannelPostCTS ( )
{
Name = Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( Name ) ) ,
2024-03-31 23:57:12 -04:00
Description = Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( Decription ) ) ,
2024-03-20 23:18:34 -04:00
EncoderTypes = new [ ] { EncoderType . UTF16 } ,
EncryptionKeys = new long [ ] { 0 } ,
DescriptionEncoderType = EncoderType . UTF8 ,
TitleEncoderType = EncoderType . UTF8 ,
Parent = parent . ID ,
DescriptionEncryptionKey = 0 ,
TitleEncryptionKey = 0 ,
2024-08-27 10:57:22 -04:00
RoleOverrides = Array . Empty < RoleOverrideCTS > ( ) ,
2024-03-20 23:18:34 -04:00
UserOverrides = Array . Empty < UserOverrideCTS > ( ) ,
Type = ChannelType . TextAndVoice ,
PictureType = PictureType . none
} ,
ChannelPostCTSContext . Default . ChannelPostCTS ,
ChannelSTCContext . Default . ChannelSTC ,
CancellationToken . None ) ;
2024-08-27 10:57:22 -04:00
2024-03-20 23:18:34 -04:00
return new SocketChannel ( )
{
ID = res . ID ,
CategoryID = res . Parent ,
2024-03-31 23:57:12 -04:00
Description = Decription ,
2024-03-20 23:18:34 -04:00
DescriptionEncoderType = res . DescriptionEncoderType ,
DescriptionEncryptionKey = res . DescriptionEncryptionKey ,
EncoderTypes = res . EncoderTypes ,
EncryptionKeys = res . EncryptionKeys ,
Epoch = res . Epoch ,
Name = Name ,
RoleOverrides = res . RoleOverrides ,
UserOverrides = res . UserOverrides ,
Type = res . Type ,
TitleEncoderType = res . TitleEncoderType ,
TitleEncryptionKey = res . TitleEncryptionKey ,
PictureType = res . PictureType ,
2024-11-18 23:24:23 -05:00
Server = this
2024-03-20 23:18:34 -04:00
} ;
}
2023-08-21 10:58:17 -04:00
public async Task < Tuser > GetUser < Tuser > ( long UserId , CancellationToken CancellationToken ) where Tuser : SocketUser , new ( )
{
2024-03-20 23:18:34 -04:00
SocketUserSTC user ;
2023-08-21 10:58:17 -04:00
if ( poeople . Count > 0 & & poeople . Any ( s = > s . Id = = UserId ) )
{
Tuser temp = poeople . Where ( s = > s is Tuser & & s . Id = = UserId ) . Cast < Tuser > ( ) . FirstOrDefault ( ) ! ;
return temp ;
}
while ( true )
{
if ( CanRequest )
{
user = await GetFromServer ( "socketuser" ,
2024-03-20 23:18:34 -04:00
SocketUserSTCContext . Default . SocketUserSTC ,
2023-08-21 10:58:17 -04:00
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 ) ;
}
}
if ( user is null | | user . Error is not null )
{
string error = "User was null" ;
if ( user is not null & & user . Error is not null ) error = $"{user.Error}: {user.ErrorMessage}" ;
throw new Exception ( $"Something went wrong getting your user information\n{error}" ) ;
}
Tuser u = new ( ) ;
2024-03-31 23:57:12 -04:00
if ( typeof ( Tuser ) . FullName = = typeof ( SocketUser ) . FullName )
2023-08-21 10:58:17 -04:00
{
u = new ( )
{
Server = this ,
Id = user . ID ,
2024-08-27 10:57:22 -04:00
ServerProfile = user . ServerProfile ,
2023-08-21 10:58:17 -04:00
RoleIds = user . RoleIds ,
Status = user . Status
} ;
}
else
{
u = ( new SocketAppUser ( )
{
Server = this ,
Id = user . ID ,
2024-08-27 10:57:22 -04:00
ServerProfile = user . ServerProfile ,
2023-08-21 10:58:17 -04:00
SelectedChannel = user . SelectedChannel ,
RoleIds = user . RoleIds ,
Status = user . Status ,
} as Tuser ) ! ;
}
poeople . Add ( u ) ;
return u ;
}
2024-08-27 10:57:22 -04:00
public Tuser GetUser < Tuser > ( long UserId ) where Tuser : SocketUser , new ( )
2024-03-20 23:18:34 -04:00
{
2024-08-27 10:57:22 -04:00
SocketUserSTC user ;
if ( poeople . Count > 0 & & poeople . Any ( s = > s . Id = = UserId ) )
2024-03-20 23:18:34 -04:00
{
2024-08-27 10:57:22 -04:00
Tuser temp = poeople . Where ( s = > s is Tuser & & s . Id = = UserId ) . Cast < Tuser > ( ) . FirstOrDefault ( ) ! ;
2024-03-20 23:18:34 -04:00
return temp ;
}
while ( true )
{
if ( CanRequest )
{
2024-08-27 10:57:22 -04:00
user = GetFromServerRaw ( "socketuser" ,
SocketUserSTCContext . Default . SocketUserSTC ,
new KeyValuePair < string , string? > ( "id" , UserId . ToString ( ) ) ) ;
2024-03-20 23:18:34 -04:00
break ;
}
}
if ( user is null ) throw new Exception ( "Server did not return a user" ) ;
2024-08-27 10:57:22 -04:00
if ( poeople . Count > 0 & & poeople . Any ( s = > s . Id = = UserId ) )
2024-03-20 23:18:34 -04:00
{
2024-08-27 10:57:22 -04:00
foreach ( IUser ? p in poeople . Where ( s = > s . Id = = UserId ) )
2024-03-20 23:18:34 -04:00
{
2024-08-27 10:57:22 -04:00
poeople . Remove ( p ) ;
2024-03-20 23:18:34 -04:00
}
}
if ( user is null | | user . Error is not null )
{
string error = "User was null" ;
if ( user is not null & & user . Error is not null ) error = $"{user.Error}: {user.ErrorMessage}" ;
throw new Exception ( $"Something went wrong getting your user information\n{error}" ) ;
}
2024-08-27 10:57:22 -04:00
Tuser u = new ( ) ;
if ( typeof ( Tuser ) . FullName = = typeof ( SocketUser ) . FullName )
{
u = new ( )
{
Server = this ,
Id = user . ID ,
ServerProfile = user . ServerProfile ,
RoleIds = user . RoleIds ,
Status = user . Status
} ;
}
else
{
u = ( new SocketAppUser ( )
{
Server = this ,
Id = user . ID ,
ServerProfile = user . ServerProfile ,
SelectedChannel = user . SelectedChannel ,
RoleIds = user . RoleIds ,
Status = user . Status ,
} as Tuser ) ! ;
}
poeople . Add ( u ) ;
return u ;
}
public async Task < ServerProfile > GetProfile ( long ProfileId , CancellationToken CancellationToken )
{
ProfileSTC user ;
if ( profiles . Count > 0 & & profiles . Any ( s = > s . ID = = ProfileId ) )
{
ServerProfile temp = profiles . Where ( s = > s . ID = = ProfileId ) . FirstOrDefault ( ) ! ;
return temp ;
}
while ( true )
{
if ( CanRequest )
{
user = await GetFromServer ( "socketprofile" ,
ChannelProfileSTCContext . Default . ProfileSTC ,
CancellationToken ,
new KeyValuePair < string , string? > ( "id" , ProfileId . ToString ( ) ) ) ;
break ;
}
}
if ( user is null ) throw new Exception ( "Server did not return a user" ) ;
if ( profiles . Count > 0 & & profiles . Any ( s = > s . ID = = ProfileId ) )
{
_ = profiles . RemoveAll ( s = > s . ID = = ProfileId ) ;
}
if ( user is null | | user . Error is not null )
{
string error = "User was null" ;
if ( user is not null & & user . Error is not null ) error = $"{user.Error}: {user.ErrorMessage}" ;
throw new Exception ( $"Something went wrong getting your user information\n{error}" ) ;
}
ServerProfile u = new ( )
2024-03-20 23:18:34 -04:00
{
Server = this ,
2024-08-27 10:57:22 -04:00
ID = user . ID ,
2024-03-20 23:18:34 -04:00
DisplayName = user . DisplayName ,
PictureType = user . PictureType ,
Controllers = user . Controllers ,
2024-11-18 23:24:23 -05:00
RoleControllers = user . RoleControllers
2024-03-20 23:18:34 -04:00
} ;
2024-08-27 10:57:22 -04:00
profiles . Add ( u ) ;
2024-03-20 23:18:34 -04:00
return u ;
}
2024-08-27 10:57:22 -04:00
public async Task < ServerProfile [ ] > GetMyProfiles ( CancellationToken CancellationToken )
{
ProfileListSTC Prof ;
while ( true )
{
if ( CanRequest )
{
Prof = await GetFromServer ( "socketprofile/myprofiles" ,
ProfileListSTCContext . Default . ProfileListSTC ,
CancellationToken ) ;
break ;
}
}
if ( Prof is null ) throw new Exception ( "Server did not return a Profile List" ) ;
List < ServerProfile > profiles_ = new ( ) ;
foreach ( ProfileSTC user in Prof . Profiles )
{
if ( profiles . Count > 0 & & profiles . Any ( s = > s . ID = = user . ID ) )
{
_ = profiles . RemoveAll ( s = > s . ID = = user . ID ) ;
}
if ( user is null | | user . Error is not null )
{
string error = "Profile was null" ;
if ( user is not null & & user . Error is not null ) error = $"{user.Error}: {user.ErrorMessage}" ;
throw new Exception ( $"Something went wrong getting your profile information\n{error}" ) ;
}
ServerProfile u = new ( )
{
Server = this ,
ID = user . ID ,
DisplayName = user . DisplayName ,
PictureType = user . PictureType ,
Controllers = user . Controllers ,
2024-11-18 23:24:23 -05:00
RoleControllers = user . RoleControllers
2024-08-27 10:57:22 -04:00
} ;
profiles_ . Add ( u ) ;
profiles . Add ( u ) ;
}
return profiles_ . ToArray ( ) ;
}
2023-08-21 10:58:17 -04:00
/// <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 )
2023-07-10 14:19:03 -04:00
{
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-08-21 10:58:17 -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 ;
2023-07-10 14:19:03 -04:00
}
2023-08-21 10:58:17 -04:00
2023-08-25 12:07:36 -04:00
public string Name { get ; private set ; }
public string Description { get ; private set ; }
2023-07-08 09:06:13 -04:00
}