@@ -35,7 +35,7 @@ namespace Discord.Commands | |||
return; | |||
//Ignore messages from ourselves | |||
if (e.Message.UserId == client.CurrentUserId) | |||
if (e.Message.User == client.CurrentUser) | |||
return; | |||
//Check for the command character | |||
@@ -248,7 +248,7 @@ namespace Discord | |||
SendMessageResponse response = null; | |||
try | |||
{ | |||
response = await _api.SendMessage(msg.Channel.Id, msg.RawText, msg.MentionIds, msg.Nonce, msg.IsTTS).ConfigureAwait(false); | |||
response = await _api.SendMessage(msg.Channel.Id, msg.RawText, msg.Mentions.Select(x => x.Id), msg.Nonce, msg.IsTTS).ConfigureAwait(false); | |||
} | |||
catch (WebException) { break; } | |||
catch (HttpException) { hasFailed = true; } | |||
@@ -61,8 +61,6 @@ namespace Discord | |||
internal Servers Servers => _servers; | |||
private readonly Servers _servers; | |||
public Server PMServer { get; } | |||
/// <summary> Returns the server with the specified id, or null if none was found. </summary> | |||
public Server GetServer(string id) => _servers[id]; | |||
@@ -29,7 +29,7 @@ namespace Discord | |||
RaiseEvent(nameof(UserRemoved), () => UserRemoved(this, new MemberEventArgs(member))); | |||
} | |||
public event EventHandler ProfileUpdated; | |||
private void RaiseProfileUpdated(GlobalUser user) | |||
private void RaiseProfileUpdated() | |||
{ | |||
if (ProfileUpdated != null) | |||
RaiseEvent(nameof(ProfileUpdated), () => ProfileUpdated(this, EventArgs.Empty)); | |||
@@ -7,40 +7,38 @@ namespace Discord | |||
public partial class DiscordClient | |||
{ | |||
public IDiscordVoiceClient GetVoiceClient(Server server) | |||
=> GetVoiceClient(server.Id); | |||
public IDiscordVoiceClient GetVoiceClient(string serverId) | |||
{ | |||
if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||
if (server.Id == null) throw new ArgumentNullException(nameof(server.Id)); | |||
if (!Config.EnableVoiceMultiserver) | |||
{ | |||
if (serverId == _voiceServerId) | |||
if (server.Id == _voiceServerId) | |||
return this; | |||
else | |||
return null; | |||
} | |||
DiscordWSClient client; | |||
if (_voiceClients.TryGetValue(serverId, out client)) | |||
if (_voiceClients.TryGetValue(server.Id, out client)) | |||
return client; | |||
else | |||
return null; | |||
} | |||
private async Task<IDiscordVoiceClient> CreateVoiceClient(string serverId) | |||
private async Task<IDiscordVoiceClient> CreateVoiceClient(Server server) | |||
{ | |||
if (!Config.EnableVoiceMultiserver) | |||
{ | |||
_voiceServerId = serverId; | |||
_voiceServerId = server.Id; | |||
return this; | |||
} | |||
var client = _voiceClients.GetOrAdd(serverId, _ => | |||
var client = _voiceClients.GetOrAdd(server.Id, _ => | |||
{ | |||
var config = _config.Clone(); | |||
config.LogLevel = _config.LogLevel;// (LogMessageSeverity)Math.Min((int)_config.LogLevel, (int)LogMessageSeverity.Warning); | |||
config.VoiceOnly = true; | |||
config.VoiceClientId = unchecked(++_nextVoiceClientId); | |||
return new DiscordWSClient(config, serverId); | |||
return new DiscordWSClient(config, server.Id); | |||
}); | |||
client.LogMessage += (s, e) => RaiseOnLog(e.Severity, e.Source, $"(#{client.Config.VoiceClientId}) {e.Message}"); | |||
await client.Connect(_gateway, _token).ConfigureAwait(false); | |||
@@ -52,28 +50,26 @@ namespace Discord | |||
if (channel == null) throw new ArgumentNullException(nameof(channel)); | |||
CheckReady(); //checkVoice is done inside the voice client | |||
var client = await CreateVoiceClient(channel.Server.Id).ConfigureAwait(false); | |||
var client = await CreateVoiceClient(channel.Server).ConfigureAwait(false); | |||
await client.JoinChannel(channel.Id).ConfigureAwait(false); | |||
return client; | |||
} | |||
public Task LeaveVoiceServer(Server server) | |||
=> LeaveVoiceServer(server?.Id); | |||
public async Task LeaveVoiceServer(string serverId) | |||
public async Task LeaveVoiceServer(Server server) | |||
{ | |||
if (server == null) throw new ArgumentNullException(nameof(server)); | |||
CheckReady(checkVoice: true); | |||
if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||
if (Config.EnableVoiceMultiserver) | |||
{ | |||
DiscordWSClient client; | |||
if (_voiceClients.TryRemove(serverId, out client)) | |||
if (_voiceClients.TryRemove(server.Id, out client)) | |||
await client.Disconnect().ConfigureAwait(false); | |||
} | |||
else | |||
{ | |||
await _voiceSocket.Disconnect().ConfigureAwait(false); | |||
_dataSocket.SendLeaveVoice(serverId); | |||
_dataSocket.SendLeaveVoice(server.Id); | |||
} | |||
} | |||
} | |||
@@ -599,7 +599,7 @@ namespace Discord | |||
if (user != null) | |||
{ | |||
user.Update(data); | |||
RaiseProfileUpdated(user); | |||
RaiseProfileUpdated(); | |||
} | |||
} | |||
break; | |||
@@ -84,11 +84,11 @@ namespace Discord | |||
} | |||
internal override void OnCached() | |||
{ | |||
if (IsPrivate) | |||
{ | |||
var recipient = _client.Users[_recipientId, _serverId]; | |||
var recipient = _client.Users[_recipientId, null]; | |||
Name = "@" + recipient.Name; | |||
recipient.GlobalUser.PrivateChannel = this; | |||
Recipient = recipient; | |||
} | |||
else | |||
@@ -96,7 +96,8 @@ namespace Discord | |||
var server = _client.Servers[_serverId]; | |||
server.AddChannel(this); | |||
Server = server; | |||
} | |||
Recipient = null; | |||
} | |||
} | |||
internal override void OnUncached() | |||
{ | |||
@@ -104,7 +105,7 @@ namespace Discord | |||
if (server != null) | |||
server.RemoveChannel(this); | |||
Server = null; | |||
var recipient = Recipient; | |||
if (recipient != null) | |||
recipient.GlobalUser.PrivateChannel = null; | |||
@@ -22,7 +22,17 @@ namespace Discord | |||
/// <summary> Returns the private messaging channel with this user, if one exists. </summary> | |||
[JsonIgnore] | |||
public Channel PrivateChannel { get; internal set; } | |||
public Channel PrivateChannel | |||
{ | |||
get { return _privateChannel; } | |||
internal set | |||
{ | |||
_privateChannel = value; | |||
if (value == null) | |||
CheckUser(); | |||
} | |||
} | |||
private Channel _privateChannel; | |||
/// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary> | |||
[JsonIgnore] | |||
@@ -51,10 +61,12 @@ namespace Discord | |||
internal void RemoveUser(User user) | |||
{ | |||
if (_users.TryRemove(user.UniqueId, out user)) | |||
{ | |||
if (_users.Count == 0) | |||
_client.GlobalUsers.TryRemove(Id); | |||
} | |||
CheckUser(); | |||
} | |||
internal void CheckUser() | |||
{ | |||
if (_users.Count == 0 && PrivateChannel == null) | |||
_client.GlobalUsers.TryRemove(Id); | |||
} | |||
public override string ToString() => Id; | |||
@@ -6,8 +6,6 @@ namespace Discord | |||
{ | |||
public sealed class Invite : CachedObject | |||
{ | |||
/// <summary> Returns the unique code for this invite. </summary> | |||
public string Code { get; private set; } | |||
/// <summary> Returns, if enabled, an alternative human-readable code for URLs. </summary> | |||
public string XkcdCode { get; } | |||
/// <summary> Time (in seconds) until the invite expires. Set to 0 to never expire. </summary> | |||
@@ -22,7 +20,7 @@ namespace Discord | |||
public bool IsTemporary { get; private set; } | |||
/// <summary> Returns a URL for this invite using XkcdCode if available or Id if not. </summary> | |||
public string Url => API.Endpoints.InviteUrl(XkcdCode ?? Code); | |||
public string Url => API.Endpoints.InviteUrl(XkcdCode ?? Id); | |||
/// <summary> Returns the user that created this invite. </summary> | |||
[JsonIgnore] | |||
@@ -92,7 +92,6 @@ namespace Discord | |||
} | |||
private string _cleanText; | |||
private string _channelId, _userId; | |||
/// <summary> Returns the local unique identifier for this message. </summary> | |||
public string Nonce { get; internal set; } | |||
@@ -123,10 +122,7 @@ namespace Discord | |||
/// <summary> Returns a collection of all embeded content in this message. </summary> | |||
public Embed[] Embeds { get; private set; } | |||
private static readonly Embed[] _initialEmbeds = new Embed[0]; | |||
private static readonly string[] _initialMentions = new string[0]; | |||
/// <summary> Returns a collection of all user ids mentioned in this message. </summary> | |||
public string[] MentionIds { get; private set; } | |||
/// <summary> Returns a collection of all users mentioned in this message. </summary> | |||
[JsonIgnore] | |||
public IEnumerable<User> Mentions { get; internal set; } | |||
@@ -137,14 +133,14 @@ namespace Discord | |||
/// <summary> Returns the channel this message was sent to. </summary> | |||
[JsonIgnore] | |||
public Channel Channel { get; private set; } | |||
private readonly string _channelId; | |||
/// <summary> Returns true if the current user created this message. </summary> | |||
public bool IsAuthor => _client.CurrentUserId == UserId; | |||
/// <summary> Returns the id of the author of this message. </summary> | |||
public string UserId { get; } | |||
public bool IsAuthor => _client.CurrentUserId == _userId; | |||
/// <summary> Returns the author of this message. </summary> | |||
[JsonIgnore] | |||
public User User => _client.Users[_userId, Channel.Server.Id]; | |||
public User User { get; private set; } | |||
private readonly string _userId; | |||
internal Message(DiscordClient client, string id, string channelId, string userId) | |||
: base(client, id) | |||
@@ -153,7 +149,6 @@ namespace Discord | |||
_userId = userId; | |||
Attachments = _initialAttachments; | |||
Embeds = _initialEmbeds; | |||
MentionIds = _initialMentions; | |||
} | |||
internal override void OnCached() | |||
{ | |||
@@ -161,6 +156,10 @@ namespace Discord | |||
var channel = _client.Channels[_channelId]; | |||
channel.AddMessage(this); | |||
Channel = channel; | |||
var user = _client.Users[_channelId, channel.Server?.Id]; | |||
//user.AddMessage(this); | |||
User = user; | |||
} | |||
internal override void OnUncached() | |||
{ | |||
@@ -169,7 +168,12 @@ namespace Discord | |||
if (channel != null) | |||
channel.RemoveMessage(this); | |||
Channel = null; | |||
} | |||
var user = User; | |||
/*if (user != null) | |||
user.RemoveMessage(this);*/ | |||
User = null; | |||
} | |||
internal void Update(MessageInfo model) | |||
{ | |||
@@ -207,8 +211,8 @@ namespace Discord | |||
EditedTimestamp = model.EditedTimestamp; | |||
if (model.Mentions != null) | |||
{ | |||
MentionIds = model.Mentions.Select(x => x.Id)?.ToArray(); | |||
IsMentioningMe = MentionIds.Contains(_client.CurrentUserId); | |||
Mentions = model.Mentions.Select(x => _client.Users[x.Id, Channel.Server?.Id]).ToArray(); | |||
IsMentioningMe = model.Mentions.Any(x => x.Id == _client.CurrentUserId); | |||
} | |||
if (model.Content != null) | |||
{ | |||
@@ -64,7 +64,7 @@ namespace Discord | |||
/// <summary> Returns a collection of all messages this user has sent on this server that are still in cache. </summary> | |||
[JsonIgnore] | |||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.UserId == Id && x.Server.Id == _serverId); | |||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.User.Id == Id && x.Server.Id == _serverId); | |||
/// <summary> Returns a collection of all channels this user is a member of. </summary> | |||
[JsonIgnore] | |||