diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 1f001d361..3dbcfef5c 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -94,9 +94,6 @@ API\Enums\PermissionTarget.cs - - API\Enums\Region.cs - API\Enums\StringEnum.cs @@ -259,6 +256,9 @@ Models\Permissions.cs + + Models\Region.cs + Models\Role.cs diff --git a/src/Discord.Net/API/Converters/StringEnumConverter.cs b/src/Discord.Net/API/Converters/StringEnumConverter.cs new file mode 100644 index 000000000..251c5ff05 --- /dev/null +++ b/src/Discord.Net/API/Converters/StringEnumConverter.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Discord.API.Converters +{ + public class StringEnumConverter + { + } +} diff --git a/src/Discord.Net/DiscordAPIClientConfig.cs b/src/Discord.Net/DiscordAPIClientConfig.cs index 0fde36c2c..9fb036f7d 100644 --- a/src/Discord.Net/DiscordAPIClientConfig.cs +++ b/src/Discord.Net/DiscordAPIClientConfig.cs @@ -6,6 +6,8 @@ namespace Discord { public class DiscordAPIClientConfig { + internal static readonly string UserAgent = $"Discord.Net/{DiscordClient.Version} (https://github.com/RogueException/Discord.Net)"; + /// 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. public LogMessageSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } } private LogMessageSeverity _logLevel = LogMessageSeverity.Info; @@ -21,15 +23,6 @@ namespace Discord public NetworkCredential ProxyCredentials { get { return _proxyCredentials; } set { SetValue(ref _proxyCredentials, value); } } 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 protected bool _isLocked; internal void Lock() { _isLocked = true; } diff --git a/src/Discord.Net/DiscordClient.Messages.cs b/src/Discord.Net/DiscordClient.Messages.cs index 19bbdef18..f8fa09eb8 100644 --- a/src/Discord.Net/DiscordClient.Messages.cs +++ b/src/Discord.Net/DiscordClient.Messages.cs @@ -261,7 +261,7 @@ namespace Discord } /// Deserializes messages from JSON format and imports them into the message cache. - public IEnumerable ImportMessages(string json) + public IEnumerable ImportMessages(Channel channel, string json) { if (json == null) throw new ArgumentNullException(nameof(json)); @@ -269,8 +269,8 @@ namespace Discord .Select(x => { var msg = new Message(this, - x["Id"].Value(), - x["ChannelId"].Value(), + x["Id"].Value(), + channel.Id, x["UserId"].Value()); var reader = x.CreateReader(); diff --git a/src/Discord.Net/DiscordClient.Servers.cs b/src/Discord.Net/DiscordClient.Servers.cs index 889c5879e..b52901fa0 100644 --- a/src/Discord.Net/DiscordClient.Servers.cs +++ b/src/Discord.Net/DiscordClient.Servers.cs @@ -86,19 +86,19 @@ namespace Discord if (region == null) throw new ArgumentNullException(nameof(region)); 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); server.Update(response); return server; } /// Edits the provided server, changing only non-null attributes. - 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)); 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); } @@ -112,5 +112,12 @@ namespace Discord catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } //return _servers.TryRemove(server.Id); } + + public async Task> GetVoiceRegions() + { + CheckReady(); + + return (await _api.GetVoiceRegions()).Select(x => new Region { Id = x.Id, Name = x.Name, Hostname = x.Hostname, Port = x.Port }); + } } } \ No newline at end of file diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index c9ef3366b..12e246ea6 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Threading.Tasks; namespace Discord @@ -12,12 +13,14 @@ namespace Discord /// Provides a connection to the DiscordApp service. 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 Random _rand; - private readonly JsonSerializer _socketSerializer, _messageImporter; + private readonly JsonSerializer _messageImporter; private readonly ConcurrentQueue _pendingMessages; private readonly ConcurrentDictionary _voiceClients; - private readonly Dictionary _services; + private readonly Dictionary _singletons; private bool _sentInitialLog; private uint _nextVoiceClientId; private UserStatus _status; @@ -47,7 +50,7 @@ namespace Discord _roles = new Roles(this, cacheLock); _servers = new Servers(this, cacheLock); _globalUsers = new GlobalUsers(this, cacheLock); - _services = new Dictionary(); + _singletons = new Dictionary(); _status = UserStatus.Online; @@ -162,16 +165,9 @@ namespace Discord if (Config.UseMessageQueue) _pendingMessages = new ConcurrentQueue(); - - _socketSerializer = new JsonSerializer(); - _socketSerializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; -#if TEST_RESPONSES - _serializer.CheckAdditionalContent = true; - _serializer.MissingMemberHandling = MissingMemberHandling.Error; -#endif - + _messageImporter = new JsonSerializer(); - _messageImporter.ContractResolver = new MessageImporterResolver(); + _messageImporter.ContractResolver = new Message.ImportResolver(); } internal override VoiceWebSocket CreateVoiceSocket() { @@ -276,25 +272,34 @@ namespace Discord _privateUser = null; } + public T AddSingleton(T obj) + where T : class + { + _singletons.Add(typeof(T), obj); + return obj; + } + public T GetSingleton(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 obj) where T : class, IService { - _services.Add(typeof(T), obj); + AddSingleton(obj); obj.Install(this); return obj; } public T GetService(bool required = true) where T : class, IService - { - 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; - } + => GetSingleton(required); protected override IEnumerable GetTasks() { @@ -314,7 +319,7 @@ namespace Discord case "READY": //Resync { base.OnReceivedEvent(e).Wait(); //This cannot be an await, or we'll get later messages before we're ready - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); _privateUser = _users.GetOrAdd(data.User.Id, null); _privateUser.Update(data.User); _privateUser.Global.Update(data.User); @@ -339,7 +344,7 @@ namespace Discord //Servers case "GUILD_CREATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); if (data.Unavailable != true) { var server = _servers.GetOrAdd(data.Id); @@ -353,7 +358,7 @@ namespace Discord break; case "GUILD_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var server = _servers[data.Id]; if (server != null) { @@ -364,7 +369,7 @@ namespace Discord break; case "GUILD_DELETE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var server = _servers.TryRemove(data.Id); if (server != null) { @@ -379,7 +384,7 @@ namespace Discord //Channels case "CHANNEL_CREATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); Channel channel; if (data.IsPrivate) { @@ -395,7 +400,7 @@ namespace Discord break; case "CHANNEL_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var channel = _channels[data.Id]; if (channel != null) { @@ -406,7 +411,7 @@ namespace Discord break; case "CHANNEL_DELETE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var channel = _channels.TryRemove(data.Id); if (channel != null) RaiseChannelDestroyed(channel); @@ -416,7 +421,7 @@ namespace Discord //Members case "GUILD_MEMBER_ADD": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _users.GetOrAdd(data.User.Id, data.GuildId); user.Update(data); if (Config.TrackActivity) @@ -426,7 +431,7 @@ namespace Discord break; case "GUILD_MEMBER_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _users[data.User.Id, data.GuildId]; if (user != null) { @@ -437,7 +442,7 @@ namespace Discord break; case "GUILD_MEMBER_REMOVE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _users.TryRemove(data.UserId, data.GuildId); if (user != null) RaiseUserLeft(user); @@ -445,7 +450,7 @@ namespace Discord break; case "GUILD_MEMBERS_CHUNK": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); foreach (var memberData in data.Members) { var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId); @@ -458,7 +463,7 @@ namespace Discord //Roles case "GUILD_ROLE_CREATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var role = _roles.GetOrAdd(data.Data.Id, data.GuildId); role.Update(data.Data); var server = _servers[data.GuildId]; @@ -469,7 +474,7 @@ namespace Discord break; case "GUILD_ROLE_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var role = _roles[data.Data.Id]; if (role != null) { @@ -480,7 +485,7 @@ namespace Discord break; case "GUILD_ROLE_DELETE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var role = _roles.TryRemove(data.RoleId); if (role != null) { @@ -495,7 +500,7 @@ namespace Discord //Bans case "GUILD_BAN_ADD": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var server = _servers[data.GuildId]; if (server != null) { @@ -507,7 +512,7 @@ namespace Discord break; case "GUILD_BAN_REMOVE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var server = _servers[data.GuildId]; if (server != null) { @@ -521,7 +526,7 @@ namespace Discord //Messages case "MESSAGE_CREATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); Message msg = null; bool isAuthor = data.Author.Id == _userId; @@ -548,7 +553,7 @@ namespace Discord break; case "MESSAGE_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var msg = _messages[data.Id]; if (msg != null) { @@ -559,7 +564,7 @@ namespace Discord break; case "MESSAGE_DELETE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var msg = _messages.TryRemove(data.Id); if (msg != null) RaiseMessageDeleted(msg); @@ -567,7 +572,7 @@ namespace Discord break; case "MESSAGE_ACK": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var msg = GetMessage(data.MessageId); if (msg != null) RaiseMessageReadRemotely(msg); @@ -577,7 +582,7 @@ namespace Discord //Statuses case "PRESENCE_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _users.GetOrAdd(data.User.Id, data.GuildId); if (user != null) { @@ -588,7 +593,7 @@ namespace Discord break; case "TYPING_START": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var channel = _channels[data.ChannelId]; if (channel != null) { @@ -614,7 +619,7 @@ namespace Discord //Voice case "VOICE_STATE_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _users[data.UserId, data.GuildId]; if (user != null) { @@ -633,7 +638,7 @@ namespace Discord //Settings case "USER_UPDATE": { - var data = e.Payload.ToObject(_socketSerializer); + var data = e.Payload.ToObject(_dataSocketSerializer); var user = _globalUsers[data.Id]; if (user != null) { diff --git a/src/Discord.Net/DiscordWSClient.cs b/src/Discord.Net/DiscordWSClient.cs index d79cdf7a5..14f020fda 100644 --- a/src/Discord.Net/DiscordWSClient.cs +++ b/src/Discord.Net/DiscordWSClient.cs @@ -1,5 +1,6 @@ using Discord.Net; using Discord.Net.WebSockets; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -23,9 +24,9 @@ namespace Discord protected readonly DiscordWSClientConfig _config; protected readonly ManualResetEvent _disconnectedEvent; protected readonly ManualResetEventSlim _connectedEvent; + protected ExceptionDispatchInfo _disconnectReason; internal readonly DataWebSocket _dataSocket; internal readonly VoiceWebSocket _voiceSocket; - protected ExceptionDispatchInfo _disconnectReason; protected string _gateway, _token; protected long? _userId, _voiceServerId; private Task _runTask; @@ -44,6 +45,10 @@ namespace Discord private CancellationTokenSource _cancelTokenSource; protected CancellationToken _cancelToken; + internal JsonSerializer DataSocketSerializer => _dataSocketSerializer; + internal JsonSerializer VoiceSocketSerializer => _voiceSocketSerializer; + protected readonly JsonSerializer _dataSocketSerializer, _voiceSocketSerializer; + /// Initializes a new instance of the DiscordClient class. public DiscordWSClient(DiscordWSClientConfig config = null) { @@ -55,6 +60,32 @@ namespace Discord _disconnectedEvent = new ManualResetEvent(true); _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(); if (_config.EnableVoice) _voiceSocket = CreateVoiceSocket(); diff --git a/src/Discord.Net/Helpers/AsyncCollection.cs b/src/Discord.Net/Helpers/AsyncCollection.cs index 1035a45d2..f173eaefb 100644 --- a/src/Discord.Net/Helpers/AsyncCollection.cs +++ b/src/Discord.Net/Helpers/AsyncCollection.cs @@ -84,15 +84,21 @@ namespace Discord lock (_writerLock) { - TValue newItem = createFunc(); - result = _dictionary.GetOrAdd(key, newItem); - if (result == newItem) + if (!_dictionary.ContainsKey(key)) { - result.Cache(); - RaiseItemCreated(result); + result = createFunc(); + if (result.Cache()) + { + _dictionary.TryAdd(key, result); + RaiseItemCreated(result); + } + else + result.Uncache(); + return result; } + else + return _dictionary[key]; } - return result; } protected void Import(IEnumerable> items) { @@ -101,9 +107,13 @@ namespace Discord foreach (var pair in items) { var value = pair.Value; - _dictionary.TryAdd(pair.Key, value); - value.Cache(); - RaiseItemCreated(value); + if (value.Cache()) + { + _dictionary.TryAdd(pair.Key, value); + RaiseItemCreated(value); + } + else + value.Uncache(); } } } diff --git a/src/Discord.Net/Helpers/CachedObject.cs b/src/Discord.Net/Helpers/CachedObject.cs index d0232b91a..dcd3b3c4a 100644 --- a/src/Discord.Net/Helpers/CachedObject.cs +++ b/src/Discord.Net/Helpers/CachedObject.cs @@ -31,10 +31,14 @@ namespace Discord _client = client; } - internal void Cache() + internal bool Cache() { - LoadReferences(); - _isCached = true; + if (LoadReferences()) + { + _isCached = true; + return true; + } + return false; } internal void Uncache() { @@ -44,7 +48,7 @@ namespace Discord _isCached = false; } } - internal abstract void LoadReferences(); + internal abstract bool LoadReferences(); internal abstract void UnloadReferences(); } } diff --git a/src/Discord.Net/Helpers/Reference.cs b/src/Discord.Net/Helpers/Reference.cs index ff9aa79ae..3ea7705e8 100644 --- a/src/Discord.Net/Helpers/Reference.cs +++ b/src/Discord.Net/Helpers/Reference.cs @@ -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() diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index ce9db815b..b2233aa20 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -124,12 +124,12 @@ namespace Discord if (client.Config.MessageCacheLength > 0) _messages = new ConcurrentDictionary(); } - internal override void LoadReferences() + internal override bool LoadReferences() { if (IsPrivate) - _recipient.Load(); + return _recipient.Load(); else - _server.Load(); + return _server.Load(); } internal override void UnloadReferences() { diff --git a/src/Discord.Net/Models/GlobalUser.cs b/src/Discord.Net/Models/GlobalUser.cs index f43fef90b..016f522e0 100644 --- a/src/Discord.Net/Models/GlobalUser.cs +++ b/src/Discord.Net/Models/GlobalUser.cs @@ -44,7 +44,7 @@ namespace Discord { _users = new ConcurrentDictionary(); } - internal override void LoadReferences() { } + internal override bool LoadReferences() { return true; } internal override void UnloadReferences() { //Don't need to clean _users - they're considered owned by server diff --git a/src/Discord.Net/Models/Invite.cs b/src/Discord.Net/Models/Invite.cs index 4601dadf5..a89da9abc 100644 --- a/src/Discord.Net/Models/Invite.cs +++ b/src/Discord.Net/Models/Invite.cs @@ -82,7 +82,7 @@ namespace Discord { XkcdCode = xkcdPass; } - internal override void LoadReferences() { } + internal override bool LoadReferences() { return true; } internal override void UnloadReferences() { } internal void Update(InviteReference model) diff --git a/src/Discord.Net/Models/Message.cs b/src/Discord.Net/Models/Message.cs index 0fd2fd057..2c1c0731c 100644 --- a/src/Discord.Net/Models/Message.cs +++ b/src/Discord.Net/Models/Message.cs @@ -15,24 +15,25 @@ namespace Discord Queued, Failed } - internal class MessageImporterResolver : DefaultContractResolver + + public sealed class Message : CachedObject { - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + internal class ImportResolver : DefaultContractResolver { - var property = base.CreateProperty(member, memberSerialization); - if (member is PropertyInfo) + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { - if (!(member as PropertyInfo).CanWrite) - return null; + 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 + property.Writable = true; //Handles private setters + } + return property; } - return property; } - } - public sealed class Message : CachedObject - { public sealed class Attachment : File { /// Unique identifier for this file. @@ -173,6 +174,8 @@ namespace Discord x => { var channel = Channel; + if (channel == null) return null; + if (!channel.IsPrivate) return _client.Users[x, channel.Server.Id]; else @@ -181,10 +184,9 @@ namespace Discord Attachments = _initialAttachments; Embeds = _initialEmbeds; } - internal override void LoadReferences() + internal override bool LoadReferences() { - _channel.Load(); - _user.Load(); + return _channel.Load() && _user.Load(); } internal override void UnloadReferences() { diff --git a/src/Discord.Net/Models/Region.cs b/src/Discord.Net/Models/Region.cs new file mode 100644 index 000000000..f37d6949e --- /dev/null +++ b/src/Discord.Net/Models/Region.cs @@ -0,0 +1,10 @@ +namespace Discord +{ + public sealed class Region + { + public string Hostname; + public int Port; + public string Id; + public string Name; + } +} diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 420edec27..285cc59f3 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -47,9 +47,9 @@ namespace Discord Color = new Color(0); Color.Lock(); } - internal override void LoadReferences() + internal override bool LoadReferences() { - _server.Load(); + return _server.Load(); } internal override void UnloadReferences() { diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index a403e2cc5..50236161a 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -103,9 +103,10 @@ namespace Discord //Local Cache _bans = new ConcurrentDictionary(); } - internal override void LoadReferences() + internal override bool LoadReferences() { _afkChannel.Load(); + return true; } internal override void UnloadReferences() { diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index c0c02a835..2fe2e95c7 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -148,10 +148,10 @@ namespace Discord if (serverId == null) UpdateRoles(null); } - internal override void LoadReferences() + internal override bool LoadReferences() { - _globalUser.Load(); - _server.Load(); + return _globalUser.Load() && + (IsPrivate || _server.Load()); } internal override void UnloadReferences() { diff --git a/src/Discord.Net/Net/Rest/SharpRestEngine.cs b/src/Discord.Net/Net/Rest/SharpRestEngine.cs index 64382eaca..2dfc0780d 100644 --- a/src/Discord.Net/Net/Rest/SharpRestEngine.cs +++ b/src/Discord.Net/Net/Rest/SharpRestEngine.cs @@ -20,7 +20,7 @@ namespace Discord.Net.Rest { PreAuthenticate = false, ReadWriteTimeout = _config.APITimeout, - UserAgent = _config.UserAgent + UserAgent = DiscordAPIClientConfig.UserAgent }; if (_config.ProxyUrl != null) _client.Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials); diff --git a/src/Discord.Net/Net/WebSockets/DataWebSocket.cs b/src/Discord.Net/Net/WebSockets/DataWebSocket.cs index d8bcce68a..659cb26a0 100644 --- a/src/Discord.Net/Net/WebSockets/DataWebSocket.cs +++ b/src/Discord.Net/Net/WebSockets/DataWebSocket.cs @@ -82,13 +82,13 @@ namespace Discord.Net.WebSockets JToken token = msg.Payload as JToken; if (msg.Type == "READY") { - var payload = token.ToObject(); + var payload = token.ToObject(_client.DataSocketSerializer); _sessionId = payload.SessionId; _heartbeatInterval = payload.HeartbeatInterval; } else if (msg.Type == "RESUMED") { - var payload = token.ToObject(); + var payload = token.ToObject(_client.DataSocketSerializer); _heartbeatInterval = payload.HeartbeatInterval; } RaiseReceivedEvent(msg.Type, token); @@ -98,7 +98,7 @@ namespace Discord.Net.WebSockets break; case 7: //Redirect { - var payload = (msg.Payload as JToken).ToObject(); + var payload = (msg.Payload as JToken).ToObject(_client.DataSocketSerializer); if (payload.Url != null) { Host = payload.Url; diff --git a/src/Discord.Net/Net/WebSockets/VoiceWebSocket.cs b/src/Discord.Net/Net/WebSockets/VoiceWebSocket.cs index a060f78d1..37da540b8 100644 --- a/src/Discord.Net/Net/WebSockets/VoiceWebSocket.cs +++ b/src/Discord.Net/Net/WebSockets/VoiceWebSocket.cs @@ -443,7 +443,7 @@ namespace Discord.Net.WebSockets { if (_state != (int)WebSocketState.Connected) { - var payload = (msg.Payload as JToken).ToObject(); + var payload = (msg.Payload as JToken).ToObject(_client.VoiceSocketSerializer); _heartbeatInterval = payload.HeartbeatInterval; _ssrc = payload.SSRC; _endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port); @@ -486,7 +486,7 @@ namespace Discord.Net.WebSockets break; case 4: //SESSION_DESCRIPTION { - var payload = (msg.Payload as JToken).ToObject(); + var payload = (msg.Payload as JToken).ToObject(_client.VoiceSocketSerializer); _secretKey = payload.SecretKey; SendIsTalking(true); EndConnect(); @@ -494,7 +494,7 @@ namespace Discord.Net.WebSockets break; case 5: { - var payload = (msg.Payload as JToken).ToObject(); + var payload = (msg.Payload as JToken).ToObject(_client.VoiceSocketSerializer); RaiseIsSpeaking(payload.UserId, payload.IsSpeaking); } break;