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 : IServer { internal Server() { } public async Task 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 GetUser(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 GetChannel(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 GetChannel(long id, JsonTypeInfo 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().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 GetMessage(long id, CancellationToken CancellationToken) { SocketMessage message; while (true) { if (CanRequest) { message = await GetFromServer("socketmessage", SocketMessageContext.Default.SocketMessage, CancellationToken, new System.Collections.Generic.KeyValuePair("msg_id", id.ToString())); break; } } if (message is not null) return message; throw new Exception("Server did not return a message"); } /// /// Sends the server a request to update the of you account /// /// The you want to set your status to /// public async 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 GetUser(long UserId, JsonTypeInfo 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().FirstOrDefault()!; return temp; } while (true) { if (CanRequest) { user = await GetFromServer("socketuser", Json, CancellationToken, new KeyValuePair("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 Payload, JsonTypeInfo jsonTypeInfo) where Tvalue : IncomingWSS { ServerOut?.Send(JsonSerializer.Serialize(Payload, jsonTypeInfo)); } public HttpResponseMessage GetFromServer(string Path, CancellationToken CancellationToken, params KeyValuePair[] 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 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[] 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 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 GetFromServer(string Path, JsonTypeInfo Type, CancellationToken CancellationToken, params KeyValuePair[] 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 SendServer(string Path, Tvalue Payload, JsonTypeInfo jsonTypeInfo, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] 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 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 SendServer(string Path, string File, JsonTypeInfo ReturnjsonTypeInfo, CancellationToken CancellationToken, params KeyValuePair[] 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 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(); } } }