mirror of
https://github.com/yawaflua/SPWorlds.git
synced 2025-12-08 19:49:28 +02:00
Add project files.
This commit is contained in:
33
.github/workflows/dotnet.yml
vendored
Normal file
33
.github/workflows/dotnet.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# This workflow will build a .NET project
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
|
||||
|
||||
name: .NET
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release --no-restore
|
||||
- name: Test
|
||||
run: dotnet test --no-build --verbosity normal
|
||||
- name: Publish
|
||||
uses: brandedoutcast/publish-nuget@v2.5.5
|
||||
with:
|
||||
PROJECT_FILE_PATH: SPWorldsApi.csproj
|
||||
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
|
||||
39
HttpClient/HttpRequest.cs
Normal file
39
HttpClient/HttpRequest.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SPWorldsApi.HttpClient
|
||||
{
|
||||
public class HttpRequest(string BASE_URL, AuthenticationHeaderValue AuthHeader)
|
||||
{
|
||||
internal async Task<string> SendRequest(string endpoint, HttpMethod method = null, object body = null)
|
||||
{
|
||||
method ??= body == null ? HttpMethod.Get : HttpMethod.Post;
|
||||
|
||||
HttpResponseMessage message;
|
||||
var client = new System.Net.Http.HttpClient();
|
||||
|
||||
using (var requestMessage = new HttpRequestMessage(method, BASE_URL + endpoint))
|
||||
{
|
||||
requestMessage.Content = new StringContent(
|
||||
JsonSerializer.Serialize(body),
|
||||
Encoding.UTF8, "application/json"
|
||||
);
|
||||
|
||||
requestMessage.Headers.Authorization = AuthHeader;
|
||||
|
||||
message = await client.SendAsync(requestMessage);
|
||||
|
||||
}
|
||||
|
||||
client.Dispose();
|
||||
|
||||
return await message.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
72
Payments/IPaymentWrapper.cs
Normal file
72
Payments/IPaymentWrapper.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
using SPWorldsApi.Utils;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace SPWorldsApi.Payments
|
||||
{
|
||||
internal interface IPaymentWrapper
|
||||
{
|
||||
HttpClient.HttpRequest client { get; set; }
|
||||
|
||||
internal async Task<string> SendRequest(string endpoint, HttpMethod method = null, object body = null)
|
||||
{
|
||||
return await client.SendRequest(endpoint, method, body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get card from spworlds
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<ICard> GetCard()
|
||||
=> (await SendRequest("card")).Deserialize<ICard>();
|
||||
|
||||
/// <summary>
|
||||
/// Create transaction
|
||||
/// </summary>
|
||||
/// <param name="receiver">receiver card</param>
|
||||
/// <param name="amount">amount of AR</param>
|
||||
/// <param name="comment">comment to transaction</param>
|
||||
/// <returns>balance of card</returns>
|
||||
public async Task<int> CreateTransaction(string receiver, int amount, string comment)
|
||||
{
|
||||
var transitionInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "receiver", receiver },
|
||||
{ "amount", amount },
|
||||
{ "comment", comment }
|
||||
};
|
||||
|
||||
var response = JsonNode.Parse(await SendRequest(endpoint: "transactions", body: transitionInfo));
|
||||
return (int)response["balance"];
|
||||
}
|
||||
|
||||
public async Task<string> InitPayment(IPaymentItems[] items, string redirectUrl, string webhookUrl, string data)
|
||||
{
|
||||
var paymentInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "items", JsonSerializer.Serialize(items).ToLower()},
|
||||
{ "redirectUrl", redirectUrl },
|
||||
{ "webhookUrl", webhookUrl },
|
||||
{ "data", data }
|
||||
};
|
||||
|
||||
var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo));
|
||||
var url = payment["url"];
|
||||
|
||||
return (string)url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create payment url
|
||||
/// </summary>
|
||||
/// <param name="paymentData"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> InitPayment(IPaymentData paymentData)
|
||||
{
|
||||
var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: JsonSerializer.Serialize(paymentData)));
|
||||
return (string)payment["url"];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
47
Program.cs
Normal file
47
Program.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using SPWorldsApi.HttpClient;
|
||||
using SPWorldsApi.Payments;
|
||||
using SPWorldsApi.Users;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SPWorldsApi
|
||||
{
|
||||
public sealed class SPWorlds : IPaymentWrapper, IUserWrapper
|
||||
{
|
||||
internal string token { get; }
|
||||
public HttpRequest client { get; set; }
|
||||
string BASE_URL { get; set; } = "https://spworlds.ru/api/public";
|
||||
AuthenticationHeaderValue AuthHeader { get; set; }
|
||||
|
||||
public SPWorlds(string id, string token)
|
||||
{
|
||||
var BearerToken = $"{id}:{token}";
|
||||
this.token = token;
|
||||
string Base64BearerToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(BearerToken));
|
||||
|
||||
AuthHeader = new("Bearer", Base64BearerToken);
|
||||
client = new(BASE_URL, AuthHeader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validating wenhook from site
|
||||
/// </summary>
|
||||
/// <param name="requestBody">Body of request</param>
|
||||
/// <param name="base64Hash">X-Body-Hash</param>
|
||||
/// <returns></returns>
|
||||
public bool ValidateWebhook(string requestBody, string base64Hash)
|
||||
{
|
||||
byte[] requestData = Encoding.UTF8.GetBytes(requestBody);
|
||||
|
||||
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(token)))
|
||||
{
|
||||
byte[] hashBytes = hmac.ComputeHash(requestData);
|
||||
|
||||
string computedHash = Convert.ToBase64String(hashBytes);
|
||||
|
||||
return base64Hash.Equals(computedHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
README.md
Normal file
98
README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> spworlds API
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> - [Mih4n](https://github.com/Mih4n/spworlds-csharp-library), <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
|
||||
# CS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> dotnet <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> API <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> API [<EFBFBD><EFBFBD><EFBFBD>](https://github.com/sp-worlds/api-docs).
|
||||
|
||||
## <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CLI
|
||||
(`dotnet`), NuGet <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
|
||||
```bash
|
||||
dotnet add package spworlds
|
||||
```
|
||||
|
||||
## <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
```cs
|
||||
...
|
||||
|
||||
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
var spw = new SPWorldsApi("[<5B><><EFBFBD> <20><><EFBFBD><EFBFBD>]", "[<5B><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>]");
|
||||
|
||||
```
|
||||
|
||||
## <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20><>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> `https://example.com/success`, <20> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> `https://api.example.com/webhook` <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> `SomeString`. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> ID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
|
||||
```cs
|
||||
const url = await sp.InitPayment(
|
||||
[
|
||||
new PaymentItems() { Name = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", Count = 1, Price = 16, Comment = "<22><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"}
|
||||
],
|
||||
"https://example.com/success",
|
||||
"https://api.example.com/webhook",
|
||||
"SomeString"
|
||||
);
|
||||
```
|
||||
<EFBFBD><EFBFBD><EFBFBD>
|
||||
```cs
|
||||
[HttpPost("/create_payment_url/")]
|
||||
public async Task<IActionResult> GetCreatePaymentFunction([FromBody] PaymentData paymentData)
|
||||
{
|
||||
const url = await sp.InitPayment(paymentData);
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
```
|
||||
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 11111 <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "<22> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!"
|
||||
|
||||
```cs
|
||||
await sp.CreateTransaction("11111", 16, "<22> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!");
|
||||
```
|
||||
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
```cs
|
||||
int balance = await sp.GetCardBalance();
|
||||
```
|
||||
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Discord <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
|
||||
```cs
|
||||
IUser user = await sp.GetUser("111111111111111111");
|
||||
|
||||
if (user.Name == "yawaflua")
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
```
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SkinPart <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 64, 128 <20> <20>.<2E>., <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> User, <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>:
|
||||
|
||||
```cs
|
||||
IUser user = await sp.GetUser("111111111111111111");
|
||||
const faceUrl = user.GetSkinPart(SkinPart.face);
|
||||
```
|
||||
|
||||
### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD>:
|
||||
```cs
|
||||
bool IsWebHook = await sp.ValidateWebHook(WebHookText, X_Body_Hash);
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pull <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
24
SPWorldsApi.csproj
Normal file
24
SPWorldsApi.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PackageId>spworldsapi</PackageId>
|
||||
<Description>Библиотека, созданная для облегчения работы с API сайта spworlds.ru . Что-то добавить или обновить можно в github проекта.</Description>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Version>1.0.0</Version>
|
||||
<Authors>yawaflua</Authors>
|
||||
<Company>yawaflua</Company>
|
||||
<RepositoryUrl>https://github.com/yawaflua/spworlds</RepositoryUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
25
SPWorldsApi.sln
Normal file
25
SPWorldsApi.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.9.34728.123
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPWorldsApi", "SPWorldsApi.csproj", "{AD0307C9-8042-44D2-B773-4DEB62D27F3D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AD0307C9-8042-44D2-B773-4DEB62D27F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AD0307C9-8042-44D2-B773-4DEB62D27F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AD0307C9-8042-44D2-B773-4DEB62D27F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AD0307C9-8042-44D2-B773-4DEB62D27F3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B52E51DB-0209-420D-9359-424764DC76C7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
13
Types/Enums/SkinPart.cs
Normal file
13
Types/Enums/SkinPart.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace SPWorldsApi.Types.Enums
|
||||
{
|
||||
public enum SkinPart
|
||||
{
|
||||
face,
|
||||
front,
|
||||
front_full,
|
||||
head,
|
||||
bust,
|
||||
full,
|
||||
skin
|
||||
}
|
||||
}
|
||||
8
Types/Interfaces/ICard.cs
Normal file
8
Types/Interfaces/ICard.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface ICard
|
||||
{
|
||||
public int Balance { get; set; }
|
||||
public string Webhook { get; set; }
|
||||
}
|
||||
}
|
||||
12
Types/Interfaces/ICity.cs
Normal file
12
Types/Interfaces/ICity.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface ICity
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string description { get; set; }
|
||||
public int x { get; set; }
|
||||
public int z { get; set; }
|
||||
public bool isMayor { get; set; }
|
||||
}
|
||||
}
|
||||
10
Types/Interfaces/IPaymentData.cs
Normal file
10
Types/Interfaces/IPaymentData.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IPaymentData
|
||||
{
|
||||
public IPaymentItems[] Items { get; set; }
|
||||
public string RedirectUrl { get; set; }
|
||||
public string WebHookUrl { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
}
|
||||
10
Types/Interfaces/IPaymentItems.cs
Normal file
10
Types/Interfaces/IPaymentItems.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IPaymentItems
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
public int Price { get; set; }
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
}
|
||||
29
Types/Interfaces/IUser.cs
Normal file
29
Types/Interfaces/IUser.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using SPWorldsApi.Types.Enums;
|
||||
using SPWorldsApi.Types.Models;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IUser
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Uuid { get; }
|
||||
|
||||
|
||||
public static async Task<IUser> CreateUserAsync(string name)
|
||||
{
|
||||
string? uuid;
|
||||
using (System.Net.Http.HttpClient client = new())
|
||||
{
|
||||
uuid = (string?)JsonNode.Parse(await client.GetStringAsync($"https://api.mojang.com/users/profiles/minecraft/{name}"))["id"];
|
||||
}
|
||||
User user = new(name, uuid);
|
||||
return user;
|
||||
}
|
||||
|
||||
public string GetSkinPart(SkinPart skinPart, string size = "64")
|
||||
{
|
||||
return (string)$"https://avatar.spworlds.ru/{skinPart}/{size}/{Name}";
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Types/Interfaces/IUserAccount.cs
Normal file
14
Types/Interfaces/IUserAccount.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IUserAccount
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string username { get; set; }
|
||||
public string minecraftUUID { get; set; }
|
||||
public string status { get; set; }
|
||||
public List<string> roles { get; set; }
|
||||
public ICity city { get; set; }
|
||||
public List<IUserCard> cards { get; set; }
|
||||
public DateTime createdAt { get; set; }
|
||||
}
|
||||
}
|
||||
10
Types/Interfaces/IUserCard.cs
Normal file
10
Types/Interfaces/IUserCard.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IUserCard
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string number { get; set; }
|
||||
public int color { get; set; }
|
||||
}
|
||||
}
|
||||
8
Types/Interfaces/IWebhookResponse.cs
Normal file
8
Types/Interfaces/IWebhookResponse.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace SPWorldsApi.Types.Interfaces
|
||||
{
|
||||
public interface IWebhookResponse
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Webhook { get; set; }
|
||||
}
|
||||
}
|
||||
10
Types/Models/Card.cs
Normal file
10
Types/Models/Card.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class Card : ICard
|
||||
{
|
||||
public int Balance { get; set; }
|
||||
public string Webhook { get; set; }
|
||||
}
|
||||
}
|
||||
14
Types/Models/City.cs
Normal file
14
Types/Models/City.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class City : ICity
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string description { get; set; }
|
||||
public int x { get; set; }
|
||||
public int z { get; set; }
|
||||
public bool isMayor { get; set; }
|
||||
}
|
||||
}
|
||||
12
Types/Models/PaymentData.cs
Normal file
12
Types/Models/PaymentData.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class PaymentData : IPaymentData
|
||||
{
|
||||
public IPaymentItems[] Items { get; set; }
|
||||
public string RedirectUrl { get; set; }
|
||||
public string WebHookUrl { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
}
|
||||
12
Types/Models/PaymentItems.cs
Normal file
12
Types/Models/PaymentItems.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
public class PaymentItems : IPaymentItems
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
public int Price { get; set; }
|
||||
public string? Comment { get; set; } = null;
|
||||
}
|
||||
}
|
||||
16
Types/Models/User.cs
Normal file
16
Types/Models/User.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class User : IUser
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Uuid { get; }
|
||||
|
||||
public User(string name, string uuid)
|
||||
{
|
||||
Name = name;
|
||||
Uuid = uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Types/Models/UserAccount.cs
Normal file
16
Types/Models/UserAccount.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class UserAccount : IUserAccount
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string username { get; set; }
|
||||
public string minecraftUUID { get; set; }
|
||||
public string status { get; set; }
|
||||
public List<string> roles { get; set; }
|
||||
public ICity city { get; set; }
|
||||
public List<IUserCard> cards { get; set; }
|
||||
public DateTime createdAt { get; set; }
|
||||
}
|
||||
}
|
||||
12
Types/Models/UserCard.cs
Normal file
12
Types/Models/UserCard.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class UserCard : IUserCard
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string number { get; set; }
|
||||
public int color { get; set; }
|
||||
}
|
||||
}
|
||||
10
Types/Models/WebhookResponse.cs
Normal file
10
Types/Models/WebhookResponse.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
|
||||
namespace SPWorldsApi.Types.Models
|
||||
{
|
||||
internal class WebhookResponse : IWebhookResponse
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Webhook { get; set; }
|
||||
}
|
||||
}
|
||||
49
Users/IUserWrapper.cs
Normal file
49
Users/IUserWrapper.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using SPWorldsApi.Types.Interfaces;
|
||||
using SPWorldsApi.Types.Models;
|
||||
using SPWorldsApi.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SPWorldsApi.Users
|
||||
{
|
||||
internal interface IUserWrapper
|
||||
{
|
||||
HttpClient.HttpRequest client { get; set; }
|
||||
internal async Task<string> SendRequest(string endpoint, HttpMethod method = null, object body = null)
|
||||
{
|
||||
return await client.SendRequest(endpoint, method, body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user cards by nickname
|
||||
/// </summary>
|
||||
/// <param name="username">Username of player</param>
|
||||
/// <returns>Array of cards</returns>
|
||||
public async Task<IUserCard[]> GetUserCardsAsync(string username)
|
||||
=> (await SendRequest($"accounts/{username}/cards")).Deserialize<IUserCard[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Get user info from site
|
||||
/// </summary>
|
||||
/// <param name="discordId">Discord id of user</param>
|
||||
/// <returns></returns>
|
||||
public async Task<IUser> GetUser(string discordId)
|
||||
=> (await SendRequest($"users/{discordId}")).Deserialize<IUser>();
|
||||
|
||||
public async Task<IUserAccount> GetMeAsync()
|
||||
=> (await SendRequest("accounts/me")).Deserialize<IUserAccount>();
|
||||
|
||||
/// <summary>
|
||||
/// Setting up a webhook to card
|
||||
/// </summary>
|
||||
/// <param name="webhookUrl">Url of webhook</param>
|
||||
/// <returns></returns>
|
||||
public async Task<IWebhookResponse> SetWebhook(string webhookUrl)
|
||||
=> (await SendRequest("card/webhook", HttpMethod.Put, @$"{{ ""url"": ""{webhookUrl}"" }}")).Deserialize<IWebhookResponse>();
|
||||
|
||||
}
|
||||
}
|
||||
23
Utils/Deserialization.cs
Normal file
23
Utils/Deserialization.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace SPWorldsApi.Utils
|
||||
{
|
||||
internal static class Deserialization
|
||||
{
|
||||
public static TClass Deserialize<TClass>(this string body) where TClass : class
|
||||
{
|
||||
TClass? objectToReturn = JsonSerializer.Deserialize<TClass>(body);
|
||||
if (objectToReturn == null)
|
||||
throw new Exception($"Error with deserializing object");
|
||||
else
|
||||
return objectToReturn;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user