Luski.Net/Luski.net/JsonTypes/SocketChannel.cs

173 lines
6.1 KiB
C#
Executable File

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<IUser> Members
{
get
{
if (MemberIdList is null || MemberIdList.Length == 0) return Array.Empty<IUser>().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<IUser> _members = new();
public async Task<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<TChannel> GetChannel<TChannel>(long id, JsonTypeInfo<TChannel> 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<TChannel>().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
{
}