diff --git a/src/Types/PaymentData.cs b/src/Types/PaymentData.cs new file mode 100644 index 0000000..0a93126 --- /dev/null +++ b/src/Types/PaymentData.cs @@ -0,0 +1,9 @@ +namespace spworlds.Types; + +public class PaymentData +{ + public int Amount; + public string RedirectUrl; + public string WebHookUrl; + public string Data; +} \ No newline at end of file diff --git a/src/Types/SkinPart.cs b/src/Types/SkinPart.cs new file mode 100644 index 0000000..fe1f2b7 --- /dev/null +++ b/src/Types/SkinPart.cs @@ -0,0 +1,13 @@ +namespace spworlds.Types; + +public enum SkinPart +{ + face; + front; + front_full; + head; + bust; + full; + skin; + +} diff --git a/src/Types/User.cs b/src/Types/User.cs new file mode 100644 index 0000000..6396b12 --- /dev/null +++ b/src/Types/User.cs @@ -0,0 +1,25 @@ +using spworlds; +using System.Text.Json.Nodes; +namespace spworlds.Types; + +public class User +{ + public readonly string Name + public readonly string Uuid + public readonly JsonNode profile + + private HttpClient client = new(); + + public bool IsPlayer() => Name != null ? true : false; + + public User(string name) + { + Uuid = JsonNode.Parse(client.GetStringAsync($"https://api.mojang.com/users/profiles/minecraft/{name}"))["id"]; + profile = JsonNode.Parse(client.GetStringAsync($"https://sessionserver.mojang.com/session/minecraft/profile/{Uuid}")); + } + + public string GetSkinPart(SkinPart skinPart, string size = "64") + { + return (string)$"https://visage.surgeplay.com/{skinPart}/{size}/{this.profile["profileId"]}" + } +} diff --git a/src/spworlds.cs b/src/spworlds.cs index ba03877..26a92f8 100644 --- a/src/spworlds.cs +++ b/src/spworlds.cs @@ -1,113 +1,134 @@ -using System.Net.Http.Headers; -using System.Text.Json; -using System.Text; -using System.Text.Json.Nodes; -using System.Security.Cryptography; -using System.Runtime.InteropServices; - -namespace spworlds; - -public class SPWorlds -{ - private readonly HttpClient client; - - public SPWorlds(string id, string token) - { - client = new HttpClient(); - var BearerToken = $"{id}:{token}"; - var token = token - string Base64BearerToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(BearerToken)); - - client.BaseAddress = new Uri("https://spworlds.ru/api/public/"); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Base64BearerToken); - } - - private async Task ValidateWebhook(string webhook, string body_hash) - { - // Если я правильно все понял, то вот - // Конвертим из string в bytes body_hash - byte[] body = Encoding.UTF8.GetBytes(body_hash); - // потом конвертим вебхук - byte[] webhook = Encoding.UTF8.GetBytes(webhook); - // создаем объект с токеном(тоже encoded в bytes) для сопостовления - var key = new HMACSHA256(Encoding.UTF8.GetBytes(token)); - // Переводим в Base64 - string webhook_64 = Convert.ToBase64String(key.ComputeHash(webhook)); - return webhook_64.Equals(body); - /** - * Тот же код, но на Python: - hmac_data = hmac.new(token.encode('utf - 8'), webhook.encode('utf - 8'), sha256).digest() - base64_data = b64encode(hmac_data) - return hmac.compare_digest(base64_data, body_hash.encode('utf-8')) - **/ - } - - private async Task SendRequest(string endpoint, Boolean getResult = true, Dictionary? body = null) - { - string respond; - string jsonBody; - - if (body == null) - { - return respond = client.GetAsync(endpoint).Result.Content.ReadAsStringAsync().Result; - } - else - { - jsonBody = JsonSerializer.Serialize(body); - var payload = new StringContent(jsonBody, Encoding.UTF8, "application/json"); - - if (getResult) - return respond = client.PostAsync(endpoint, payload).Result.Content.ReadAsStringAsync().Result; - else - await client.PostAsync(endpoint, payload); - } - - return null; - } - - public async Task GetBalance() - { - string respond = await SendRequest("card"); - - var card = JsonObject.Parse(respond); - var balance = card["balance"]; - - return (int)balance; - } - - public async Task CreateTransaction(string receiver, int amount, string comment) - { - var transitionInfo = new Dictionary - { - { "receiver", receiver }, - { "amount", amount }, - { "comment", comment } - }; - - await SendRequest(endpoint: "transactions", body: transitionInfo); - } - - public async Task GetUser(string discordId) - { - var user = JsonObject.Parse(await SendRequest($"users/{discordId}")); - var userName = user["username"]; - - return (string)userName; - } - - public async Task InitPayment(int amount, string redirectUrl, string webhookUrl, string data) - { - var paymentInfo = new Dictionary - { - { "amount", amount }, - { "redirectUrl", redirectUrl }, - { "webhookUrl", webhookUrl }, - { "data", data } - }; - - var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo)); - var url = payment["url"]; - - return (string)url; - } -} +using System.Net.Http.Headers; +using System.Text.Json; +using System.Text; +using System.Text.Json.Nodes; +using System.Security.Cryptography; +using System.Runtime.InteropServices; + +using spworlds.Types; +namespace spworlds; + +public class SPWorlds +{ + private readonly HttpClient client; + private string token; + + public SPWorlds(string id, string token) + { + client = new HttpClient(); + var BearerToken = $"{id}:{token}"; + this.token = token; + string Base64BearerToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(BearerToken)); + + client.BaseAddress = new Uri("https://spworlds.ru/api/public/"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Base64BearerToken); + } + + + // Полностью бесполезная функция, вебхук, возвращающийся от сайта по факту невозможно валидировать. + private async Task ValidateWebHook(string webHook, string bodyHash) + { + // Если я правильно все понял, то вот + // Конвертим из string в bytes body_hash + byte[] body = Encoding.UTF8.GetBytes(bodyHash); + // потом конвертим вебхук + byte[] webhook = Encoding.UTF8.GetBytes(webHook); + // создаем объект с токеном(тоже encoded в bytes) для сопостовления + var key = new HMACSHA256(Encoding.UTF8.GetBytes(token)); + // Переводим в Base64 + string webhook64 = Convert.ToBase64String(key.ComputeHash(webhook)); + return webhook64.Equals(body); + /** + * Тот же код, но на Python: + hmacData = hmac.new(token.encode('utf - 8'), webhook.encode('utf - 8'), sha256).digest() + base64Data = b64encode(hmacData) + return hmac.compare_digest(base64Data, bodyHash.encode('utf-8')) + **/ + } + + private async Task SendRequest(string endpoint, Boolean getResult = true, Dictionary? body = null) + { + string respond; + string jsonBody; + + if (body == null) + { + return respond = client.GetAsync(endpoint).Result.Content.ReadAsStringAsync().Result; + } + else + { + jsonBody = JsonSerializer.Serialize(body); + var payload = new StringContent(jsonBody, Encoding.UTF8, "application/json"); + + if (getResult) + return respond = client.PostAsync(endpoint, payload).Result.Content.ReadAsStringAsync().Result; + else + await client.PostAsync(endpoint, payload); + } + + return null; + } + + public async Task GetBalance() + { + string respond = await SendRequest("card"); + + var card = JsonObject.Parse(respond); + var balance = card["balance"]; + + return (int)balance; + } + + public async Task CreateTransaction(string receiver, int amount, string comment) + { + var transitionInfo = new Dictionary + { + { "receiver", receiver }, + { "amount", amount }, + { "comment", comment } + }; + + await SendRequest(endpoint: "transactions", body: transitionInfo); + } + + public async Task GetUser(string discordId) + { + var userResponse = JsonObject.Parse(await SendRequest($"users/{discordId}")); + var userName = userResponse["username"]; + User user = new() { Name = userName} + return (User)user; + } + + public async Task InitPayment(int amount, string redirectUrl, string webhookUrl, string data) + { + var paymentInfo = new Dictionary + { + { "amount", amount }, + { "redirectUrl", redirectUrl }, + { "webhookUrl", webhookUrl }, + { "data", data } + }; + + var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo)); + var url = payment["url"]; + + return (string)url; + } + + public async Task InitPayment(PaymentData paymentData) + { + var paymentInfo = new Dictionary + { + { "amount", paymentData.Amount }, + { "redirectUrl", paymentData.RedirectUrl }, + { "webhookUrl", paymentData.WebHookUrl }, + { "data", paymentData.Data } + }; + + var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo)); + var url = payment["url"]; + + return (string)url; + } +} +