271 lines
13 KiB
C#
271 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization.Metadata;
|
|
using System.Threading;
|
|
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;
|
|
|
|
namespace Luski.net;
|
|
|
|
public partial class Server<TUser> : IServer
|
|
{
|
|
internal Server()
|
|
{ }
|
|
|
|
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
|
|
{
|
|
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}");
|
|
}
|
|
|
|
public async Task<Tuser> GetUser<Tuser>(long UserID, CancellationToken CancellationToken) where Tuser : SocketUserBase, new()
|
|
{
|
|
Tuser user = new();
|
|
switch (user)
|
|
{
|
|
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");
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
public async Task<TChannel> GetChannel<TChannel>(long Channel, CancellationToken CancellationToken) where TChannel : MainSocketChannel, new()
|
|
{
|
|
TChannel Return = new();
|
|
switch (Return)
|
|
{
|
|
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");
|
|
}
|
|
return Return;
|
|
}
|
|
|
|
internal async Task<TChannel> GetChannel<TChannel>(long id, JsonTypeInfo<TChannel> Json, CancellationToken CancellationToken) where TChannel : MainSocketChannel, new()
|
|
{
|
|
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)
|
|
{
|
|
if (CanRequest)
|
|
{
|
|
request = await GetFromServer($"SocketChannel/Get/{id}", Json, CancellationToken);
|
|
break;
|
|
}
|
|
}
|
|
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))
|
|
{
|
|
foreach (MainSocketChannel? p in chans.Where(s => s.Id == request.Id))
|
|
{
|
|
chans.Remove(p);
|
|
}
|
|
}
|
|
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}'"),
|
|
};
|
|
}
|
|
|
|
public async Task<SocketMessage> GetMessage(long id, CancellationToken CancellationToken)
|
|
{
|
|
SocketMessage message;
|
|
while (true)
|
|
{
|
|
if (CanRequest)
|
|
{
|
|
message = await GetFromServer("socketmessage",
|
|
SocketMessageContext.Default.SocketMessage,
|
|
CancellationToken,
|
|
new System.Collections.Generic.KeyValuePair<string, string?>("msg_id", id.ToString()));
|
|
break;
|
|
}
|
|
}
|
|
if (message is not null) return message;
|
|
throw new Exception("Server did not return a message");
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
IncomingHTTP? data = await SendServer("SocketUserProfile/Status", new Status() { UserStatus = Status }, StatusContext.Default.Status, IncomingHTTPContext.Default.IncomingHTTP, CancellationToken);
|
|
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;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
internal async Task<Tuser> GetUser<Tuser>(long UserId, JsonTypeInfo<Tuser> Json, CancellationToken CancellationToken) where Tuser : SocketUserBase, new()
|
|
{
|
|
Tuser user;
|
|
if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId))
|
|
{
|
|
Tuser temp = poeople.Where(s => s is Tuser && s.Id == UserId).Cast<Tuser>().FirstOrDefault()!;
|
|
return temp;
|
|
}
|
|
while (true)
|
|
{
|
|
if (CanRequest)
|
|
{
|
|
user = await GetFromServer("socketuser",
|
|
Json,
|
|
CancellationToken,
|
|
new KeyValuePair<string, string?>("id", UserId.ToString()));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (user is null) throw new Exception("Server did not return a user");
|
|
if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId))
|
|
{
|
|
foreach (IUser? p in poeople.Where(s => s.Id == UserId))
|
|
{
|
|
poeople.Remove(p);
|
|
}
|
|
}
|
|
poeople.Add(user);
|
|
return user;
|
|
}
|
|
|
|
public void SendServer<Tvalue>(Tvalue Payload, JsonTypeInfo<Tvalue> jsonTypeInfo) where Tvalue : IncomingWSS
|
|
{
|
|
ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo));
|
|
}
|
|
|
|
public HttpResponseMessage GetFromServer(string Path, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers)
|
|
{
|
|
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;
|
|
}
|
|
|
|
public Task GetFromServer(string Path, string File, CancellationToken CancellationToken, params KeyValuePair<string, string?>[] Headers)
|
|
{
|
|
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;
|
|
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()
|
|
{
|
|
HttpResponseMessage ServerResponce = GetFromServer(Path, CancellationToken, Headers);
|
|
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);
|
|
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()
|
|
{
|
|
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;
|
|
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;
|
|
try
|
|
{
|
|
Tresult? temp = JsonSerializer.Deserialize(ServerResponce.Content.ReadAsStreamAsync(CancellationToken).Result, ReturnjsonTypeInfo);
|
|
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()
|
|
{
|
|
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;
|
|
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);
|
|
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();
|
|
}
|
|
}
|
|
} |