diff --git a/Luski.net/API.cs b/Luski.net/API.cs index a6c87f0..7b239f5 100644 --- a/Luski.net/API.cs +++ b/Luski.net/API.cs @@ -7,15 +7,15 @@ namespace Luski.net; public class API { - public Server MainServer { get; internal set; } - internal List> InternalServers { get; } = new(); - public IReadOnlyList> LoadedServers => InternalServers.AsReadOnly(); + public MainServer MainServer { get; internal set; } + internal List InternalServers { get; } = new(); + public IReadOnlyList LoadedServers => InternalServers.AsReadOnly(); - public Server GetPublicServer(string Domain, string Version = "v1") + public PublicServer GetPublicServer(string Domain, string Version = "v1") { - IEnumerable> isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version)); + IEnumerable isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version)); if (isl.Any()) return isl.First(); - Server s = new() + PublicServer s = new() { Domain = Domain, ApiVersion = Version, @@ -24,7 +24,7 @@ public class API return s; } - public Server GetMainServer(string Domain, string Version = "v1") + public MainServer GetMainServer(string Domain, string Version = "v1") { MainServer = new() { diff --git a/Luski.net/Enums/ServerCacheMode.cs b/Luski.net/Enums/ServerCacheMode.cs new file mode 100644 index 0000000..fa9b152 --- /dev/null +++ b/Luski.net/Enums/ServerCacheMode.cs @@ -0,0 +1,8 @@ +namespace Luski.net.Enums; + +public enum ServerCacheMode : byte +{ + None, + Encrypted, + Unencrypted +} \ No newline at end of file diff --git a/Luski.net/Interfaces/IServer.cs b/Luski.net/Interfaces/IServer.cs index 5214204..e20115c 100644 --- a/Luski.net/Interfaces/IServer.cs +++ b/Luski.net/Interfaces/IServer.cs @@ -33,6 +33,5 @@ public interface IServer public Task SendServer(string Path, string File, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : IncomingHTTP, new(); - public Task GetUser(long UserID, CancellationToken CancellationToken) where Tuser : SocketUserBase, new(); } \ No newline at end of file diff --git a/Luski.net/Interfaces/IUser.cs b/Luski.net/Interfaces/IUser.cs index d06108f..26d8bc5 100755 --- a/Luski.net/Interfaces/IUser.cs +++ b/Luski.net/Interfaces/IUser.cs @@ -35,8 +35,5 @@ public interface IUser /// /// Task GetUserKey(CancellationToken CancellationToken); - /// - /// The server that the user comes from - /// - IServer Server { get; } + } diff --git a/Luski.net/Luski.net.csproj b/Luski.net/Luski.net.csproj index a4622e6..7e53d0b 100755 --- a/Luski.net/Luski.net.csproj +++ b/Luski.net/Luski.net.csproj @@ -13,7 +13,7 @@ https://github.com/JacobTech-com/Luski.net True 1.0.0 - 1.1.3-alpha23 + 1.1.3-alpha24 diff --git a/Luski.net/Server.Account.cs b/Luski.net/MainServer.Account.cs similarity index 89% rename from Luski.net/Server.Account.cs rename to Luski.net/MainServer.Account.cs index e450715..72d3bf7 100644 --- a/Luski.net/Server.Account.cs +++ b/Luski.net/MainServer.Account.cs @@ -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 +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 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"; diff --git a/Luski.net/MainServer.Events.cs b/Luski.net/MainServer.Events.cs new file mode 100644 index 0000000..011ebe1 --- /dev/null +++ b/Luski.net/MainServer.Events.cs @@ -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? MessageReceived; + + public event Func? ReceivedFriendRequest; + + public event Func? FriendRequestResult; +} \ No newline at end of file diff --git a/Luski.net/MainServer.Incoming.cs b/Luski.net/MainServer.Incoming.cs new file mode 100644 index 0000000..7d769e6 --- /dev/null +++ b/Luski.net/MainServer.Incoming.cs @@ -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(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(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(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(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); + } + } +} \ No newline at end of file diff --git a/Luski.net/MainServer.cs b/Luski.net/MainServer.cs new file mode 100644 index 0000000..1b23222 --- /dev/null +++ b/Luski.net/MainServer.cs @@ -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 GetChannel(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 GetChannel(long id, JsonTypeInfo 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().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 GetUser(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 GetMessage(long id, CancellationToken CancellationToken) + { + MainSocketMessage message; + while (true) + { + if (CanRequest) + { + message = await GetFromServer("socketmessage", + MainSocketMessageContext.Default.MainSocketMessage, + CancellationToken, + new System.Collections.Generic.KeyValuePair("msg_id", id.ToString())); + break; + } + } + if (message is not null) return message; + throw new Exception("Server did not return a message"); + } + + /// + /// Sends the server a request to update the of you account + /// + /// The you want to set your status to + /// + public async 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 GetUser(long UserId, JsonTypeInfo 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().FirstOrDefault()!; + return temp; + } + while (true) + { + if (CanRequest) + { + user = await GetFromServer("socketuser", + Json, + CancellationToken, + new KeyValuePair("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; + } +} \ No newline at end of file diff --git a/Luski.net/PublicServer.cs b/Luski.net/PublicServer.cs new file mode 100644 index 0000000..63bbd3e --- /dev/null +++ b/Luski.net/PublicServer.cs @@ -0,0 +1,6 @@ +namespace Luski.net; + +public class PublicServer : Server +{ + +} \ No newline at end of file diff --git a/Luski.net/Server.Events.cs b/Luski.net/Server.Events.cs index 132efcd..e1cb506 100644 --- a/Luski.net/Server.Events.cs +++ b/Luski.net/Server.Events.cs @@ -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 +public partial class Server { - public event Func? MessageReceived; - public event Func? UserStatusUpdate; - public event Func? ReceivedFriendRequest; - - public event Func? FriendRequestResult; - public event Func? 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); + } } \ No newline at end of file diff --git a/Luski.net/Server.Globals.cs b/Luski.net/Server.Globals.cs index 4959487..1a81f79 100644 --- a/Luski.net/Server.Globals.cs +++ b/Luski.net/Server.Globals.cs @@ -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 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 poeople = new(); + public long UserID { get; internal set; } = 0; internal List chans { get; set; } = new(); public string Cache { @@ -33,7 +34,7 @@ public partial class Server 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); diff --git a/Luski.net/Server.Incoming.cs b/Luski.net/Server.Incoming.cs index 75f9347..f749c14 100644 --- a/Luski.net/Server.Incoming.cs +++ b/Luski.net/Server.Incoming.cs @@ -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 +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(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(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(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(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)); } } \ No newline at end of file diff --git a/Luski.net/Server.cs b/Luski.net/Server.cs index 814b71d..6420dbd 100644 --- a/Luski.net/Server.cs +++ b/Luski.net/Server.cs @@ -20,7 +20,7 @@ using File = System.IO.File; namespace Luski.net; -public partial class Server : IServer +public partial class Server { internal Server() { } @@ -35,161 +35,6 @@ public partial class Server : IServer return File.ReadAllBytes($"{Cache}/servers/{Domain}"); } - public async Task GetUser(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 GetChannel(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 GetChannel(long id, JsonTypeInfo 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().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 GetMessage(long id, CancellationToken CancellationToken) - { - SocketMessage message; - while (true) - { - if (CanRequest) - { - message = await GetFromServer("socketmessage", - SocketMessageContext.Default.SocketMessage, - CancellationToken, - new System.Collections.Generic.KeyValuePair("msg_id", id.ToString())); - break; - } - } - if (message is not null) return message; - throw new Exception("Server did not return a message"); - } - - /// - /// Sends the server a request to update the of you account - /// - /// The you want to set your status to - /// - public async 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 GetUser(long UserId, JsonTypeInfo 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().FirstOrDefault()!; - return temp; - } - while (true) - { - if (CanRequest) - { - user = await GetFromServer("socketuser", - Json, - CancellationToken, - new KeyValuePair("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 Payload, JsonTypeInfo jsonTypeInfo) where Tvalue : IncomingWSS { ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo)); diff --git a/Luski.net/Structures/Main/MainSocketAppUser.cs b/Luski.net/Structures/Main/MainSocketAppUser.cs index 7d3dc8d..20e3a59 100755 --- a/Luski.net/Structures/Main/MainSocketAppUser.cs +++ b/Luski.net/Structures/Main/MainSocketAppUser.cs @@ -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 Channels @@ -35,17 +40,17 @@ public class MainSocketAppUser : SocketUserBase, IAppUser _Channels = new List(); foreach (long channel in ChannelIdList) { - MainSocketChannel s = (Server as Server).GetChannel(channel, + MainSocketChannel s = Server.GetChannel(channel, MainSocketChannelContext.Default.MainSocketChannel, CancellationToken.None).Result; - (Server as Server)!.chans.Remove(s); + Server.chans.Remove(s); switch (s.Type) { case ChannelType.GROUP: - _Channels.Add((Server as Server).GetChannel(channel, + _Channels.Add(Server.GetChannel(channel, MainSocketGroupChannelContext.Default.MainSocketGroupChannel, CancellationToken.None).Result); break; case ChannelType.DM: - _Channels.Add((Server as Server).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)!.poeople.Any(s => s.Id == User.Id)) + if (Server.poeople.Any(s => s.Id == User.Id)) { - IEnumerable b = (Server as Server)!.poeople.Where(s => s.Id == User.Id); + IEnumerable b = Server.poeople.Where(s => s.Id == User.Id); foreach (IUser item in b) { - (Server as Server)!.poeople.Remove(item); + Server.poeople.Remove(item); } - (Server as Server)!.poeople.Add(User); + Server.poeople.Add(User); } else { - (Server as Server)!.poeople.Add(User); + Server.poeople.Add(User); } _Friends.Add(User); } internal void RemoveFriendRequest(MainSocketRemoteUser User) { - if ((Server as Server)!.poeople.Any(s => s.Id == User.Id)) + if (Server.poeople.Any(s => s.Id == User.Id)) { - IEnumerable b = (Server as Server)!.poeople.Where(s => s.Id == User.Id); + IEnumerable b = Server.poeople.Where(s => s.Id == User.Id); foreach (IUser item in b) { - (Server as Server)!.poeople.Remove(item); + Server.poeople.Remove(item); } - } - (Server as Server)!.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)!.poeople.Any(s => s.Id == User.Id)) + if (Server.poeople.Any(s => s.Id == User.Id)) { - IEnumerable b = (Server as Server)!.poeople.Where(s => s.Id == User.Id); + IEnumerable b = Server.poeople.Where(s => s.Id == User.Id); foreach (IUser item in b) { - (Server as Server)!.poeople.Remove(item); + Server.poeople.Remove(item); } - (Server as Server)!.poeople.Add(User); + Server.poeople.Add(User); } else { - (Server as Server)!.poeople.Add(User); + Server.poeople.Add(User); } _FriendRequests.Add(User); } diff --git a/Luski.net/Structures/Main/MainSocketChannel.cs b/Luski.net/Structures/Main/MainSocketChannel.cs index a46b6e1..5d5bdd2 100755 --- a/Luski.net/Structures/Main/MainSocketChannel.cs +++ b/Luski.net/Structures/Main/MainSocketChannel.cs @@ -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(member, CancellationToken.None).Result); - else _members.Add(Server.IAppUser); + if (member != Server.User.Id) _members.Add(Server.GetUser(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).User?.Id) + if (i.Id != Server.User.Id) { long key = i.GetUserKey(CancellationToken).Result; if (true) diff --git a/Luski.net/Structures/Main/MainSocketDMChannel.cs b/Luski.net/Structures/Main/MainSocketDMChannel.cs index c330a3d..8e9b77f 100755 --- a/Luski.net/Structures/Main/MainSocketDMChannel.cs +++ b/Luski.net/Structures/Main/MainSocketDMChannel.cs @@ -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(list.FirstOrDefault(), CancellationToken.None).Result; } return _user; diff --git a/Luski.net/Structures/SocketMessage.cs b/Luski.net/Structures/Main/MainSocketMessage.cs similarity index 77% rename from Luski.net/Structures/SocketMessage.cs rename to Luski.net/Structures/Main/MainSocketMessage.cs index 5e41bda..f51ca04 100755 --- a/Luski.net/Structures/SocketMessage.cs +++ b/Luski.net/Structures/Main/MainSocketMessage.cs @@ -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 GetAuthor(CancellationToken CancellationToken) { - if (Server.IAppUser!.Id != AuthorID) return await Server.GetUser(AuthorID, CancellationToken); - else return Server.IAppUser; + if (Server.User.Id != AuthorID) return await Server.GetUser(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 { } diff --git a/Luski.net/Structures/Main/MainSocketRemoteUser.cs b/Luski.net/Structures/Main/MainSocketRemoteUser.cs index 9ac8862..34ab431 100755 --- a/Luski.net/Structures/Main/MainSocketRemoteUser.cs +++ b/Luski.net/Structures/Main/MainSocketRemoteUser.cs @@ -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] diff --git a/Luski.net/Structures/Main/MainSocketTextChannel.cs b/Luski.net/Structures/Main/MainSocketTextChannel.cs index ce83d2e..f07062a 100755 --- a/Luski.net/Structures/Main/MainSocketTextChannel.cs +++ b/Luski.net/Structures/Main/MainSocketTextChannel.cs @@ -17,9 +17,9 @@ namespace Luski.net.Structures.Main; public class MainSocketTextChannel : MainSocketChannel { - public async Task GetMessage(long ID, CancellationToken CancellationToken) + public async Task GetMessage(long ID, CancellationToken CancellationToken) { - return await (Server as Server)!.GetMessage(ID, CancellationToken); + return await Server.GetMessage(ID, CancellationToken); } public async Task GetPicture(CancellationToken CancellationToken) @@ -36,7 +36,7 @@ public class MainSocketTextChannel : MainSocketChannel } } - public async Task> GetMessages(long Message_Id, CancellationToken CancellationToken, int count = 50) + public async Task> 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(); + if (data.Messages is null) data.Messages = Array.Empty(); 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); + return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList); } else { @@ -79,7 +79,7 @@ public class MainSocketTextChannel : MainSocketChannel } } - public async Task> GetMessages(CancellationToken CancellationToken, int count = 50) + public async Task> 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(); + if (data.Messages is null) data.Messages = Array.Empty(); 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); + return await Task.FromResult(data.Messages.ToList().AsReadOnly() as IReadOnlyList); } else { diff --git a/Luski.net/Structures/SocketUserBase.cs b/Luski.net/Structures/Main/MainSocketUserBase.cs similarity index 85% rename from Luski.net/Structures/SocketUserBase.cs rename to Luski.net/Structures/Main/MainSocketUserBase.cs index f29c9ec..7b63322 100644 --- a/Luski.net/Structures/SocketUserBase.cs +++ b/Luski.net/Structures/Main/MainSocketUserBase.cs @@ -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 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 { } \ No newline at end of file diff --git a/Luski.net/Structures/SocketBulkMessage.cs b/Luski.net/Structures/Main/SocketBulkMessage.cs similarity index 83% rename from Luski.net/Structures/SocketBulkMessage.cs rename to Luski.net/Structures/Main/SocketBulkMessage.cs index 3ec44d4..5a5b336 100755 --- a/Luski.net/Structures/SocketBulkMessage.cs +++ b/Luski.net/Structures/Main/SocketBulkMessage.cs @@ -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))] diff --git a/Luski.net/Structures/Public/MainSocketUserBase.cs b/Luski.net/Structures/Public/MainSocketUserBase.cs new file mode 100644 index 0000000..0252a20 --- /dev/null +++ b/Luski.net/Structures/Public/MainSocketUserBase.cs @@ -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 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 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 +{ + +} \ No newline at end of file diff --git a/Luski.net/Structures/Public/PublicSocketAppUser.cs b/Luski.net/Structures/Public/PublicSocketAppUser.cs index 0b7250b..65706f5 100755 --- a/Luski.net/Structures/Public/PublicSocketAppUser.cs +++ b/Luski.net/Structures/Public/PublicSocketAppUser.cs @@ -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]