Server Separation.

I moved the two server types to their own classes to prevent API calls to a server, not of that type.
This commit is contained in:
JacobTech 2023-07-08 09:06:13 -04:00
parent 106d0d6078
commit d8fbf281d0
24 changed files with 464 additions and 377 deletions

View File

@ -7,15 +7,15 @@ namespace Luski.net;
public class API
{
public Server<MainSocketAppUser> MainServer { get; internal set; }
internal List<Server<PublicSocketAppUser>> InternalServers { get; } = new();
public IReadOnlyList<Server<PublicSocketAppUser>> LoadedServers => InternalServers.AsReadOnly();
public MainServer MainServer { get; internal set; }
internal List<PublicServer> InternalServers { get; } = new();
public IReadOnlyList<PublicServer> LoadedServers => InternalServers.AsReadOnly();
public Server<PublicSocketAppUser> GetPublicServer(string Domain, string Version = "v1")
public PublicServer GetPublicServer(string Domain, string Version = "v1")
{
IEnumerable<Server<PublicSocketAppUser>> isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version));
IEnumerable<PublicServer> isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version));
if (isl.Any()) return isl.First();
Server<PublicSocketAppUser> s = new()
PublicServer s = new()
{
Domain = Domain,
ApiVersion = Version,
@ -24,7 +24,7 @@ public class API
return s;
}
public Server<MainSocketAppUser> GetMainServer(string Domain, string Version = "v1")
public MainServer GetMainServer(string Domain, string Version = "v1")
{
MainServer = new()
{

View File

@ -0,0 +1,8 @@
namespace Luski.net.Enums;
public enum ServerCacheMode : byte
{
None,
Encrypted,
Unencrypted
}

View File

@ -33,6 +33,5 @@ public interface IServer
public Task<Tresult> SendServer<Tresult>(string Path, string File, JsonTypeInfo<Tresult> ReturnjsonTypeInfo,
CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers)
where Tresult : IncomingHTTP, new();
public Task<Tuser> GetUser<Tuser>(long UserID, CancellationToken CancellationToken) where Tuser : SocketUserBase, new();
}

View File

@ -35,8 +35,5 @@ public interface IUser
/// </summary>
/// <returns></returns>
Task<long> GetUserKey(CancellationToken CancellationToken);
/// <summary>
/// The server that the user comes from
/// </summary>
IServer Server { get; }
}

View File

@ -13,7 +13,7 @@
<RepositoryUrl>https://github.com/JacobTech-com/Luski.net</RepositoryUrl>
<IncludeSymbols>True</IncludeSymbols>
<FileVersion>1.0.0</FileVersion>
<Version>1.1.3-alpha23</Version>
<Version>1.1.3-alpha24</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
@ -14,23 +15,22 @@ using Luski.net.JsonTypes.WSS;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using WebSocketSharp;
using File = System.IO.File;
namespace Luski.net;
public partial class Server<TUser>
public partial class MainServer
{
public void Login(string Email, string Password, CancellationToken CancellationToken)
public void Login(string Email, string Password, System.Threading.CancellationToken CancellationToken)
{
Both(Email, Password, CancellationToken);
}
public void CreateAccount(string Email, string Password, string Username, string PFP, CancellationToken CancellationToken)
public void CreateAccount(string Email, string Password, string Username, string PFP, System.Threading.CancellationToken CancellationToken)
{
Both(Email, Password, CancellationToken, Username, PFP);
}
private void Both(string Email, string Password, CancellationToken CancellationToken, string? Username = null, string? pfp = null)
private void Both(string Email, string Password, System.Threading.CancellationToken CancellationToken, string? Username = null, string? pfp = null)
{
if (!ClientEncryption.Generating)
{
@ -95,15 +95,9 @@ public partial class Server<TUser>
long id = long.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(
Token.Split('.')[0]
)));
TUser t = new();
User = t switch
{
MainSocketAppUser => (GetUser(id, MainSocketAppUserContext.Default.MainSocketAppUser,
CancellationToken.None)
.Result as TUser)!,
_ => (GetUser(id, PublicSocketAppUserContext.Default.PublicSocketAppUser, CancellationToken.None)
.Result as TUser)!
};
User = GetUser(id, MainSocketAppUserContext.Default.MainSocketAppUser,
CancellationToken)
.Result;
if (User is null || User.Error is not null)
{
string error = "User was null";

View File

@ -0,0 +1,15 @@
using System;
using System.Threading.Tasks;
using Luski.net.Structures;
using Luski.net.Structures.Main;
namespace Luski.net;
public partial class MainServer
{
public event Func<MainSocketMessage, Task>? MessageReceived;
public event Func<MainSocketRemoteUser, Task>? ReceivedFriendRequest;
public event Func<MainSocketRemoteUser, bool, Task>? FriendRequestResult;
}

View File

@ -0,0 +1,116 @@
using System;
using System.Text.Json;
using System.Threading;
using JacobTechEncryption;
using Luski.net.Enums;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
using Luski.net.JsonTypes.WSS;
using Luski.net.Structures;
using Luski.net.Structures.Main;
using WebSocketSharp;
namespace Luski.net;
public partial class MainServer
{
private void DataFromServer(object? sender, MessageEventArgs e)
{
if (e.IsPing) return;
try
{
Console.WriteLine("From Server: {0}", e.Data);
IncomingWSS? data = JsonSerializer.Deserialize(e.Data, IncomingWSSContext.Default.IncomingWSS);
switch (data?.Type)
{
case DataType.Login:
Console.WriteLine("Pre auth");
WSSLogin n = JsonSerializer.Deserialize(e.Data, WSSLoginContext.Default.WSSLogin)!;
Token = n.Token;
Console.WriteLine("Token: {0}",Token);
break;
case DataType.Error:
if (Token is null)
{
Error = data.Error;
}
else
{
Exception(new Exception(data.Error));
}
break;
case DataType.Message_Create:
if (MessageReceived is not null)
{
MainSocketMessage? m = JsonSerializer.Deserialize<MainSocketMessage>(e.Data);
if (m is not null)
{
m.decrypt(ClientEncryption.File.Channels.GetKey(m.ChannelID), CancellationToken.None);
_ = MessageReceived.Invoke(m);
}
}
break;
case DataType.Status_Update:
StatusUpdate? SU = JsonSerializer.Deserialize<StatusUpdate>(e.Data);
if (SU is not null)
{
MainSocketRemoteUser after = GetUser(SU.id, MainSocketRemoteUserContext.Default.MainSocketRemoteUser, CancellationToken.None).Result;
after.Status = SU.after;
MainSocketRemoteUser before = after.Clone();
before.Status = SU.before;
StatusUpdate(before, after);
}
break;
case DataType.Friend_Request:
if (ReceivedFriendRequest is not null)
{
FriendRequest? request =
JsonSerializer.Deserialize(e.Data, FriendRequestContext.Default.FriendRequest);
if (request is not null)
_ = ReceivedFriendRequest.Invoke(GetUser(request.Id,
MainSocketRemoteUserContext.Default.MainSocketRemoteUser,
CancellationToken.None).Result);
}
break;
case DataType.Friend_Request_Result:
FriendRequestResult? FRR = JsonSerializer.Deserialize<FriendRequestResult>(e.Data);
if (FRR is not null && FRR.Channel is not null && FRR.Id is not null &&
FRR.Result is not null)
{
MainSocketDMChannel chan = GetChannel((long)FRR.Channel,
MainSocketDMChannelContext.Default.MainSocketDMChannel,
CancellationToken.None).Result;
chans.Add(chan);
MainSocketRemoteUser from1 = GetUser((long)FRR.Id,
MainSocketRemoteUserContext.Default.MainSocketRemoteUser,
CancellationToken.None).Result;
//from1.Channel = chan;
if (FriendRequestResult is not null) _ = FriendRequestResult.Invoke(from1, (bool)FRR.Result);
}
break;
case DataType.Key_Exchange:
try
{
KeyExchange? KE = JsonSerializer.Deserialize<KeyExchange>(e.Data);
if (KE is not null)
ClientEncryption.File.Channels.AddKey(KE.channel,
ClientEncryption.Encoder.GetString(Encryption.RSA.Decrypt(Convert.FromBase64String(KE.key), ClientEncryption.ofkey)));
}
catch (Exception ex)
{
Exception(ex);
}
break;
default:
Console.WriteLine("Unknown");
break;
}
}
catch (Exception exception)
{
Exception(exception);
}
}
}

171
Luski.net/MainServer.cs Normal file
View File

@ -0,0 +1,171 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
namespace Luski.net;
public partial class MainServer : Server
{
public MainSocketAppUser User { get; internal set; } = default!;
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))
{
return chans.Where(s => s is TChannel && s.Id == id).Cast<TChannel>().FirstOrDefault()!;
}
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);
}
}
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;
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,
new System.Collections.Generic.KeyValuePair<string, string?>("msg_id", id.ToString()));
break;
}
}
if (message is not null) return message;
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)
{
IncomingHTTP? data = await SendServer("SocketUserProfile/Status", new Status() { UserStatus = Status }, StatusContext.Default.Status, IncomingHTTPContext.Default.IncomingHTTP, CancellationToken);
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()!;
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);
}
}
poeople.Add(user);
return user;
}
}

View File

@ -0,0 +1,6 @@
namespace Luski.net;
public class PublicServer : Server
{
}

View File

@ -1,20 +1,22 @@
using System;
using System.Threading.Tasks;
using Luski.net.Interfaces;
using Luski.net.JsonTypes;
using Luski.net.Structures;
namespace Luski.net;
public partial class Server<TUser>
public partial class Server
{
public event Func<SocketMessage, Task>? MessageReceived;
public event Func<IUser, IUser, Task>? UserStatusUpdate;
public event Func<MainSocketRemoteUser, Task>? ReceivedFriendRequest;
public event Func<MainSocketRemoteUser, bool, Task>? FriendRequestResult;
public event Func<Exception, Task>? OnError;
internal void Exception(Exception e)
{
if (OnError is not null) OnError.Invoke(e);
}
internal void StatusUpdate(IUser u1, IUser u2)
{
if (UserStatusUpdate is not null) UserStatusUpdate.Invoke(u1, u2);
}
}

View File

@ -4,23 +4,24 @@ using System.IO;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes;
using Luski.net.Structures;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using WebSocketSharp;
namespace Luski.net;
public partial class Server<TUser> where TUser : class, IAppUser, new()
public partial class Server
{
public ServerType ServerType { get; internal set; } = ServerType.Public;
public string Domain { get; internal set; } = default!;
public IAppUser IAppUser => User;
public TUser User { get; internal set; }
public ServerCacheMode CacheMode { get; set; } = ServerCacheMode.None;
public string ApiVersion { get; internal set; } = "v1";
private WebSocket? ServerOut;
internal WebSocket? ServerOut;
internal string? Token = null, Error = null, gen = null;
internal bool CanRequest = false, login = false;
internal List<IUser> poeople = new();
public long UserID { get; internal set; } = 0;
internal List<MainSocketChannel> chans { get; set; } = new();
public string Cache
{
@ -33,7 +34,7 @@ public partial class Server<TUser> where TUser : class, IAppUser, new()
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += "Data/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += User.Id + "/";
path += UserID + "/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += "Cache/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);

View File

@ -1,131 +1,12 @@
using System;
using System.Text.Json;
using System.Threading;
using JacobTechEncryption;
using Luski.net.Enums;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
using Luski.net.JsonTypes.WSS;
using Luski.net.Structures;
using Luski.net.Structures.Main;
using WebSocketSharp;
namespace Luski.net;
public partial class Server<TUser>
public partial class Server
{
private void ServerOut_OnError(object? sender, WebSocketSharp.ErrorEventArgs e)
internal void ServerOut_OnError(object? sender, ErrorEventArgs e)
{
if (OnError is not null) OnError.Invoke(new Exception(e.Message));
}
private void DataFromServer(object? sender, MessageEventArgs e)
{
if (e.IsPing) return;
try
{
Console.WriteLine("From Server: {0}", e.Data);
IncomingWSS? data = JsonSerializer.Deserialize(e.Data, IncomingWSSContext.Default.IncomingWSS);
switch (data?.Type)
{
case DataType.Login:
Console.WriteLine("Pre auth");
WSSLogin n = JsonSerializer.Deserialize(e.Data, WSSLoginContext.Default.WSSLogin)!;
Token = n.Token;
Console.WriteLine("Token: {0}",Token);
break;
case DataType.Error:
if (Token is null)
{
Error = data.Error;
}
else
{
if (OnError is not null)
{
_ = OnError.Invoke(new Exception(data.Error));
}
}
break;
case DataType.Message_Create:
if (MessageReceived is not null)
{
SocketMessage? m = JsonSerializer.Deserialize<SocketMessage>(e.Data);
if (m is not null)
{
m.decrypt(ClientEncryption.File.Channels.GetKey(m.ChannelID), CancellationToken.None);
_ = MessageReceived.Invoke(m);
}
}
break;
case DataType.Status_Update:
if (UserStatusUpdate is not null)
{
StatusUpdate? SU = JsonSerializer.Deserialize<StatusUpdate>(e.Data);
if (SU is not null)
{
MainSocketRemoteUser after = GetUser(SU.id, MainSocketRemoteUserContext.Default.MainSocketRemoteUser, CancellationToken.None).Result;
after.Status = SU.after;
MainSocketRemoteUser before = after.Clone();
before.Status = SU.before;
_ = UserStatusUpdate.Invoke(before, after);
}
}
break;
case DataType.Friend_Request:
if (ReceivedFriendRequest is not null)
{
FriendRequest? request =
JsonSerializer.Deserialize(e.Data, FriendRequestContext.Default.FriendRequest);
if (request is not null)
_ = ReceivedFriendRequest.Invoke(GetUser(request.Id,
MainSocketRemoteUserContext.Default.MainSocketRemoteUser,
CancellationToken.None).Result);
}
break;
case DataType.Friend_Request_Result:
if (FriendRequestResult is not null)
{
FriendRequestResult? FRR = JsonSerializer.Deserialize<FriendRequestResult>(e.Data);
if (FRR is not null && FRR.Channel is not null && FRR.Id is not null &&
FRR.Result is not null)
{
MainSocketDMChannel chan = GetChannel((long)FRR.Channel,
MainSocketDMChannelContext.Default.MainSocketDMChannel,
CancellationToken.None).Result;
chans.Add(chan);
MainSocketRemoteUser from1 = GetUser((long)FRR.Id,
MainSocketRemoteUserContext.Default.MainSocketRemoteUser,
CancellationToken.None).Result;
//from1.Channel = chan;
_ = FriendRequestResult.Invoke(from1, (bool)FRR.Result);
}
}
break;
case DataType.Key_Exchange:
try
{
KeyExchange? KE = JsonSerializer.Deserialize<KeyExchange>(e.Data);
if (KE is not null)
ClientEncryption.File.Channels.AddKey(KE.channel,
ClientEncryption.Encoder.GetString(Encryption.RSA.Decrypt(Convert.FromBase64String(KE.key), ClientEncryption.ofkey)));
}
catch (Exception ex)
{
if (OnError is not null) OnError.Invoke(ex);
}
break;
default:
Console.WriteLine("Unknown");
break;
}
}
catch (Exception exception)
{
if (OnError is not null) _ = OnError.Invoke(exception);
else throw exception;
}
this.Exception(new Exception(e.Message));
}
}

View File

@ -20,7 +20,7 @@ using File = System.IO.File;
namespace Luski.net;
public partial class Server<TUser> : IServer
public partial class Server
{
internal Server()
{ }
@ -35,161 +35,6 @@ public partial class Server<TUser> : IServer
return File.ReadAllBytes($"{Cache}/servers/{Domain}");
}
public async Task<Tuser> GetUser<Tuser>(long UserID, CancellationToken CancellationToken) where Tuser : SocketUserBase, new()
{
Tuser user = new();
switch (user)
{
case MainSocketAppUser:
user = (GetUser(UserID, MainSocketAppUserContext.Default.MainSocketAppUser, CancellationToken).Result as Tuser)!;
break;
case PublicSocketAppUser:
user = (GetUser(UserID, PublicSocketAppUserContext.Default.PublicSocketAppUser, CancellationToken).Result as Tuser)!;
break;
case SocketUserBase:
user = (GetUser(UserID, SocketUserBaseContext.Default.SocketUserBase, CancellationToken).Result as Tuser)!;
break;
case null:
throw new NullReferenceException(nameof(Tuser));
default:
throw new Exception("Unknown channel type");
}
return user;
}
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))
{
return chans.Where(s => s is TChannel && s.Id == id).Cast<TChannel>().FirstOrDefault()!;
}
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);
}
}
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 async Task<SocketMessage> GetMessage(long id, CancellationToken CancellationToken)
{
SocketMessage message;
while (true)
{
if (CanRequest)
{
message = await GetFromServer("socketmessage",
SocketMessageContext.Default.SocketMessage,
CancellationToken,
new System.Collections.Generic.KeyValuePair<string, string?>("msg_id", id.ToString()));
break;
}
}
if (message is not null) return message;
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)
{
IncomingHTTP? data = await SendServer("SocketUserProfile/Status", new Status() { UserStatus = Status }, StatusContext.Default.Status, IncomingHTTPContext.Default.IncomingHTTP, CancellationToken);
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 as SocketUserBase)!.Status = Status;
return Task.CompletedTask;
}
internal async Task<Tuser> GetUser<Tuser>(long UserId, JsonTypeInfo<Tuser> Json, CancellationToken CancellationToken) where Tuser : SocketUserBase, 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()!;
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);
}
}
poeople.Add(user);
return user;
}
public void SendServer<Tvalue>(Tvalue Payload, JsonTypeInfo<Tvalue> jsonTypeInfo) where Tvalue : IncomingWSS
{
ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo));

View File

@ -14,14 +14,19 @@ using Luski.net.JsonTypes;
namespace Luski.net.Structures.Main;
public class MainSocketAppUser : SocketUserBase, IAppUser
public class MainSocketAppUser : MainSocketUserBase, IAppUser
{
[JsonPropertyName("selected_channel")]
[JsonInclude]
public long SelectedChannel { get; internal set; } = default!;
[JsonPropertyName("username")]
[JsonInclude]
public string Username { get; internal set; } = default!;
[JsonPropertyName("flags")]
[JsonInclude]
public UserFlag Flags { get; internal set; } = default!;
public MainServer Server { get; internal set; } = default!;
[JsonIgnore]
public IReadOnlyList<MainSocketChannel> Channels
@ -35,17 +40,17 @@ public class MainSocketAppUser : SocketUserBase, IAppUser
_Channels = new List<MainSocketChannel>();
foreach (long channel in ChannelIdList)
{
MainSocketChannel s = (Server as Server<MainSocketAppUser>).GetChannel(channel,
MainSocketChannel s = Server.GetChannel(channel,
MainSocketChannelContext.Default.MainSocketChannel, CancellationToken.None).Result;
(Server as Server<MainSocketAppUser>)!.chans.Remove(s);
Server.chans.Remove(s);
switch (s.Type)
{
case ChannelType.GROUP:
_Channels.Add((Server as Server<MainSocketAppUser>).GetChannel(channel,
_Channels.Add(Server.GetChannel(channel,
MainSocketGroupChannelContext.Default.MainSocketGroupChannel, CancellationToken.None).Result);
break;
case ChannelType.DM:
_Channels.Add((Server as Server<MainSocketAppUser>).GetChannel(channel,
_Channels.Add(Server.GetChannel(channel,
MainSocketDMChannelContext.Default.MainSocketDMChannel, CancellationToken.None).Result);
break;
}
@ -100,9 +105,6 @@ public class MainSocketAppUser : SocketUserBase, IAppUser
return _Friends.AsReadOnly();
}
}
[JsonPropertyName("selected_channel")]
[JsonInclude]
public long SelectedChannel { get; internal set; } = default!;
[JsonPropertyName("channels")]
[JsonInclude]
public long[] ChannelIdList { get; internal set; } = default!;
@ -127,33 +129,33 @@ public class MainSocketAppUser : SocketUserBase, IAppUser
internal void AddFriend(MainSocketRemoteUser User)
{
if ((Server as Server<MainSocketAppUser>)!.poeople.Any(s => s.Id == User.Id))
if (Server.poeople.Any(s => s.Id == User.Id))
{
IEnumerable<IUser> b = (Server as Server<MainSocketAppUser>)!.poeople.Where(s => s.Id == User.Id);
IEnumerable<IUser> b = Server.poeople.Where(s => s.Id == User.Id);
foreach (IUser item in b)
{
(Server as Server<MainSocketAppUser>)!.poeople.Remove(item);
Server.poeople.Remove(item);
}
(Server as Server<MainSocketAppUser>)!.poeople.Add(User);
Server.poeople.Add(User);
}
else
{
(Server as Server<MainSocketAppUser>)!.poeople.Add(User);
Server.poeople.Add(User);
}
_Friends.Add(User);
}
internal void RemoveFriendRequest(MainSocketRemoteUser User)
{
if ((Server as Server<MainSocketAppUser>)!.poeople.Any(s => s.Id == User.Id))
if (Server.poeople.Any(s => s.Id == User.Id))
{
IEnumerable<IUser> b = (Server as Server<MainSocketAppUser>)!.poeople.Where(s => s.Id == User.Id);
IEnumerable<IUser> b = Server.poeople.Where(s => s.Id == User.Id);
foreach (IUser item in b)
{
(Server as Server<MainSocketAppUser>)!.poeople.Remove(item);
Server.poeople.Remove(item);
}
}
(Server as Server<MainSocketAppUser>)!.poeople.Add(User);
}
Server.poeople.Add(User);
foreach (MainSocketRemoteUser user in _FriendRequests)
{
if (User.Id == user.Id)
@ -165,18 +167,18 @@ public class MainSocketAppUser : SocketUserBase, IAppUser
internal void AddFriendRequest(MainSocketRemoteUser User)
{
if ((Server as Server<MainSocketAppUser>)!.poeople.Any(s => s.Id == User.Id))
if (Server.poeople.Any(s => s.Id == User.Id))
{
IEnumerable<IUser> b = (Server as Server<MainSocketAppUser>)!.poeople.Where(s => s.Id == User.Id);
IEnumerable<IUser> b = Server.poeople.Where(s => s.Id == User.Id);
foreach (IUser item in b)
{
(Server as Server<MainSocketAppUser>)!.poeople.Remove(item);
Server.poeople.Remove(item);
}
(Server as Server<MainSocketAppUser>)!.poeople.Add(User);
Server.poeople.Add(User);
}
else
{
(Server as Server<MainSocketAppUser>)!.poeople.Add(User);
Server.poeople.Add(User);
}
_FriendRequests.Add(User);
}

View File

@ -34,7 +34,9 @@ public class MainSocketChannel : IncomingHTTP
[JsonPropertyName("type")]
[JsonInclude]
public ChannelType Type { get; internal set; } = default!;
public IServer Server { get; internal set; }
public MainServer Server { get; internal set; } = default!;
[JsonPropertyName("members")]
[JsonInclude]
public long[] MemberIdList { get; internal set; } = default!;
@ -49,8 +51,8 @@ public class MainSocketChannel : IncomingHTTP
_members = new();
foreach (long member in MemberIdList)
{
if (member != Server.IAppUser!.Id) _members.Add(Server.GetUser<MainSocketRemoteUser>(member, CancellationToken.None).Result);
else _members.Add(Server.IAppUser);
if (member != Server.User.Id) _members.Add(Server.GetUser<MainSocketRemoteUser>(member, CancellationToken.None).Result);
else _members.Add(Server.User);
}
}
return _members.AsReadOnly();
@ -74,7 +76,7 @@ public class MainSocketChannel : IncomingHTTP
MaxDegreeOfParallelism = num
}, i =>
{
if (i.Id != (Server as Server<MainSocketAppUser>).User?.Id)
if (i.Id != Server.User.Id)
{
long key = i.GetUserKey(CancellationToken).Result;
if (true)

View File

@ -14,7 +14,7 @@ public class MainSocketDMChannel : MainSocketTextChannel
if (_user is null)
{
var list = MemberIdList.ToList();
list.Remove(Server.IAppUser.Id);
list.Remove(Server.User.Id);
_user = Server.GetUser<MainSocketRemoteUser>(list.FirstOrDefault(), CancellationToken.None).Result;
}
return _user;

View File

@ -1,20 +1,17 @@
using Luski.net.Interfaces;
using Luski.net.JsonTypes.BaseTypes;
using System;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using JacobTechEncryption;
namespace Luski.net.Structures;
namespace Luski.net.Structures.Main;
public class SocketMessage : IncomingHTTP
public class MainSocketMessage : IncomingHTTP
{
public IServer Server { get; }
public MainServer Server { get; internal set; } = default!;
[JsonPropertyName("id")]
[JsonInclude]
public long Id { get; internal set; } = default!;
@ -32,8 +29,8 @@ public class SocketMessage : IncomingHTTP
public File[]? Files { get; internal set; } = default!;
public async Task<IUser> GetAuthor(CancellationToken CancellationToken)
{
if (Server.IAppUser!.Id != AuthorID) return await Server.GetUser<SocketUserBase>(AuthorID, CancellationToken);
else return Server.IAppUser;
if (Server.User.Id != AuthorID) return await Server.GetUser<MainSocketUserBase>(AuthorID, CancellationToken);
else return Server.User;
}
internal void decrypt(string? key, CancellationToken CancellationToken)
@ -51,12 +48,12 @@ public class SocketMessage : IncomingHTTP
}
}
[JsonSerializable(typeof(SocketMessage))]
[JsonSerializable(typeof(MainSocketMessage))]
[JsonSourceGenerationOptions(
GenerationMode = JsonSourceGenerationMode.Default,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
WriteIndented = false)]
public partial class SocketMessageContext : JsonSerializerContext
public partial class MainSocketMessageContext : JsonSerializerContext
{
}

View File

@ -9,10 +9,11 @@ using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Luski.net.Enums.Main;
using Luski.net.Structures;
using Luski.net.Structures.Main;
namespace Luski.net.Structures;
namespace Luski.net.Structures.Main;
public class MainSocketRemoteUser : SocketUserBase
public class MainSocketRemoteUser : MainSocketUserBase
{
[JsonPropertyName("friend_status")]
[JsonInclude]

View File

@ -17,9 +17,9 @@ namespace Luski.net.Structures.Main;
public class MainSocketTextChannel : MainSocketChannel
{
public async Task<SocketMessage> GetMessage(long ID, CancellationToken CancellationToken)
public async Task<MainSocketMessage> GetMessage(long ID, CancellationToken CancellationToken)
{
return await (Server as Server<MainSocketAppUser>)!.GetMessage(ID, CancellationToken);
return await Server.GetMessage(ID, CancellationToken);
}
public async Task<byte[]> GetPicture(CancellationToken CancellationToken)
@ -36,7 +36,7 @@ public class MainSocketTextChannel : MainSocketChannel
}
}
public async Task<IReadOnlyList<SocketMessage>> GetMessages(long Message_Id, CancellationToken CancellationToken, int count = 50)
public async Task<IReadOnlyList<MainSocketMessage>> GetMessages(long Message_Id, CancellationToken CancellationToken, int count = 50)
{
if (count > 200)
{
@ -61,7 +61,7 @@ public class MainSocketTextChannel : MainSocketChannel
string? key = ClientEncryption.File.Channels.GetKey(Id);
if (data is null) throw new Exception("Invalid data from server");
if (data.Messages is null) data.Messages = Array.Empty<SocketMessage>();
if (data.Messages is null) data.Messages = Array.Empty<MainSocketMessage>();
Parallel.ForEach(data.Messages, new ParallelOptions()
{
MaxDegreeOfParallelism = num
@ -70,7 +70,7 @@ public class MainSocketTextChannel : MainSocketChannel
i.decrypt(key, CancellationToken);
});
key = null;
return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList<SocketMessage>);
return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList<MainSocketMessage>);
}
else
{
@ -79,7 +79,7 @@ public class MainSocketTextChannel : MainSocketChannel
}
}
public async Task<IReadOnlyList<SocketMessage>> GetMessages(CancellationToken CancellationToken, int count = 50)
public async Task<IReadOnlyList<MainSocketMessage>> GetMessages(CancellationToken CancellationToken, int count = 50)
{
try
{
@ -106,7 +106,7 @@ public class MainSocketTextChannel : MainSocketChannel
int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 5) * 2.0));
if (num == 0) num = 1;
string? key = ClientEncryption.File.Channels.GetKey(Id);
if (data.Messages is null) data.Messages = Array.Empty<SocketMessage>();
if (data.Messages is null) data.Messages = Array.Empty<MainSocketMessage>();
Parallel.ForEach(data.Messages, new ParallelOptions()
{
MaxDegreeOfParallelism = num
@ -116,7 +116,7 @@ public class MainSocketTextChannel : MainSocketChannel
});
key = null;
Console.WriteLine($"Messages decrypted in {(DateTime.Now - start).TotalSeconds}");
return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList<SocketMessage>);
return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList<MainSocketMessage>);
}
else
{

View File

@ -5,10 +5,11 @@ using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes.BaseTypes;
namespace Luski.net.Structures;
namespace Luski.net.Structures.Main;
public class SocketUserBase : IncomingHTTP, IUser
public class MainSocketUserBase : IncomingHTTP, IUser
{
public MainServer Server { get; internal set; } = default!;
[JsonPropertyName("id")]
[JsonInclude]
public long Id { get; internal set; } = default!;
@ -21,9 +22,6 @@ public class SocketUserBase : IncomingHTTP, IUser
[JsonPropertyName("picture_type")]
[JsonInclude]
public PictureType PictureType { get; internal set; } = default!;
[JsonIgnore]
public IServer Server { get; internal set; } = default!;
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
{
if (Server.Cache != null)
@ -41,13 +39,13 @@ public class SocketUserBase : IncomingHTTP, IUser
}
}
[JsonSerializable(typeof(SocketUserBase))]
[JsonSerializable(typeof(MainSocketUserBase))]
[JsonSourceGenerationOptions(
GenerationMode = JsonSourceGenerationMode.Default,
PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never)]
internal partial class SocketUserBaseContext : JsonSerializerContext
internal partial class MainSocketUserBaseContext : JsonSerializerContext
{
}

View File

@ -1,13 +1,13 @@
using Luski.net.JsonTypes.BaseTypes;
using System.Text.Json.Serialization;
namespace Luski.net.Structures;
namespace Luski.net.Structures.Main;
internal class SocketBulkMessage : IncomingHTTP
{
[JsonPropertyName("messages")]
[JsonInclude]
public SocketMessage[]? Messages { get; set; } = default!;
public MainSocketMessage[]? Messages { get; set; } = default!;
}
[JsonSerializable(typeof(SocketBulkMessage))]

View File

@ -0,0 +1,51 @@
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes.BaseTypes;
namespace Luski.net.Structures.Public;
public class PublicSocketUserBase : IncomingHTTP, IUser
{
public PublicServer Server { get; internal set; } = default!;
[JsonPropertyName("id")]
[JsonInclude]
public long Id { get; internal set; } = default!;
[JsonPropertyName("username")]
[JsonInclude]
public string DisplayName { get; internal set; } = default!;
[JsonPropertyName("status")]
[JsonInclude]
public UserStatus Status { get; internal set; } = default!;
[JsonPropertyName("picture_type")]
[JsonInclude]
public PictureType PictureType { get; internal set; } = default!;
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
{
if (Server.Cache != null)
{
bool isc = System.IO.File.Exists($"{Server.Cache}/avatars/{Id}");
if (!isc) await Server.GetFromServer($"socketuserprofile/Avatar/{Id}", $"{Server.Cache}/avatars/{Id}", CancellationToken);
}
return System.IO.File.ReadAllBytes($"{Server.Cache}/avatars/{Id}");
}
public Task<long> GetUserKey(CancellationToken CancellationToken)
{
string data = Server.GetFromServer($"Keys/GetUserKey/{Id}", CancellationToken).Content.ReadAsStringAsync().Result;
return Task.FromResult(long.Parse(data));
}
}
[JsonSerializable(typeof(PublicSocketUserBase))]
[JsonSourceGenerationOptions(
GenerationMode = JsonSourceGenerationMode.Default,
PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never)]
internal partial class PublicSocketUserBaseContext : JsonSerializerContext
{
}

View File

@ -10,10 +10,11 @@ using System.Threading.Tasks;
using JacobTechEncryption;
using Luski.net.Enums;
using Luski.net.Enums.Main;
using Luski.net.Structures.Main;
namespace Luski.net.Structures.Public;
public class PublicSocketAppUser : SocketUserBase, IAppUser
public class PublicSocketAppUser : PublicSocketUserBase, IAppUser
{
[JsonPropertyName("selected_channel")]
[JsonInclude]