using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using JacobTechEncryption; using JacobTechEncryption.Enums; using Luski.net.Enums; using Luski.Shared.PublicServers.V1.Enums; using Luski.Shared.PublicServers.V1.ServerToClient.HTTP; namespace Luski.net.Structures.Public; public class SocketChannel { public PublicServer Server { get; init; } = default!; public long ID { get; internal set; } internal long CategoryID { get; set; } internal RoleOverrideSTC[] RoleOverrides { get; set; } internal UserOverrideSTC[] UserOverrides { get; set; } SocketCategory? RawParent = null; List? RawRoleOverides = null; List? RawUserOverides = null; public PictureType PictureType { get; internal set; } public async Task> GetMessages(CancellationToken CancellationToken, SocketMessage Last, 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("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; 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, TimeStamp = i.Timestamp, ChannelID = ID, AuthorID = i.AuthorID, Context = i.Context, EncryptionKey = i.EncryptionKey, EncoderType = i.EncoderType, FileIDs = ff.ToArray(), _Files = sf, ProfileID = i.ProfileID }); } 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> 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, TimeStamp = i.Timestamp, EncryptionKey = i.EncryptionKey, EncoderType = i.EncoderType, FileIDs = ff.ToArray(), _Files = sf, ProfileID = i.ProfileID }); } 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, ServerProfile? Profile = null, params string[] files) { return await Server.SendMessage(this, msg, ReplyTo, Profile, files); } public async Task SendMessage(string msg, SocketMessage? ReplyTo = null, ServerProfile? Profile = null, params SocketFile[] files) { return await Server.SendMessage(this, msg, ReplyTo, Profile, files); } public async Task GetPicture(CancellationToken CancellationToken) { bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.ChannelIcons) + ID.ToString()); if (!isc) await Server.GetFromServer($"SocketChannel/GetPicture", Server.Storage.GetStorageDirectory(StorageDirectory.ChannelIcons) + ID.ToString(), CancellationToken, new KeyValuePair("id", ID.ToString())); return Server.Storage.GetResourceStream(StorageDirectory.ChannelIcons, ID.ToString()); } public async Task GetParent() { if (CategoryID != -1 && RawParent is null) { RawParent = await Server.GetCategory(CategoryID, CancellationToken.None); } return RawParent!; } public ChannelType Type { get; internal set; } public DateTime Epoch { get; internal set; } public string Name { get; internal set; } public string Description { get; internal set; } public Task GetRoleOverrides() { if (RawRoleOverides is null) { RawRoleOverides = new(); foreach (var ro in RoleOverrides) { RawRoleOverides.Add(new() { Server = this.Server, ParentRoleID = ro.RoleID, GoodPermissions = ro.GoodPermissions, BadPermissions = ro.BadPermissions }); } } return Task.FromResult(RawRoleOverides!.ToArray()); } public Task GetUserOverride() { if (RawUserOverides is null) { RawUserOverides = new(); } return Task.FromResult(RawUserOverides!.ToArray()); } public async Task GetMembers() { ServerPermission req = ServerPermission.ViewThis; List GoodMembers = new(); List GoodRoles = new(); List BadRoles = new(); List GoodPeople = new(); foreach (UserOverride cro in await GetUserOverride()) { if ((cro.GoodPermissions & req) == req) GoodMembers.Add(cro.UserID); } foreach (RoleOverride ro in (await GetRoleOverrides())) { if ((ro.GoodPermissions & req) == req) { GoodRoles.Add(ro.ParentRoleID); } else if ((ro.BadPermissions & req) == req) { BadRoles.Add(ro.ParentRoleID); } } bool bad = false; foreach (Role Role in Server.roles.OrderBy(s => s.Index)) { if (BadRoles.Contains(Role.ID)) { bad = true; } if (bad && GoodRoles.Contains(Role.ID)) { bad = false; } if (!bad) { foreach (var m in await Role.GetMembers()) { var t = GoodPeople.Where(s => s.Id == m.Id); if (t.Count() == 0) GoodPeople.Add(m); } } } foreach (long m in GoodMembers) { var t = GoodPeople.Where(s => s.Id == m); if (t.Count() == 0) GoodPeople.Add(await Server.GetUser(m, CancellationToken.None)); } return GoodPeople.ToArray(); } public long TitleEncryptionKey { get; internal set; } public long DescriptionEncryptionKey { get; internal set; } public long[] EncryptionKeys { get; internal set; } public EncoderType TitleEncoderType { get; internal set; } public EncoderType DescriptionEncoderType { get; internal set; } public EncoderType[] EncoderTypes { get; internal set; } }