442 lines
19 KiB
C#
442 lines
19 KiB
C#
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<RoleOverride>? RawRoleOverides = null;
|
|
List<UserOverride>? RawUserOverides = null;
|
|
public PictureType PictureType { get; internal set; }
|
|
|
|
public async Task<IReadOnlyList<SocketMessage>> 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<string, string?>("id", ID.ToString()),
|
|
new KeyValuePair<string, string?>("mostrecentid", Last.ID.ToString()),
|
|
new KeyValuePair<string, string?>("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<MessageSTC>();
|
|
List<SocketMessage> 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<long>();
|
|
List<SocketFile> 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<IReadOnlyList<SocketMessage>> 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<string, string?>("id", ID.ToString()),
|
|
new KeyValuePair<string, string?>("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<MessageSTC>();
|
|
List<SocketMessage> 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<long>();
|
|
List<SocketFile> 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<SocketMessage> SendMessage(string msg, SocketMessage? ReplyTo = null,
|
|
ServerProfile? Profile = null, params string[] files)
|
|
{
|
|
return await Server.SendMessage(this, msg, ReplyTo, Profile, files);
|
|
}
|
|
|
|
public async Task<SocketMessage> SendMessage(string msg, SocketMessage? ReplyTo = null,
|
|
ServerProfile? Profile = null, params SocketFile[] files)
|
|
{
|
|
return await Server.SendMessage(this, msg, ReplyTo, Profile, files);
|
|
}
|
|
|
|
|
|
|
|
public async Task<Stream> 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<string, string?>("id", ID.ToString()));
|
|
return Server.Storage.GetResourceStream(StorageDirectory.ChannelIcons, ID.ToString());
|
|
}
|
|
|
|
public async Task<SocketCategory> GetParent()
|
|
{
|
|
if (CategoryID != -1 && RawParent is null)
|
|
{
|
|
RawParent = await Server.GetCategory<SocketCategory>(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<RoleOverride[]> 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<UserOverride[]> GetUserOverride()
|
|
{
|
|
if (RawUserOverides is null)
|
|
{
|
|
RawUserOverides = new();
|
|
}
|
|
|
|
return Task.FromResult(RawUserOverides!.ToArray());
|
|
}
|
|
|
|
public async Task<SocketUser[]> GetMembers()
|
|
{
|
|
ServerPermission req = ServerPermission.ViewThis;
|
|
List<long> GoodMembers = new();
|
|
List<long> GoodRoles = new();
|
|
List<long> BadRoles = new();
|
|
List<SocketUser> 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<SocketUser>(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; }
|
|
} |