Fixed race condition, better handled serialization errors, and added singleton store
This commit is contained in:
@@ -94,9 +94,6 @@
|
|||||||
<Compile Include="..\Discord.Net\API\Enums\PermissionTarget.cs">
|
<Compile Include="..\Discord.Net\API\Enums\PermissionTarget.cs">
|
||||||
<Link>API\Enums\PermissionTarget.cs</Link>
|
<Link>API\Enums\PermissionTarget.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\API\Enums\Region.cs">
|
|
||||||
<Link>API\Enums\Region.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\Discord.Net\API\Enums\StringEnum.cs">
|
<Compile Include="..\Discord.Net\API\Enums\StringEnum.cs">
|
||||||
<Link>API\Enums\StringEnum.cs</Link>
|
<Link>API\Enums\StringEnum.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -259,6 +256,9 @@
|
|||||||
<Compile Include="..\Discord.Net\Models\Permissions.cs">
|
<Compile Include="..\Discord.Net\Models\Permissions.cs">
|
||||||
<Link>Models\Permissions.cs</Link>
|
<Link>Models\Permissions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Models\Region.cs">
|
||||||
|
<Link>Models\Region.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Models\Role.cs">
|
<Compile Include="..\Discord.Net\Models\Role.cs">
|
||||||
<Link>Models\Role.cs</Link>
|
<Link>Models\Role.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
11
src/Discord.Net/API/Converters/StringEnumConverter.cs
Normal file
11
src/Discord.Net/API/Converters/StringEnumConverter.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord.API.Converters
|
||||||
|
{
|
||||||
|
public class StringEnumConverter
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public class DiscordAPIClientConfig
|
public class DiscordAPIClientConfig
|
||||||
{
|
{
|
||||||
|
internal static readonly string UserAgent = $"Discord.Net/{DiscordClient.Version} (https://github.com/RogueException/Discord.Net)";
|
||||||
|
|
||||||
/// <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>
|
/// <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); } }
|
public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
|
||||||
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;
|
private LogMessageSeverity _logLevel = LogMessageSeverity.Info;
|
||||||
@@ -21,15 +23,6 @@ namespace Discord
|
|||||||
public NetworkCredential ProxyCredentials { get { return _proxyCredentials; } set { SetValue(ref _proxyCredentials, value); } }
|
public NetworkCredential ProxyCredentials { get { return _proxyCredentials; } set { SetValue(ref _proxyCredentials, value); } }
|
||||||
private NetworkCredential _proxyCredentials = null;
|
private NetworkCredential _proxyCredentials = null;
|
||||||
|
|
||||||
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
|
//Lock
|
||||||
protected bool _isLocked;
|
protected bool _isLocked;
|
||||||
internal void Lock() { _isLocked = true; }
|
internal void Lock() { _isLocked = true; }
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Deserializes messages from JSON format and imports them into the message cache.</summary>
|
/// <summary> Deserializes messages from JSON format and imports them into the message cache.</summary>
|
||||||
public IEnumerable<Message> ImportMessages(string json)
|
public IEnumerable<Message> ImportMessages(Channel channel, string json)
|
||||||
{
|
{
|
||||||
if (json == null) throw new ArgumentNullException(nameof(json));
|
if (json == null) throw new ArgumentNullException(nameof(json));
|
||||||
|
|
||||||
@@ -269,8 +269,8 @@ namespace Discord
|
|||||||
.Select(x =>
|
.Select(x =>
|
||||||
{
|
{
|
||||||
var msg = new Message(this,
|
var msg = new Message(this,
|
||||||
x["Id"].Value<long>(),
|
x["Id"].Value<long>(),
|
||||||
x["ChannelId"].Value<long>(),
|
channel.Id,
|
||||||
x["UserId"].Value<long>());
|
x["UserId"].Value<long>());
|
||||||
|
|
||||||
var reader = x.CreateReader();
|
var reader = x.CreateReader();
|
||||||
|
|||||||
@@ -86,19 +86,19 @@ namespace Discord
|
|||||||
if (region == null) throw new ArgumentNullException(nameof(region));
|
if (region == null) throw new ArgumentNullException(nameof(region));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
var response = await _api.CreateServer(name, region.Value).ConfigureAwait(false);
|
var response = await _api.CreateServer(name, region.Id).ConfigureAwait(false);
|
||||||
var server = _servers.GetOrAdd(response.Id);
|
var server = _servers.GetOrAdd(response.Id);
|
||||||
server.Update(response);
|
server.Update(response);
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Edits the provided server, changing only non-null attributes. </summary>
|
/// <summary> Edits the provided server, changing only non-null attributes. </summary>
|
||||||
public async Task EditServer(Server server, string name = null, Region region = null, ImageType iconType = ImageType.Png, byte[] icon = null)
|
public async Task EditServer(Server server, string name = null, string region = null, ImageType iconType = ImageType.Png, byte[] icon = null)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region.Value, iconType: iconType, icon: icon).ConfigureAwait(false);
|
var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region, iconType: iconType, icon: icon).ConfigureAwait(false);
|
||||||
server.Update(response);
|
server.Update(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,5 +112,12 @@ namespace Discord
|
|||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
|
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
|
||||||
//return _servers.TryRemove(server.Id);
|
//return _servers.TryRemove(server.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Region>> GetVoiceRegions()
|
||||||
|
{
|
||||||
|
CheckReady();
|
||||||
|
|
||||||
|
return (await _api.GetVoiceRegions()).Select(x => new Region { Id = x.Id, Name = x.Name, Hostname = x.Hostname, Port = x.Port });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -12,12 +13,14 @@ namespace Discord
|
|||||||
/// <summary> Provides a connection to the DiscordApp service. </summary>
|
/// <summary> Provides a connection to the DiscordApp service. </summary>
|
||||||
public sealed partial class DiscordClient : DiscordWSClient
|
public sealed partial class DiscordClient : DiscordWSClient
|
||||||
{
|
{
|
||||||
|
public static readonly string Version = typeof(DiscordClientConfig).GetTypeInfo().Assembly.GetName().Version.ToString(3);
|
||||||
|
|
||||||
private readonly DiscordAPIClient _api;
|
private readonly DiscordAPIClient _api;
|
||||||
private readonly Random _rand;
|
private readonly Random _rand;
|
||||||
private readonly JsonSerializer _socketSerializer, _messageImporter;
|
private readonly JsonSerializer _messageImporter;
|
||||||
private readonly ConcurrentQueue<Message> _pendingMessages;
|
private readonly ConcurrentQueue<Message> _pendingMessages;
|
||||||
private readonly ConcurrentDictionary<long, DiscordWSClient> _voiceClients;
|
private readonly ConcurrentDictionary<long, DiscordWSClient> _voiceClients;
|
||||||
private readonly Dictionary<Type, IService> _services;
|
private readonly Dictionary<Type, object> _singletons;
|
||||||
private bool _sentInitialLog;
|
private bool _sentInitialLog;
|
||||||
private uint _nextVoiceClientId;
|
private uint _nextVoiceClientId;
|
||||||
private UserStatus _status;
|
private UserStatus _status;
|
||||||
@@ -47,7 +50,7 @@ namespace Discord
|
|||||||
_roles = new Roles(this, cacheLock);
|
_roles = new Roles(this, cacheLock);
|
||||||
_servers = new Servers(this, cacheLock);
|
_servers = new Servers(this, cacheLock);
|
||||||
_globalUsers = new GlobalUsers(this, cacheLock);
|
_globalUsers = new GlobalUsers(this, cacheLock);
|
||||||
_services = new Dictionary<Type, IService>();
|
_singletons = new Dictionary<Type, object>();
|
||||||
|
|
||||||
_status = UserStatus.Online;
|
_status = UserStatus.Online;
|
||||||
|
|
||||||
@@ -162,16 +165,9 @@ namespace Discord
|
|||||||
|
|
||||||
if (Config.UseMessageQueue)
|
if (Config.UseMessageQueue)
|
||||||
_pendingMessages = new ConcurrentQueue<Message>();
|
_pendingMessages = new ConcurrentQueue<Message>();
|
||||||
|
|
||||||
_socketSerializer = new JsonSerializer();
|
|
||||||
_socketSerializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
|
||||||
#if TEST_RESPONSES
|
|
||||||
_serializer.CheckAdditionalContent = true;
|
|
||||||
_serializer.MissingMemberHandling = MissingMemberHandling.Error;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_messageImporter = new JsonSerializer();
|
_messageImporter = new JsonSerializer();
|
||||||
_messageImporter.ContractResolver = new MessageImporterResolver();
|
_messageImporter.ContractResolver = new Message.ImportResolver();
|
||||||
}
|
}
|
||||||
internal override VoiceWebSocket CreateVoiceSocket()
|
internal override VoiceWebSocket CreateVoiceSocket()
|
||||||
{
|
{
|
||||||
@@ -276,25 +272,34 @@ namespace Discord
|
|||||||
_privateUser = null;
|
_privateUser = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T AddSingleton<T>(T obj)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
_singletons.Add(typeof(T), obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
public T GetSingleton<T>(bool required = true)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
object singleton;
|
||||||
|
T singletonT = null;
|
||||||
|
if (_singletons.TryGetValue(typeof(T), out singleton))
|
||||||
|
singletonT = singleton as T;
|
||||||
|
|
||||||
|
if (singletonT == null && required)
|
||||||
|
throw new InvalidOperationException($"This operation requires {nameof(T)} to be added to {nameof(DiscordClient)}.");
|
||||||
|
return singletonT;
|
||||||
|
}
|
||||||
public T AddService<T>(T obj)
|
public T AddService<T>(T obj)
|
||||||
where T : class, IService
|
where T : class, IService
|
||||||
{
|
{
|
||||||
_services.Add(typeof(T), obj);
|
AddSingleton(obj);
|
||||||
obj.Install(this);
|
obj.Install(this);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
public T GetService<T>(bool required = true)
|
public T GetService<T>(bool required = true)
|
||||||
where T : class, IService
|
where T : class, IService
|
||||||
{
|
=> GetSingleton<T>(required);
|
||||||
IService service;
|
|
||||||
T serviceT = null;
|
|
||||||
if (_services.TryGetValue(typeof(T), out service))
|
|
||||||
serviceT = service as T;
|
|
||||||
|
|
||||||
if (serviceT == null && required)
|
|
||||||
throw new InvalidOperationException($"This operation requires {nameof(T)} to be added to {nameof(DiscordClient)}.");
|
|
||||||
return serviceT;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<Task> GetTasks()
|
protected override IEnumerable<Task> GetTasks()
|
||||||
{
|
{
|
||||||
@@ -314,7 +319,7 @@ namespace Discord
|
|||||||
case "READY": //Resync
|
case "READY": //Resync
|
||||||
{
|
{
|
||||||
base.OnReceivedEvent(e).Wait(); //This cannot be an await, or we'll get later messages before we're ready
|
base.OnReceivedEvent(e).Wait(); //This cannot be an await, or we'll get later messages before we're ready
|
||||||
var data = e.Payload.ToObject<ReadyEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<ReadyEvent>(_dataSocketSerializer);
|
||||||
_privateUser = _users.GetOrAdd(data.User.Id, null);
|
_privateUser = _users.GetOrAdd(data.User.Id, null);
|
||||||
_privateUser.Update(data.User);
|
_privateUser.Update(data.User);
|
||||||
_privateUser.Global.Update(data.User);
|
_privateUser.Global.Update(data.User);
|
||||||
@@ -339,7 +344,7 @@ namespace Discord
|
|||||||
//Servers
|
//Servers
|
||||||
case "GUILD_CREATE":
|
case "GUILD_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<GuildCreateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<GuildCreateEvent>(_dataSocketSerializer);
|
||||||
if (data.Unavailable != true)
|
if (data.Unavailable != true)
|
||||||
{
|
{
|
||||||
var server = _servers.GetOrAdd(data.Id);
|
var server = _servers.GetOrAdd(data.Id);
|
||||||
@@ -353,7 +358,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_UPDATE":
|
case "GUILD_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<GuildUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<GuildUpdateEvent>(_dataSocketSerializer);
|
||||||
var server = _servers[data.Id];
|
var server = _servers[data.Id];
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
@@ -364,7 +369,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_DELETE":
|
case "GUILD_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<GuildDeleteEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<GuildDeleteEvent>(_dataSocketSerializer);
|
||||||
var server = _servers.TryRemove(data.Id);
|
var server = _servers.TryRemove(data.Id);
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
@@ -379,7 +384,7 @@ namespace Discord
|
|||||||
//Channels
|
//Channels
|
||||||
case "CHANNEL_CREATE":
|
case "CHANNEL_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<ChannelCreateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<ChannelCreateEvent>(_dataSocketSerializer);
|
||||||
Channel channel;
|
Channel channel;
|
||||||
if (data.IsPrivate)
|
if (data.IsPrivate)
|
||||||
{
|
{
|
||||||
@@ -395,7 +400,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "CHANNEL_UPDATE":
|
case "CHANNEL_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<ChannelUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<ChannelUpdateEvent>(_dataSocketSerializer);
|
||||||
var channel = _channels[data.Id];
|
var channel = _channels[data.Id];
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
{
|
{
|
||||||
@@ -406,7 +411,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "CHANNEL_DELETE":
|
case "CHANNEL_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<ChannelDeleteEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<ChannelDeleteEvent>(_dataSocketSerializer);
|
||||||
var channel = _channels.TryRemove(data.Id);
|
var channel = _channels.TryRemove(data.Id);
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
RaiseChannelDestroyed(channel);
|
RaiseChannelDestroyed(channel);
|
||||||
@@ -416,7 +421,7 @@ namespace Discord
|
|||||||
//Members
|
//Members
|
||||||
case "GUILD_MEMBER_ADD":
|
case "GUILD_MEMBER_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MemberAddEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MemberAddEvent>(_dataSocketSerializer);
|
||||||
var user = _users.GetOrAdd(data.User.Id, data.GuildId);
|
var user = _users.GetOrAdd(data.User.Id, data.GuildId);
|
||||||
user.Update(data);
|
user.Update(data);
|
||||||
if (Config.TrackActivity)
|
if (Config.TrackActivity)
|
||||||
@@ -426,7 +431,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_MEMBER_UPDATE":
|
case "GUILD_MEMBER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MemberUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MemberUpdateEvent>(_dataSocketSerializer);
|
||||||
var user = _users[data.User.Id, data.GuildId];
|
var user = _users[data.User.Id, data.GuildId];
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
@@ -437,7 +442,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_MEMBER_REMOVE":
|
case "GUILD_MEMBER_REMOVE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MemberRemoveEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MemberRemoveEvent>(_dataSocketSerializer);
|
||||||
var user = _users.TryRemove(data.UserId, data.GuildId);
|
var user = _users.TryRemove(data.UserId, data.GuildId);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
RaiseUserLeft(user);
|
RaiseUserLeft(user);
|
||||||
@@ -445,7 +450,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_MEMBERS_CHUNK":
|
case "GUILD_MEMBERS_CHUNK":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MembersChunkEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MembersChunkEvent>(_dataSocketSerializer);
|
||||||
foreach (var memberData in data.Members)
|
foreach (var memberData in data.Members)
|
||||||
{
|
{
|
||||||
var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId);
|
var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId);
|
||||||
@@ -458,7 +463,7 @@ namespace Discord
|
|||||||
//Roles
|
//Roles
|
||||||
case "GUILD_ROLE_CREATE":
|
case "GUILD_ROLE_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<RoleCreateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<RoleCreateEvent>(_dataSocketSerializer);
|
||||||
var role = _roles.GetOrAdd(data.Data.Id, data.GuildId);
|
var role = _roles.GetOrAdd(data.Data.Id, data.GuildId);
|
||||||
role.Update(data.Data);
|
role.Update(data.Data);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.GuildId];
|
||||||
@@ -469,7 +474,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_ROLE_UPDATE":
|
case "GUILD_ROLE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<RoleUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<RoleUpdateEvent>(_dataSocketSerializer);
|
||||||
var role = _roles[data.Data.Id];
|
var role = _roles[data.Data.Id];
|
||||||
if (role != null)
|
if (role != null)
|
||||||
{
|
{
|
||||||
@@ -480,7 +485,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_ROLE_DELETE":
|
case "GUILD_ROLE_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<RoleDeleteEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<RoleDeleteEvent>(_dataSocketSerializer);
|
||||||
var role = _roles.TryRemove(data.RoleId);
|
var role = _roles.TryRemove(data.RoleId);
|
||||||
if (role != null)
|
if (role != null)
|
||||||
{
|
{
|
||||||
@@ -495,7 +500,7 @@ namespace Discord
|
|||||||
//Bans
|
//Bans
|
||||||
case "GUILD_BAN_ADD":
|
case "GUILD_BAN_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<BanAddEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<BanAddEvent>(_dataSocketSerializer);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.GuildId];
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
@@ -507,7 +512,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "GUILD_BAN_REMOVE":
|
case "GUILD_BAN_REMOVE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<BanRemoveEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<BanRemoveEvent>(_dataSocketSerializer);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.GuildId];
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
@@ -521,7 +526,7 @@ namespace Discord
|
|||||||
//Messages
|
//Messages
|
||||||
case "MESSAGE_CREATE":
|
case "MESSAGE_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MessageCreateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MessageCreateEvent>(_dataSocketSerializer);
|
||||||
Message msg = null;
|
Message msg = null;
|
||||||
|
|
||||||
bool isAuthor = data.Author.Id == _userId;
|
bool isAuthor = data.Author.Id == _userId;
|
||||||
@@ -548,7 +553,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "MESSAGE_UPDATE":
|
case "MESSAGE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MessageUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MessageUpdateEvent>(_dataSocketSerializer);
|
||||||
var msg = _messages[data.Id];
|
var msg = _messages[data.Id];
|
||||||
if (msg != null)
|
if (msg != null)
|
||||||
{
|
{
|
||||||
@@ -559,7 +564,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "MESSAGE_DELETE":
|
case "MESSAGE_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MessageDeleteEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MessageDeleteEvent>(_dataSocketSerializer);
|
||||||
var msg = _messages.TryRemove(data.Id);
|
var msg = _messages.TryRemove(data.Id);
|
||||||
if (msg != null)
|
if (msg != null)
|
||||||
RaiseMessageDeleted(msg);
|
RaiseMessageDeleted(msg);
|
||||||
@@ -567,7 +572,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "MESSAGE_ACK":
|
case "MESSAGE_ACK":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MessageAckEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MessageAckEvent>(_dataSocketSerializer);
|
||||||
var msg = GetMessage(data.MessageId);
|
var msg = GetMessage(data.MessageId);
|
||||||
if (msg != null)
|
if (msg != null)
|
||||||
RaiseMessageReadRemotely(msg);
|
RaiseMessageReadRemotely(msg);
|
||||||
@@ -577,7 +582,7 @@ namespace Discord
|
|||||||
//Statuses
|
//Statuses
|
||||||
case "PRESENCE_UPDATE":
|
case "PRESENCE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<PresenceUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<PresenceUpdateEvent>(_dataSocketSerializer);
|
||||||
var user = _users.GetOrAdd(data.User.Id, data.GuildId);
|
var user = _users.GetOrAdd(data.User.Id, data.GuildId);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
@@ -588,7 +593,7 @@ namespace Discord
|
|||||||
break;
|
break;
|
||||||
case "TYPING_START":
|
case "TYPING_START":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<TypingStartEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<TypingStartEvent>(_dataSocketSerializer);
|
||||||
var channel = _channels[data.ChannelId];
|
var channel = _channels[data.ChannelId];
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
{
|
{
|
||||||
@@ -614,7 +619,7 @@ namespace Discord
|
|||||||
//Voice
|
//Voice
|
||||||
case "VOICE_STATE_UPDATE":
|
case "VOICE_STATE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<MemberVoiceStateUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<MemberVoiceStateUpdateEvent>(_dataSocketSerializer);
|
||||||
var user = _users[data.UserId, data.GuildId];
|
var user = _users[data.UserId, data.GuildId];
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
@@ -633,7 +638,7 @@ namespace Discord
|
|||||||
//Settings
|
//Settings
|
||||||
case "USER_UPDATE":
|
case "USER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<UserUpdateEvent>(_socketSerializer);
|
var data = e.Payload.ToObject<UserUpdateEvent>(_dataSocketSerializer);
|
||||||
var user = _globalUsers[data.Id];
|
var user = _globalUsers[data.Id];
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
using Discord.Net.WebSockets;
|
using Discord.Net.WebSockets;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -23,9 +24,9 @@ namespace Discord
|
|||||||
protected readonly DiscordWSClientConfig _config;
|
protected readonly DiscordWSClientConfig _config;
|
||||||
protected readonly ManualResetEvent _disconnectedEvent;
|
protected readonly ManualResetEvent _disconnectedEvent;
|
||||||
protected readonly ManualResetEventSlim _connectedEvent;
|
protected readonly ManualResetEventSlim _connectedEvent;
|
||||||
|
protected ExceptionDispatchInfo _disconnectReason;
|
||||||
internal readonly DataWebSocket _dataSocket;
|
internal readonly DataWebSocket _dataSocket;
|
||||||
internal readonly VoiceWebSocket _voiceSocket;
|
internal readonly VoiceWebSocket _voiceSocket;
|
||||||
protected ExceptionDispatchInfo _disconnectReason;
|
|
||||||
protected string _gateway, _token;
|
protected string _gateway, _token;
|
||||||
protected long? _userId, _voiceServerId;
|
protected long? _userId, _voiceServerId;
|
||||||
private Task _runTask;
|
private Task _runTask;
|
||||||
@@ -44,6 +45,10 @@ namespace Discord
|
|||||||
private CancellationTokenSource _cancelTokenSource;
|
private CancellationTokenSource _cancelTokenSource;
|
||||||
protected CancellationToken _cancelToken;
|
protected CancellationToken _cancelToken;
|
||||||
|
|
||||||
|
internal JsonSerializer DataSocketSerializer => _dataSocketSerializer;
|
||||||
|
internal JsonSerializer VoiceSocketSerializer => _voiceSocketSerializer;
|
||||||
|
protected readonly JsonSerializer _dataSocketSerializer, _voiceSocketSerializer;
|
||||||
|
|
||||||
/// <summary> Initializes a new instance of the DiscordClient class. </summary>
|
/// <summary> Initializes a new instance of the DiscordClient class. </summary>
|
||||||
public DiscordWSClient(DiscordWSClientConfig config = null)
|
public DiscordWSClient(DiscordWSClientConfig config = null)
|
||||||
{
|
{
|
||||||
@@ -55,6 +60,32 @@ namespace Discord
|
|||||||
_disconnectedEvent = new ManualResetEvent(true);
|
_disconnectedEvent = new ManualResetEvent(true);
|
||||||
_connectedEvent = new ManualResetEventSlim(false);
|
_connectedEvent = new ManualResetEventSlim(false);
|
||||||
|
|
||||||
|
_dataSocketSerializer = new JsonSerializer();
|
||||||
|
_dataSocketSerializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
||||||
|
#if TEST_RESPONSES
|
||||||
|
_dataSocketSerializer.CheckAdditionalContent = true;
|
||||||
|
_dataSocketSerializer.MissingMemberHandling = MissingMemberHandling.Error;
|
||||||
|
#else
|
||||||
|
_dataSocketSerializer.Error += (s, e) =>
|
||||||
|
{
|
||||||
|
e.ErrorContext.Handled = true;
|
||||||
|
RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.DataWebSocket, "Serialization Failed", e.ErrorContext.Error);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_voiceSocketSerializer = new JsonSerializer();
|
||||||
|
_voiceSocketSerializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
|
||||||
|
#if TEST_RESPONSES
|
||||||
|
_voiceSocketSerializer.CheckAdditionalContent = true;
|
||||||
|
_voiceSocketSerializer.MissingMemberHandling = MissingMemberHandling.Error;
|
||||||
|
#else
|
||||||
|
_voiceSocketSerializer.Error += (s, e) =>
|
||||||
|
{
|
||||||
|
e.ErrorContext.Handled = true;
|
||||||
|
RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.VoiceWebSocket, "Serialization Failed", e.ErrorContext.Error);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
_dataSocket = CreateDataSocket();
|
_dataSocket = CreateDataSocket();
|
||||||
if (_config.EnableVoice)
|
if (_config.EnableVoice)
|
||||||
_voiceSocket = CreateVoiceSocket();
|
_voiceSocket = CreateVoiceSocket();
|
||||||
|
|||||||
@@ -84,15 +84,21 @@ namespace Discord
|
|||||||
|
|
||||||
lock (_writerLock)
|
lock (_writerLock)
|
||||||
{
|
{
|
||||||
TValue newItem = createFunc();
|
if (!_dictionary.ContainsKey(key))
|
||||||
result = _dictionary.GetOrAdd(key, newItem);
|
|
||||||
if (result == newItem)
|
|
||||||
{
|
{
|
||||||
result.Cache();
|
result = createFunc();
|
||||||
RaiseItemCreated(result);
|
if (result.Cache())
|
||||||
|
{
|
||||||
|
_dictionary.TryAdd(key, result);
|
||||||
|
RaiseItemCreated(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result.Uncache();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return _dictionary[key];
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
protected void Import(IEnumerable<KeyValuePair<TKey, TValue>> items)
|
protected void Import(IEnumerable<KeyValuePair<TKey, TValue>> items)
|
||||||
{
|
{
|
||||||
@@ -101,9 +107,13 @@ namespace Discord
|
|||||||
foreach (var pair in items)
|
foreach (var pair in items)
|
||||||
{
|
{
|
||||||
var value = pair.Value;
|
var value = pair.Value;
|
||||||
_dictionary.TryAdd(pair.Key, value);
|
if (value.Cache())
|
||||||
value.Cache();
|
{
|
||||||
RaiseItemCreated(value);
|
_dictionary.TryAdd(pair.Key, value);
|
||||||
|
RaiseItemCreated(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value.Uncache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,14 @@ namespace Discord
|
|||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Cache()
|
internal bool Cache()
|
||||||
{
|
{
|
||||||
LoadReferences();
|
if (LoadReferences())
|
||||||
_isCached = true;
|
{
|
||||||
|
_isCached = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
internal void Uncache()
|
internal void Uncache()
|
||||||
{
|
{
|
||||||
@@ -44,7 +48,7 @@ namespace Discord
|
|||||||
_isCached = false;
|
_isCached = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal abstract void LoadReferences();
|
internal abstract bool LoadReferences();
|
||||||
internal abstract void UnloadReferences();
|
internal abstract void UnloadReferences();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Load()
|
public bool Load()
|
||||||
{
|
{
|
||||||
return Value; //Used for precaching
|
return Value != null; //Used for precaching
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unload()
|
public void Unload()
|
||||||
|
|||||||
@@ -124,12 +124,12 @@ namespace Discord
|
|||||||
if (client.Config.MessageCacheLength > 0)
|
if (client.Config.MessageCacheLength > 0)
|
||||||
_messages = new ConcurrentDictionary<long, Message>();
|
_messages = new ConcurrentDictionary<long, Message>();
|
||||||
}
|
}
|
||||||
internal override void LoadReferences()
|
internal override bool LoadReferences()
|
||||||
{
|
{
|
||||||
if (IsPrivate)
|
if (IsPrivate)
|
||||||
_recipient.Load();
|
return _recipient.Load();
|
||||||
else
|
else
|
||||||
_server.Load();
|
return _server.Load();
|
||||||
}
|
}
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
_users = new ConcurrentDictionary<long, User>();
|
_users = new ConcurrentDictionary<long, User>();
|
||||||
}
|
}
|
||||||
internal override void LoadReferences() { }
|
internal override bool LoadReferences() { return true; }
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
//Don't need to clean _users - they're considered owned by server
|
//Don't need to clean _users - they're considered owned by server
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
XkcdCode = xkcdPass;
|
XkcdCode = xkcdPass;
|
||||||
}
|
}
|
||||||
internal override void LoadReferences() { }
|
internal override bool LoadReferences() { return true; }
|
||||||
internal override void UnloadReferences() { }
|
internal override void UnloadReferences() { }
|
||||||
|
|
||||||
internal void Update(InviteReference model)
|
internal void Update(InviteReference model)
|
||||||
|
|||||||
@@ -15,24 +15,25 @@ namespace Discord
|
|||||||
Queued,
|
Queued,
|
||||||
Failed
|
Failed
|
||||||
}
|
}
|
||||||
internal class MessageImporterResolver : DefaultContractResolver
|
|
||||||
{
|
|
||||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
|
||||||
{
|
|
||||||
var property = base.CreateProperty(member, memberSerialization);
|
|
||||||
if (member is PropertyInfo)
|
|
||||||
{
|
|
||||||
if (!(member as PropertyInfo).CanWrite)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
property.Writable = true; //Handles private setters
|
|
||||||
}
|
|
||||||
return property;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class Message : CachedObject<long>
|
public sealed class Message : CachedObject<long>
|
||||||
{
|
{
|
||||||
|
internal class ImportResolver : DefaultContractResolver
|
||||||
|
{
|
||||||
|
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||||
|
{
|
||||||
|
var property = base.CreateProperty(member, memberSerialization);
|
||||||
|
if (member is PropertyInfo)
|
||||||
|
{
|
||||||
|
if (member.Name == nameof(ChannelId) || !(member as PropertyInfo).CanWrite)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
property.Writable = true; //Handles private setters
|
||||||
|
}
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class Attachment : File
|
public sealed class Attachment : File
|
||||||
{
|
{
|
||||||
/// <summary> Unique identifier for this file. </summary>
|
/// <summary> Unique identifier for this file. </summary>
|
||||||
@@ -173,6 +174,8 @@ namespace Discord
|
|||||||
x =>
|
x =>
|
||||||
{
|
{
|
||||||
var channel = Channel;
|
var channel = Channel;
|
||||||
|
if (channel == null) return null;
|
||||||
|
|
||||||
if (!channel.IsPrivate)
|
if (!channel.IsPrivate)
|
||||||
return _client.Users[x, channel.Server.Id];
|
return _client.Users[x, channel.Server.Id];
|
||||||
else
|
else
|
||||||
@@ -181,10 +184,9 @@ namespace Discord
|
|||||||
Attachments = _initialAttachments;
|
Attachments = _initialAttachments;
|
||||||
Embeds = _initialEmbeds;
|
Embeds = _initialEmbeds;
|
||||||
}
|
}
|
||||||
internal override void LoadReferences()
|
internal override bool LoadReferences()
|
||||||
{
|
{
|
||||||
_channel.Load();
|
return _channel.Load() && _user.Load();
|
||||||
_user.Load();
|
|
||||||
}
|
}
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
|
|||||||
10
src/Discord.Net/Models/Region.cs
Normal file
10
src/Discord.Net/Models/Region.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
public sealed class Region
|
||||||
|
{
|
||||||
|
public string Hostname;
|
||||||
|
public int Port;
|
||||||
|
public string Id;
|
||||||
|
public string Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,9 +47,9 @@ namespace Discord
|
|||||||
Color = new Color(0);
|
Color = new Color(0);
|
||||||
Color.Lock();
|
Color.Lock();
|
||||||
}
|
}
|
||||||
internal override void LoadReferences()
|
internal override bool LoadReferences()
|
||||||
{
|
{
|
||||||
_server.Load();
|
return _server.Load();
|
||||||
}
|
}
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,9 +103,10 @@ namespace Discord
|
|||||||
//Local Cache
|
//Local Cache
|
||||||
_bans = new ConcurrentDictionary<long, bool>();
|
_bans = new ConcurrentDictionary<long, bool>();
|
||||||
}
|
}
|
||||||
internal override void LoadReferences()
|
internal override bool LoadReferences()
|
||||||
{
|
{
|
||||||
_afkChannel.Load();
|
_afkChannel.Load();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -148,10 +148,10 @@ namespace Discord
|
|||||||
if (serverId == null)
|
if (serverId == null)
|
||||||
UpdateRoles(null);
|
UpdateRoles(null);
|
||||||
}
|
}
|
||||||
internal override void LoadReferences()
|
internal override bool LoadReferences()
|
||||||
{
|
{
|
||||||
_globalUser.Load();
|
return _globalUser.Load() &&
|
||||||
_server.Load();
|
(IsPrivate || _server.Load());
|
||||||
}
|
}
|
||||||
internal override void UnloadReferences()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Discord.Net.Rest
|
|||||||
{
|
{
|
||||||
PreAuthenticate = false,
|
PreAuthenticate = false,
|
||||||
ReadWriteTimeout = _config.APITimeout,
|
ReadWriteTimeout = _config.APITimeout,
|
||||||
UserAgent = _config.UserAgent
|
UserAgent = DiscordAPIClientConfig.UserAgent
|
||||||
};
|
};
|
||||||
if (_config.ProxyUrl != null)
|
if (_config.ProxyUrl != null)
|
||||||
_client.Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials);
|
_client.Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials);
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ namespace Discord.Net.WebSockets
|
|||||||
JToken token = msg.Payload as JToken;
|
JToken token = msg.Payload as JToken;
|
||||||
if (msg.Type == "READY")
|
if (msg.Type == "READY")
|
||||||
{
|
{
|
||||||
var payload = token.ToObject<ReadyEvent>();
|
var payload = token.ToObject<ReadyEvent>(_client.DataSocketSerializer);
|
||||||
_sessionId = payload.SessionId;
|
_sessionId = payload.SessionId;
|
||||||
_heartbeatInterval = payload.HeartbeatInterval;
|
_heartbeatInterval = payload.HeartbeatInterval;
|
||||||
}
|
}
|
||||||
else if (msg.Type == "RESUMED")
|
else if (msg.Type == "RESUMED")
|
||||||
{
|
{
|
||||||
var payload = token.ToObject<ResumedEvent>();
|
var payload = token.ToObject<ResumedEvent>(_client.DataSocketSerializer);
|
||||||
_heartbeatInterval = payload.HeartbeatInterval;
|
_heartbeatInterval = payload.HeartbeatInterval;
|
||||||
}
|
}
|
||||||
RaiseReceivedEvent(msg.Type, token);
|
RaiseReceivedEvent(msg.Type, token);
|
||||||
@@ -98,7 +98,7 @@ namespace Discord.Net.WebSockets
|
|||||||
break;
|
break;
|
||||||
case 7: //Redirect
|
case 7: //Redirect
|
||||||
{
|
{
|
||||||
var payload = (msg.Payload as JToken).ToObject<RedirectEvent>();
|
var payload = (msg.Payload as JToken).ToObject<RedirectEvent>(_client.DataSocketSerializer);
|
||||||
if (payload.Url != null)
|
if (payload.Url != null)
|
||||||
{
|
{
|
||||||
Host = payload.Url;
|
Host = payload.Url;
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ namespace Discord.Net.WebSockets
|
|||||||
{
|
{
|
||||||
if (_state != (int)WebSocketState.Connected)
|
if (_state != (int)WebSocketState.Connected)
|
||||||
{
|
{
|
||||||
var payload = (msg.Payload as JToken).ToObject<VoiceReadyEvent>();
|
var payload = (msg.Payload as JToken).ToObject<VoiceReadyEvent>(_client.VoiceSocketSerializer);
|
||||||
_heartbeatInterval = payload.HeartbeatInterval;
|
_heartbeatInterval = payload.HeartbeatInterval;
|
||||||
_ssrc = payload.SSRC;
|
_ssrc = payload.SSRC;
|
||||||
_endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port);
|
_endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port);
|
||||||
@@ -486,7 +486,7 @@ namespace Discord.Net.WebSockets
|
|||||||
break;
|
break;
|
||||||
case 4: //SESSION_DESCRIPTION
|
case 4: //SESSION_DESCRIPTION
|
||||||
{
|
{
|
||||||
var payload = (msg.Payload as JToken).ToObject<JoinServerEvent>();
|
var payload = (msg.Payload as JToken).ToObject<JoinServerEvent>(_client.VoiceSocketSerializer);
|
||||||
_secretKey = payload.SecretKey;
|
_secretKey = payload.SecretKey;
|
||||||
SendIsTalking(true);
|
SendIsTalking(true);
|
||||||
EndConnect();
|
EndConnect();
|
||||||
@@ -494,7 +494,7 @@ namespace Discord.Net.WebSockets
|
|||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
{
|
{
|
||||||
var payload = (msg.Payload as JToken).ToObject<IsTalkingEvent>();
|
var payload = (msg.Payload as JToken).ToObject<IsTalkingEvent>(_client.VoiceSocketSerializer);
|
||||||
RaiseIsSpeaking(payload.UserId, payload.IsSpeaking);
|
RaiseIsSpeaking(payload.UserId, payload.IsSpeaking);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user