Browse Source

Split DiscordClientConfig into DiscordSimpleClientConfig

tags/docs-0.9
RogueException 9 years ago
parent
commit
2c3cea036d
6 changed files with 121 additions and 98 deletions
  1. +3
    -0
      src/Discord.Net.Net45/Discord.Net.csproj
  2. +2
    -2
      src/Discord.Net/DiscordClient.API.cs
  3. +18
    -16
      src/Discord.Net/DiscordClient.cs
  4. +3
    -69
      src/Discord.Net/DiscordClientConfig.cs
  5. +9
    -11
      src/Discord.Net/DiscordSimpleClient.cs
  6. +86
    -0
      src/Discord.Net/DiscordSimpleClientConfig.cs

+ 3
- 0
src/Discord.Net.Net45/Discord.Net.csproj View File

@@ -157,6 +157,9 @@
<Compile Include="..\Discord.Net\DiscordSimpleClient.Voice.cs">
<Link>DiscordSimpleClient.Voice.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DiscordSimpleClientConfig.cs">
<Link>DiscordSimpleClientConfig.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Enums\ChannelTypes.cs">
<Link>Enums\ChannelTypes.cs</Link>
</Compile>


+ 2
- 2
src/Discord.Net/DiscordClient.API.cs View File

@@ -326,7 +326,7 @@ namespace Discord
int index = i * MaxMessageSize;
string blockText = text.Substring(index, Math.Min(2000, text.Length - index));
var nonce = GenerateNonce();
if (_config.UseMessageQueue)
if (Config.UseMessageQueue)
{
var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, CurrentUserId);
var currentMember = _members[msg.UserId, channel.ServerId];
@@ -481,7 +481,7 @@ namespace Discord
if (msg != null)
{
msg.Update(x);
if (_config.TrackActivity)
if (Config.TrackActivity)
{
if (channel.IsPrivate)
{


+ 18
- 16
src/Discord.Net/DiscordClient.cs View File

@@ -24,6 +24,8 @@ namespace Discord
private bool _sentInitialLog;
private uint _nextVoiceClientId;

public new DiscordClientConfig Config => _config as DiscordClientConfig;

/// <summary> Returns the current logged-in user. </summary>
public User CurrentUser => _currentUser;
private User _currentUser;
@@ -50,13 +52,13 @@ namespace Discord

/// <summary> Initializes a new instance of the DiscordClient class. </summary>
public DiscordClient(DiscordClientConfig config = null)
: base(config)
: base(config, enableVoice: config.VoiceMode != DiscordVoiceMode.Disabled && !config.EnableVoiceMultiserver)
{
_rand = new Random();
_api = new DiscordAPIClient(_config.LogLevel, _config.UserAgent, _config.APITimeout);
if (_config.UseMessageQueue)
if (Config.UseMessageQueue)
_pendingMessages = new ConcurrentQueue<Message>();
if (_config.EnableVoiceMultiserver)
if (Config.EnableVoiceMultiserver)
_voiceClients = new ConcurrentDictionary<string, DiscordSimpleClient>();

object cacheLock = new object();
@@ -188,7 +190,7 @@ namespace Discord
_users.Cleared += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Cleared Users");
}

if (_config.UseMessageQueue)
if (Config.UseMessageQueue)
_pendingMessages = new ConcurrentQueue<Message>();

_serializer = new JsonSerializer();
@@ -211,7 +213,7 @@ namespace Discord
{
member.IsSpeaking = value;
RaiseUserIsSpeaking(member, value);
if (_config.TrackActivity)
if (Config.TrackActivity)
member.UpdateActivity();
}
}
@@ -272,7 +274,7 @@ namespace Discord

if (_config.VoiceMode != DiscordVoiceMode.Disabled)
{
if (_config.EnableVoiceMultiserver)
if (Config.EnableVoiceMultiserver)
{
var tasks = _voiceClients
.Select(x => x.Value.Disconnect())
@@ -282,7 +284,7 @@ namespace Discord
}
}

if (_config.UseMessageQueue)
if (Config.UseMessageQueue)
{
Message ignored;
while (_pendingMessages.TryDequeue(out ignored)) { }
@@ -302,7 +304,7 @@ namespace Discord
private Task MessageQueueLoop()
{
var cancelToken = CancelToken;
int interval = _config.MessageQueueInterval;
int interval = Config.MessageQueueInterval;

return Task.Run(async () =>
{
@@ -449,7 +451,7 @@ namespace Discord
user.Update(data.User);
var member = _members.GetOrAdd(data.User.Id, data.GuildId);
member.Update(data);
if (_config.TrackActivity)
if (Config.TrackActivity)
member.UpdateActivity();
RaiseUserAdded(member);
}
@@ -536,7 +538,7 @@ namespace Discord

bool isAuthor = data.Author.Id == CurrentUserId;
bool hasFinishedSending = false;
if (_config.UseMessageQueue && isAuthor && data.Nonce != null)
if (Config.UseMessageQueue && isAuthor && data.Nonce != null)
{
msg = _messages.Remap("nonce" + data.Nonce, data.Id);
if (msg != null)
@@ -550,7 +552,7 @@ namespace Discord
if (msg == null)
msg = _messages.GetOrAdd(data.Id, data.ChannelId, data.Author.Id);
msg.Update(data);
if (_config.TrackActivity)
if (Config.TrackActivity)
{
var channel = msg.Channel;
if (channel == null || channel.IsPrivate)
@@ -567,7 +569,7 @@ namespace Discord
}
}

if (_config.AckMessages && isAuthor)
if (Config.AckMessages && isAuthor)
await _api.AckMessage(data.Id, data.ChannelId);

if (hasFinishedSending)
@@ -632,7 +634,7 @@ namespace Discord
if (channel != null)
RaiseUserIsTyping(user, channel);
}
if (_config.TrackActivity)
if (Config.TrackActivity)
{
if (channel.IsPrivate)
{
@@ -709,7 +711,7 @@ namespace Discord
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));

if (!_config.EnableVoiceMultiserver)
if (!Config.EnableVoiceMultiserver)
{
if (serverId == _voiceServerId)
return this;
@@ -725,7 +727,7 @@ namespace Discord
}
private async Task<IDiscordVoiceClient> CreateVoiceClient(string serverId)
{
if (!_config.EnableVoiceMultiserver)
if (!Config.EnableVoiceMultiserver)
{
_voiceServerId = serverId;
return this;
@@ -738,7 +740,7 @@ namespace Discord
config.EnableVoiceMultiserver = false;
config.VoiceOnly = true;
config.VoiceClientId = unchecked(++_nextVoiceClientId);
return new DiscordSimpleClient(config, serverId);
return new DiscordSimpleClient(config, true, serverId);
});
client.LogMessage += (s, e) => RaiseOnLog(e.Severity, e.Source, $"(#{client.Config.VoiceClientId}) {e.Message}");
await client.Connect(_gateway, _token).ConfigureAwait(false);


+ 3
- 69
src/Discord.Net/DiscordClientConfig.cs View File

@@ -3,58 +3,18 @@ using System.Reflection;

namespace Discord
{
[Flags]
public enum DiscordVoiceMode
{
Disabled = 0x00,
Incoming = 0x01,
Outgoing = 0x02,
Both = Outgoing | Incoming
}

public sealed class DiscordClientConfig
{
/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;

/// <summary> Max time in milliseconds to wait for DiscordClient to connect and initialize. </summary>
public int ConnectionTimeout { get { return _connectionTimeout; } set { SetValue(ref _connectionTimeout, value); } }
private int _connectionTimeout = 30000;
/// <summary> Gets or sets the time (in milliseconds) to wait after an unexpected disconnect before reconnecting. </summary>
public int ReconnectDelay { get { return _reconnectDelay; } set { SetValue(ref _reconnectDelay, value); } }
private int _reconnectDelay = 1000;
/// <summary> Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying. </summary>
public int FailedReconnectDelay { get { return _failedReconnectDelay; } set { SetValue(ref _failedReconnectDelay, value); } }
private int _failedReconnectDelay = 10000;
/// <summary> Max time (in milliseconds) to wait for an API request to complete. </summary>
public int APITimeout { get { return _apiTimeout; } set { SetValue(ref _apiTimeout, value); } }
private int _apiTimeout = 10000;

/// <summary> Gets or sets the time (in milliseconds) to wait when the websocket's message queue is empty before checking again. </summary>
public int WebSocketInterval { get { return _webSocketInterval; } set { SetValue(ref _webSocketInterval, value); } }
private int _webSocketInterval = 100;
public class DiscordClientConfig : DiscordSimpleClientConfig
{
/// <summary> Gets or sets the time (in milliseconds) to wait when the message queue is empty before checking again. </summary>
public int MessageQueueInterval { get { return _messageQueueInterval; } set { SetValue(ref _messageQueueInterval, value); } }
private int _messageQueueInterval = 100;
/// <summary> Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. This value is the target maximum but is not guaranteed, the buffer will often go slightly above this value. </summary>
public int VoiceBufferLength { get { return _voiceBufferLength; } set { SetValue(ref _voiceBufferLength, value); } }
private int _voiceBufferLength = 1000;

//Experimental Features
#if !DNXCORE50
/// <summary> (Experimental) Enables the voice websocket and UDP client and specifies how it will be used. Any option other than Disabled requires the opus .dll or .so be in the local lib/ folder. </summary>
public DiscordVoiceMode VoiceMode { get { return _voiceMode; } set { SetValue(ref _voiceMode, value); } }
private DiscordVoiceMode _voiceMode = DiscordVoiceMode.Disabled;
/// <summary> (Experimental) Enables the voice websocket and UDP client. This option requires the libsodium .dll or .so be in the local lib/ folder. </summary>
public bool EnableVoiceEncryption { get { return _enableVoiceEncryption; } set { SetValue(ref _enableVoiceEncryption, value); } }
private bool _enableVoiceEncryption = true;
/// <summary> (Experimental) Enables the client to be simultaneously connected to multiple channels at once (Discord still limits you to one channel per server). </summary>
public bool EnableVoiceMultiserver { get { return _enableVoiceMultiserver; } set { SetValue(ref _enableVoiceMultiserver, value); } }
private bool _enableVoiceMultiserver = false;
#else
internal DiscordVoiceMode VoiceMode => DiscordVoiceMode.Disabled;
internal bool EnableVoiceEncryption => false;
internal bool EnableVoiceMultiserver => false;
#endif
/// <summary> (Experimental) Enables or disables the internal message queue. This will allow SendMessage to return immediately and handle messages internally. Messages will set the IsQueued and HasFailed properties to show their progress. </summary>
@@ -67,33 +27,7 @@ namespace Discord
public bool AckMessages { get { return _ackMessages; } set { SetValue(ref _ackMessages, value); } }
private bool _ackMessages = false;

//Internals
internal bool VoiceOnly { get { return _voiceOnly; } set { SetValue(ref _voiceOnly, value); } }
private bool _voiceOnly;
internal uint VoiceClientId { get { return _voiceClientId; } set { SetValue(ref _voiceClientId, value); } }
private uint _voiceClientId;


internal string UserAgent
{
get
{
string version = typeof(DiscordClientConfig).GetTypeInfo().Assembly.GetName().Version.ToString(2);
return $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)";
}
}

//Lock
private bool _isLocked;
internal void Lock() { _isLocked = true; }
private void SetValue<T>(ref T storage, T value)
{
if (_isLocked)
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
storage = value;
}

public DiscordClientConfig Clone()
public new DiscordClientConfig Clone()
{
var config = this.MemberwiseClone() as DiscordClientConfig;
config._isLocked = false;


+ 9
- 11
src/Discord.Net/DiscordSimpleClient.cs View File

@@ -32,8 +32,8 @@ namespace Discord
private bool _wasDisconnectUnexpected;

/// <summary> Returns the configuration object used to make this client. Note that this object cannot be edited directly - to change the configuration of this client, use the DiscordClient(DiscordClientConfig config) constructor. </summary>
public DiscordClientConfig Config => _config;
protected readonly DiscordClientConfig _config;
public DiscordSimpleClientConfig Config => _config;
protected readonly DiscordSimpleClientConfig _config;

/// <summary> Returns the id of the current logged-in user. </summary>
public string CurrentUserId => _currentUserId;
@@ -50,27 +50,25 @@ namespace Discord
private CancellationToken _cancelToken;

/// <summary> Initializes a new instance of the DiscordClient class. </summary>
public DiscordSimpleClient(DiscordClientConfig config = null)
public DiscordSimpleClient(DiscordSimpleClientConfig config = null)
: this(config, enableVoice: config.VoiceMode != DiscordVoiceMode.Disabled) { }
internal DiscordSimpleClient(DiscordSimpleClientConfig config = null, bool enableVoice = false, string voiceServerId = null)
{
_config = config ?? new DiscordClientConfig();
_config = config ?? new DiscordSimpleClientConfig();
_config.Lock();

_enableVoice = _config.VoiceMode != DiscordVoiceMode.Disabled && !_config.EnableVoiceMultiserver;
_enableVoice = enableVoice;
_voiceServerId = voiceServerId;

_state = (int)DiscordClientState.Disconnected;
_cancelToken = new CancellationToken(true);
_disconnectedEvent = new ManualResetEvent(true);
_connectedEvent = new ManualResetEventSlim(false);
_dataSocket = CreateDataSocket();
if (_enableVoice)
_voiceSocket = CreateVoiceSocket();
}
internal DiscordSimpleClient(DiscordClientConfig config = null, string serverId = null)
: this(config)
{
_voiceServerId = serverId;
}

internal virtual DataWebSocket CreateDataSocket()
{


+ 86
- 0
src/Discord.Net/DiscordSimpleClientConfig.cs View File

@@ -0,0 +1,86 @@
using System;
using System.Reflection;

namespace Discord
{
[Flags]
public enum DiscordVoiceMode
{
Disabled = 0x00,
Incoming = 0x01,
Outgoing = 0x02,
Both = Outgoing | Incoming
}

public class DiscordSimpleClientConfig
{
/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;

/// <summary> Max time in milliseconds to wait for DiscordClient to connect and initialize. </summary>
public int ConnectionTimeout { get { return _connectionTimeout; } set { SetValue(ref _connectionTimeout, value); } }
private int _connectionTimeout = 30000;
/// <summary> Gets or sets the time (in milliseconds) to wait after an unexpected disconnect before reconnecting. </summary>
public int ReconnectDelay { get { return _reconnectDelay; } set { SetValue(ref _reconnectDelay, value); } }
private int _reconnectDelay = 1000;
/// <summary> Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying. </summary>
public int FailedReconnectDelay { get { return _failedReconnectDelay; } set { SetValue(ref _failedReconnectDelay, value); } }
private int _failedReconnectDelay = 10000;
/// <summary> Max time (in milliseconds) to wait for an API request to complete. </summary>
public int APITimeout { get { return _apiTimeout; } set { SetValue(ref _apiTimeout, value); } }
private int _apiTimeout = 10000;

/// <summary> Gets or sets the time (in milliseconds) to wait when the websocket's message queue is empty before checking again. </summary>
public int WebSocketInterval { get { return _webSocketInterval; } set { SetValue(ref _webSocketInterval, value); } }
private int _webSocketInterval = 100;
/// <summary> Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. This value is the target maximum but is not guaranteed, the buffer will often go slightly above this value. </summary>
public int VoiceBufferLength { get { return _voiceBufferLength; } set { SetValue(ref _voiceBufferLength, value); } }
private int _voiceBufferLength = 1000;

//Experimental Features
#if !DNXCORE50
/// <summary> (Experimental) Enables the voice websocket and UDP client and specifies how it will be used. Any option other than Disabled requires the opus .dll or .so be in the local lib/ folder. </summary>
public DiscordVoiceMode VoiceMode { get { return _voiceMode; } set { SetValue(ref _voiceMode, value); } }
private DiscordVoiceMode _voiceMode = DiscordVoiceMode.Disabled;
/// <summary> (Experimental) Enables the voice websocket and UDP client. This option requires the libsodium .dll or .so be in the local lib/ folder. </summary>
public bool EnableVoiceEncryption { get { return _enableVoiceEncryption; } set { SetValue(ref _enableVoiceEncryption, value); } }
private bool _enableVoiceEncryption = true;
#else
internal DiscordVoiceMode VoiceMode => DiscordVoiceMode.Disabled;
internal bool EnableVoiceEncryption => false;
#endif

//Internals
internal bool VoiceOnly { get { return _voiceOnly; } set { SetValue(ref _voiceOnly, value); } }
private bool _voiceOnly;
internal uint VoiceClientId { get { return _voiceClientId; } set { SetValue(ref _voiceClientId, value); } }
private uint _voiceClientId;

internal string UserAgent
{
get
{
string version = typeof(DiscordClientConfig).GetTypeInfo().Assembly.GetName().Version.ToString(2);
return $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)";
}
}

//Lock
protected bool _isLocked;
internal void Lock() { _isLocked = true; }
protected void SetValue<T>(ref T storage, T value)
{
if (_isLocked)
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
storage = value;
}

public DiscordClientConfig Clone()
{
var config = this.MemberwiseClone() as DiscordClientConfig;
config._isLocked = false;
return config;
}
}
}

Loading…
Cancel
Save