diff --git a/DisCatSharp/DiscordConfiguration.cs b/DisCatSharp/DiscordConfiguration.cs
index c47950077..606e5e98d 100644
--- a/DisCatSharp/DiscordConfiguration.cs
+++ b/DisCatSharp/DiscordConfiguration.cs
@@ -1,268 +1,268 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Net;
using DisCatSharp.Net.Udp;
using DisCatSharp.Net.WebSocket;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace DisCatSharp
{
///
/// Represents configuration for and .
///
public sealed class DiscordConfiguration
{
///
/// Sets the token used to identify the client.
///
public string Token
{
internal get => this._token;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException(nameof(value), "Token cannot be null, empty, or all whitespace.");
this._token = value.Trim();
}
}
private string _token = "";
///
/// Sets the type of the token used to identify the client.
/// Defaults to .
///
public TokenType TokenType { internal get; set; } = TokenType.Bot;
///
/// Sets the minimum logging level for messages.
/// Typically, the default value of is ok for most uses.
///
public LogLevel MinimumLogLevel { internal get; set; } = LogLevel.Information;
///
/// Overwrites the api version.
/// Defaults to 9.
///
public string ApiVersion { internal get; set; } = "9";
///
/// Sets whether to rely on Discord for NTP (Network Time Protocol) synchronization with the "X-Ratelimit-Reset-After" header.
/// If the system clock is unsynced, setting this to true will ensure ratelimits are synced with Discord and reduce the risk of hitting one.
/// This should only be set to false if the system clock is synced with NTP.
/// Defaults to true.
///
public bool UseRelativeRatelimit { internal get; set; } = true;
///
/// Allows you to overwrite the time format used by the internal debug logger.
/// Only applicable when is set left at default value. Defaults to ISO 8601-like format.
///
public string LogTimestampFormat { internal get; set; } = "yyyy-MM-dd HH:mm:ss zzz";
///
/// Sets the member count threshold at which guilds are considered large.
/// Defaults to 250.
///
public int LargeThreshold { internal get; set; } = 250;
///
/// Sets whether to automatically reconnect in case a connection is lost.
/// Defaults to true.
///
public bool AutoReconnect { internal get; set; } = true;
///
/// Sets the ID of the shard to connect to.
/// If not sharding, or sharding automatically, this value should be left with the default value of 0.
///
public int ShardId { internal get; set; } = 0;
///
/// Sets the total number of shards the bot is on. If not sharding, this value should be left with a default value of 1.
/// If sharding automatically, this value will indicate how many shards to boot. If left default for automatic sharding, the client will determine the shard count automatically.
///
public int ShardCount { internal get; set; } = 1;
///
/// Sets the level of compression for WebSocket traffic.
/// Disabling this option will increase the amount of traffic sent via WebSocket. Setting will enable compression for READY and GUILD_CREATE payloads. Setting will enable compression for the entire WebSocket stream, drastically reducing amount of traffic.
/// Defaults to .
///
public GatewayCompressionLevel GatewayCompressionLevel { internal get; set; } = GatewayCompressionLevel.Stream;
///
/// Sets the size of the global message cache.
/// Setting this to 0 will disable message caching entirely. Defaults to 1024.
///
public int MessageCacheSize { internal get; set; } = 1024;
///
/// Sets the proxy to use for HTTP and WebSocket connections to Discord.
/// Defaults to null.
///
public IWebProxy Proxy { internal get; set; } = null;
///
/// Sets the timeout for HTTP requests.
/// Set to to disable timeouts.
/// Defaults to 20 seconds.
///
public TimeSpan HttpTimeout { internal get; set; } = TimeSpan.FromSeconds(20);
///
/// Defines that the client should attempt to reconnect indefinitely.
/// This is typically a very bad idea to set to true, as it will swallow all connection errors.
/// Defaults to false.
///
public bool ReconnectIndefinitely { internal get; set; } = false;
///
/// Sets whether the client should attempt to cache members if exclusively using unprivileged intents.
///
/// This will only take effect if there are no or
/// intents specified. Otherwise, this will always be overwritten to true.
///
/// Defaults to true.
///
public bool AlwaysCacheMembers { internal get; set; } = true;
///
/// Sets the gateway intents for this client.
/// If set, the client will only receive events that they specify with intents.
/// Defaults to .
///
public DiscordIntents Intents { internal get; set; } = DiscordIntents.AllUnprivileged;
///
/// Sets the factory method used to create instances of WebSocket clients.
- /// Use and equivalents on other implementations to switch out client implementations.
- /// Defaults to .
+ /// Use and equivalents on other implementations to switch out client implementations.
+ /// Defaults to .
///
public WebSocketClientFactoryDelegate WebSocketClientFactory
{
internal get => this._webSocketClientFactory;
set
{
if (value == null)
throw new InvalidOperationException("You need to supply a valid WebSocket client factory method.");
this._webSocketClientFactory = value;
}
}
private WebSocketClientFactoryDelegate _webSocketClientFactory = WebSocketClient.CreateNew;
///
/// Sets the factory method used to create instances of UDP clients.
/// Use and equivalents on other implementations to switch out client implementations.
/// Defaults to .
///
public UdpClientFactoryDelegate UdpClientFactory
{
internal get => this._udpClientFactory;
set => this._udpClientFactory = value ?? throw new InvalidOperationException("You need to supply a valid UDP client factory method.");
}
private UdpClientFactoryDelegate _udpClientFactory = DCSUdpClient.CreateNew;
///
/// Sets the logger implementation to use.
/// To create your own logger, implement the instance.
/// Defaults to built-in implementation.
///
public ILoggerFactory LoggerFactory { internal get; set; } = null;
///
/// Sets if the bot's status should show the mobile icon.
/// Defaults to false.
///
public bool MobileStatus { internal get; set; } = false;
///
/// Use canary.
/// Defaults to false.
///
public bool UseCanary { internal get; set; } = false;
///
/// Refresh full guild channel cache.
/// Defaults to false.
///
public bool AutoRefreshChannelCache { internal get; set; } = false;
///
/// Sets the service provider.
/// This allows passing data around without resorting to static members.
/// Defaults to null.
///
public IServiceProvider ServiceProvider { internal get; set; } = new ServiceCollection().BuildServiceProvider(true);
///
/// Creates a new configuration with default values.
///
public DiscordConfiguration()
{ }
///
/// Utilized via Dependency Injection Pipeline
///
///
[ActivatorUtilitiesConstructor]
public DiscordConfiguration(IServiceProvider provider)
{
this.ServiceProvider = provider;
}
///
/// Creates a clone of another discord configuration.
///
/// Client configuration to clone.
public DiscordConfiguration(DiscordConfiguration other)
{
this.Token = other.Token;
this.TokenType = other.TokenType;
this.MinimumLogLevel = other.MinimumLogLevel;
this.UseRelativeRatelimit = other.UseRelativeRatelimit;
this.LogTimestampFormat = other.LogTimestampFormat;
this.LargeThreshold = other.LargeThreshold;
this.AutoReconnect = other.AutoReconnect;
this.ShardId = other.ShardId;
this.ShardCount = other.ShardCount;
this.GatewayCompressionLevel = other.GatewayCompressionLevel;
this.MessageCacheSize = other.MessageCacheSize;
this.WebSocketClientFactory = other.WebSocketClientFactory;
this.UdpClientFactory = other.UdpClientFactory;
this.Proxy = other.Proxy;
this.HttpTimeout = other.HttpTimeout;
this.ReconnectIndefinitely = other.ReconnectIndefinitely;
this.Intents = other.Intents;
this.LoggerFactory = other.LoggerFactory;
this.MobileStatus = other.MobileStatus;
this.UseCanary = other.UseCanary;
this.AutoRefreshChannelCache = other.AutoRefreshChannelCache;
this.ApiVersion = other.ApiVersion;
this.ServiceProvider = other.ServiceProvider;
}
}
}
diff --git a/DisCatSharp/Net/WebSocket/IWebSocketClient.cs b/DisCatSharp/Net/WebSocket/IWebSocketClient.cs
index 81aa701dd..3925c5f3c 100644
--- a/DisCatSharp/Net/WebSocket/IWebSocketClient.cs
+++ b/DisCatSharp/Net/WebSocket/IWebSocketClient.cs
@@ -1,116 +1,117 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using DisCatSharp.EventArgs;
using DisCatSharp.Common.Utilities;
using Microsoft.Extensions.DependencyInjection;
namespace DisCatSharp.Net.WebSocket
{
///
/// Creates an instance of a WebSocket client implementation.
///
/// Proxy settings to use for the new WebSocket client instance.
+ /// Service provider.
/// Constructed WebSocket client implementation.
public delegate IWebSocketClient WebSocketClientFactoryDelegate(IWebProxy proxy, IServiceProvider provider);
///
/// Represents a base abstraction for all WebSocket client implementations.
///
public interface IWebSocketClient : IDisposable
{
///
/// Gets the proxy settings for this client.
///
IWebProxy Proxy { get; }
///
/// Gets the collection of default headers to send when connecting to the remote endpoint.
///
IReadOnlyDictionary DefaultHeaders { get; }
///
/// Gets the service provider.
///
internal IServiceProvider ServiceProvider { get; set; }
///
/// Connects to a specified remote WebSocket endpoint.
///
/// The URI of the WebSocket endpoint.
Task ConnectAsync(Uri uri);
///
/// Disconnects the WebSocket connection.
///
/// The code
/// The message
/// Lala Sabathil,06.07.2021
/// Lala Sabathil,06.07.2021
Task DisconnectAsync(int code = 1000, string message = "");
///
/// Send a message to the WebSocket server.
///
/// The message to send.
Task SendMessageAsync(string message);
///
/// Adds a header to the default header collection.
///
/// Name of the header to add.
/// Value of the header to add.
/// Whether the operation succeeded.
bool AddDefaultHeader(string name, string value);
///
/// Removes a header from the default header collection.
///
/// Name of the header to remove.
/// Whether the operation succeeded.
bool RemoveDefaultHeader(string name);
///
/// Triggered when the client connects successfully.
///
event AsyncEventHandler Connected;
///
/// Triggered when the client is disconnected.
///
event AsyncEventHandler Disconnected;
///
/// Triggered when the client receives a message from the remote party.
///
event AsyncEventHandler MessageReceived;
///
/// Triggered when an error occurs in the client.
///
event AsyncEventHandler ExceptionThrown;
}
}