173 lines
6.1 KiB
C#
Executable File
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
|
|
{
|
|
|
|
} |