diff --git a/Luski.net/API.cs b/Luski.net/API.cs index 885b2cf..306244d 100644 --- a/Luski.net/API.cs +++ b/Luski.net/API.cs @@ -1,10 +1,17 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Net.Http; +using System.Text.Json; using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; +using System.Threading; using System.Threading.Tasks; using Luski.net.Enums; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net; @@ -14,28 +21,86 @@ public class API public MainServer MainServer { get; internal set; } public bool IsAnyServerLoggedin { get; internal set; } + + public const string DefaultVersion = "v1"; + + internal List Versions = new() + { + DefaultVersion + }; + + public IReadOnlyList SupportedVersions => Versions.AsReadOnly(); internal List InternalServers { get; } = new(); public IReadOnlyList LoadedServers => InternalServers.AsReadOnly(); - - public Task TryGetPublicServer(out PublicServer Server, string Domain, string Version = "v1", + + private static HttpResponseMessage GetFromServer(string Domain, string ApiVersion, bool Secure, string Path, CancellationToken CancellationToken, params KeyValuePair[] Headers) + { + using HttpClient web = new(); + web.Timeout = TimeSpan.FromSeconds(10); + if (Headers is not null && Headers.Length > 0) foreach (KeyValuePair header in Headers) web.DefaultRequestHeaders.Add(header.Key, header.Value); + return web.GetAsync($"{(Secure ? "https" : "http" )}://{Domain}/{ApiVersion}/{Path}", cancellationToken: CancellationToken).Result; + } + private static Task GetFromServer(string Domain, string ApiVersion, bool Secure, string Path, JsonTypeInfo Type, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : STC, new() + { + HttpResponseMessage ServerResponce = GetFromServer(Domain, ApiVersion, Secure, Path, CancellationToken, Headers); + Tresult temp = new(); + string raw = ServerResponce.Content.ReadAsStringAsync(CancellationToken).Result; + try + { + temp = JsonSerializer.Deserialize(raw, Type)!; + } + catch (Exception e) + { + Console.WriteLine("JSON parse failed for the following data as type {0}\n{1}", temp.GetType(), raw); + } + if (temp is null) return Task.FromResult(new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with empty data" }); + return Task.FromResult(temp); + } + + public Task GetServerInfo(string Domain, string Version = DefaultVersion, bool Secure = true) + { + ServerInfoSTC? si = GetFromServer(Domain, Version, Secure, "socketserver", ServerInfoSTCContext.Default.ServerInfoSTC, CancellationToken.None).Result; + if (si is null) throw new Exception("Bad Response"); + return Task.FromResult(si); + } + + public Task TryGetServerInfo([NotNullWhen(true)]out ServerInfoSTC? si, string Domain, string Version = DefaultVersion, + bool Secure = true) + { + + try + { + si = GetServerInfo(Domain, Version, Secure).Result; + return Task.FromResult(true); + } + catch (Exception e) + { + si = null; + return Task.FromResult(false); + } + } + + public Task TryGetPublicServer(out PublicServer Server, string Domain, string Version = DefaultVersion, + bool Secure = true, bool GenerateEncryption = true, bool LogConsole = false) { try { - Task result = GetPublicServer(Domain, Version, Secure); + Task result = GetPublicServer(Domain, Version, Secure, GenerateEncryption, LogConsole); Task.WaitAll(result); Server = result.Result; return Task.FromResult(true); } catch (Exception e) { - Console.WriteLine(e); + if (!e.Message.Contains("Connection refused")) Console.WriteLine(e); Server = null!; return Task.FromResult(false); } } - public async Task GetPublicServer(string Domain, string Version = "v1", bool Secure = true) + + public async Task GetPublicServer(string Domain, string Version = DefaultVersion, bool Secure = true, bool GenerateEncryption = true, bool LogConsole = false) { PublicServer s; try @@ -64,7 +129,6 @@ public class API bool b = await s.LoginViaToken(f); if (b) { - Console.WriteLine("Auto Login Successful"); IsAnyServerLoggedin = true; } else @@ -82,7 +146,7 @@ public class API return s; } - public MainServer GetMainServer(string Domain, string Version = "v1") + public MainServer GetMainServer(string Domain, string Version = DefaultVersion) { DateTime dt = DateTime.UtcNow; Console.WriteLine("Conecting to main server '{0}' using API {1}.", Domain, Version); diff --git a/Luski.net/Converters.cs b/Luski.net/Converters.cs index edd770e..102371b 100644 --- a/Luski.net/Converters.cs +++ b/Luski.net/Converters.cs @@ -1,6 +1,3 @@ -using Luski.net.JsonTypes.Public; -using Luski.net.Structures.Public; - namespace Luski.net; public static class Converters diff --git a/Luski.net/Enums/DataType.cs b/Luski.net/Enums/DataType.cs old mode 100755 new mode 100644 index 37dea2a..6a5189a --- a/Luski.net/Enums/DataType.cs +++ b/Luski.net/Enums/DataType.cs @@ -1,4 +1,4 @@ -namespace Luski.net.Enums; +namespace Luski.net.Enums; public enum DataType { @@ -15,4 +15,4 @@ public enum DataType Error, Key_Exchange, MAX -} +} \ No newline at end of file diff --git a/Luski.net/Enums/ErrorCode.cs b/Luski.net/Enums/ErrorCode.cs deleted file mode 100755 index 70139d1..0000000 --- a/Luski.net/Enums/ErrorCode.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Luski.net.Enums; - -public enum ErrorCode -{ - MissingToken, - InvalidToken, - MissingPostData, - InvalidPostData, - Forbidden, - ServerError, - MissingHeader, - InvalidHeader, - InvalidURL -} diff --git a/Luski.net/Enums/PictureType.cs b/Luski.net/Enums/PictureType.cs deleted file mode 100755 index 721bc28..0000000 --- a/Luski.net/Enums/PictureType.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Luski.net.Enums; - -public enum PictureType : short -{ - none, - png, - jpeg, - bmp, - gif, - ico, - svg, - tif, - webp -} diff --git a/Luski.net/Enums/Public/ChannelType.cs b/Luski.net/Enums/Public/ChannelType.cs deleted file mode 100755 index e52037b..0000000 --- a/Luski.net/Enums/Public/ChannelType.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Luski.net.Enums.Public; - -public enum ChannelType : short -{ - TextAndVoice = 0 -} diff --git a/Luski.net/Enums/Public/DataType.cs b/Luski.net/Enums/Public/DataType.cs deleted file mode 100644 index 723e4bf..0000000 --- a/Luski.net/Enums/Public/DataType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Luski.net.Enums.Public; - -public enum DataType -{ - Token, - MessageCreate -} \ No newline at end of file diff --git a/Luski.net/Enums/Public/ServerPermission.cs b/Luski.net/Enums/Public/ServerPermission.cs deleted file mode 100644 index 89c9ac4..0000000 --- a/Luski.net/Enums/Public/ServerPermission.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Luski.net.Enums.Public; - -public enum ServerPermission : long -{ - ViewChannels, - MoveChannels, - EditChannels, - EditChannelPermissions, - CreateChannels, - DeleteChannels, - ViewCategories, - MoveCategories, - EditCategories, - EditCategoryPermissions, - CreateCategories, - DeleteCategories, - DeleteKeys, - ManageRoles, - ViewLogs, - ManageServer, - Invite, - Nickname, - ManageNacknames, - Kick, - Ban, - SendMessages, - SendFiles, - ChannelAndServerPings, - PingSomeone, - ManageMessages, - ReadMessageHistory, - UseServerCommands, - JoinVoice, - SpeakInVoice, - MuteMembers, - DeafenMembers, - MoveMembers -} \ No newline at end of file diff --git a/Luski.net/Enums/StorageDirectory.cs b/Luski.net/Enums/StorageDirectory.cs index 2f32ac4..f524ff1 100644 --- a/Luski.net/Enums/StorageDirectory.cs +++ b/Luski.net/Enums/StorageDirectory.cs @@ -10,5 +10,6 @@ public enum StorageDirectory : byte ChannelIcons, Messages, StorageInfo, - Files + Files, + ProfileAvatars } \ No newline at end of file diff --git a/Luski.net/Enums/UserStatus.cs b/Luski.net/Enums/UserStatus.cs deleted file mode 100755 index 439d9fb..0000000 --- a/Luski.net/Enums/UserStatus.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Luski.net.Enums; - -public enum UserStatus : short -{ - Offline, - Online, - Idle, - DoNotDisturb, - Invisible -} diff --git a/Luski.net/Interfaces/IAppUser.cs b/Luski.net/Interfaces/IAppUser.cs index d29c9b3..f49a1e6 100644 --- a/Luski.net/Interfaces/IAppUser.cs +++ b/Luski.net/Interfaces/IAppUser.cs @@ -1,5 +1,4 @@ -using Luski.net.Enums; -using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.Interfaces; diff --git a/Luski.net/Interfaces/IServer.cs b/Luski.net/Interfaces/IServer.cs index e20115c..908bb89 100644 --- a/Luski.net/Interfaces/IServer.cs +++ b/Luski.net/Interfaces/IServer.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Luski.net.JsonTypes.BaseTypes; using Luski.net.Structures; using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Interfaces; @@ -23,15 +24,15 @@ public interface IServer public Task GetFromServer(string Path, JsonTypeInfo Type, CancellationToken CancellationToken, params KeyValuePair[] Headers) - where Tresult : IncomingHTTP, new(); + where Tresult : STC, new(); public Task SendServer(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) - where Tvalue : IWebRequest where Tresult : IncomingHTTP, new(); + where Tvalue : IWebRequest where Tresult : STC, new(); public Task SendServer(string Path, string File, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) - where Tresult : IncomingHTTP, new(); + where Tresult : STC, new(); } \ No newline at end of file diff --git a/Luski.net/Interfaces/IUser.cs b/Luski.net/Interfaces/IUser.cs index 609b996..68d4de9 100755 --- a/Luski.net/Interfaces/IUser.cs +++ b/Luski.net/Interfaces/IUser.cs @@ -1,9 +1,9 @@ using System.IO; using System.Threading; -using Luski.net.Enums; using System.Threading.Tasks; -using Luski.net.JsonTypes; using Luski.net.Structures; +using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.Interfaces; @@ -24,6 +24,11 @@ public interface IUser /// The current status of the user /// UserStatus Status { get; } + + /// + /// The color of the display name + /// + Task GetColor(); /// /// will returen the picture type of the user /// diff --git a/Luski.net/JsonTypes/BaseTypes/IncomingHTTP.cs b/Luski.net/JsonTypes/BaseTypes/IncomingHTTP.cs deleted file mode 100755 index ff6c3f8..0000000 --- a/Luski.net/JsonTypes/BaseTypes/IncomingHTTP.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Luski.net.Enums; -using System.ComponentModel; -using System.Net; -using System.Text.Json.Serialization; - -namespace Luski.net.JsonTypes.BaseTypes; - -[Browsable(false)] -[EditorBrowsable(EditorBrowsableState.Never)] -public class IncomingHTTP -{ - [JsonPropertyName("error")] - [JsonInclude] - public ErrorCode? Error { get; internal set; } = default!; -#pragma warning disable SYSLIB1037 // Deserialization of init-only properties is currently not supported in source generation mode. - [JsonIgnore] - public HttpStatusCode StatusCode { get; init; } -#pragma warning restore SYSLIB1037 // Deserialization of init-only properties is currently not supported in source generation mode. - [JsonPropertyName("error_message")] - [JsonInclude] - public string? ErrorMessage { get; internal set; } = default!; -} - -[JsonSerializable(typeof(IncomingHTTP))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class IncomingHTTPContext : JsonSerializerContext -{ - -} diff --git a/Luski.net/JsonTypes/FriendRequestResult.cs b/Luski.net/JsonTypes/FriendRequestResult.cs index 2d78f98..5d39096 100755 --- a/Luski.net/JsonTypes/FriendRequestResult.cs +++ b/Luski.net/JsonTypes/FriendRequestResult.cs @@ -1,9 +1,10 @@ using Luski.net.JsonTypes.BaseTypes; using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.JsonTypes; -internal class FriendRequestResult : IncomingHTTP +internal class FriendRequestResult : STC { [JsonPropertyName("channel")] [JsonInclude] diff --git a/Luski.net/JsonTypes/HTTP/Channel.cs b/Luski.net/JsonTypes/HTTP/Channel.cs deleted file mode 100755 index 1150e5f..0000000 --- a/Luski.net/JsonTypes/HTTP/Channel.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Luski.net.JsonTypes.BaseTypes; -using System.Text.Json.Serialization; - -namespace Luski.net.JsonTypes.HTTP; - -internal class Channel : HTTPRequest -{ - [JsonPropertyName("id")] - [JsonInclude] - public long Id { get; set; } = default!; -} - -[JsonSerializable(typeof(Channel))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class ChannelContext : JsonSerializerContext -{ - -} diff --git a/Luski.net/JsonTypes/HTTP/FriendRequest.cs b/Luski.net/JsonTypes/HTTP/FriendRequest.cs index 707818b..ce6fc6e 100755 --- a/Luski.net/JsonTypes/HTTP/FriendRequest.cs +++ b/Luski.net/JsonTypes/HTTP/FriendRequest.cs @@ -1,9 +1,10 @@ using Luski.net.JsonTypes.BaseTypes; using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; namespace Luski.net.JsonTypes.HTTP; -internal class FriendRequest : HTTPRequest +internal class FriendRequest : CTS { [JsonPropertyName("code")] [JsonInclude] diff --git a/Luski.net/JsonTypes/HTTP/FriendRequestResultOut.cs b/Luski.net/JsonTypes/HTTP/FriendRequestResultOut.cs index 7517c7a..d5cd88a 100755 --- a/Luski.net/JsonTypes/HTTP/FriendRequestResultOut.cs +++ b/Luski.net/JsonTypes/HTTP/FriendRequestResultOut.cs @@ -1,9 +1,10 @@ using Luski.net.JsonTypes.BaseTypes; using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; namespace Luski.net.JsonTypes.HTTP; -internal class FriendRequestResultOut : HTTPRequest +internal class FriendRequestResultOut : CTS { [JsonPropertyName("id")] [JsonInclude] diff --git a/Luski.net/JsonTypes/HTTP/Message.cs b/Luski.net/JsonTypes/HTTP/Message.cs deleted file mode 100755 index ee6f9a5..0000000 --- a/Luski.net/JsonTypes/HTTP/Message.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Luski.net.JsonTypes.BaseTypes; -using System.Text.Json.Serialization; - -namespace Luski.net.JsonTypes.HTTP; - -internal class Message : HTTPRequest -{ - [JsonPropertyName("channel_id")] - [JsonInclude] - public long Channel { get; set; } = default!; - [JsonPropertyName("content")] - [JsonInclude] - public string Context { get; set; } = default!; - [JsonPropertyName("files")] - [JsonInclude] - public long[] Files { get; set; } = default!; -} - -[JsonSerializable(typeof(Message))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class MessageContext : JsonSerializerContext -{ - -} diff --git a/Luski.net/JsonTypes/HTTP/Status.cs b/Luski.net/JsonTypes/HTTP/Status.cs deleted file mode 100755 index f447753..0000000 --- a/Luski.net/JsonTypes/HTTP/Status.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.Enums; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.HTTP; - -internal class Status : HTTPRequest -{ - [JsonPropertyName("status")] - [JsonInclude] - public UserStatus UserStatus { get; set; } = default!; -} - -[JsonSerializable(typeof(Status))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class StatusContext : JsonSerializerContext -{ - -} diff --git a/Luski.net/JsonTypes/KeyExchange.cs b/Luski.net/JsonTypes/KeyExchange.cs index 310f846..ff25400 100755 --- a/Luski.net/JsonTypes/KeyExchange.cs +++ b/Luski.net/JsonTypes/KeyExchange.cs @@ -3,6 +3,7 @@ internal class KeyExchange { public long channel { get; set; } = default!; + public long id { get; set; } = default!; public string key { get; set; } = default!; public long? to { get; set; } = default!; diff --git a/Luski.net/JsonTypes/LocalServerInfo.cs b/Luski.net/JsonTypes/LocalServerInfo.cs index 8489c80..4d65bb0 100644 --- a/Luski.net/JsonTypes/LocalServerInfo.cs +++ b/Luski.net/JsonTypes/LocalServerInfo.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.Shared; namespace Luski.net.JsonTypes; diff --git a/Luski.net/JsonTypes/Login.cs b/Luski.net/JsonTypes/Login.cs deleted file mode 100755 index be52591..0000000 --- a/Luski.net/JsonTypes/Login.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Luski.net.JsonTypes.BaseTypes; -using System.Text.Json.Serialization; - -namespace Luski.net.JsonTypes; - -internal class Login : IncomingHTTP -{ - [JsonPropertyName("login_token")] - public string? Token { get; set; } = default!; - -} - -[JsonSerializable(typeof(Login))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class LoginContext : JsonSerializerContext -{ - -} diff --git a/Luski.net/JsonTypes/OfflineData.cs b/Luski.net/JsonTypes/OfflineData.cs deleted file mode 100644 index 2d88763..0000000 --- a/Luski.net/JsonTypes/OfflineData.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes; - -public class OfflineData : IncomingHTTP -{ - [JsonPropertyName("data")] - [JsonInclude] - public string[]? Data { get; internal set; } = default!; -} - -[JsonSerializable(typeof(OfflineData))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class OfflineDataContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/OfflineKeyData.cs b/Luski.net/JsonTypes/OfflineKeyData.cs index 1f4b978..3aaf56b 100755 --- a/Luski.net/JsonTypes/OfflineKeyData.cs +++ b/Luski.net/JsonTypes/OfflineKeyData.cs @@ -1,9 +1,10 @@ using Luski.net.JsonTypes.BaseTypes; using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.JsonTypes; -internal class OfflineKeyData : IncomingHTTP +internal class OfflineKeyData : STC { public KeyExchange[]? keys { get; internal set; } = default!; } diff --git a/Luski.net/JsonTypes/Public/Category.cs b/Luski.net/JsonTypes/Public/Category.cs deleted file mode 100644 index ba19fd2..0000000 --- a/Luski.net/JsonTypes/Public/Category.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Text.Json.Serialization; -using JacobTechEncryption.Enums; -using Luski.net.Enums; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.Public; - -public class Category : IncomingHTTP -{ - [JsonInclude] - [JsonPropertyName("id")] - public long ID { get; set; } - [JsonInclude] - [JsonPropertyName("picture_type")] - public PictureType PictureType { get; set; } - [JsonInclude] - [JsonPropertyName("color")] - public string Color { get; set; } - [JsonInclude] - [JsonPropertyName("name")] - public string Name { get; set; } - [JsonInclude] - [JsonPropertyName("description")] - public string Description { get; set; } - [JsonInclude] - [JsonPropertyName("parent")] - public long Parent { get; set; } - [JsonInclude] - [JsonPropertyName("inner_categories")] - public long[] InnerCategories { get; set; } - [JsonInclude] - [JsonPropertyName("channels")] - public long[] Channels { get; set; } - [JsonInclude] - [JsonPropertyName("role_overides")] - public long[] RoleOverides { get; set; } - [JsonInclude] - [JsonPropertyName("member_overides")] - public long[] UserOverides { get; set; } - [JsonInclude] - [JsonPropertyName("title_encryption_key")] - public long TitleEncryptionKey { get; set; } - [JsonInclude] - [JsonPropertyName("description_encryption_key")] - public long DescriptionEncryptionKey { get; set; } - [JsonInclude] - [JsonPropertyName("title_encoder_type")] - public EncoderType TitleEncoderType { get; set; } - [JsonInclude] - [JsonPropertyName("description_encoder_type")] - public EncoderType DescriptionEncoderType { get; set; } -} - -[JsonSerializable(typeof(Category))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, - WriteIndented = false, - DefaultIgnoreCondition = JsonIgnoreCondition.Never)] -internal partial class PublicCategoryContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/Channel.cs b/Luski.net/JsonTypes/Public/Channel.cs deleted file mode 100644 index 938cb4b..0000000 --- a/Luski.net/JsonTypes/Public/Channel.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Text.Json.Serialization; -using JacobTechEncryption.Enums; -using Luski.net.Enums; -using Luski.net.Enums.Public; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.Public; - -public class Channel : IncomingHTTP -{ - [JsonInclude] - [JsonPropertyName("id")] - public long ID { get; set; } - [JsonInclude] - [JsonPropertyName("parent")] - public long Parent { get; set; } - [JsonInclude] - [JsonPropertyName("color")] - public string Color { get; set; } - [JsonInclude] - [JsonPropertyName("type")] - public ChannelType Type { get; set; } - [JsonInclude] - [JsonPropertyName("epoch")] - public DateTime Epoch { get; set; } - [JsonInclude] - [JsonPropertyName("name")] - public string Name { get; set; } - [JsonInclude] - [JsonPropertyName("description")] - public string Description { get; set; } - [JsonInclude] - [JsonPropertyName("role_overides")] - public long[] RoleOverides { get; set; } - [JsonInclude] - [JsonPropertyName("member_overides")] - public long[] UserOverides { get; set; } - [JsonInclude] - [JsonPropertyName("title_encryption_key")] - public long TitleEncryptionKey { get; set; } - [JsonInclude] - [JsonPropertyName("description_encryption_key")] - public long DescriptionEncryptionKey { get; set; } - [JsonInclude] - [JsonPropertyName("encryption_keys")] - public long[] EncryptionKeys { get; set; } - [JsonInclude] - [JsonPropertyName("title_encoder_type")] - public EncoderType TitleEncoderType { get; set; } - [JsonInclude] - [JsonPropertyName("description_encoder_type")] - public EncoderType DescriptionEncoderType { get; set; } - [JsonInclude] - [JsonPropertyName("encoder_types")] - public EncoderType[] EncoderTypes { get; set; } - [JsonInclude] - [JsonPropertyName("picture_type")] - public PictureType PictureType { get; set; } -} - -[JsonSerializable(typeof(Channel))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, - WriteIndented = false, - DefaultIgnoreCondition = JsonIgnoreCondition.Never)] -internal partial class PublicChannelContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/PublicMessage.cs b/Luski.net/JsonTypes/Public/PublicMessage.cs deleted file mode 100644 index d06f627..0000000 --- a/Luski.net/JsonTypes/Public/PublicMessage.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json.Serialization; -using JacobTechEncryption.Enums; - -namespace Luski.net.JsonTypes.Public; - -public class PublicMessage -{ - [JsonInclude] - [JsonPropertyName("id")] - public long ID { get; internal set; } - [JsonInclude] - [JsonPropertyName("channel_id")] - public long ChannelID { get; internal set; } - [JsonInclude] - [JsonPropertyName("author_id")] - public long AuthorID { get; internal set; } - [JsonInclude] - [JsonPropertyName("ts")] - public long TimeStamp { get; internal set; } - [JsonInclude] - [JsonPropertyName("context")] - public string Context { get; internal set; } - [JsonInclude] - [JsonPropertyName("encryption_key")] - public long EncryptionKey { get; internal set; } - [JsonInclude] - [JsonPropertyName("files")] - public pFile[] Files { get; internal set; } - [JsonInclude] - [JsonPropertyName("encoder_type")] - public EncoderType EncoderType { get; internal set; } -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/PublicSocketBulkMessage.cs b/Luski.net/JsonTypes/Public/PublicSocketBulkMessage.cs deleted file mode 100644 index 50ebef3..0000000 --- a/Luski.net/JsonTypes/Public/PublicSocketBulkMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.Public; - -public class PublicSocketBulkMessage : IncomingHTTP -{ - [JsonInclude] - [JsonPropertyName("messages")] - public PublicMessage[]? Messages { get; set; } = default!; -} - -[JsonSerializable(typeof(PublicSocketBulkMessage))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false, - DefaultIgnoreCondition = JsonIgnoreCondition.Never)] -internal partial class PublicSocketBulkMessageContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/Role.cs b/Luski.net/JsonTypes/Public/Role.cs deleted file mode 100644 index 7b32ed0..0000000 --- a/Luski.net/JsonTypes/Public/Role.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.Enums.Public; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.Public; - -public class Role : IncomingHTTP -{ - public long id { get; set; } - public string name { get; set; } - public string display_name { get; set; } - public int index { get; set; } - public string color { get; set; } - public string description { get; set; } - public ServerPermission[] server_permissions { get; set; } - public long[] members_list { get; set; } -} - -[JsonSerializable(typeof(Role))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, - WriteIndented = false, - DefaultIgnoreCondition = JsonIgnoreCondition.Never)] -internal partial class RoleContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/SocketUser.cs b/Luski.net/JsonTypes/Public/SocketUser.cs deleted file mode 100644 index bd8ba68..0000000 --- a/Luski.net/JsonTypes/Public/SocketUser.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.Enums; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes.Public; - -public class SocketUser : IncomingHTTP -{ - [JsonInclude] - [JsonPropertyName("id")] - public long ID { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("displayname")] - public string DisplayName { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("selected_channel")] - public long SelectedChannel { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("status")] - public UserStatus Status { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("picture_type")] - public PictureType PictureType { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("roles")] - public long[] RoleIds { get; internal set; } = default!; - [JsonInclude] - [JsonPropertyName("username")] - public string Username { get; internal set; } = default!; -} - -[JsonSerializable(typeof(SocketUser))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, - WriteIndented = false, - DefaultIgnoreCondition = JsonIgnoreCondition.Never)] -internal partial class PublicSocketUserContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/Public/pFile.cs b/Luski.net/JsonTypes/Public/pFile.cs deleted file mode 100644 index 0a749ba..0000000 --- a/Luski.net/JsonTypes/Public/pFile.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json.Serialization; -using JacobTechEncryption.Enums; - -namespace Luski.net.JsonTypes.Public; - -public class pFile -{ - [JsonInclude] - [JsonPropertyName("id")] - public long ID { get; set; } - [JsonInclude] - [JsonPropertyName("name")] - public string Name { get; set; } - [JsonInclude] - [JsonPropertyName("channel")] - public long Channel { get; set; } - [JsonInclude] - [JsonPropertyName("encoder_type")] - public EncoderType Encoder { get; set; } - [JsonInclude] - [JsonPropertyName("name_encoder_type")] - public EncoderType NameEncoder { get; set; } - [JsonInclude] - [JsonPropertyName("encryption_key")] - public long Key { get; set; } - [JsonInclude] - [JsonPropertyName("name_encryption_key")] - public long NameKey { get; set; } - [JsonInclude] - [JsonPropertyName("size")] - public long Size { get; set; } -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/ServerData.cs b/Luski.net/JsonTypes/ServerData.cs deleted file mode 100644 index 3e25f0b..0000000 --- a/Luski.net/JsonTypes/ServerData.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Luski.net.JsonTypes; - -public class ServerData -{ - [JsonInclude] - [JsonPropertyName("address")] - public string DomainAndPort = default!; - [JsonInclude] - [JsonPropertyName("secure")] - public bool Secure; -} - -[JsonSerializable(typeof(ServerData))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class ServerDataContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/ServerInfo.cs b/Luski.net/JsonTypes/ServerInfo.cs deleted file mode 100644 index f341418..0000000 --- a/Luski.net/JsonTypes/ServerInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes; - -public class ServerInfo : IncomingHTTP -{ - public string name { get; set; } - public string wssv4 { get; set; } - public string description { get; set; } - public long owner { get; set; } - - [JsonInclude] - [JsonPropertyName("alternate_servers")] - public ServerData[] AlternateServers { get; set; } = default!; -} - -[JsonSerializable(typeof(ServerInfo))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class ServerInfoContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/StatusUpdate.cs b/Luski.net/JsonTypes/StatusUpdate.cs index 7719a7d..e274f78 100755 --- a/Luski.net/JsonTypes/StatusUpdate.cs +++ b/Luski.net/JsonTypes/StatusUpdate.cs @@ -1,5 +1,5 @@ -using Luski.net.Enums; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.JsonTypes; diff --git a/Luski.net/JsonTypes/StorageInfoJSON.cs b/Luski.net/JsonTypes/StorageInfoJSON.cs deleted file mode 100644 index 40ce429..0000000 --- a/Luski.net/JsonTypes/StorageInfoJSON.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.Interfaces; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes; - -public class StorageInfoJSON : IncomingHTTP, IWebRequest -{ - public long id { get; set; } - public string password { get; set; } - public bool update { get; set; } -} - -[JsonSerializable(typeof(StorageInfoJSON))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = true)] -internal partial class StorageInfoJSONContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/UserKeyGetRequest.cs b/Luski.net/JsonTypes/UserKeyGetRequest.cs deleted file mode 100644 index 7cae546..0000000 --- a/Luski.net/JsonTypes/UserKeyGetRequest.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Text.Json.Serialization; -using JacobTechEncryption.Enums; -using Luski.net.Interfaces; - -namespace Luski.net.JsonTypes; - -public class UserKeyGetRequest : IWebRequest -{ - public long id { get; set; } - public long owner { get; set; } - public EncryptionType encryption_type { get; set; } - public string key_data { get; set; } -} - -[JsonSerializable(typeof(UserKeyGetRequest))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = false)] -internal partial class UserKeyGetRequestContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/UserKeysGetRequest.cs b/Luski.net/JsonTypes/UserKeysGetRequest.cs deleted file mode 100644 index 3e140e9..0000000 --- a/Luski.net/JsonTypes/UserKeysGetRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; -using Luski.net.JsonTypes.BaseTypes; - -namespace Luski.net.JsonTypes; - -public class UserKeysGetRequest : IncomingHTTP -{ - public UserKeyGetRequest[] keys { get; set; } -} - -[JsonSerializable(typeof(UserKeysGetRequest))] -[JsonSourceGenerationOptions( - GenerationMode = JsonSourceGenerationMode.Default, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - WriteIndented = true)] -internal partial class UserKeysGetRequestContext : JsonSerializerContext -{ - -} \ No newline at end of file diff --git a/Luski.net/JsonTypes/WSS/IncomingWSS.cs b/Luski.net/JsonTypes/WSS/IncomingWSS.cs index d7fce29..36501d0 100755 --- a/Luski.net/JsonTypes/WSS/IncomingWSS.cs +++ b/Luski.net/JsonTypes/WSS/IncomingWSS.cs @@ -1,5 +1,5 @@ -using Luski.net.Enums.Public; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.JsonTypes.BaseTypes; @@ -11,6 +11,9 @@ public class BetterIncomingWSS [JsonPropertyName("error")] [JsonInclude] public string Error { get; set; } = default!; + [JsonPropertyName("data")] + [JsonInclude] + public object? Data { get; set; } } [JsonSerializable(typeof(BetterIncomingWSS))] diff --git a/Luski.net/JsonTypes/WSS/ServerEvent.cs b/Luski.net/JsonTypes/WSS/ServerEvent.cs index 7ce8406..33cfa5e 100644 --- a/Luski.net/JsonTypes/WSS/ServerEvent.cs +++ b/Luski.net/JsonTypes/WSS/ServerEvent.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; -using Luski.net.Enums.Public; -using Luski.net.Interfaces; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.JsonTypes.WSS; diff --git a/Luski.net/Luski.net.csproj b/Luski.net/Luski.net.csproj index 3501b6c..ad568a1 100755 --- a/Luski.net/Luski.net.csproj +++ b/Luski.net/Luski.net.csproj @@ -13,11 +13,11 @@ https://github.com/JacobTech-com/Luski.net True 1.0.0 - 2.0.0-alpha25 + 2.0.0-alpha65 - + diff --git a/Luski.net/MainServer.Account.cs b/Luski.net/MainServer.Account.cs index b47a5fd..9d97239 100644 --- a/Luski.net/MainServer.Account.cs +++ b/Luski.net/MainServer.Account.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net.Http; using System.Security.Authentication; using System.Text; @@ -13,6 +12,8 @@ using Luski.net.Enums; using Luski.net.JsonTypes; using Luski.net.JsonTypes.WSS; using Luski.net.Structures.Main; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; using WebSocketSharp; namespace Luski.net; @@ -38,7 +39,7 @@ public partial class MainServer while (!EncryptionHandler.Generated) { } login = true; - Login json; + LoginSTC json; List> heads = new() { new("key", EncryptionHandler.MyPublicKey), @@ -56,7 +57,7 @@ public partial class MainServer json = SendServer( "CreateAccount", pfp, - LoginContext.Default.Login, + LoginSTCContext.Default.LoginSTC, CancellationToken, heads.ToArray()).Result; } @@ -64,7 +65,7 @@ public partial class MainServer { json = GetFromServer( "Login", - LoginContext.Default.Login, + LoginSTCContext.Default.LoginSTC, CancellationToken, heads.ToArray()).Result; } @@ -113,7 +114,7 @@ public partial class MainServer } EncryptionHandler.Hash = EncryptionHandler.LocalPasswordEncrypt(Encoding.Unicode.GetBytes(Username.ToLower() + Password)); - OfflineData offlinedata = GetFromServer("Keys/GetOfflineData", OfflineDataContext.Default.OfflineData, CancellationToken).Result; + OfflineDataBlobSTC offlinedata = GetFromServer("Keys/GetOfflineData", OfflineDataBlobSTCContext.Default.OfflineDataBlobSTC, CancellationToken).Result; if (offlinedata is not null && offlinedata.Error is null && offlinedata.Data is not null && offlinedata.Data.Length > 0) { foreach (string keyex in offlinedata.Data) diff --git a/Luski.net/MainServer.cs b/Luski.net/MainServer.cs index 26f2f76..f8c3c47 100644 --- a/Luski.net/MainServer.cs +++ b/Luski.net/MainServer.cs @@ -7,14 +7,15 @@ using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; -using Luski.net.Enums; using Luski.net.Enums.Main; using Luski.net.Interfaces; using Luski.net.JsonTypes; -using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.HTTP; using Luski.net.Structures.Main; -using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; +using ChannelType = Luski.net.Enums.Main.ChannelType; namespace Luski.net; @@ -209,7 +210,7 @@ public partial class MainServer : Server /// 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); + STC? data = await SendServer("SocketUserProfile/Status", new StatusUpdateCTS() { Status = Status }, StatusUpdateCTSContext.Default.StatusUpdateCTS, STCContext.Default.STC, 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); diff --git a/Luski.net/PublicServer.Account.cs b/Luski.net/PublicServer.Account.cs index 900aa6a..0542b7a 100644 --- a/Luski.net/PublicServer.Account.cs +++ b/Luski.net/PublicServer.Account.cs @@ -10,11 +10,13 @@ using JacobTechEncryption; using JacobTechEncryption.Enums; using Luski.net.Enums; using Luski.net.JsonTypes; -using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.WSS; using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; using WebSocketSharp; -using DataType = Luski.net.Enums.Public.DataType; +using DataType = Luski.Shared.PublicServers.V1.Enums.DataType; namespace Luski.net; @@ -22,183 +24,44 @@ public partial class PublicServer { public async Task Login(string Username, string Password, CancellationToken CancellationToken) { - return await Both(Username, Password, CancellationToken); + return await All(Username, CancellationToken, Password); } - public async Task CreateAccount(string Username, string Password, string Displayname, string PFP, CancellationToken CancellationToken) + public async Task CreateAccount(string Username, string Password, string DisplayName, string PFP, CancellationToken CancellationToken) { - return await Both(Username, Password, CancellationToken, Displayname, PFP); + return await All(Username, CancellationToken, Password, DisplayName, PFP); } internal async Task LoginViaToken(string t) { - CancellationToken CancellationToken = CancellationToken.None; - if (!EncryptionHandler.Generating) - { - EncryptionHandler.GenerateKeys(); - } - while (!EncryptionHandler.Generated) { } - - login = true; - Login json; - List> heads = new() - { - new("key", EncryptionHandler.MyPublicKey), - new("token", Convert.ToBase64String(Encryption.RSA.Encrypt(t, EncryptionHandler.ServerPublicKey, EncoderType.UTF16))), - }; - - json = await GetFromServer( - "SocketAccount/AccessToken", - LoginContext.Default.Login, - CancellationToken, - heads.ToArray()); - if (json.Error is not null) throw new Exception($"Luski appears to be down at the current moment: {json.ErrorMessage}"); - if (EncryptionHandler.OfflinePrivateKey is null || EncryptionHandler.OfflinePublicKey is null) throw new Exception("Something went wrong generating the offline keys"); - login = false; - if (json is not null && json.Error is null) - { - ServerOut = new WebSocket(wssurl); - ServerOut.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12; - ServerOut.OnMessage += DataFromServer; - ServerOut.EmitOnPing = true; - ServerOut.WaitTime = new TimeSpan(0, 0, 5); - ServerOut.OnError += ServerOut_OnError; - ServerOut.Connect(); - SendServer(DataType.Token, new WSSLogin() { Token = json.Token! }); - while (Token is null && Error is null) - { - Thread.Sleep(500); - } - if (Error is not null) - { - throw new Exception(Error); - } - - if (Token is null) throw new Exception("Server did not send a token"); - CanRequest = true; - long id = long.Parse(Encoding.UTF8.GetString(Convert.FromBase64String( - Token.Split('.')[0] - ))); - User = await GetUser(id, CancellationToken); - StorageInfoJSON data; - if (Storage.StorageID == 0) - { - EncryptionHandler.Hash = Storage.GenerateStorage(); - data = await SendServer("OfflineData/Info", - new StorageInfoJSON() - { - id = 0, - update = false, - password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) - }, - StorageInfoJSONContext.Default.StorageInfoJSON, - StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, - new KeyValuePair("storage_id", Storage.StorageID.ToString())); - Storage.setid(data.id); - } - else - { - data = await GetFromServer("OfflineData/Info", StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, new KeyValuePair("storage_id", Storage.StorageID.ToString())); - } - - if (data.update) - { - EncryptionHandler.Hash = Storage.UpdateStorage(Convert.FromBase64String(data.password)); - _ = await SendServerPatch("OfflineData/Info", - new StorageInfoJSON() - { - id = 0, - update = false, - password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) - }, - StorageInfoJSONContext.Default.StorageInfoJSON, - StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, - new KeyValuePair("storage_id", Storage.StorageID.ToString())); - } - try - { - _ = EncryptionHandler.GetKey(0); - } - catch (Exception e) - { - EncryptionHandler.SetKey(0, new() - { - EncryptionType = EncryptionType.None, - Key = string.Empty - }); - } - _ = await UpdateStatus(UserStatus.Online, CancellationToken); - KeyValuePair stor = new("storage_id", Storage.StorageID.ToString()); - OfflineData offlinedata = await GetFromServer("OfflineData", OfflineDataContext.Default.OfflineData, CancellationToken, stor); - if (offlinedata is not null && offlinedata.Error is null && offlinedata.Data is not null && offlinedata.Data.Length > 0) - { - string pkey = Storage.GetResourceKeyRaw( - StorageDirectory.ServerKeys, - "pkey", - EncryptionHandler.Hash - ); - foreach (string keyexx in offlinedata.Data) - { - string keyex = Encoding.UTF8.GetString(Convert.FromBase64String(keyexx)); - KeyExchange? okd = JsonSerializer.Deserialize(keyex); - if (okd is not null && !string.IsNullOrEmpty(okd.key)) - { - Storage.SetResourceKey( - StorageDirectory.ChannelKeys, - okd.channel.ToString(), - EncryptionHandler.Hash, - Encoding.Unicode.GetString( - Encryption.RSA.Decrypt( - Convert.FromBase64String(okd.key), - pkey - ) - ) - ); - } - } - } - Storage.SetResourceKey(StorageDirectory.ServerKeys, "pkey", EncryptionHandler.Hash, EncryptionHandler.OfflinePrivateKey); - UserKeyGetRequest OfflineKeySetRequest = new() - { - key_data = Convert.ToBase64String(Encoding.UTF8.GetBytes(EncryptionHandler.OfflinePublicKey)), - encryption_type = EncryptionType.RSA - }; - _ = await SendServer("Keys/SetOfflineKey", - OfflineKeySetRequest, - UserKeyGetRequestContext.Default.UserKeyGetRequest, - IncomingHTTPContext.Default.IncomingHTTP, - CancellationToken.None, - stor); - EncryptionHandler.OfflinePublicKey = null!; - EncryptionHandler.OfflinePrivateKey = null!; - //API_Handler.IsAnyServerLoggedin = true; - return true; - } - else - { - throw new Exception(json?.ErrorMessage); - } - - //API_Handler.IsAnyServerLoggedin = true; - return true; + Console.WriteLine("Starting Auto Login:"); + bool b = await All(t, CancellationToken.None); + Console.WriteLine($"Auto Login {(b ? "Successful" : "Failed")}"); + return b; } - private async Task Both(string Username, string Password, CancellationToken CancellationToken, string? Displayname = null, string? pfp = null) + private async Task All(string Username, CancellationToken CancellationToken, string? Password = null, string? Displayname = null, string? pfp = null) { + DateTime dt = DateTime.UtcNow; + Console.WriteLine("Encryption: " + DateTime.UtcNow.Subtract(dt).ToString("g")); if (!EncryptionHandler.Generating) { EncryptionHandler.GenerateKeys(); } while (!EncryptionHandler.Generated) { } - + Console.WriteLine("Encryption 2: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + List> FailedSystems = new(); login = true; - Login json; + LoginSTC json; List> heads = new() { new("key", EncryptionHandler.MyPublicKey), - new("username", Convert.ToBase64String(Encryption.RSA.Encrypt(Username, EncryptionHandler.ServerPublicKey, EncoderType.UTF16))), - new("password", EncryptionHandler.RemotePasswordEncrypt(Encryption.Generic.Encoders[(int)EncoderType.UTF16].GetBytes(Password))) + new((Password is null ? "token" : "username"), Convert.ToBase64String(Encryption.RSA.Encrypt(Username, EncryptionHandler.ServerPublicKey, EncoderType.UTF16))) }; + if (Password is not null) + { + heads.Add(new("password", EncryptionHandler.RemotePasswordEncrypt(Encryption.Generic.Encoders[(int)EncoderType.UTF16].GetBytes(Password)))); + } if (File.Exists("LastPassVer.txt") && int.TryParse(File.ReadAllText("LastPassVer.txt"), out int lpv) && lpv < EncryptionHandler.PasswordVersion && lpv >= 0) { heads.Add(new("old_password", EncryptionHandler.RemotePasswordEncrypt(Encoding.Unicode.GetBytes(Password), lpv))); @@ -210,19 +73,25 @@ public partial class PublicServer json = await SendServer( "SocketAccount", pfp, - LoginContext.Default.Login, + LoginSTCContext.Default.LoginSTC, CancellationToken, heads.ToArray()); } else { json = await GetFromServer( - "SocketAccount", - LoginContext.Default.Login, + (Password is null ? "SocketAccount/AccessToken": "SocketAccount"), + LoginSTCContext.Default.LoginSTC, CancellationToken, heads.ToArray()); } - if (json.Error is not null) throw new Exception($"Luski appears to be down at the current moment: {json.ErrorMessage}"); + Console.WriteLine("Account Result: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + if (json.Error is not null) + { + Console.WriteLine(json.ErrorMessage); + return false; + throw new Exception($"Luski appears to be down at the current moment: {json.ErrorMessage}"); + } if (EncryptionHandler.OfflinePrivateKey is null || EncryptionHandler.OfflinePublicKey is null) throw new Exception("Something went wrong generating the offline keys"); login = false; if (json is not null && json.Error is null) @@ -234,15 +103,17 @@ public partial class PublicServer ServerOut.EmitOnPing = true; ServerOut.OnError += ServerOut_OnError; ServerOut.Connect(); + Console.WriteLine("WSS Connection: " + DateTime.UtcNow.Subtract(dt).ToString("g")); SendServer(DataType.Token, new WSSLogin() { Token = json.Token! }); while (Token is null && Error is null) { - Thread.Sleep(500); + Thread.Sleep(200); } if (Error is not null) { throw new Exception(Error); } + Console.WriteLine("WSS Login: " + DateTime.UtcNow.Subtract(dt).ToString("g")); if (Token is null) throw new Exception("Server did not send a token"); CanRequest = true; @@ -250,108 +121,161 @@ public partial class PublicServer Token.Split('.')[0] ))); User = await GetUser(id, CancellationToken); - StorageInfoJSON data; - if (Storage.StorageID == 0) - { - EncryptionHandler.Hash = Storage.GenerateStorage(); - data = await SendServer("OfflineData/Info", - new StorageInfoJSON() - { - id = 0, - update = false, - password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) - }, - StorageInfoJSONContext.Default.StorageInfoJSON, - StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, - new KeyValuePair("storage_id", Storage.StorageID.ToString())); - Storage.setid(data.id); - } - else - { - data = await GetFromServer("OfflineData/Info", StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, new KeyValuePair("storage_id", Storage.StorageID.ToString())); - } + User.Username = Username; + Console.WriteLine("Get our info: " + DateTime.UtcNow.Subtract(dt).ToString("g")); - if (data.update) - { - EncryptionHandler.Hash = Storage.UpdateStorage(Convert.FromBase64String(data.password)); - _ = await SendServerPatch("OfflineData/Info", - new StorageInfoJSON() - { - id = 0, - update = false, - password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) - }, - StorageInfoJSONContext.Default.StorageInfoJSON, - StorageInfoJSONContext.Default.StorageInfoJSON, CancellationToken, - new KeyValuePair("storage_id", Storage.StorageID.ToString())); - } + #region Extra Systems + + Task.Run(async () => { + #region Data Storage try { - _ = EncryptionHandler.GetKey(0); + StorageInfoSTC data; + if (Storage.StorageID == 0) + { + EncryptionHandler.Hash = Storage.GenerateStorage(); + data = await SendServer("OfflineData/Info", + new StorageInfoCTS() + { + Password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) + }, + StorageInfoCTSContext.Default.StorageInfoCTS, + StorageInfoSTCContext.Default.StorageInfoSTC, CancellationToken, + new KeyValuePair("storage_id", Storage.StorageID.ToString())); + Storage.setid(data.ID); + } + else + { + data = await GetFromServer("OfflineData/Info", StorageInfoSTCContext.Default.StorageInfoSTC, CancellationToken, new KeyValuePair("storage_id", Storage.StorageID.ToString())); + } + Console.WriteLine("Offline Data Info: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + if (data.Update) + { + EncryptionHandler.Hash = Storage.UpdateStorage(Convert.FromBase64String(data.Password)); + _ = await SendServerPatch("OfflineData/Info", + new StorageInfoCTS() + { + Password = Convert.ToBase64String(Encryption.AES.Encrypt(EncryptionHandler.Hash, Storage.GetResourceBytes(StorageDirectory.StorageInfo, "lpk"))) + }, + StorageInfoCTSContext.Default.StorageInfoCTS, + StorageInfoSTCContext.Default.StorageInfoSTC, CancellationToken, + new KeyValuePair("storage_id", Storage.StorageID.ToString())); + Console.WriteLine("Data Update: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + } } catch (Exception e) { - EncryptionHandler.SetKey(0, new() - { - EncryptionType = EncryptionType.None, - Key = string.Empty - }); + FailedSystems.Add(new("Data Storage", e.Message, e)); } - _ = await UpdateStatus(UserStatus.Online, CancellationToken); - //EncryptionHandler.Hash = EncryptionHandler.LocalPasswordEncrypt(Encoding.Unicode.GetBytes(Username.ToLower() + Password)); - KeyValuePair stor = new("storage_id", Storage.StorageID.ToString()); - OfflineData offlinedata = await GetFromServer("OfflineData", OfflineDataContext.Default.OfflineData, CancellationToken, stor); - if (offlinedata is not null && offlinedata.Error is null && offlinedata.Data is not null && offlinedata.Data.Length > 0) + #endregion + + #region Key Generation + try { - string pkey = Storage.GetResourceKeyRaw( - StorageDirectory.ServerKeys, - "pkey", - EncryptionHandler.Hash - ); - foreach (string keyexx in offlinedata.Data) + try { - string keyex = Encoding.UTF8.GetString(Convert.FromBase64String(keyexx)); - KeyExchange? okd = JsonSerializer.Deserialize(keyex); - if (okd is not null && !string.IsNullOrEmpty(okd.key)) + _ = EncryptionHandler.GetKey(0); + } + catch (Exception e) + { + EncryptionHandler.SetKey(0, new() { - Storage.SetResourceKey( - StorageDirectory.ChannelKeys, - okd.channel.ToString(), - EncryptionHandler.Hash, - Encoding.Unicode.GetString( - Encryption.RSA.Decrypt( - Convert.FromBase64String(okd.key), - pkey - ) - ) - ); - } + EncryptionType = EncryptionType.None, + Key = string.Empty + }); + Console.WriteLine("Key 0: " + DateTime.UtcNow.Subtract(dt).ToString("g")); } } - System.IO.File.WriteAllText("LastPassVer.txt", EncryptionHandler.PasswordVersion.ToString()); - Storage.SetResourceKey(StorageDirectory.ServerKeys, "pkey", EncryptionHandler.Hash, EncryptionHandler.OfflinePrivateKey); - UserKeyGetRequest OfflineKeySetRequest = new() + catch (Exception e) { - key_data = Convert.ToBase64String(Encoding.UTF8.GetBytes(EncryptionHandler.OfflinePublicKey)), - encryption_type = EncryptionType.RSA - }; - _ = await SendServer("Keys/SetOfflineKey", - OfflineKeySetRequest, - UserKeyGetRequestContext.Default.UserKeyGetRequest, - IncomingHTTPContext.Default.IncomingHTTP, - CancellationToken.None, - stor); - // using HttpClient setkey = new(); - // setkey.DefaultRequestHeaders.Add("token", Token); - // _ = await setkey.PostAsync($"{(Secure ? "https" : "http" )}://{Domain}/{ApiVersion}/Keys/SetOfflineKey", new StringContent(EncryptionHandler.OfflinePublicKey)); - EncryptionHandler.OfflinePublicKey = null!; - EncryptionHandler.OfflinePrivateKey = null!; - //API_Handler.IsAnyServerLoggedin = true; + FailedSystems.Add(new("Key Generation", "Key 0 Failed to generate", e)); + } + #endregion + + #region Auto Status + try + { + _ = await UpdateStatus(UserStatus.Online, CancellationToken); + Console.WriteLine("Status: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + } + catch (Exception e) + { + FailedSystems.Add(new("Auto Status", "Failed to set status on the server", e)); + } + #endregion + + #region Local Storage Cleanup + try + { + KeyValuePair stor = new("storage_id", Storage.StorageID.ToString()); + OfflineDataBlobSTC offlinedata = await GetFromServer("OfflineData", OfflineDataBlobSTCContext.Default.OfflineDataBlobSTC, CancellationToken, stor); + Console.WriteLine("Offline Data: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + if (offlinedata is not null && offlinedata.Error is null && offlinedata.Data is not null && offlinedata.Data.Length > 0) + { + string pkey = Storage.GetResourceKeyRaw( + StorageDirectory.ServerKeys, + "pkey", + EncryptionHandler.Hash + ); + foreach (string keyexx in offlinedata.Data) + { + string keyex = Encoding.UTF8.GetString(Convert.FromBase64String(keyexx)); + KeyExchange? okd = JsonSerializer.Deserialize(keyex); + if (okd is not null && !string.IsNullOrEmpty(okd.key)) + { + Storage.SetResourceKey( + StorageDirectory.ServerKeys, + okd.id.ToString(), + EncryptionHandler.Hash, + Encoding.Unicode.GetString( + Encryption.RSA.Decrypt( + Convert.FromBase64String(okd.key), + pkey + ) + ) + ); + } + } + } + System.IO.File.WriteAllText("LastPassVer.txt", EncryptionHandler.PasswordVersion.ToString()); + Storage.SetResourceKey(StorageDirectory.ServerKeys, "pkey", EncryptionHandler.Hash, EncryptionHandler.OfflinePrivateKey); + KeyPostCTS OfflineKeySetRequest = new() + { + Data = Convert.ToBase64String(Encoding.UTF8.GetBytes(EncryptionHandler.OfflinePublicKey)), + EncryptionType = EncryptionType.RSA + }; + _ = await SendServer("Keys/SetOfflineKey", + OfflineKeySetRequest, + KeyPostCTSContext.Default.KeyPostCTS, + STCContext.Default.STC, + CancellationToken.None, + stor); + Console.WriteLine("Offline Key: " + DateTime.UtcNow.Subtract(dt).ToString("g")); + EncryptionHandler.OfflinePublicKey = null!; + EncryptionHandler.OfflinePrivateKey = null!; + } + catch (Exception e) + { + FailedSystems.Add(new("Local Storage Cleanup", "Failed to clean the local storage", e)); + } + #endregion + + if (FailedSystems.Count > 0) + { + Console.WriteLine("Some systems have failed:"); + foreach (Tuple System in FailedSystems) + { + Console.WriteLine($"\t{System.Item1}:\n\t\tMessage: {System.Item2}\n\t\tError Details: {System.Item3}"); + } + } }); + + + #endregion + return true; } else throw new Exception(json?.ErrorMessage); - //API_Handler.IsAnyServerLoggedin = true; return true; } } \ No newline at end of file diff --git a/Luski.net/PublicServer.Incoming.cs b/Luski.net/PublicServer.Incoming.cs index 926c9df..3c01ab7 100644 --- a/Luski.net/PublicServer.Incoming.cs +++ b/Luski.net/PublicServer.Incoming.cs @@ -1,11 +1,17 @@ using System; -using System.IO; +using System.Collections.Generic; using System.Text.Json; +using JacobTechEncryption; +using JacobTechEncryption.Enums; using Luski.net.Enums; using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.WSS; +using Luski.net.Structures; +using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; using WebSocketSharp; -using DataType = Luski.net.Enums.Public.DataType; +using File = System.IO.File; +using DataType = Luski.Shared.PublicServers.V1.Enums.DataType; namespace Luski.net; @@ -14,6 +20,10 @@ public partial class PublicServer private void DataFromServer(object? sender, MessageEventArgs e) { if (e.IsPing) return; + if (PrintServerMessages) + { + Console.WriteLine(e.Data); + } try { BetterIncomingWSS? data = JsonSerializer.Deserialize(e.Data, BetterIncomingWSSContext.Default.BetterIncomingWSS); @@ -25,6 +35,52 @@ public partial class PublicServer n.SessionToken); Token = n.Token; break; + case DataType.MessageCreate: + MessageSTC smsg = JsonSerializer.Deserialize(data.Data!.ToString()!, MessageSTCContext.Default.MessageSTC)!; + List fl = new(); + foreach (var VARIABLE in smsg.Files) + { + fl.Add(VARIABLE.ID); + } + + if (smsg.EncryptionKey == 0) + { + if (string.IsNullOrEmpty(smsg.Context)) + { + smsg.Context = ""; + } + else smsg.Context = Encryption.Generic.Encoders[(int)smsg.EncoderType] + .GetString(Convert.FromBase64String(smsg.Context)); + } + else + { + LocalKeyInfo key = EncryptionHandler.GetKey(smsg.EncryptionKey); + switch (key.EncryptionType) + { + case EncryptionType.RSA: + smsg.Context = Encryption.RSA.Decrypt(Convert.FromBase64String(smsg.Context), key.Key, + smsg.EncoderType); + break; + default: + smsg.Context = Encryption.Generic.Encoders[(int)smsg.EncoderType] + .GetString(Convert.FromBase64String(smsg.Context)); + break; + } + } + SocketMessage sm = new() + { + ID = smsg.ID, + AuthorID = smsg.AuthorID, + ChannelID = smsg.ChannelID, + Context = smsg.Context, + EncoderType = smsg.EncoderType, + EncryptionKey = smsg.EncryptionKey, + FileIDs = fl.ToArray(), + Server = this, + IsProfile = smsg.IsProfile + }; + if (MessageReceived is not null) MessageReceived.Invoke(sm); + break; default: Console.WriteLine("Unknown"); break; diff --git a/Luski.net/PublicServer.cs b/Luski.net/PublicServer.cs index 1539d63..6412524 100644 --- a/Luski.net/PublicServer.cs +++ b/Luski.net/PublicServer.cs @@ -3,28 +3,29 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; -using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; using JacobTechEncryption.Enums; using Luski.net.Enums; -using Luski.net.Enums.Main; using Luski.net.Interfaces; using Luski.net.JsonTypes; -using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.HTTP; -using Luski.net.JsonTypes.Public; using Luski.net.Structures; using Luski.net.Structures.Public; -using Channel = Luski.net.JsonTypes.Public.Channel; +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; using Role = Luski.net.Structures.Public.Role; +using SocketChannelProfile = Luski.net.Structures.Public.SocketChannelProfile; using SocketUser = Luski.net.Structures.Public.SocketUser; namespace Luski.net; public partial class PublicServer : Server { + public event Func? MessageReceived; public List chans { get; } = new(); public List cats { get; } = new(); public List roles { get; } = new(); @@ -35,15 +36,24 @@ public partial class PublicServer : Server base(Domain, API_Version, Secure) { } - internal static async Task GetServer(string Domain, string API_Version, bool Secure = true) + internal static async Task GetServer(string Domain, string API_Version, bool Secure = true, bool GenerateEncryption = true, bool LogConsole = false) { DateTime dt = DateTime.UtcNow; Console.WriteLine("Connecting to public server '{0}' using API {1}.", Domain, API_Version); PublicServer s = new(Domain, API_Version, Secure); - ServerInfo? si = null; + s.PrintServerMessages = LogConsole; + if (GenerateEncryption) + { + Thread t = new(_ => + { + s.EncryptionHandler.GenerateKeys(); + }); + t.Start(); + } + ServerInfoSTC? si = null; try { - si = await s.GetFromServer("socketserver", ServerInfoContext.Default.ServerInfo, CancellationToken.None); + si = await s.GetFromServer("socketserver", ServerInfoSTCContext.Default.ServerInfoSTC, CancellationToken.None); s.EncryptionHandler.ServerPublicKey = await (await new HttpClient() .GetAsync($"{(s.Secure ? "https" : "http")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey")) .Content @@ -64,7 +74,7 @@ public partial class PublicServer : Server try { - si = await s.GetFromServer("socketserver", ServerInfoContext.Default.ServerInfo, CancellationToken.None); + si = await s.GetFromServer("socketserver", ServerInfoSTCContext.Default.ServerInfoSTC, CancellationToken.None); s.EncryptionHandler.ServerPublicKey = await (await new HttpClient() .GetAsync($"{(s.Secure ? "https" : "http")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey")) .Content @@ -81,17 +91,20 @@ public partial class PublicServer : Server if (si is null) throw; } - s.Name = si.name; - s.Description = si.description; - s.wssurl = si.wssv4; + s.Name = si.Name; + s.Description = si.Description; + s.wssurl = si.WSSv4Address; s.ServerType = ServerType.Public; + s.OwnerID = si.Owner; 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; } + + public long OwnerID { get; private set; } = 0; public async Task GetCategory(long id, CancellationToken CancellationToken) where TCategory : SocketCategory, new() { - Category request; + CategorySTC request; if (cats.Count > 0 && cats.Any(s => s.ID == id)) { return (cats.Where(s => s is TCategory && s.ID == id).First() as TCategory)!; @@ -100,7 +113,7 @@ public partial class PublicServer : Server { if (CanRequest) { - request = await GetFromServer($"SocketCategory", PublicCategoryContext.Default.Category, CancellationToken, new KeyValuePair("id", id.ToString())); + request = await GetFromServer($"SocketCategory", CategorySTCContext.Default.CategorySTC, CancellationToken, new KeyValuePair("id", id.ToString())); break; } } @@ -115,7 +128,14 @@ public partial class PublicServer : Server } } - LocalKeyInfo deckey = EncryptionHandler.GetKey(request.DescriptionEncryptionKey); + LocalKeyInfo deckey; + if (request.DescriptionEncryptionKey != 0) + deckey = EncryptionHandler.GetKey(request.DescriptionEncryptionKey); + else deckey = new() + { + EncryptionType = EncryptionType.None, + Key = string.Empty + }; string dec = deckey.EncryptionType switch { EncryptionType.RSA => Encryption.RSA.Decrypt(Convert.FromBase64String(request.Description), deckey.Key, request.DescriptionEncoderType), @@ -123,7 +143,14 @@ public partial class PublicServer : Server Encryption.AES.Decrypt(Convert.FromBase64String(request.Description), deckey.Key)), _ => Encryption.Generic.Encoders[(short)request.DescriptionEncoderType].GetString(Convert.FromBase64String(request.Description)) }; - LocalKeyInfo nkey = EncryptionHandler.GetKey(request.TitleEncryptionKey); + LocalKeyInfo nkey; + if (request.TitleEncryptionKey != 0) + nkey = EncryptionHandler.GetKey(request.TitleEncryptionKey); + else nkey = new() + { + EncryptionType = EncryptionType.None, + Key = string.Empty + }; string n = nkey.EncryptionType switch { EncryptionType.RSA => Encryption.RSA.Decrypt(Convert.FromBase64String(request.Name), nkey.Key, request.TitleEncoderType), @@ -142,8 +169,8 @@ public partial class PublicServer : Server Channels = request.Channels, Categories = request.InnerCategories, Name = n, - RoleOverides = request.RoleOverides, - UserOverides = request.UserOverides, + RoleOverides = request.RoleOverrides, + UserOverides = request.UserOverrides, TitleEncoderType = request.TitleEncoderType, TitleEncryptionKey = request.TitleEncryptionKey, Server = this, @@ -161,32 +188,88 @@ public partial class PublicServer : Server _ => new Exception($"Unknown data: '{request.ErrorMessage}'"), }; } - + public async Task GetRole(long id) { Role[] r = roles.Where(s => s.ID == id).ToArray(); if (r.Length > 0) return r[0]; - JsonTypes.Public.Role s = await GetFromServer("SocketRole?id=" + id.ToString(), RoleContext.Default.Role, CancellationToken.None); + RoleSTC s = await GetFromServer("SocketRole?id=" + id.ToString(), RoleSTCContext.Default.RoleSTC, CancellationToken.None); Role role = new() { Server = this, - ID = s.id, - Color = new(s.color), - Description = s.description, - DisplayName = s.display_name, - MembersListID = s.members_list, - Name = s.name, - Index = s.index, - ServerPermissions = s.server_permissions + ID = s.ID, + Color = new(s.Color), + Description = s.Description, + DisplayName = s.DisplayName, + MembersListID = s.Members, + Name = s.Name, + Index = s.Index, + ServerPermissions = s.ServerPermissions }; roles.Add(role); return role; } + + public async Task SendMessage(TChannel channel, string msg, SocketMessage? ReplyTo = null, + SocketChannelProfile? FakeProfile = null) where TChannel : SocketChannel, new() + { + 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) + }); + } + MessageCTS pcsm = new() + { + Files = Array.Empty(), + ChannelID = channel.ID, + EncryptionKey = channel.EncryptionKeys[0], + Encoding = channel.EncoderTypes[0], + Base64Context = bc + }; + if (FakeProfile is not null) + { + pcsm.Profile = FakeProfile.Id; + } + + + + MessageSTC smsg = await channel.Server.SendServer("socketmessage", pcsm, + MessageCTSContext.Default.MessageCTS, MessageSTCContext.Default.MessageSTC, + CancellationToken.None); + List fl = new(); + foreach (var VARIABLE in smsg.Files) + { + fl.Add(VARIABLE.ID); + } + SocketMessage sm = new() + { + ID = smsg.ID, + AuthorID = smsg.AuthorID, + ChannelID = channel.ID, + Context = msg, + EncoderType = smsg.EncoderType, + EncryptionKey = smsg.EncryptionKey, + FileIDs = fl.ToArray(), + Server = channel.Server, + IsProfile = smsg.IsProfile + }; + return sm; + } public async Task GetChannel(long id, CancellationToken CancellationToken) where TChannel : SocketChannel, new() { - Channel request; + ChannelSTC request; if (chans.Count > 0 && chans.Any(s => s.ID == id)) { return (chans.Where(s => s is TChannel && s.ID == id).First() as TChannel)!; @@ -195,7 +278,7 @@ public partial class PublicServer : Server { if (CanRequest) { - request = await GetFromServer($"SocketChannel", PublicChannelContext.Default.Channel, CancellationToken, new KeyValuePair("id", id.ToString())); + request = await GetFromServer($"SocketChannel", ChannelSTCContext.Default.ChannelSTC, CancellationToken, new KeyValuePair("id", id.ToString())); break; } } @@ -210,7 +293,14 @@ public partial class PublicServer : Server } } - LocalKeyInfo deckey = EncryptionHandler.GetKey(request.DescriptionEncryptionKey); + LocalKeyInfo deckey; + if (request.DescriptionEncryptionKey != 0) + deckey = EncryptionHandler.GetKey(request.DescriptionEncryptionKey); + else deckey = new() + { + EncryptionType = EncryptionType.None, + Key = string.Empty + }; string dec = deckey.EncryptionType switch { EncryptionType.RSA => Encryption.RSA.Decrypt(Convert.FromBase64String(request.Description), deckey.Key, request.DescriptionEncoderType), @@ -218,7 +308,14 @@ public partial class PublicServer : Server Encryption.AES.Decrypt(Convert.FromBase64String(request.Description), deckey.Key)), _ => Encryption.Generic.Encoders[(short)request.DescriptionEncoderType].GetString(Convert.FromBase64String(request.Description)) }; - LocalKeyInfo nkey = EncryptionHandler.GetKey(request.TitleEncryptionKey); + LocalKeyInfo nkey; + if (request.TitleEncryptionKey != 0) + nkey = EncryptionHandler.GetKey(request.TitleEncryptionKey); + else nkey = new() + { + EncryptionType = EncryptionType.None, + Key = string.Empty + }; string n = nkey.EncryptionType switch { EncryptionType.RSA => Encryption.RSA.Decrypt(Convert.FromBase64String(request.Name), nkey.Key, request.TitleEncoderType), @@ -238,8 +335,8 @@ public partial class PublicServer : Server EncryptionKeys = request.EncryptionKeys, Epoch = request.Epoch, Name = n, - RoleOverides = request.RoleOverides, - UserOverides = request.UserOverides, + RoleOverrides = request.RoleOverrides, + UserOverrides = request.UserOverrides, Type = request.Type, TitleEncoderType = request.TitleEncoderType, TitleEncryptionKey = request.TitleEncryptionKey, @@ -259,10 +356,56 @@ public partial class PublicServer : Server _ => new Exception($"Unknown data: '{request.ErrorMessage}'"), }; } + + public async Task MakeChannel(SocketCategory parent, string Name, string Decription) + { + ChannelSTC res = await SendServer( + "SocketChannel", + new ChannelPostCTS() + { + Name = Convert.ToBase64String(Encoding.UTF8.GetBytes(Name)), + Description = Convert.ToBase64String(Encoding.UTF8.GetBytes(Description)), + EncoderTypes = new[] { EncoderType.UTF16 }, + EncryptionKeys = new long[] { 0 }, + DescriptionEncoderType = EncoderType.UTF8, + TitleEncoderType = EncoderType.UTF8, + Parent = parent.ID, + DescriptionEncryptionKey = 0, + TitleEncryptionKey = 0, + RoleOverrides = Array.Empty(), + UserOverrides = Array.Empty(), + Type = ChannelType.TextAndVoice, + Color = "FFFFFFFF", + PictureType = PictureType.none + }, + ChannelPostCTSContext.Default.ChannelPostCTS, + ChannelSTCContext.Default.ChannelSTC, + CancellationToken.None); + return new SocketChannel() + { + ID = res.ID, + CategoryID = res.Parent, + Description = Description, + 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, + Server = this, + Color = new(res.Color) + }; + } public async Task GetUser(long UserId, CancellationToken CancellationToken) where Tuser : SocketUser, new() { - JsonTypes.Public.SocketUser user; + SocketUserSTC user; if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId)) { Tuser temp = poeople.Where(s => s is Tuser && s.Id == UserId).Cast().FirstOrDefault()!; @@ -273,7 +416,7 @@ public partial class PublicServer : Server if (CanRequest) { user = await GetFromServer("socketuser", - PublicSocketUserContext.Default.SocketUser, + SocketUserSTCContext.Default.SocketUserSTC, CancellationToken, new KeyValuePair("id", UserId.ToString())); break; @@ -319,13 +462,60 @@ public partial class PublicServer : Server PictureType = user.PictureType, RoleIds = user.RoleIds, Status = user.Status, - Username = user.Username } as Tuser)!; } poeople.Add(u); return u; } + public async Task GetChannelProfile(long ProfileId, CancellationToken CancellationToken) + { + ChannelProfileSTC user; + if (profiles.Count > 0 && profiles.Any(s => s.Id == ProfileId)) + { + SocketChannelProfile temp = profiles.Where(s => s.Id == ProfileId).FirstOrDefault()!; + return temp; + } + while (true) + { + if (CanRequest) + { + user = await GetFromServer("socketchannelprofile", + ChannelProfileSTCContext.Default.ChannelProfileSTC, + CancellationToken, + new KeyValuePair("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)) + { + foreach (SocketChannelProfile? p in profiles.Where(s => s.Id == ProfileId)) + { + profiles.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}"); + } + + SocketChannelProfile u = new() + { + Server = this, + Id = user.ID, + DisplayName = user.DisplayName, + PictureType = user.PictureType, + Controllers = user.Controllers, + Color = new(user.Color) + }; + poeople.Add(u); + return u; + } + /// /// Sends the server a request to update the of you account /// @@ -333,7 +523,7 @@ public partial class PublicServer : Server /// 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); + STC? data = await SendServer("SocketUserProfile/Status", new StatusUpdateCTS() { Status = Status }, StatusUpdateCTSContext.Default.StatusUpdateCTS, STCContext.Default.STC, 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); diff --git a/Luski.net/Server.Encryption.cs b/Luski.net/Server.Encryption.cs index 0cfa80c..d8a47f0 100644 --- a/Luski.net/Server.Encryption.cs +++ b/Luski.net/Server.Encryption.cs @@ -65,7 +65,7 @@ public class ServerEncryption public void GenerateKeys() { - if (!Generating) + if (!Generating && !Generated) { Generating = true; GenerateNewKeys(out MyPublicKey, out myPrivateKey); diff --git a/Luski.net/Server.Globals.cs b/Luski.net/Server.Globals.cs index 27893e5..ef7ddbb 100644 --- a/Luski.net/Server.Globals.cs +++ b/Luski.net/Server.Globals.cs @@ -15,10 +15,13 @@ public partial class Server { public ServerType ServerType { get; internal set; } = ServerType.Public; public string Domain { get; set; } = default!; + + public bool PrintServerMessages { get; set; } = false; public string ApiVersion { get; } = "v1"; internal WebSocket? ServerOut; internal string? Token = null, Error = null, gen = null; public bool IsLogedIn => Token is not null; internal bool CanRequest = false, login = false; internal List poeople = new(); + internal List profiles = new(); } \ No newline at end of file diff --git a/Luski.net/Server.Storage.cs b/Luski.net/Server.Storage.cs index b550410..4804315 100644 --- a/Luski.net/Server.Storage.cs +++ b/Luski.net/Server.Storage.cs @@ -26,7 +26,8 @@ public class ServerStorage "Channels/Icons", "Channels/Messages", "StorageInfo", - "Channels/Files" + "Files", + "Channels/Profiles" }; private static readonly int[] CantDelete = new[] @@ -94,7 +95,23 @@ public class ServerStorage { byte[] NewPassword = new byte[100]; byte[] lpk = GetResourceBytes(StorageDirectory.StorageInfo, "lpk"); - OldPassword = Encryption.AES.Decrypt(OldPassword, lpk); + try + { + OldPassword = Encryption.AES.Decrypt(OldPassword, lpk); + } + catch (Exception e) + { + Console.WriteLine("Attempting to generate a new storage"); + try + { + return GenerateStorage(); + } + catch + { + throw new Exception("Failed To Decrypt Local Storage.", e); + } + } + using (RandomNumberGenerator provider = RandomNumberGenerator.Create()) { provider.GetBytes(NewPassword); diff --git a/Luski.net/Server.cs b/Luski.net/Server.cs index c1d62f4..441aa11 100644 --- a/Luski.net/Server.cs +++ b/Luski.net/Server.cs @@ -13,6 +13,9 @@ using Luski.net.Enums; using Luski.net.Interfaces; using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.WSS; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; using File = System.IO.File; namespace Luski.net; @@ -47,7 +50,7 @@ public partial class Server ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo)); } - public void SendServer(Enums.Public.DataType Type, IServerEvent Payload) + public void SendServer(Luski.Shared.PublicServers.V1.Enums.DataType Type, IServerEvent Payload) { ServerOut?.Send(JsonSerializer.Serialize(new WSSOut() { @@ -82,10 +85,9 @@ public partial class Server return Task.CompletedTask; } - public async Task GetFromServer(string Path, JsonTypeInfo Type, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : IncomingHTTP, new() + public async Task GetFromServer(string Path, JsonTypeInfo Type, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : STC, new() { HttpResponseMessage ServerResponce = GetFromServer(Path, CancellationToken, Headers); - //if (!ServerResponce.IsSuccessStatusCode) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with status code {(int)ServerResponce.StatusCode}:{ServerResponce.StatusCode}" }; Tresult temp = new(); string raw = ServerResponce.Content.ReadAsStringAsync(CancellationToken).Result; try @@ -100,7 +102,7 @@ public partial class Server return temp; } - public async Task SendServer(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tvalue : IWebRequest where Tresult : IncomingHTTP, new() + public async Task SendServer(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tvalue : CTS where Tresult : STC, new() { using HttpClient web = new(); if (!login) web.DefaultRequestHeaders.Add("token", Token); @@ -118,7 +120,7 @@ public partial class Server catch { return error; } } - public async Task SendServerPatch(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tvalue : IWebRequest where Tresult : IncomingHTTP, new() + public async Task SendServerPatch(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tvalue : CTS where Tresult : STC, new() { using HttpClient web = new(); if (!login) web.DefaultRequestHeaders.Add("token", Token); @@ -138,7 +140,7 @@ public partial class Server catch { return error; } } - public async Task SendServer(string Path, string File, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : IncomingHTTP, new() + public async Task SendServer(string Path, string File, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] Headers) where Tresult : STC, new() { var fs = System.IO.File.OpenRead(File); try diff --git a/Luski.net/Structures/File.cs b/Luski.net/Structures/File.cs index d012a44..29b7be6 100755 --- a/Luski.net/Structures/File.cs +++ b/Luski.net/Structures/File.cs @@ -13,10 +13,11 @@ using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; using Luski.net.Interfaces; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures; -public class File : IncomingHTTP +public class File : STC { public MainServer Server { get; internal set; } [JsonInclude] diff --git a/Luski.net/Structures/Main/MainSocketChannel.cs b/Luski.net/Structures/Main/MainSocketChannel.cs index a71e541..3fa3c14 100755 --- a/Luski.net/Structures/Main/MainSocketChannel.cs +++ b/Luski.net/Structures/Main/MainSocketChannel.cs @@ -14,10 +14,11 @@ using JacobTechEncryption; using JacobTechEncryption.Enums; using Luski.net.Enums.Main; using Luski.net.JsonTypes; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Main; -public class MainSocketChannel : IncomingHTTP +public class MainSocketChannel : STC { [JsonInclude] [JsonPropertyName("id")] diff --git a/Luski.net/Structures/Main/MainSocketMessage.cs b/Luski.net/Structures/Main/MainSocketMessage.cs index f51ca04..e59a425 100755 --- a/Luski.net/Structures/Main/MainSocketMessage.cs +++ b/Luski.net/Structures/Main/MainSocketMessage.cs @@ -6,10 +6,11 @@ using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Main; -public class MainSocketMessage : IncomingHTTP +public class MainSocketMessage : STC { public MainServer Server { get; internal set; } = default!; [JsonPropertyName("id")] diff --git a/Luski.net/Structures/Main/MainSocketTextChannel.cs b/Luski.net/Structures/Main/MainSocketTextChannel.cs index f0a596b..4674af9 100755 --- a/Luski.net/Structures/Main/MainSocketTextChannel.cs +++ b/Luski.net/Structures/Main/MainSocketTextChannel.cs @@ -11,7 +11,10 @@ using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; using JacobTechEncryption.Enums; -using Luski.net.Enums.Main; +using Luski.Shared.PublicServers.V1.ClientToServer.HTTP; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; +using ChannelType = Luski.net.Enums.Main.ChannelType; namespace Luski.net.Structures.Main; @@ -138,10 +141,13 @@ public class MainSocketTextChannel : MainSocketChannel public async Task SendMessage(string Message, CancellationToken CancellationToken, params File?[] Files) { string key = Server.EncryptionHandler.GetChannelKey(Id); - JsonTypes.HTTP.Message m = new() + MessageCTS m = new() { - Context = Convert.ToBase64String(Encryption.RSA.Encrypt(Message, key, EncoderType.UTF8)), - Channel = Id, + Base64Context = Convert.ToBase64String(Encryption.RSA.Encrypt(Message, key, EncoderType.UTF8)), + ChannelID = Id, + Profile = null, + EncryptionKey = 0, + Encoding = EncoderType.UTF8 }; if (Files is not null && Files.Length > 0) { @@ -157,7 +163,7 @@ public class MainSocketTextChannel : MainSocketChannel } m.Files = bb.ToArray(); } - IncomingHTTP data = await Server.SendServer("socketmessage", m, net.JsonTypes.HTTP.MessageContext.Default.Message, IncomingHTTPContext.Default.IncomingHTTP, CancellationToken); + STC data = await Server.SendServer("socketmessage", m, MessageCTSContext.Default.MessageCTS, STCContext.Default.STC, CancellationToken); if (data.Error is not null && data.ErrorMessage != "Server responded with empty data") throw new Exception(data.ErrorMessage); return Task.CompletedTask; } diff --git a/Luski.net/Structures/Main/MainSocketUserBase.cs b/Luski.net/Structures/Main/MainSocketUserBase.cs index bf3eb69..1f6fbb6 100644 --- a/Luski.net/Structures/Main/MainSocketUserBase.cs +++ b/Luski.net/Structures/Main/MainSocketUserBase.cs @@ -1,14 +1,17 @@ +using System; using System.IO; 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; +using Luski.net.Structures.Public; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Main; -public class MainSocketUserBase : IncomingHTTP, IUser +public class MainSocketUserBase : STC, IUser { public MainServer Server { get; internal set; } = default!; [JsonPropertyName("id")] @@ -23,6 +26,11 @@ public class MainSocketUserBase : IncomingHTTP, IUser [JsonPropertyName("picture_type")] [JsonInclude] public PictureType PictureType { get; internal set; } = default!; + + public Task GetColor() + { + throw new NotImplementedException(); + } public async Task GetAvatar(CancellationToken CancellationToken) { bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.Avatars) + Id.ToString()); diff --git a/Luski.net/Structures/Main/SocketBulkMessage.cs b/Luski.net/Structures/Main/SocketBulkMessage.cs index 5a5b336..f936006 100755 --- a/Luski.net/Structures/Main/SocketBulkMessage.cs +++ b/Luski.net/Structures/Main/SocketBulkMessage.cs @@ -1,9 +1,10 @@ -using Luski.net.JsonTypes.BaseTypes; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Main; -internal class SocketBulkMessage : IncomingHTTP +internal class SocketBulkMessage : STC + { [JsonPropertyName("messages")] [JsonInclude] diff --git a/Luski.net/Structures/Public/Color.cs b/Luski.net/Structures/Public/Color.cs index bc225b2..02156c6 100644 --- a/Luski.net/Structures/Public/Color.cs +++ b/Luski.net/Structures/Public/Color.cs @@ -6,35 +6,35 @@ public class Color { public Color(string servercol) { - Bytes = servercol; + Bytes = Convert.FromHexString(servercol); } public Color(byte R, byte G, byte B, byte A) { - Bytes = $"{Convert.ToChar(R)}{Convert.ToChar(G)}{Convert.ToChar(B)}{Convert.ToChar(A)}"; + Bytes = new byte[] {R, G, B, A}; } - private string Bytes; - - public string ToDB() + public string ToDatabaseStr() { - return Bytes; + return Convert.ToHexString(Bytes); } + + private byte[] Bytes; public byte A { - get => (byte)(Bytes[3]); + get => Bytes[3]; } public byte R { - get => (byte)(Bytes[0]); + get => Bytes[0]; } public byte G { - get => (byte)(Bytes[1]); + get => Bytes[1]; } public byte B { - get => (byte)(Bytes[2]); + get => Bytes[2]; } } \ No newline at end of file diff --git a/Luski.net/Structures/Public/Role.cs b/Luski.net/Structures/Public/Role.cs index d5a3b78..bed89d0 100644 --- a/Luski.net/Structures/Public/Role.cs +++ b/Luski.net/Structures/Public/Role.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Luski.net.Enums.Public; +using Luski.Shared.PublicServers.V1.Enums; namespace Luski.net.Structures.Public; @@ -13,7 +13,7 @@ public class Role public required Color Color { get; init; } = default!; public required string Description { get; init; } = default!; public required string DisplayName { get; init; } = default!; - public required ServerPermission[] ServerPermissions { get; init; } = default!; + public required ServerPermission ServerPermissions { get; init; } = default!; public required long[] MembersListID { get; init; } = default!; private List? RawUsers = null; diff --git a/Luski.net/Structures/Public/RoleOveride.cs b/Luski.net/Structures/Public/RoleOveride.cs index c79ebce..27dd63a 100644 --- a/Luski.net/Structures/Public/RoleOveride.cs +++ b/Luski.net/Structures/Public/RoleOveride.cs @@ -1,4 +1,6 @@ using System.Threading.Tasks; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.Shared; namespace Luski.net.Structures.Public; @@ -6,7 +8,10 @@ public class RoleOveride { public long ID { get; init; } public long ParentRoleID { get; init; } - internal string[] RawOverides { get; init; } + + public ServerPermission GoodPermissions { get; set; } + + public ServerPermission BadPermissions { get; set; } private Role? Parent = null; public Task GetRole() diff --git a/Luski.net/Structures/Public/SocketAppUser.cs b/Luski.net/Structures/Public/SocketAppUser.cs index b29e5c5..0b91c08 100755 --- a/Luski.net/Structures/Public/SocketAppUser.cs +++ b/Luski.net/Structures/Public/SocketAppUser.cs @@ -1,6 +1,9 @@ -using System.Threading; +using System.Collections.Generic; +using System.Linq; +using System.Threading; using System.Threading.Tasks; -using Luski.net.Enums; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.Shared; namespace Luski.net.Structures.Public; @@ -13,5 +16,39 @@ public class SocketAppUser : SocketUser return await Server.GetChannel(SelectedChannel, Token); } - public string Username { get; init; } = default!; + public async Task HasAccessToCategory(SocketCategory Category, ServerPermission RequiredPerms) + { + if (Category.Server != Server) return false; + if (Server.OwnerID == Id) return true; + Role[] UserRoleIDList = await GetRoles(); + RequiredPerms |= ServerPermission.ViewThis; + + ServerPermission GoodPerms = ServerPermission.None; + + UserOverride[] CatUserOverides = await Category.GetUserOverrides(); + foreach (UserOverride CatUserOveride in CatUserOverides) + { + if (CatUserOveride.UserID != Id) continue; + if ((CatUserOveride.BadPermissions & RequiredPerms) > ServerPermission.None) return false; + + GoodPerms |= CatUserOveride.GoodPermissions; + } + RoleOveride[] CatRoleOverides = await Category.GetRoleOverrides(); + foreach (RoleOveride CatRoleOveride in CatRoleOverides) + { + if (!RoleIds.Contains(CatRoleOveride.ParentRoleID)) continue; + if ((CatRoleOveride.BadPermissions & RequiredPerms) > ServerPermission.None) return false; + + GoodPerms |= CatRoleOveride.GoodPermissions; + } + + foreach (Role RoleID in UserRoleIDList) + { + if (((RoleID.ServerPermissions & RequiredPerms) ^ GoodPerms) > ServerPermission.None) return false; + GoodPerms |= RoleID.ServerPermissions; + } + return GoodPerms.HasPermission(RequiredPerms); + } + + public string Username { get; internal set; } = default!; } \ No newline at end of file diff --git a/Luski.net/Structures/Public/SocketCategory.cs b/Luski.net/Structures/Public/SocketCategory.cs index 0e60844..fe0511a 100644 --- a/Luski.net/Structures/Public/SocketCategory.cs +++ b/Luski.net/Structures/Public/SocketCategory.cs @@ -1,10 +1,8 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using JacobTechEncryption.Enums; -using Luski.net.Enums.Public; namespace Luski.net.Structures.Public; @@ -20,7 +18,7 @@ public class SocketCategory internal long[] Categories { get; set; } SocketCategory? RawParent = null; List? RawRoleOverides = null; - List? RawUserOverides = null; + List? RawUserOverides = null; List? RawChan = null; List? RawCat = null; @@ -81,7 +79,7 @@ public class SocketCategory public string Name { get; internal set; } public string Description { get; internal set; } - public Task GetRoleOverides() + public Task GetRoleOverrides() { if (RawRoleOverides is null) { @@ -90,7 +88,7 @@ public class SocketCategory return Task.FromResult(RawRoleOverides!.ToArray()); } - public Task GetUserOveride() + public Task GetUserOverrides() { if (RawUserOverides is null) { diff --git a/Luski.net/Structures/Public/SocketChannel.cs b/Luski.net/Structures/Public/SocketChannel.cs index 0c184e1..938f26e 100644 --- a/Luski.net/Structures/Public/SocketChannel.cs +++ b/Luski.net/Structures/Public/SocketChannel.cs @@ -6,8 +6,8 @@ using System.Threading.Tasks; using JacobTechEncryption; using JacobTechEncryption.Enums; using Luski.net.Enums; -using Luski.net.Enums.Public; -using Luski.net.JsonTypes.Public; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Public; @@ -17,14 +17,14 @@ public class SocketChannel public Color Color { get; init; } public long ID { get; internal set; } internal long CategoryID { get; set; } - internal long[] RoleOverides { get; set; } - internal long[] UserOverides { get; set; } + internal long[] RoleOverrides { get; set; } + internal long[] UserOverrides { get; set; } SocketCategory? RawParent = null; List? RawRoleOverides = null; - List? RawUserOverides = null; + List? RawUserOverides = null; public PictureType PictureType { get; internal set; } - public async Task> GetMessages(CancellationToken CancellationToken, int count = 50) + public async Task> GetMessages(CancellationToken CancellationToken, SocketMessage Last, int count = 50) { try { @@ -38,18 +38,17 @@ public class SocketChannel } else { - PublicSocketBulkMessage data = await Server.GetFromServer("SocketBulkMessage", - PublicSocketBulkMessageContext.Default.PublicSocketBulkMessage, + SocketBulkMessageSTC data = await Server.GetFromServer("SocketBulkMessage", + SocketBulkMessageSTCContext.Default.SocketBulkMessageSTC, CancellationToken, new KeyValuePair("id", ID.ToString()), + new KeyValuePair("mostrecentid", Last.ID.ToString()), new KeyValuePair("messages", count.ToString())); if (data is not null && !data.Error.HasValue) { int num = Convert.ToInt32(6); if (num == 0) num = 1; - //string key = Server.EncryptionHandler.GetKey(enc) - //string key = Server.EncryptionHandler.GetChannelKey(ID); - if (data.Messages is null) data.Messages = Array.Empty(); + if (data.Messages is null) data.Messages = Array.Empty(); List mmmm = new(); ParallelLoopResult p = Parallel.ForEach(data.Messages, new ParallelOptions() { @@ -113,11 +112,11 @@ public class SocketChannel } }); - foreach (PublicMessage i in data.Messages) + foreach (MessageSTC i in data.Messages) { var ff = new List(); List sf = new(); - foreach (pFile v in i.Files) + foreach (ServerFileInfoSTC v in i.Files) { sf.Add(new() { @@ -128,7 +127,6 @@ public class SocketChannel NameEncoder = v.NameEncoder, Key = v.Key, NameKey = v.NameKey, - Channel = v.Channel, Server = Server }); ff.Add(v.ID); @@ -139,12 +137,12 @@ public class SocketChannel ID = i.ID, ChannelID = ID, AuthorID = i.AuthorID, - TimeStamp = i.TimeStamp, Context = i.Context, EncryptionKey = i.EncryptionKey, EncoderType = i.EncoderType, FileIDs = ff.ToArray(), - _Files = sf + _Files = sf, + IsProfile = i.IsProfile }); } return await Task.FromResult(mmmm.AsReadOnly()); @@ -169,6 +167,154 @@ public class SocketChannel } } + public async Task> GetMessages(CancellationToken CancellationToken, int count = 50) + { + try + { + if (count > 200) + { + throw new Exception("You can not request more than 200 messages at a time"); + } + else if (count < 1) + { + throw new Exception("You must request at least 1 message"); + } + else + { + SocketBulkMessageSTC data = await Server.GetFromServer("SocketBulkMessage", + SocketBulkMessageSTCContext.Default.SocketBulkMessageSTC, + CancellationToken, + new KeyValuePair("id", ID.ToString()), + new KeyValuePair("messages", count.ToString())); + if (data is not null && !data.Error.HasValue) + { + int num = Convert.ToInt32(6); + if (num == 0) num = 1; + if (data.Messages is null) data.Messages = Array.Empty(); + List mmmm = new(); + ParallelLoopResult p = Parallel.ForEach(data.Messages, new ParallelOptions() + { + MaxDegreeOfParallelism = num + }, i => + { + if (i.EncryptionKey == 0) + { + if (string.IsNullOrEmpty(i.Context)) + { + i.Context = ""; + } + else i.Context = Encryption.Generic.Encoders[(int)i.EncoderType] + .GetString(Convert.FromBase64String(i.Context)); + } + else + { + LocalKeyInfo key = Server.EncryptionHandler.GetKey(i.EncryptionKey); + switch (key.EncryptionType) + { + case EncryptionType.RSA: + i.Context = Encryption.RSA.Decrypt(Convert.FromBase64String(i.Context), key.Key, + i.EncoderType); + break; + default: + i.Context = Encryption.Generic.Encoders[(int)i.EncoderType] + .GetString(Convert.FromBase64String(i.Context)); + break; + } + } + + if (i.Files.Length > 0) + { + for (int j = 0; j < i.Files.Length; j++) + { + if (i.Files[j].Key == 0) + { + if (string.IsNullOrEmpty(i.Files[j].Name)) + { + i.Files[j].Name = ""; + } + else i.Files[j].Name = Encryption.Generic.Encoders[(int)i.Files[j].NameEncoder] + .GetString(Convert.FromBase64String(i.Files[j].Name)); + } + else + { + LocalKeyInfo key = Server.EncryptionHandler.GetKey(i.Files[j].NameKey); + switch (key.EncryptionType) + { + case EncryptionType.RSA: + i.Files[j].Name = Encryption.RSA.Decrypt(Convert.FromBase64String(i.Context), key.Key, + i.Files[j].NameEncoder); + break; + default: + i.Files[j].Name = Encryption.Generic.Encoders[(int)i.Files[j].NameEncoder] + .GetString(Convert.FromBase64String(i.Context)); + break; + } + } + } + } + }); + + foreach (MessageSTC i in data.Messages) + { + var ff = new List(); + List sf = new(); + foreach (ServerFileInfoSTC v in i.Files) + { + sf.Add(new() + { + ID = v.ID, + Size = v.Size, + Name = v.Name, + Encoder = v.Encoder, + NameEncoder = v.NameEncoder, + Key = v.Key, + NameKey = v.NameKey, + Server = Server + }); + ff.Add(v.ID); + } + mmmm.Add(new() + { + Server = Server, + ID = i.ID, + ChannelID = ID, + AuthorID = i.AuthorID, + Context = i.Context, + EncryptionKey = i.EncryptionKey, + EncoderType = i.EncoderType, + FileIDs = ff.ToArray(), + _Files = sf, + IsProfile = i.IsProfile + }); + } + return await Task.FromResult(mmmm.AsReadOnly()); + } + else + { + throw data?.Error switch + { + ErrorCode.InvalidToken => new Exception("Your current token is no longer valid"), + ErrorCode.ServerError => new Exception($"Error from server: {data.ErrorMessage}"), + ErrorCode.InvalidHeader => new Exception(data.ErrorMessage), + ErrorCode.MissingHeader => new Exception("The header sent to the server was not found. This may be because you app is couropt or you are using the wron API version"), + ErrorCode.Forbidden => new Exception("You are not allowed to do this request"), + _ => new Exception(data?.Error.ToString()), + }; + } + } + } + catch (Exception) + { + throw; + } + } + + public async Task SendMessage(string msg, SocketMessage? ReplyTo = null, + SocketChannelProfile? FakeProfile = null) + { + return await Server.SendMessage(this, msg, ReplyTo, FakeProfile); + } + public async Task GetPicture(CancellationToken CancellationToken) { bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.ChannelIcons) + ID.ToString()); @@ -199,7 +345,7 @@ public class SocketChannel return Task.FromResult(RawRoleOverides!.ToArray()); } - public Task GetUserOveride() + public Task GetUserOveride() { if (RawUserOverides is null) { diff --git a/Luski.net/Structures/Public/SocketChannelProfile.cs b/Luski.net/Structures/Public/SocketChannelProfile.cs new file mode 100644 index 0000000..4a32322 --- /dev/null +++ b/Luski.net/Structures/Public/SocketChannelProfile.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Luski.net.Enums; +using Luski.net.Interfaces; +using Luski.Shared.PublicServers.V1.Enums; + +namespace Luski.net.Structures.Public; + +public class SocketChannelProfile : IUser +{ + public PublicServer Server { get; init; } = default!; + public long Id { get; init; } = default!; + public string DisplayName { get; init; } = default!; + public virtual UserStatus Status { get; init; } = UserStatus.Online; + public PictureType PictureType { get; init; } = default!; + public long[] Controllers { get; internal set; } = default!; + + internal Color Color { get; set; } = default!; + + public Task GetColor() + { + return Task.FromResult(Color); + } + + public async Task GetAvatar(CancellationToken CancellationToken) + { + bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.ProfileAvatars) + Id.ToString()); + if (!isc) await Server.GetFromServer($"socketchannelprofile/Avatar/{Id}", Server.Storage.GetStorageDirectory(StorageDirectory.ProfileAvatars) + Id.ToString(), CancellationToken); + return Server.Storage.GetResourceStream(StorageDirectory.ProfileAvatars, Id.ToString()); + } + + public Task GetUserKeys(CancellationToken CancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Luski.net/Structures/Public/SocketFile.cs b/Luski.net/Structures/Public/SocketFile.cs index b167566..db14fdc 100644 --- a/Luski.net/Structures/Public/SocketFile.cs +++ b/Luski.net/Structures/Public/SocketFile.cs @@ -10,7 +10,6 @@ public class SocketFile { public required PublicServer Server { get; init; } public required long ID { get; init; } - public required long Channel { get; init; } public required string Name { get; init; } public required EncoderType Encoder { get; init; } public required EncoderType NameEncoder { get; init; } @@ -20,9 +19,9 @@ public class SocketFile public async Task GetCache(CancellationToken CancellationToken) { - string d = Server.Storage.GetStorageDirectory(StorageDirectory.Files) + Channel.ToString() + "-" + ID.ToString(); + string d = Server.Storage.GetStorageDirectory(StorageDirectory.Files) + ID.ToString(); bool isc = System.IO.File.Exists(d); - if (!isc) await Server.GetFromServer($"socketfile?id={ID}&channel={Channel}", d, CancellationToken); - return Server.Storage.GetResourceStream(StorageDirectory.Files, Channel.ToString() + "-" + ID.ToString()); + if (!isc) await Server.GetFromServer($"socketfile?id={ID}", d, CancellationToken); + return Server.Storage.GetResourceStream(StorageDirectory.Files, ID.ToString()); } } \ No newline at end of file diff --git a/Luski.net/Structures/Public/SocketMessage.cs b/Luski.net/Structures/Public/SocketMessage.cs index 6b5617a..fec334c 100644 --- a/Luski.net/Structures/Public/SocketMessage.cs +++ b/Luski.net/Structures/Public/SocketMessage.cs @@ -8,14 +8,14 @@ namespace Luski.net.Structures.Public; public class SocketMessage { - public PublicServer Server { get; init; } = default!; - public long ID { get; internal set; } - public long ChannelID { get; internal set; } - public long AuthorID { get; internal set; } - public long TimeStamp { get; internal set; } + public required PublicServer Server { get; init; } = default!; + public required long ID { get; init; } + public required long ChannelID { get; init; } + public required long AuthorID { get; init; } public string Context { get; internal set; } - public long EncryptionKey { get; internal set; } + public required long EncryptionKey { get; init; } public long[] FileIDs { get; internal set; } + public required bool IsProfile { get; init; } public EncoderType EncoderType { get; internal set; } private SocketChannel? RawParent; private IUser? au; @@ -40,8 +40,16 @@ public class SocketMessage { if (au is null) { - if (AuthorID == Server.User.Id) au = Server.User; - else au = await Server.GetUser(ChannelID, token); + if (IsProfile) + { + au = await Server.GetChannelProfile(AuthorID, token); + } + else + { + if (AuthorID == Server.User.Id) au = Server.User; + else au = await Server.GetUser(AuthorID, token); + } + } return au; diff --git a/Luski.net/Structures/Public/SocketUser.cs b/Luski.net/Structures/Public/SocketUser.cs index 82a1761..cdee224 100644 --- a/Luski.net/Structures/Public/SocketUser.cs +++ b/Luski.net/Structures/Public/SocketUser.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using Luski.net.Classes; using Luski.net.Enums; using Luski.net.Interfaces; using Luski.net.JsonTypes; -using Luski.net.JsonTypes.BaseTypes; +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Public; @@ -21,6 +21,11 @@ public class SocketUser : IUser public PictureType PictureType { get; init; } = default!; public long[] RoleIds { get; init; } = default!; private List? RawRoles = null; + + public async Task GetColor() + { + return (await GetRoles())[0].Color; + } public async Task GetRoles() { @@ -47,16 +52,16 @@ public class SocketUser : IUser public Task GetUserKeys(CancellationToken CancellationToken) { - UserKeysGetRequest data = Server.GetFromServer($"Keys/UserKeys/{Id}", UserKeysGetRequestContext.Default.UserKeysGetRequest, CancellationToken).Result; + KeysGetSTC data = Server.GetFromServer($"Keys/UserKeys/{Id}", KeysGetSTCContext.Default.KeysGetSTC, CancellationToken).Result; List pki = new(); - foreach (UserKeyGetRequest key in data.keys) + foreach (KeyGetSTC key in data.Keys) { pki.Add(new() { - Id = key.id, - Owner = key.owner, - EncryptionType = key.encryption_type, - Data = Convert.FromBase64String(key.key_data) + Id = key.ID, + Owner = key.Owner, + EncryptionType = key.EncryptionType, + Data = Convert.FromBase64String(key.Data) }); } return Task.FromResult(pki.ToArray()); diff --git a/Luski.net/Structures/Public/UserOveride.cs b/Luski.net/Structures/Public/UserOveride.cs deleted file mode 100644 index 35771ec..0000000 --- a/Luski.net/Structures/Public/UserOveride.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Luski.net.Structures.Public; - -public class UserOveride -{ - -} \ No newline at end of file diff --git a/Luski.net/Structures/Public/UserOverride.cs b/Luski.net/Structures/Public/UserOverride.cs new file mode 100644 index 0000000..e7e7955 --- /dev/null +++ b/Luski.net/Structures/Public/UserOverride.cs @@ -0,0 +1,14 @@ +using Luski.Shared.PublicServers.V1.Enums; +using Luski.Shared.PublicServers.V1.Shared; + +namespace Luski.net.Structures.Public; + +public class UserOverride +{ + public required long ID { get; init; } = default!; + public required long UserID { get; init; } = default!; + + public ServerPermission GoodPermissions { get; set; } + + public ServerPermission BadPermissions { get; set; } +} \ No newline at end of file