using Luski.net.Enums; using Luski.net.Interfaces; using Luski.net.JsonTypes.BaseTypes; using System.Collections.Generic; using System; using System.Text.Json.Serialization; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Luski.net.JsonTypes.WSS; using System.Text.Json.Serialization.Metadata; namespace Luski.net.JsonTypes; public class SocketChannel : IncomingHTTP { [JsonInclude] [JsonPropertyName("id")] public long Id { get; internal set; } = default!; [JsonInclude] [JsonPropertyName("title")] public string Title { get; internal set; } = default!; [JsonInclude] [JsonPropertyName("description")] public string Description { get; internal set; } = default!; [JsonInclude] [JsonPropertyName("key")] public string Key { get; internal set; } = default!; [JsonPropertyName("type")] [JsonInclude] public ChannelType Type { get; internal set; } = default!; [JsonPropertyName("members")] [JsonInclude] public long[] MemberIdList { get; internal set; } = default!; [JsonIgnore] public IReadOnlyList Members { get { if (MemberIdList is null || MemberIdList.Length == 0) return Array.Empty().ToList().AsReadOnly(); if (_members is null || !_members.Any()) { _members = new(); foreach (long member in MemberIdList) { if (member != Server._user!.Id) _members.Add(SocketUserBase.GetUser(member, SocketRemoteUserContext.Default.SocketRemoteUser).Result); else _members.Add(Server._user); } } return _members.AsReadOnly(); } } [JsonIgnore] private List _members = new(); public async Task SendKeysToUsers() { if (Key is null) { StartKeyProcessAsync().Wait(); return Task.CompletedTask; } int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * Server.Percent) * 2.0)); if (num == 0) num = 1; string? lkey = Encryption.File.Channels.GetKey(Id); Parallel.ForEach(Members, new ParallelOptions() { MaxDegreeOfParallelism = num }, async i => { if (i.Id != Server._user?.Id) { string key = await i.GetUserKey(); if (!string.IsNullOrEmpty(key)) { WSSKeyExchange send = new() { to = i.Id, channel = Id, key = Convert.ToBase64String(Encryption.Encrypt(lkey, key)) }; Server.SendServer(send, WSSKeyExchangeContext.Default.WSSKeyExchange); } } }); return Task.CompletedTask; } internal async Task StartKeyProcessAsync() { Encryption.GenerateNewKeys(out string Public, out string Private); Key = Public; HttpResponseMessage b; using (HttpClient web = new()) { web.DefaultRequestHeaders.Add("token", Server.Token); b = web.PostAsync($"https://{Server.InternalDomain}/{Server.API_Ver}/SocketChannel/SetKey/{Id}", new StringContent(Key)).Result; } int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * Server.Percent) * 2.0)); if (num == 0) num = 1; Encryption.File.Channels.AddKey(Id, Private); Parallel.ForEach(Members, new ParallelOptions() { MaxDegreeOfParallelism = num }, i => { if (i.Id != Server._user?.Id) { string key = i.GetUserKey().Result; if (!string.IsNullOrEmpty(key)) { WSSKeyExchange send = new() { to = i.Id, channel = Id, key = Convert.ToBase64String(Encryption.Encrypt(Private, key)) }; Server.SendServer(send, WSSKeyExchangeContext.Default.WSSKeyExchange); } } }); } internal static async Task GetChannel(long id, JsonTypeInfo Json) where TChannel : SocketChannel, new() { TChannel request; if (Server.chans is null) Server.chans = new(); if (Server.chans.Count > 0 && Server.chans.Any(s => s.Id == id)) { return Server.chans.Where(s => s is TChannel && s.Id == id).Cast().FirstOrDefault()!; } while (true) { if (Server.CanRequest) { request = await Server.GetFromServer($"SocketChannel/Get/{id}", Json); break; } } if (request is null) throw new Exception("Something was wrong with the server responce"); if (request.Error is null) { if (Server.chans is null) Server.chans = new(); if (Server.chans.Count > 0 && Server.chans.Any(s => s.Id == request.Id)) { foreach (SocketChannel? p in Server.chans.Where(s => s.Id == request.Id)) { Server.chans.Remove(p); } } Server.chans.Add(request); return request; } throw request.Error switch { ErrorCode.InvalidToken => new Exception("Your current token is no longer valid"), ErrorCode.Forbidden => new Exception("The server rejected your request"), ErrorCode.ServerError => new Exception("Error from server: " + request.ErrorMessage), ErrorCode.InvalidURL or ErrorCode.MissingHeader => new Exception(request.ErrorMessage), _ => new Exception($"Unknown data: '{request.ErrorMessage}'"), }; } } [JsonSerializable(typeof(SocketChannel))] [JsonSourceGenerationOptions( GenerationMode = JsonSourceGenerationMode.Default, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, WriteIndented = false)] internal partial class SocketChannelContext : JsonSerializerContext { }