Luski.Net/Luski.net/Server.cs

271 lines
13 KiB
C#
Raw Normal View History

2023-01-01 22:50:39 -05:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
2023-01-01 22:50:39 -05:00
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
2023-01-01 22:50:39 -05:00
using System.Threading.Tasks;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
using Luski.net.Structures;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using File = System.IO.File;
2023-01-01 22:50:39 -05:00
namespace Luski.net;
public partial class Server<TUser> : IServer
2023-01-01 22:50:39 -05:00
{
internal Server()
{ }
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
2023-01-01 22:50:39 -05:00
{
if (Cache != null)
{
bool isc = File.Exists($"{Cache}/servers/{Domain}");
if (!isc) await GetFromServer($"socketserver/Avatar/", $"{Cache}/servers/{Domain}-{ApiVersion}", CancellationToken);
}
return File.ReadAllBytes($"{Cache}/servers/{Domain}");
2023-01-01 22:50:39 -05:00
}
public async Task<Tuser> GetUser<Tuser>(long UserID, CancellationToken CancellationToken) where Tuser : SocketUserBase, new()
2023-01-01 22:50:39 -05:00
{
Tuser user = new();
switch (user)
2023-01-01 22:50:39 -05:00
{
case MainSocketAppUser:
user = (GetUser(UserID, MainSocketAppUserContext.Default.MainSocketAppUser, CancellationToken).Result as Tuser)!;
break;
case PublicSocketAppUser:
user = (GetUser(UserID, PublicSocketAppUserContext.Default.PublicSocketAppUser, CancellationToken).Result as Tuser)!;
break;
case SocketUserBase:
user = (GetUser(UserID, SocketUserBaseContext.Default.SocketUserBase, CancellationToken).Result as Tuser)!;
break;
case null:
throw new NullReferenceException(nameof(Tuser));
default:
throw new Exception("Unknown channel type");
2023-01-01 22:50:39 -05:00
}
return user;
}
public async Task<TChannel> GetChannel<TChannel>(long Channel, CancellationToken CancellationToken) where TChannel : MainSocketChannel, new()
{
TChannel Return = new();
switch (Return)
2023-01-01 22:50:39 -05:00
{
case MainSocketDMChannel:
Return = (await GetChannel(Channel, MainSocketDMChannelContext.Default.MainSocketDMChannel, CancellationToken) as TChannel)!;
break;
case MainSocketGroupChannel:
Return = (await GetChannel(Channel, MainSocketGroupChannelContext.Default.MainSocketGroupChannel, CancellationToken) as TChannel)!;
break;
case MainSocketTextChannel:
Return = (await GetChannel(Channel, MainSocketTextChannelContext.Default.MainSocketTextChannel, CancellationToken) as TChannel)!;
break;
case MainSocketChannel:
Return = (await GetChannel(Channel, MainSocketChannelContext.Default.MainSocketChannel, CancellationToken) as TChannel)!;
break;
case null:
throw new NullReferenceException(nameof(TChannel));
default:
throw new Exception("Unknown channel type");
2023-01-01 22:50:39 -05:00
}
return Return;
2023-01-01 22:50:39 -05:00
}
internal async Task<TChannel> GetChannel<TChannel>(long id, JsonTypeInfo<TChannel> Json, CancellationToken CancellationToken) where TChannel : MainSocketChannel, new()
2023-01-01 22:50:39 -05:00
{
TChannel request;
if (chans.Count > 0 && chans.Any(s => s.Id == id))
{
return chans.Where(s => s is TChannel && s.Id == id).Cast<TChannel>().FirstOrDefault()!;
}
while (true)
2023-01-01 22:50:39 -05:00
{
if (CanRequest)
2023-01-01 22:50:39 -05:00
{
request = await GetFromServer($"SocketChannel/Get/{id}", Json, CancellationToken);
break;
2023-01-01 22:50:39 -05:00
}
}
if (request is null) throw new Exception("Something was wrong with the server responce");
if (request.Error is null)
{
if (chans.Count > 0 && chans.Any(s => s.Id == request.Id))
2023-01-01 22:50:39 -05:00
{
foreach (MainSocketChannel? p in chans.Where(s => s.Id == request.Id))
{
chans.Remove(p);
}
2023-01-01 22:50:39 -05:00
}
chans.Add(request);
return request;
2023-01-01 22:50:39 -05:00
}
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}'"),
};
2023-01-01 22:50:39 -05:00
}
public async Task<SocketMessage> GetMessage(long id, CancellationToken CancellationToken)
2023-01-01 22:50:39 -05:00
{
SocketMessage message;
while (true)
2023-01-01 22:50:39 -05:00
{
if (CanRequest)
2023-01-01 22:50:39 -05:00
{
message = await GetFromServer("socketmessage",
SocketMessageContext.Default.SocketMessage,
CancellationToken,
new System.Collections.Generic.KeyValuePair<string, string?>("msg_id", id.ToString()));
break;
}
2023-01-01 22:50:39 -05:00
}
if (message is not null) return message;
throw new Exception("Server did not return a message");
2023-01-01 22:50:39 -05:00
}
2023-01-01 22:50:39 -05:00
/// <summary>
/// Sends the server a request to update the <paramref name="Status"/> of you account
/// </summary>
/// <param name="Status">The <see cref="UserStatus"/> you want to set your status to</param>
/// <exception cref="Exception"></exception>
public async Task<Task> UpdateStatus(UserStatus Status, CancellationToken CancellationToken)
2023-01-01 22:50:39 -05:00
{
IncomingHTTP? data = await SendServer("SocketUserProfile/Status", new Status() { UserStatus = Status }, StatusContext.Default.Status, IncomingHTTPContext.Default.IncomingHTTP, CancellationToken);
2023-01-01 22:50:39 -05:00
if (data.Error is not null && ((int)data.StatusCode < 200 || (int)data.StatusCode > 299))
{
if (data?.ErrorMessage is not null) throw new Exception(data.ErrorMessage);
if (data?.Error is not null) throw new Exception(((int)data.Error).ToString());
else throw new Exception("Something went worng");
}
(User as SocketUserBase)!.Status = Status;
2023-01-01 22:50:39 -05:00
return Task.CompletedTask;
}
internal async Task<Tuser> GetUser<Tuser>(long UserId, JsonTypeInfo<Tuser> Json, CancellationToken CancellationToken) where Tuser : SocketUserBase, new()
2023-01-01 22:50:39 -05:00
{
Tuser user;
if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId))
2023-01-01 22:50:39 -05:00
{
Tuser temp = poeople.Where(s => s is Tuser && s.Id == UserId).Cast<Tuser>().FirstOrDefault()!;
return temp;
2023-01-01 22:50:39 -05:00
}
while (true)
2023-01-01 22:50:39 -05:00
{
if (CanRequest)
{
user = await GetFromServer("socketuser",
Json,
CancellationToken,
new KeyValuePair<string, string?>("id", UserId.ToString()));
2023-01-01 22:50:39 -05:00
break;
}
2023-01-01 22:50:39 -05:00
}
if (user is null) throw new Exception("Server did not return a user");
if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId))
2023-01-01 22:50:39 -05:00
{
foreach (IUser? p in poeople.Where(s => s.Id == UserId))
{
poeople.Remove(p);
}
2023-01-01 22:50:39 -05:00
}
poeople.Add(user);
return user;
2023-01-01 22:50:39 -05:00
}
public void SendServer<Tvalue>(Tvalue Payload, JsonTypeInfo<Tvalue> jsonTypeInfo) where Tvalue : IncomingWSS
2023-01-01 22:50:39 -05:00
{
ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo));
}
public HttpResponseMessage GetFromServer(string Path, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers)
2023-01-01 22:50:39 -05:00
{
using HttpClient web = new();
web.Timeout = TimeSpan.FromSeconds(10);
if (!login) web.DefaultRequestHeaders.Add("token", Token);
if (Headers is not null && Headers.Length > 0) foreach (KeyValuePair<string, string?> header in Headers) web.DefaultRequestHeaders.Add(header.Key, header.Value);
return web.GetAsync($"https://{Domain}/{ApiVersion}/{Path}", cancellationToken: CancellationToken).Result;
2023-01-01 22:50:39 -05:00
}
public Task GetFromServer(string Path, string File, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers)
2023-01-01 22:50:39 -05:00
{
using HttpClient web = new();
web.Timeout = TimeSpan.FromMinutes(10);
if (!login) web.DefaultRequestHeaders.Add("token", Token);
if (Headers is not null && Headers.Length > 0) foreach (KeyValuePair<string, string?> header in Headers) web.DefaultRequestHeaders.Add(header.Key, header.Value);
HttpResponseMessage Response = web.GetAsync($"https://{Domain}/{ApiVersion}/{Path}", CancellationToken).Result;
Stream stream = Response.Content.ReadAsStreamAsync(CancellationToken).Result;
2023-01-01 22:50:39 -05:00
using FileStream fs = System.IO.File.Create(File);
stream.CopyTo(fs);
return Task.CompletedTask;
}
public async Task<Tresult> GetFromServer<Tresult>(string Path, JsonTypeInfo<Tresult> Type, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers) where Tresult : IncomingHTTP, new()
2023-01-01 22:50:39 -05:00
{
HttpResponseMessage ServerResponce = GetFromServer(Path, CancellationToken, Headers);
2023-01-01 22:50:39 -05:00
if (!ServerResponce.IsSuccessStatusCode) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with status code {(int)ServerResponce.StatusCode}:{ServerResponce.StatusCode}" };
Tresult? temp = JsonSerializer.Deserialize(ServerResponce.Content.ReadAsStreamAsync(CancellationToken).Result, Type);
2023-01-01 22:50:39 -05:00
if (temp is null) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with empty data" };
return temp;
}
public async Task<Tresult> SendServer<Tvalue, Tresult>(string Path, Tvalue Payload, JsonTypeInfo<Tvalue> jsonTypeInfo, JsonTypeInfo<Tresult> ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers) where Tvalue : IWebRequest where Tresult : IncomingHTTP, new()
2023-01-01 22:50:39 -05:00
{
using HttpClient web = new();
if (!login) web.DefaultRequestHeaders.Add("token", Token);
if (Headers is not null && Headers.Length > 0) foreach (KeyValuePair<string, string?> header in Headers) web.DefaultRequestHeaders.Add(header.Key, header.Value);
HttpResponseMessage ServerResponce = web.PostAsJsonAsync($"https://{Domain}/{ApiVersion}/{Path}", Payload, jsonTypeInfo, CancellationToken).Result;
2023-01-01 22:50:39 -05:00
if (!ServerResponce.IsSuccessStatusCode) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with status code {(int)ServerResponce.StatusCode}:{ServerResponce.StatusCode}" };
Tresult error = new() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with empty data" };
if (string.IsNullOrWhiteSpace(ServerResponce.Content.ReadAsStringAsync(CancellationToken).Result)) return error;
2023-01-01 22:50:39 -05:00
try
{
Tresult? temp = JsonSerializer.Deserialize(ServerResponce.Content.ReadAsStreamAsync(CancellationToken).Result, ReturnjsonTypeInfo);
2023-01-01 22:50:39 -05:00
if (temp is null) return error;
return temp;
}
catch { return error; }
}
public async Task<Tresult> SendServer<Tresult>(string Path, string File, JsonTypeInfo<Tresult> ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers) where Tresult : IncomingHTTP, new()
2023-01-01 22:50:39 -05:00
{
var fs = System.IO.File.OpenRead(File);
try
{
using HttpClient web = new();
if (!login) web.DefaultRequestHeaders.Add("token", Token);
web.Timeout = new TimeSpan(0, 10, 0);
if (Headers is not null && Headers.Length > 0) foreach (KeyValuePair<string, string?> header in Headers) web.DefaultRequestHeaders.Add(header.Key, header.Value);
HttpResponseMessage ServerResponce = web.PostAsync($"https://{Domain}/{ApiVersion}/{Path}", new StreamContent(fs), CancellationToken).Result;
2023-01-01 22:50:39 -05:00
if (!ServerResponce.IsSuccessStatusCode) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with status code {(int)ServerResponce.StatusCode}:{ServerResponce.StatusCode}" };
try
{
Tresult? temp = JsonSerializer.Deserialize(ServerResponce.Content.ReadAsStreamAsync(CancellationToken).Result, ReturnjsonTypeInfo);
2023-01-01 22:50:39 -05:00
if (temp is null) return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with empty data" };
return temp;
}
catch { return new Tresult() { StatusCode = ServerResponce.StatusCode, Error = ErrorCode.ServerError, ErrorMessage = $"Server responded with empty data" }; }
}
finally
{
fs.Close();
}
}
}