Browse Source

api: design rest and core

pull/1435/head
Christopher Felegy 5 years ago
parent
commit
97ba033c1e
No known key found for this signature in database GPG Key ID: 3AB2CA980DDC61A9
13 changed files with 237 additions and 6 deletions
  1. +32
    -0
      TODO
  2. +1
    -0
      src/Discord.Net/Discord.Net.csproj
  3. +25
    -0
      src/Discord.Net/DiscordClient.cs
  4. +33
    -0
      src/Discord.Net/DiscordConfig.cs
  5. +23
    -0
      src/Discord.Net/IDiscordClient.cs
  6. +28
    -0
      src/Discord.Net/Rest/DiscordRestApi.cs
  7. +12
    -0
      src/Discord.Net/Rest/IDiscordRestApi.cs
  8. +52
    -0
      src/Discord.Net/Rest/JsonContentSerializer.cs
  9. +25
    -0
      src/Discord.Net/Rest/Models/GatewayInfo.cs
  10. +0
    -0
      src/Discord.Net/Rest/Requests/Test.cs
  11. +4
    -4
      src/Discord.Net/Socket/DiscordGatewayApi.cs
  12. +1
    -1
      src/Discord.Net/Socket/ISocket.cs
  13. +1
    -1
      src/Discord.Net/Socket/Providers/DefaultSocket.cs

+ 32
- 0
TODO View File

@@ -0,0 +1,32 @@
- REST
- Models
- Preconditions
- Endpoints
- Channel
- Emoji
- Guild
- Invite
- User
- Voice
- Webhook
- Gateway
- Models
- Client
- Socket
* Receive
* Compression
- Voice (long)
- Core
- CDN
- Datastore
- Entities
- Channel
- Emoji
- Guild
- User
- Tests
- Unit test Gateway stability / deadlockability?
- Extensions
- Commands
? design - use finite's or quahu's
- Interactivity

+ 1
- 0
src/Discord.Net/Discord.Net.csproj View File

@@ -4,6 +4,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Discord</RootNamespace>
</PropertyGroup>

</Project>

+ 25
- 0
src/Discord.Net/DiscordClient.cs View File

@@ -0,0 +1,25 @@
using Discord.Rest;
using Discord.Socket;
using System;
using System.Collections.Generic;
using System.Text;

namespace Discord
{
internal class DiscordClient : IDiscordClient
{
public DiscordRestApi Rest => _restApi;
public DiscordGatewayApi Gateway => _gatewayApi;

private readonly DiscordConfig _config;
private readonly DiscordRestApi _restApi;
private readonly DiscordGatewayApi _gatewayApi;

public DiscordClient(DiscordConfig config, DiscordRestApi restApi, DiscordGatewayApi gatewayApi)
{
_config = config;
_restApi = restApi;
_gatewayApi = gatewayApi;
}
}
}

+ 33
- 0
src/Discord.Net/DiscordConfig.cs View File

@@ -0,0 +1,33 @@
using Discord.Socket;
using Discord.Socket.Providers;
using System;

namespace Discord
{
public class DiscordConfig
{
/// <summary>
/// Discord.Net version
/// </summary>
public const string Version = "3.0.0a0";
/// <summary>
/// Discord.Net User-Agent
/// </summary>
public const string UserAgent = "DiscordBot (https://github.com/discord-net/Discord.Net, " + Version + ")";

/// <summary>
/// The default, fallback Gateway URI. This will generally be replaced by <see cref="Rest.IDiscordRestApi.GetGatewayAsync"/>.
/// </summary>
public static readonly Uri DefaultGatewayUri = new Uri("wss://gateway.discord.gg");
/// <summary>
/// The base URL for the Rest API.
/// </summary>
public string RestApiUrl { get; set; } = "https://discordapp.com/api/v6/";
/// <summary>
/// The URI to use when connecting to the gateway. If specified, this will override the URI Discord instructs us to use.
/// </summary>
public Uri? GatewayUri = null;

public SocketFactory SocketFactory { get; set; } = DefaultSocketFactory.Create;
}
}

+ 23
- 0
src/Discord.Net/IDiscordClient.cs View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Discord.Rest;
using Discord.Socket;

namespace Discord
{
internal interface IDiscordClient
{
static IDiscordClient Create(DiscordConfig config)
{
var rest = new DiscordRestApi(config);
var gateway = new DiscordGatewayApi(config);

return new DiscordClient(config, rest, gateway);
}

DiscordRestApi Rest { get; }
DiscordGatewayApi Gateway { get; }
}
}

+ 28
- 0
src/Discord.Net/Rest/DiscordRestApi.cs View File

@@ -0,0 +1,28 @@
using System.Text.Json;
using System.Threading.Tasks;
using Refit;
using Discord.Rest.Models;

// This is essentially a reimplementation of Wumpus.Net.Rest
namespace Discord.Rest
{
public class DiscordRestApi : IDiscordRestApi
{
private readonly IDiscordRestApi _api;

public DiscordRestApi(DiscordConfig config)
{
var jsonOptions = new JsonSerializerOptions();
var refitSettings = new RefitSettings
{
ContentSerializer = new JsonContentSerializer(jsonOptions),
};
_api = RestService.For<IDiscordRestApi>(config.RestApiUrl, refitSettings);
}

public Task<GatewayInfo> GetGatewayInfoAsync()
{
return _api.GetGatewayInfoAsync();
}
}
}

+ 12
- 0
src/Discord.Net/Rest/IDiscordRestApi.cs View File

@@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Refit;
using Discord.Rest.Models;

namespace Discord.Rest
{
public interface IDiscordRestApi
{
[Get("/gateway/bot")]
Task<GatewayInfo> GetGatewayInfoAsync();
}
}

+ 52
- 0
src/Discord.Net/Rest/JsonContentSerializer.cs View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Refit;

// https://blog.martincostello.com/refit-and-system-text-json/

namespace Discord.Rest
{
public class JsonContentSerializer : IContentSerializer
{
private static readonly MediaTypeHeaderValue _jsonMediaType = new MediaTypeHeaderValue("application/json") { CharSet = Encoding.UTF8.WebName };
private readonly JsonSerializerOptions _serializerOptions;

public JsonContentSerializer(JsonSerializerOptions serializerOptions)
{
_serializerOptions = serializerOptions;
}

public async Task<T> DeserializeAsync<T>(HttpContent content)
{
using var json = await content.ReadAsStreamAsync().ConfigureAwait(false);
return await JsonSerializer.DeserializeAsync<T>(json, _serializerOptions).ConfigureAwait(false);
}

public async Task<HttpContent> SerializeAsync<T>(T data)
{
var stream = new MemoryStream();
try
{
await JsonSerializer.SerializeAsync<T>(stream, data, _serializerOptions).ConfigureAwait(false);
await stream.FlushAsync();

var content = new StreamContent(stream);
content.Headers.ContentType = _jsonMediaType;

return content;
}
catch
{
await stream.DisposeAsync().ConfigureAwait(false);
throw;
}
}
}
}

+ 25
- 0
src/Discord.Net/Rest/Models/GatewayInfo.cs View File

@@ -0,0 +1,25 @@
#pragma warning disable CS8618 // Uninitialized NRT expected in models
using System.Text.Json.Serialization;

namespace Discord.Rest.Models
{
public class GatewayInfo
{
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("shards")]
public int Shards { get; set; }
[JsonPropertyName("session_start_limit")]
public GatewaySessionStartInfo SessionStartInfo { get; set; }
}

public class GatewaySessionStartInfo
{
[JsonPropertyName("total")]
public int Total { get; set; }
[JsonPropertyName("remaining")]
public int Remaining { get; set; }
[JsonPropertyName("reset_after")]
public int ResetAfter { get; set; }
}
}

+ 0
- 0
src/Discord.Net/Rest/Requests/Test.cs View File


src/Discord.Net/Socket/Gateway.cs → src/Discord.Net/Socket/DiscordGatewayApi.cs View File

@@ -2,17 +2,17 @@ using System;
using System.Threading;
using System.Threading.Tasks;

namespace Discord.Net.Socket
namespace Discord.Socket
{
public class Gateway
public class DiscordGatewayApi
{
static readonly Uri DefaultGatewayUri = new Uri("wss://gateway.discord.gg");

ISocket Socket { get; set; }

public Gateway(SocketFactory socketFactory)
public DiscordGatewayApi(DiscordConfig config)
{
Socket = socketFactory(OnAborted, OnPacket);
Socket = config.SocketFactory(OnAborted, OnPacket);
}

public async Task ConnectAsync(Uri? gatewayUri)

+ 1
- 1
src/Discord.Net/Socket/ISocket.cs View File

@@ -2,7 +2,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;

namespace Discord.Net.Socket
namespace Discord.Socket
{
public delegate ISocket SocketFactory(OnAbortionHandler abortionHandler, OnPacketHandler packetHandler);



+ 1
- 1
src/Discord.Net/Socket/Providers/DefaultSocket.cs View File

@@ -3,7 +3,7 @@ using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

namespace Discord.Net.Socket.Providers
namespace Discord.Socket.Providers
{
public static class DefaultSocketFactory
{


Loading…
Cancel
Save