@@ -4,7 +4,7 @@ using Newtonsoft.Json; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
[JsonObject(MemberSerialization.OptIn)] | [JsonObject(MemberSerialization.OptIn)] | ||||
public class CreateChannelRequest : IRestRequest<Channel> | |||||
public class CreateGuildChannelRequest : IRestRequest<Channel> | |||||
{ | { | ||||
string IRestRequest.Method => "POST"; | string IRestRequest.Method => "POST"; | ||||
string IRestRequest.Endpoint => $"guilds/{GuildId}/channels"; | string IRestRequest.Endpoint => $"guilds/{GuildId}/channels"; | ||||
@@ -19,7 +19,7 @@ namespace Discord.API.Rest | |||||
[JsonProperty("bitrate")] | [JsonProperty("bitrate")] | ||||
public int Bitrate { get; set; } | public int Bitrate { get; set; } | ||||
public CreateChannelRequest(ulong guildId) | |||||
public CreateGuildChannelRequest(ulong guildId) | |||||
{ | { | ||||
GuildId = guildId; | GuildId = guildId; | ||||
} | } | ||||
@@ -2,7 +2,7 @@ | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
public class CreateRoleRequest : IRestRequest<Role> | |||||
public class CreateGuildRoleRequest : IRestRequest<Role> | |||||
{ | { | ||||
string IRestRequest.Method => "POST"; | string IRestRequest.Method => "POST"; | ||||
string IRestRequest.Endpoint => $"guilds/{GuildId}/roles"; | string IRestRequest.Endpoint => $"guilds/{GuildId}/roles"; | ||||
@@ -10,7 +10,7 @@ namespace Discord.API.Rest | |||||
public ulong GuildId { get; } | public ulong GuildId { get; } | ||||
public CreateRoleRequest(ulong guildId) | |||||
public CreateGuildRoleRequest(ulong guildId) | |||||
{ | { | ||||
GuildId = guildId; | GuildId = guildId; | ||||
} | } | ||||
@@ -27,7 +27,7 @@ namespace Discord.API.Rest | |||||
[JsonProperty("icon"), JsonConverter(typeof(ImageConverter))] | [JsonProperty("icon"), JsonConverter(typeof(ImageConverter))] | ||||
public Stream Icon { get; set; } | public Stream Icon { get; set; } | ||||
[JsonProperty("owner_id")] | [JsonProperty("owner_id")] | ||||
public GuildPresence Owner { get; set; } | |||||
public GuildMember Owner { get; set; } | |||||
[JsonProperty("splash"), JsonConverter(typeof(ImageConverter))] | [JsonProperty("splash"), JsonConverter(typeof(ImageConverter))] | ||||
public Stream Splash { get; set; } | public Stream Splash { get; set; } | ||||
@@ -4,7 +4,7 @@ using Newtonsoft.Json; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
[JsonObject(MemberSerialization.OptIn)] | [JsonObject(MemberSerialization.OptIn)] | ||||
public class UpdateMemberRequest : IRestRequest | |||||
public class ModifyGuildMemberRequest : IRestRequest | |||||
{ | { | ||||
string IRestRequest.Method => "PATCH"; | string IRestRequest.Method => "PATCH"; | ||||
string IRestRequest.Endpoint => $"guilds/{GuildId}/members/{UserId}"; | string IRestRequest.Endpoint => $"guilds/{GuildId}/members/{UserId}"; | ||||
@@ -22,7 +22,7 @@ namespace Discord.API.Rest | |||||
[JsonProperty("channel_id")] | [JsonProperty("channel_id")] | ||||
public ulong? ChannelId { get; set; } | public ulong? ChannelId { get; set; } | ||||
public UpdateMemberRequest(ulong guildId, ulong userId) | |||||
public ModifyGuildMemberRequest(ulong guildId, ulong userId) | |||||
{ | { | ||||
GuildId = guildId; | GuildId = guildId; | ||||
UserId = userId; | UserId = userId; | ||||
@@ -4,7 +4,7 @@ using Newtonsoft.Json; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
[JsonObject(MemberSerialization.OptIn)] | [JsonObject(MemberSerialization.OptIn)] | ||||
public class UpdateMessageRequest : IRestRequest<Message> | |||||
public class ModifyMessageRequest : IRestRequest<Message> | |||||
{ | { | ||||
string IRestRequest.Method => "PATCH"; | string IRestRequest.Method => "PATCH"; | ||||
string IRestRequest.Endpoint => $"channels/{ChannelId}/messages/{MessageId}"; | string IRestRequest.Endpoint => $"channels/{ChannelId}/messages/{MessageId}"; | ||||
@@ -16,7 +16,7 @@ namespace Discord.API.Rest | |||||
[JsonProperty("content")] | [JsonProperty("content")] | ||||
public string Content { get; set; } = ""; | public string Content { get; set; } = ""; | ||||
public UpdateMessageRequest(ulong channelId, ulong messageId) | |||||
public ModifyMessageRequest(ulong channelId, ulong messageId) | |||||
{ | { | ||||
ChannelId = channelId; | ChannelId = channelId; | ||||
MessageId = messageId; | MessageId = messageId; | ||||
@@ -212,15 +212,13 @@ | |||||
<Compile Include="Entities\Permissions\GuildPermissions.cs" /> | <Compile Include="Entities\Permissions\GuildPermissions.cs" /> | ||||
<Compile Include="Entities\Permissions\Overwrite.cs" /> | <Compile Include="Entities\Permissions\Overwrite.cs" /> | ||||
<Compile Include="Entities\Permissions\OverwritePermissions.cs" /> | <Compile Include="Entities\Permissions\OverwritePermissions.cs" /> | ||||
<Compile Include="Entities\Presences\GuildPresence.cs" /> | |||||
<Compile Include="Entities\Presences\Presence.cs" /> | |||||
<Compile Include="Entities\Presences\VoiceState.cs" /> | |||||
<Compile Include="Entities\Role.cs" /> | |||||
<Compile Include="Entities\Users\DMUser.cs" /> | <Compile Include="Entities\Users\DMUser.cs" /> | ||||
<Compile Include="Entities\Users\GlobalUser.cs" /> | |||||
<Compile Include="Entities\Users\GuildUser.cs" /> | <Compile Include="Entities\Users\GuildUser.cs" /> | ||||
<Compile Include="Entities\Users\PublicUser.cs" /> | |||||
<Compile Include="Entities\Users\IUser.cs" /> | |||||
<Compile Include="Entities\Users\VoiceState.cs" /> | |||||
<Compile Include="Entities\Role.cs" /> | |||||
<Compile Include="Entities\Users\SelfUser.cs" /> | <Compile Include="Entities\Users\SelfUser.cs" /> | ||||
<Compile Include="Entities\Users\User.cs" /> | |||||
<Compile Include="Entities\VoiceRegion.cs" /> | <Compile Include="Entities\VoiceRegion.cs" /> | ||||
<Compile Include="Enums\ChannelType.cs" /> | <Compile Include="Enums\ChannelType.cs" /> | ||||
<Compile Include="Enums\ConnectionState.cs" /> | <Compile Include="Enums\ConnectionState.cs" /> | ||||
@@ -49,7 +49,7 @@ namespace Discord | |||||
_connectionLock = new SemaphoreSlim(1, 1); | _connectionLock = new SemaphoreSlim(1, 1); | ||||
_restClientProvider = config.RestClientProvider; | _restClientProvider = config.RestClientProvider; | ||||
UserAgent = GetUserAgent(config.AppName, config.AppVersion, config.AppUrl); | |||||
UserAgent = $"DiscordBot ({DiscordConfig.LibUrl}, v{DiscordConfig.LibVersion})"; | |||||
_logManager = new LogManager(config.LogLevel); | _logManager = new LogManager(config.LogLevel); | ||||
_logManager.Message += (s, e) => Log(this, e); | _logManager.Message += (s, e) => Log(this, e); | ||||
@@ -165,18 +165,18 @@ namespace Discord | |||||
result[i] = CreateGuild(response[i]); | result[i] = CreateGuild(response[i]); | ||||
return result.ToImmutable(); | return result.ToImmutable(); | ||||
} | } | ||||
public virtual async Task<User> GetUser(ulong id) | |||||
public virtual async Task<IUser> GetUser(ulong id) | |||||
{ | { | ||||
var response = await RestClient.Send(new GetUserRequest(id)); | var response = await RestClient.Send(new GetUserRequest(id)); | ||||
var user = CreatePublicUser(response); | |||||
var user = CreateGlobalUser(response); | |||||
return user; | return user; | ||||
} | } | ||||
public virtual async Task<User> GetUser(string username, ushort discriminator) | |||||
public virtual async Task<IUser> GetUser(string username, ushort discriminator) | |||||
{ | { | ||||
var response = await RestClient.Send(new QueryUserRequest() { Query = $"{username}#{discriminator}", Limit = 1 }); | var response = await RestClient.Send(new QueryUserRequest() { Query = $"{username}#{discriminator}", Limit = 1 }); | ||||
if (response.Length > 0) | if (response.Length > 0) | ||||
{ | { | ||||
var user = CreatePublicUser(response[0]); | |||||
var user = CreateGlobalUser(response[0]); | |||||
return user; | return user; | ||||
} | } | ||||
return null; | return null; | ||||
@@ -265,7 +265,7 @@ namespace Discord | |||||
guild.Update(model); | guild.Update(model); | ||||
return guild; | return guild; | ||||
} | } | ||||
internal virtual Message CreateMessage(IMessageChannel channel, User user, API.Message model) | |||||
internal virtual Message CreateMessage(IMessageChannel channel, IUser user, API.Message model) | |||||
{ | { | ||||
var msg = new Message(model.Id, channel, user); | var msg = new Message(model.Id, channel, user); | ||||
msg.Update(model); | msg.Update(model); | ||||
@@ -277,33 +277,33 @@ namespace Discord | |||||
role.Update(model); | role.Update(model); | ||||
return role; | return role; | ||||
} | } | ||||
internal virtual GuildUser CreateBannedUser(Guild guild, API.User model) | |||||
internal virtual DMUser CreateDMUser(DMChannel channel, API.User model) | |||||
{ | { | ||||
var user = new GuildUser(model.Id, guild, null, null); | |||||
var user = new DMUser(CreateGlobalUser(model), channel); | |||||
user.Update(model); | user.Update(model); | ||||
return user; | return user; | ||||
} | } | ||||
internal virtual DMUser CreateDMUser(DMChannel channel, API.User model) | |||||
internal virtual GuildUser CreateGuildUser(Guild guild, API.GuildMember model) | |||||
{ | { | ||||
var user = new DMUser(model.Id, channel); | |||||
var user = new GuildUser(CreateGlobalUser(model.User), guild); | |||||
user.Update(model); | user.Update(model); | ||||
return user; | return user; | ||||
} | } | ||||
internal virtual GuildUser CreateGuildUser(Guild guild, GuildPresence presence, VoiceState voiceState, API.GuildMember model) | |||||
internal virtual GuildUser CreateBannedUser(Guild guild, API.User model) | |||||
{ | { | ||||
var user = new GuildUser(model.User.Id, guild, presence, voiceState); | |||||
user.Update(model); | |||||
var user = new GuildUser(CreateGlobalUser(model), guild); | |||||
//user.Update(model); | |||||
return user; | return user; | ||||
} | } | ||||
internal virtual PublicUser CreatePublicUser(API.User model) | |||||
internal virtual SelfUser CreateSelfUser(API.User model) | |||||
{ | { | ||||
var user = new PublicUser(model.Id, this); | |||||
var user = new SelfUser(model.Id, this); | |||||
user.Update(model); | user.Update(model); | ||||
return user; | return user; | ||||
} | } | ||||
internal virtual SelfUser CreateSelfUser(API.User model) | |||||
internal virtual GlobalUser CreateGlobalUser(API.User model) | |||||
{ | { | ||||
var user = new SelfUser(model.Id, this); | |||||
var user = new GlobalUser(model.Id, this); | |||||
user.Update(model); | user.Update(model); | ||||
return user; | return user; | ||||
} | } | ||||
@@ -314,6 +314,8 @@ namespace Discord | |||||
return region; | return region; | ||||
} | } | ||||
internal virtual void RemoveUser(GlobalUser user) { } | |||||
protected virtual void Dispose(bool disposing) | protected virtual void Dispose(bool disposing) | ||||
{ | { | ||||
if (!_isDisposed) | if (!_isDisposed) | ||||
@@ -329,22 +331,6 @@ namespace Discord | |||||
} | } | ||||
public void Dispose() => Dispose(true); | public void Dispose() => Dispose(true); | ||||
private static string GetUserAgent(string appName, string appVersion, string appUrl) | |||||
{ | |||||
var sb = new StringBuilder(); | |||||
if (!string.IsNullOrEmpty(appName)) | |||||
{ | |||||
sb.Append(appName); | |||||
if (!string.IsNullOrEmpty(appVersion)) | |||||
sb.Append($"/{appVersion}"); | |||||
if (!string.IsNullOrEmpty(appUrl)) | |||||
sb.Append($" ({appUrl})"); | |||||
sb.Append(' '); | |||||
} | |||||
sb.Append($"DiscordBot ({DiscordConfig.LibUrl}, v{DiscordConfig.LibVersion})"); | |||||
return sb.ToString(); | |||||
} | |||||
protected void RaiseEvent(EventHandler eventHandler) | protected void RaiseEvent(EventHandler eventHandler) | ||||
=> eventHandler?.Invoke(this, EventArgs.Empty); | => eventHandler?.Invoke(this, EventArgs.Empty); | ||||
protected void RaiseEvent<T>(EventHandler<T> eventHandler, T eventArgs) where T : EventArgs | protected void RaiseEvent<T>(EventHandler<T> eventHandler, T eventArgs) where T : EventArgs | ||||
@@ -21,13 +21,6 @@ namespace Discord | |||||
internal const int MessageQueueInterval = 100; | internal const int MessageQueueInterval = 100; | ||||
internal const int WebSocketQueueInterval = 100; | internal const int WebSocketQueueInterval = 100; | ||||
/// <summary> Gets or sets name of your application, used in the user agent. </summary> | |||||
public string AppName { get; set; } = null; | |||||
/// <summary> Gets or sets url to your application, used in the user agent. </summary> | |||||
public string AppUrl { get; set; } = null; | |||||
/// <summary> Gets or sets the version of your application, used in the user agent. </summary> | |||||
public string AppVersion { get; set; } = null; | |||||
/// <summary> Gets or sets the minimum log level severity that will be sent to the LogMessage event. </summary> | /// <summary> Gets or sets the minimum log level severity that will be sent to the LogMessage event. </summary> | ||||
public LogSeverity LogLevel { get; set; } = LogSeverity.Info; | public LogSeverity LogLevel { get; set; } = LogSeverity.Info; | ||||
@@ -22,11 +22,9 @@ namespace Discord | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public string Name => $"@{Recipient.Username}#{Recipient.Discriminator}"; | public string Name => $"@{Recipient.Username}#{Recipient.Discriminator}"; | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public IEnumerable<User> Users => ImmutableArray.Create<User>(Discord.CurrentUser, Recipient); | |||||
public IEnumerable<IUser> Users => ImmutableArray.Create<IUser>(Discord.CurrentUser, Recipient); | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
ChannelType IChannel.Type => ChannelType.DM; | ChannelType IChannel.Type => ChannelType.DM; | ||||
/// <inheritdoc /> | |||||
IEnumerable<User> IChannel.Users => Users; | |||||
private readonly MessageManager _messages; | private readonly MessageManager _messages; | ||||
@@ -45,7 +43,7 @@ namespace Discord | |||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public User GetUser(ulong id) | |||||
public IUser GetUser(ulong id) | |||||
{ | { | ||||
if (id == Recipient.Id) | if (id == Recipient.Id) | ||||
return Recipient; | return Recipient; | ||||
@@ -27,9 +27,9 @@ namespace Discord | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public DiscordClient Discord => Guild.Discord; | public DiscordClient Discord => Guild.Discord; | ||||
/// <summary> Gets a collection of all users in this channel. </summary> | /// <summary> Gets a collection of all users in this channel. </summary> | ||||
public IEnumerable<GuildUser> Users => _permissions.GetUsers(); | |||||
public IEnumerable<GuildUser> Users => _permissions.GetMembers(); | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
IEnumerable<User> IChannel.Users => _permissions.GetUsers(); | |||||
IEnumerable<IUser> IChannel.Users => _permissions.GetMembers(); | |||||
/// <summary> Gets a collection of permission overwrites for this channel. </summary> | /// <summary> Gets a collection of permission overwrites for this channel. </summary> | ||||
public IEnumerable<Overwrite> PermissionOverwrites => _permissions.Overwrites; | public IEnumerable<Overwrite> PermissionOverwrites => _permissions.Overwrites; | ||||
@@ -50,13 +50,12 @@ namespace Discord | |||||
} | } | ||||
/// <summary> Gets a user in this channel with the given id. </summary> | /// <summary> Gets a user in this channel with the given id. </summary> | ||||
public GuildUser GetUser(ulong id) | |||||
=> _permissions.GetUser(id); | |||||
public GuildUser GetUser(ulong id) => _permissions.GetUser(id); | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
User IChannel.GetUser(ulong id) => GetUser(id); | |||||
IUser IChannel.GetUser(ulong id) => GetUser(id); | |||||
/// <summary> Gets the permission overwrite for a specific user, or null if one does not exist. </summary> | /// <summary> Gets the permission overwrite for a specific user, or null if one does not exist. </summary> | ||||
public OverwritePermissions? GetPermissionOverwrite(GuildUser user) | |||||
public OverwritePermissions? GetPermissionOverwrite(IUser user) | |||||
=> _permissions.GetOverwrite(user); | => _permissions.GetOverwrite(user); | ||||
/// <summary> Gets the permission overwrite for a specific role, or null if one does not exist. </summary> | /// <summary> Gets the permission overwrite for a specific role, or null if one does not exist. </summary> | ||||
public OverwritePermissions? GetPermissionOverwrite(Role role) | public OverwritePermissions? GetPermissionOverwrite(Role role) | ||||
@@ -74,23 +73,23 @@ namespace Discord | |||||
} | } | ||||
/// <summary> Adds or updates the permission overwrite for the given user. </summary> | /// <summary> Adds or updates the permission overwrite for the given user. </summary> | ||||
public Task UpdatePermissionOverwrite(GuildUser user, OverwritePermissions permissions) | |||||
public Task UpdatePermissionOverwrite(IUser user, OverwritePermissions permissions) | |||||
=> _permissions.AddOrUpdateOverwrite(user, permissions); | => _permissions.AddOrUpdateOverwrite(user, permissions); | ||||
/// <summary> Adds or updates the permission overwrite for the given role. </summary> | /// <summary> Adds or updates the permission overwrite for the given role. </summary> | ||||
public Task UpdatePermissionOverwrite(Role role, OverwritePermissions permissions) | public Task UpdatePermissionOverwrite(Role role, OverwritePermissions permissions) | ||||
=> _permissions.AddOrUpdateOverwrite(role, permissions); | => _permissions.AddOrUpdateOverwrite(role, permissions); | ||||
/// <summary> Removes the permission overwrite for the given user, if one exists. </summary> | /// <summary> Removes the permission overwrite for the given user, if one exists. </summary> | ||||
public Task RemovePermissionOverwrite(GuildUser user) | |||||
public Task RemovePermissionOverwrite(IUser user) | |||||
=> _permissions.RemoveOverwrite(user); | => _permissions.RemoveOverwrite(user); | ||||
/// <summary> Removes the permission overwrite for the given role, if one exists. </summary> | /// <summary> Removes the permission overwrite for the given role, if one exists. </summary> | ||||
public Task RemovePermissionOverwrite(Role role) | public Task RemovePermissionOverwrite(Role role) | ||||
=> _permissions.RemoveOverwrite(role); | => _permissions.RemoveOverwrite(role); | ||||
internal ChannelPermissions GetPermissions(GuildUser user) | |||||
internal ChannelPermissions GetPermissions(IUser user) | |||||
=> _permissions.GetPermissions(user); | => _permissions.GetPermissions(user); | ||||
internal void UpdatePermissions() | internal void UpdatePermissions() | ||||
=> _permissions.UpdatePermissions(); | => _permissions.UpdatePermissions(); | ||||
internal void UpdatePermissions(GuildUser user) | |||||
internal void UpdatePermissions(IUser user) | |||||
=> _permissions.UpdatePermissions(user); | => _permissions.UpdatePermissions(user); | ||||
/// <summary> Creates a new invite to this channel. </summary> | /// <summary> Creates a new invite to this channel. </summary> | ||||
@@ -9,9 +9,9 @@ namespace Discord | |||||
/// <summary> Gets the name of this channel. </summary> | /// <summary> Gets the name of this channel. </summary> | ||||
string Name { get; } | string Name { get; } | ||||
/// <summary> Gets a collection of all users in this channel. </summary> | /// <summary> Gets a collection of all users in this channel. </summary> | ||||
IEnumerable<User> Users { get; } | |||||
IEnumerable<IUser> Users { get; } | |||||
/// <summary> Gets a user in this channel with the given id. </summary> | /// <summary> Gets a user in this channel with the given id. </summary> | ||||
User GetUser(ulong id); | |||||
IUser GetUser(ulong id); | |||||
} | } | ||||
} | } |
@@ -27,9 +27,9 @@ namespace Discord | |||||
private ConcurrentDictionary<ulong, GuildChannel> _channels; | private ConcurrentDictionary<ulong, GuildChannel> _channels; | ||||
private ConcurrentDictionary<ulong, Member> _members; | private ConcurrentDictionary<ulong, Member> _members; | ||||
private ConcurrentDictionary<ulong, GuildPresence> _presences; | |||||
//private ConcurrentDictionary<ulong, GuildPresence> _presences; | |||||
private ConcurrentDictionary<ulong, Role> _roles; | private ConcurrentDictionary<ulong, Role> _roles; | ||||
private ConcurrentDictionary<ulong, VoiceState> _voiceStates; | |||||
//private ConcurrentDictionary<ulong, VoiceState> _voiceStates; | |||||
private ulong _ownerId; | private ulong _ownerId; | ||||
private ulong? _afkChannelId, _embedChannelId; | private ulong? _afkChannelId, _embedChannelId; | ||||
private int _userCount; | private int _userCount; | ||||
@@ -100,9 +100,9 @@ namespace Discord | |||||
_channels = new ConcurrentDictionary<ulong, GuildChannel>(); | _channels = new ConcurrentDictionary<ulong, GuildChannel>(); | ||||
_members = new ConcurrentDictionary<ulong, Member>(); | _members = new ConcurrentDictionary<ulong, Member>(); | ||||
_presences = new ConcurrentDictionary<ulong, GuildPresence>(); | |||||
//_presences = new ConcurrentDictionary<ulong, GuildPresence>(); | |||||
_roles = new ConcurrentDictionary<ulong, Role>(); | _roles = new ConcurrentDictionary<ulong, Role>(); | ||||
_voiceStates = new ConcurrentDictionary<ulong, VoiceState>(); | |||||
//_voiceStates = new ConcurrentDictionary<ulong, VoiceState>(); | |||||
} | } | ||||
internal void Update(Model model) | internal void Update(Model model) | ||||
@@ -207,7 +207,7 @@ namespace Discord | |||||
public GuildUser GetUser(string mention) => GetUser(MentionHelper.GetUserId(mention)); | public GuildUser GetUser(string mention) => GetUser(MentionHelper.GetUserId(mention)); | ||||
private GuildUser GetUser(ulong? id) => id != null ? GetUser(id.Value) : null; | private GuildUser GetUser(ulong? id) => id != null ? GetUser(id.Value) : null; | ||||
public async Task<IEnumerable<User>> GetBans() | |||||
public async Task<IEnumerable<IUser>> GetBans() | |||||
{ | { | ||||
var discord = Discord; | var discord = Discord; | ||||
var response = await Discord.RestClient.Send(new GetGuildBansRequest(Id)).ConfigureAwait(false); | var response = await Discord.RestClient.Send(new GetGuildBansRequest(Id)).ConfigureAwait(false); | ||||
@@ -229,7 +229,7 @@ namespace Discord | |||||
{ | { | ||||
if (name == null) throw new ArgumentNullException(nameof(name)); | if (name == null) throw new ArgumentNullException(nameof(name)); | ||||
var request = new CreateChannelRequest(Id) { Name = name, Type = ChannelType.Text }; | |||||
var request = new CreateGuildChannelRequest(Id) { Name = name, Type = ChannelType.Text }; | |||||
var response = await Discord.RestClient.Send(request).ConfigureAwait(false); | var response = await Discord.RestClient.Send(request).ConfigureAwait(false); | ||||
return Discord.CreateTextChannel(this, response); | return Discord.CreateTextChannel(this, response); | ||||
@@ -238,7 +238,7 @@ namespace Discord | |||||
{ | { | ||||
if (name == null) throw new ArgumentNullException(nameof(name)); | if (name == null) throw new ArgumentNullException(nameof(name)); | ||||
var request = new CreateChannelRequest(Id) { Name = name, Type = ChannelType.Voice }; | |||||
var request = new CreateGuildChannelRequest(Id) { Name = name, Type = ChannelType.Voice }; | |||||
var response = await Discord.RestClient.Send(request).ConfigureAwait(false); | var response = await Discord.RestClient.Send(request).ConfigureAwait(false); | ||||
return Discord.CreateVoiceChannel(this, response); | return Discord.CreateVoiceChannel(this, response); | ||||
@@ -251,7 +251,7 @@ namespace Discord | |||||
{ | { | ||||
if (name == null) throw new ArgumentNullException(nameof(name)); | if (name == null) throw new ArgumentNullException(nameof(name)); | ||||
var createRequest = new CreateRoleRequest(Id); | |||||
var createRequest = new CreateGuildRoleRequest(Id); | |||||
var createResponse = await Discord.RestClient.Send(createRequest).ConfigureAwait(false); | var createResponse = await Discord.RestClient.Send(createRequest).ConfigureAwait(false); | ||||
var role = Discord.CreateRole(this, createResponse); | var role = Discord.CreateRole(this, createResponse); | ||||
@@ -347,7 +347,7 @@ namespace Discord | |||||
newPermissions = GuildPermissions.All.RawValue; | newPermissions = GuildPermissions.All.RawValue; | ||||
else | else | ||||
{ | { | ||||
foreach (var role in user.Presence.Roles) | |||||
foreach (var role in user.Roles) | |||||
newPermissions |= role.Permissions.RawValue; | newPermissions |= role.Permissions.RawValue; | ||||
} | } | ||||
@@ -11,7 +11,7 @@ namespace Discord | |||||
private static readonly Regex _channelRegex = new Regex(@"<#([0-9]+)>"); | private static readonly Regex _channelRegex = new Regex(@"<#([0-9]+)>"); | ||||
private static readonly Regex _roleRegex = new Regex(@"@everyone"); | private static readonly Regex _roleRegex = new Regex(@"@everyone"); | ||||
internal static string Mention(User user) => $"<@{user.Id}>"; | |||||
internal static string Mention(IUser user) => $"<@{user.Id}>"; | |||||
internal static string Mention(IChannel channel) => $"<#{channel.Id}>"; | internal static string Mention(IChannel channel) => $"<#{channel.Id}>"; | ||||
internal static string Mention(Role role) => role.IsEveryone ? "@everyone" : ""; | internal static string Mention(Role role) => role.IsEveryone ? "@everyone" : ""; | ||||
@@ -29,7 +29,7 @@ namespace Discord | |||||
} | } | ||||
} | } | ||||
internal Message Add(Model model, User user) | |||||
internal Message Add(Model model, IUser user) | |||||
=> Add(_channel.Discord.CreateMessage(_channel, user, model)); | => Add(_channel.Discord.CreateMessage(_channel, user, model)); | ||||
private Message Add(Message message) | private Message Add(Message message) | ||||
{ | { | ||||
@@ -46,7 +46,7 @@ namespace Discord | |||||
UpdatePermissions(); | UpdatePermissions(); | ||||
} | } | ||||
public OverwritePermissions? GetOverwrite(GuildUser user) | |||||
public OverwritePermissions? GetOverwrite(IUser user) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
@@ -64,7 +64,7 @@ namespace Discord | |||||
return rule.Permissions; | return rule.Permissions; | ||||
return null; | return null; | ||||
} | } | ||||
public Task AddOrUpdateOverwrite(GuildUser user, OverwritePermissions permissions) | |||||
public Task AddOrUpdateOverwrite(IUser user, OverwritePermissions permissions) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
return AddOrUpdateOverwrite(user.Id, permissions); | return AddOrUpdateOverwrite(user.Id, permissions); | ||||
@@ -83,7 +83,7 @@ namespace Discord | |||||
}; | }; | ||||
return _channel.Discord.RestClient.Send(request); | return _channel.Discord.RestClient.Send(request); | ||||
} | } | ||||
public Task RemoveOverwrite(GuildUser user) | |||||
public Task RemoveOverwrite(IUser user) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
return RemoveOverwrite(user.Id); | return RemoveOverwrite(user.Id); | ||||
@@ -99,7 +99,7 @@ namespace Discord | |||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
} | } | ||||
public ChannelPermissions GetPermissions(GuildUser user) | |||||
public ChannelPermissions GetPermissions(IUser user) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
@@ -131,7 +131,7 @@ namespace Discord | |||||
} | } | ||||
} | } | ||||
} | } | ||||
public void UpdatePermissions(GuildUser user) | |||||
public void UpdatePermissions(IUser user) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
@@ -147,22 +147,37 @@ namespace Discord | |||||
} | } | ||||
} | } | ||||
public ChannelPermissions ResolvePermissions(GuildUser user) | |||||
public ChannelPermissions ResolvePermissions(IUser user) | |||||
{ | |||||
var permissions = new ChannelPermissions(); | |||||
ResolvePermissions(user, ref permissions); | |||||
return permissions; | |||||
} | |||||
private ChannelPermissions ResolvePermissions(GuildUser user) | |||||
{ | { | ||||
var permissions = new ChannelPermissions(); | var permissions = new ChannelPermissions(); | ||||
ResolvePermissions(user, ref permissions); | ResolvePermissions(user, ref permissions); | ||||
return permissions; | return permissions; | ||||
} | } | ||||
public bool ResolvePermissions(GuildUser user, ref ChannelPermissions permissions) | |||||
public bool ResolvePermissions(IUser user, ref ChannelPermissions permissions) | |||||
{ | { | ||||
if (user == null) throw new ArgumentNullException(nameof(user)); | if (user == null) throw new ArgumentNullException(nameof(user)); | ||||
GuildUser guildUser = _channel.GetUser(user.Id); | |||||
if (guildUser == null) | |||||
{ | |||||
permissions = ChannelPermissions.None; | |||||
return false; | |||||
} | |||||
else | |||||
return ResolvePermissions(user, ref permissions); | |||||
} | |||||
private bool ResolvePermissions(GuildUser user, ref ChannelPermissions permissions) | |||||
{ | |||||
uint newPermissions = 0; | uint newPermissions = 0; | ||||
var guild = user.Guild; | |||||
uint mask = ChannelPermissions.All(_channel.Type).RawValue; | uint mask = ChannelPermissions.All(_channel.Type).RawValue; | ||||
if (user == guild.Owner) | |||||
if (user == user.Guild.Owner) | |||||
newPermissions = mask; //Private messages and owners always have all permissions | newPermissions = mask; //Private messages and owners always have all permissions | ||||
else | else | ||||
{ | { | ||||
@@ -171,7 +186,7 @@ namespace Discord | |||||
var rules = _rules; | var rules = _rules; | ||||
Overwrite entry; | Overwrite entry; | ||||
var roles = user.Presence.Roles.ToArray(); | |||||
var roles = user.Roles.ToArray(); | |||||
if (roles.Length > 0) | if (roles.Length > 0) | ||||
{ | { | ||||
for (int i = 0; i < roles.Length; i++) | for (int i = 0; i < roles.Length; i++) | ||||
@@ -228,13 +243,13 @@ namespace Discord | |||||
} | } | ||||
else if (_channel.Type == ChannelType.Voice) | else if (_channel.Type == ChannelType.Voice) | ||||
{ | { | ||||
if (user.VoiceState?.VoiceChannel == _channel) | |||||
if (user.VoiceChannel == _channel) | |||||
return user; | return user; | ||||
} | } | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
public IEnumerable<GuildUser> GetUsers() | |||||
public IEnumerable<GuildUser> GetMembers() | |||||
{ | { | ||||
if (_users != null) | if (_users != null) | ||||
return _users.Select(x => x.Value.User); | return _users.Select(x => x.Value.User); | ||||
@@ -247,7 +262,7 @@ namespace Discord | |||||
return users.Where(x => ResolvePermissions(x, ref perms)); | return users.Where(x => ResolvePermissions(x, ref perms)); | ||||
} | } | ||||
else if (_channel.Type == ChannelType.Voice) | else if (_channel.Type == ChannelType.Voice) | ||||
return users.Where(x => x.VoiceState?.VoiceChannel == _channel); | |||||
return users.Where(x => x.VoiceChannel == _channel); | |||||
} | } | ||||
return Enumerable.Empty<GuildUser>(); | return Enumerable.Empty<GuildUser>(); | ||||
} | } | ||||
@@ -3,6 +3,7 @@ using Discord.Net; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
using System.Linq; | |||||
using System.Net; | using System.Net; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Model = Discord.API.Message; | using Model = Discord.API.Message; | ||||
@@ -11,27 +12,28 @@ namespace Discord | |||||
{ | { | ||||
public class Message : IEntity<ulong> | public class Message : IEntity<ulong> | ||||
{ | { | ||||
//TODO: Docstrings | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong Id { get; } | public ulong Id { get; } | ||||
public IMessageChannel Channel { get; } | public IMessageChannel Channel { get; } | ||||
public User User { get; } | |||||
public IUser User { get; } | |||||
public bool IsTTS { get; internal set; } | |||||
public string RawText { get; internal set; } | |||||
public string Text { get; internal set; } | |||||
public DateTime Timestamp { get; internal set; } | |||||
public bool IsTTS { get; private set; } | |||||
public string RawText { get; private set; } | |||||
public string Text { get; private set; } | |||||
public DateTime Timestamp { get; private set; } | |||||
public DateTime? EditedTimestamp { get; private set; } | public DateTime? EditedTimestamp { get; private set; } | ||||
public IReadOnlyList<Attachment> Attachments { get; private set; } | public IReadOnlyList<Attachment> Attachments { get; private set; } | ||||
public IReadOnlyList<Embed> Embeds { get; private set; } | public IReadOnlyList<Embed> Embeds { get; private set; } | ||||
public IReadOnlyList<GuildUser> MentionedUsers { get; private set; } | public IReadOnlyList<GuildUser> MentionedUsers { get; private set; } | ||||
public IReadOnlyList<GuildChannel> MentionedChannels { get; private set; } | public IReadOnlyList<GuildChannel> MentionedChannels { get; private set; } | ||||
public IReadOnlyList<Role> MentionedRoles { get; private set; } | public IReadOnlyList<Role> MentionedRoles { get; private set; } | ||||
internal int Nonce { get; set; } | |||||
public DiscordClient Discord => Channel.Discord; | public DiscordClient Discord => Channel.Discord; | ||||
public bool IsAuthor => false; | |||||
public bool IsAuthor => User.Id == Discord.CurrentUser.Id; | |||||
internal Message(ulong id, IMessageChannel channel, User user) | |||||
internal Message(ulong id, IMessageChannel channel, IUser user) | |||||
{ | { | ||||
Id = id; | Id = id; | ||||
Channel = channel; | Channel = channel; | ||||
@@ -102,7 +104,28 @@ namespace Discord | |||||
Text = text; | Text = text; | ||||
} | } | ||||
public bool IsMentioningMe(bool includeRoles = false) => false; | |||||
/// <summary> Returns true if the logged-in user was mentioned. </summary> | |||||
public bool IsMentioningMe(bool includeRoles = false) | |||||
{ | |||||
var me = Channel.GetCurrentUser() as GuildUser; | |||||
if (me != null) | |||||
{ | |||||
if (includeRoles) | |||||
return MentionedUsers.Contains(me) || MentionedRoles.Any(x => me.HasRole(x)); | |||||
else | |||||
return MentionedUsers.Contains(me); | |||||
} | |||||
return false; | |||||
} | |||||
public async Task Modify(Action<ModifyMessageRequest> func) | |||||
{ | |||||
if (func != null) throw new NullReferenceException(nameof(func)); | |||||
var req = new ModifyMessageRequest(Channel.Id, Id); | |||||
func(req); | |||||
await Discord.RestClient.Send(req).ConfigureAwait(false); | |||||
} | |||||
public Task Update() { throw new NotSupportedException(); } //TODO: Not supported yet | public Task Update() { throw new NotSupportedException(); } //TODO: Not supported yet | ||||
@@ -63,8 +63,8 @@ namespace Discord | |||||
public bool DeafenMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.DeafenMembers); | public bool DeafenMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.DeafenMembers); | ||||
/// <summary> If True, a user may move other users between voice channels. </summary> | /// <summary> If True, a user may move other users between voice channels. </summary> | ||||
public bool MoveMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.MoveMembers); | public bool MoveMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.MoveMembers); | ||||
/// <summary> If True, a user may use voice activation rather than push-to-talk. </summary> | |||||
public bool UseVoiceActivation => PermissionsHelper.GetValue(RawValue, PermissionBit.UseVoiceActivation); | |||||
/// <summary> If True, a user may use voice-activity-detection rather than push-to-talk. </summary> | |||||
public bool UseVAD => PermissionsHelper.GetValue(RawValue, PermissionBit.UseVAD); | |||||
/// <summary> Creates a new ChannelPermissions with the provided packed value. </summary> | /// <summary> Creates a new ChannelPermissions with the provided packed value. </summary> | ||||
public ChannelPermissions(uint rawValue) { RawValue = rawValue; } | public ChannelPermissions(uint rawValue) { RawValue = rawValue; } | ||||
@@ -93,7 +93,7 @@ namespace Discord | |||||
PermissionsHelper.SetValue(ref value, muteMembers, PermissionBit.MuteMembers); | PermissionsHelper.SetValue(ref value, muteMembers, PermissionBit.MuteMembers); | ||||
PermissionsHelper.SetValue(ref value, deafenMembers, PermissionBit.DeafenMembers); | PermissionsHelper.SetValue(ref value, deafenMembers, PermissionBit.DeafenMembers); | ||||
PermissionsHelper.SetValue(ref value, moveMembers, PermissionBit.MoveMembers); | PermissionsHelper.SetValue(ref value, moveMembers, PermissionBit.MoveMembers); | ||||
PermissionsHelper.SetValue(ref value, useVoiceActivation, PermissionBit.UseVoiceActivation); | |||||
PermissionsHelper.SetValue(ref value, useVoiceActivation, PermissionBit.UseVAD); | |||||
RawValue = value; | RawValue = value; | ||||
} | } | ||||
@@ -52,8 +52,8 @@ namespace Discord | |||||
public bool DeafenMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.DeafenMembers); | public bool DeafenMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.DeafenMembers); | ||||
/// <summary> If True, a user may move other users between voice channels. </summary> | /// <summary> If True, a user may move other users between voice channels. </summary> | ||||
public bool MoveMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.MoveMembers); | public bool MoveMembers => PermissionsHelper.GetValue(RawValue, PermissionBit.MoveMembers); | ||||
/// <summary> If True, a user may use voice activation rather than push-to-talk. </summary> | |||||
public bool UseVoiceActivation => PermissionsHelper.GetValue(RawValue, PermissionBit.UseVoiceActivation); | |||||
/// <summary> If True, a user may use voice-activity-detection rather than push-to-talk. </summary> | |||||
public bool UseVAD => PermissionsHelper.GetValue(RawValue, PermissionBit.UseVAD); | |||||
/// <summary> Creates a new GuildPermissions with the provided packed value. </summary> | /// <summary> Creates a new GuildPermissions with the provided packed value. </summary> | ||||
public GuildPermissions(uint rawValue) { RawValue = rawValue; } | public GuildPermissions(uint rawValue) { RawValue = rawValue; } | ||||
@@ -86,7 +86,7 @@ namespace Discord | |||||
PermissionsHelper.SetValue(ref value, muteMembers, PermissionBit.MuteMembers); | PermissionsHelper.SetValue(ref value, muteMembers, PermissionBit.MuteMembers); | ||||
PermissionsHelper.SetValue(ref value, deafenMembers, PermissionBit.DeafenMembers); | PermissionsHelper.SetValue(ref value, deafenMembers, PermissionBit.DeafenMembers); | ||||
PermissionsHelper.SetValue(ref value, moveMembers, PermissionBit.MoveMembers); | PermissionsHelper.SetValue(ref value, moveMembers, PermissionBit.MoveMembers); | ||||
PermissionsHelper.SetValue(ref value, useVoiceActivation, PermissionBit.UseVoiceActivation); | |||||
PermissionsHelper.SetValue(ref value, useVoiceActivation, PermissionBit.UseVAD); | |||||
RawValue = value; | RawValue = value; | ||||
} | } | ||||
@@ -51,8 +51,8 @@ namespace Discord | |||||
public PermValue DeafenMembers => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.DeafenMembers); | public PermValue DeafenMembers => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.DeafenMembers); | ||||
/// <summary> If True, a user may move other users between voice channels. </summary> | /// <summary> If True, a user may move other users between voice channels. </summary> | ||||
public PermValue MoveMembers => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.MoveMembers); | public PermValue MoveMembers => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.MoveMembers); | ||||
/// <summary> If True, a user may use voice activation rather than push-to-talk. </summary> | |||||
public PermValue UseVoiceActivation => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.UseVoiceActivation); | |||||
/// <summary> If True, a user may use voice-activity-detection rather than push-to-talk. </summary> | |||||
public PermValue UseVAD => PermissionsHelper.GetValue(AllowValue, DenyValue, PermissionBit.UseVAD); | |||||
/// <summary> Creates a new OverwritePermissions with the provided allow and deny packed values. </summary> | /// <summary> Creates a new OverwritePermissions with the provided allow and deny packed values. </summary> | ||||
public OverwritePermissions(uint allowValue, uint denyValue) | public OverwritePermissions(uint allowValue, uint denyValue) | ||||
@@ -83,7 +83,7 @@ namespace Discord | |||||
PermissionsHelper.SetValue(ref allowValue, ref denyValue, muteMembers, PermissionBit.MuteMembers); | PermissionsHelper.SetValue(ref allowValue, ref denyValue, muteMembers, PermissionBit.MuteMembers); | ||||
PermissionsHelper.SetValue(ref allowValue, ref denyValue, deafenMembers, PermissionBit.DeafenMembers); | PermissionsHelper.SetValue(ref allowValue, ref denyValue, deafenMembers, PermissionBit.DeafenMembers); | ||||
PermissionsHelper.SetValue(ref allowValue, ref denyValue, moveMembers, PermissionBit.MoveMembers); | PermissionsHelper.SetValue(ref allowValue, ref denyValue, moveMembers, PermissionBit.MoveMembers); | ||||
PermissionsHelper.SetValue(ref allowValue, ref denyValue, useVoiceActivation, PermissionBit.UseVoiceActivation); | |||||
PermissionsHelper.SetValue(ref allowValue, ref denyValue, useVoiceActivation, PermissionBit.UseVAD); | |||||
AllowValue = allowValue; | AllowValue = allowValue; | ||||
DenyValue = denyValue; | DenyValue = denyValue; | ||||
@@ -1,33 +0,0 @@ | |||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
using System.Linq; | |||||
using Model = Discord.API.MemberPresence; | |||||
namespace Discord | |||||
{ | |||||
public class GuildPresence : Presence | |||||
{ | |||||
public Guild Guild { get; } | |||||
public ulong UserId { get; } | |||||
/// <inheritdoc /> | |||||
public IReadOnlyList<Role> Roles { get; private set; } | |||||
internal GuildPresence(ulong userId, Guild guild) | |||||
{ | |||||
UserId = userId; | |||||
Guild = guild; | |||||
} | |||||
internal override void Update(Model model) | |||||
{ | |||||
base.Update(model); | |||||
Roles = model.Roles.Select(x => Guild.GetRole(x)).ToImmutableArray(); | |||||
} | |||||
public bool HasRole(Role role) => false; | |||||
//TODO: Unsure about these | |||||
/*public Task AddRoles(params Role[] roles) => xxx; | |||||
public Task RemoveRoles(params Role[] roles) => xxx;*/ | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
using Model = Discord.API.MemberPresence; | |||||
namespace Discord | |||||
{ | |||||
public class Presence | |||||
{ | |||||
public string CurrentGame { get; private set; } | |||||
public UserStatus Status { get; private set; } | |||||
internal Presence() { } | |||||
internal virtual void Update(Model model) | |||||
{ | |||||
CurrentGame = model.Game?.Name; | |||||
Status = model.Status; | |||||
} | |||||
} | |||||
} |
@@ -1,15 +1,42 @@ | |||||
namespace Discord | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
using Model = Discord.API.User; | |||||
namespace Discord | |||||
{ | { | ||||
public class DMUser : User | |||||
public class DMUser : IUser | |||||
{ | { | ||||
public DMChannel Channel { get; } | |||||
private readonly GlobalUser _user; | |||||
public override DiscordClient Discord => Channel.Discord; | |||||
public DMChannel Channel { get; } | |||||
/// <inheritdoc /> | |||||
public DiscordClient Discord => _user.Discord; | |||||
/// <inheritdoc /> | |||||
public ulong Id => _user.Id; | |||||
/// <inheritdoc /> | |||||
public string Username => _user.Username; | |||||
/// <inheritdoc /> | |||||
public ushort Discriminator => _user.Discriminator; | |||||
/// <inheritdoc /> | |||||
public bool IsBot => _user.IsBot; | |||||
/// <inheritdoc /> | |||||
public string CurrentGame => _user.CurrentGame; | |||||
/// <inheritdoc /> | |||||
public UserStatus Status => _user.Status; | |||||
/// <inheritdoc /> | |||||
public string AvatarUrl => _user.AvatarUrl; | |||||
/// <inheritdoc /> | |||||
public string Mention => _user.Mention; | |||||
internal DMUser(ulong id, DMChannel channel) | |||||
: base(id) | |||||
internal DMUser(GlobalUser user, DMChannel channel) | |||||
{ | { | ||||
_user = user; | |||||
Channel = channel; | Channel = channel; | ||||
} | } | ||||
public void Update(Model model) => _user.Update(model); | |||||
public virtual Task Update() { throw new NotSupportedException(); } | |||||
} | } | ||||
} | } |
@@ -4,25 +4,29 @@ using Model = Discord.API.User; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public abstract class User : IEntity<ulong> | |||||
public class GlobalUser : IUser, IEntity<ulong> | |||||
{ | { | ||||
private string _avatarId; | private string _avatarId; | ||||
private int _refCount; | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public ulong Id { get; } | public ulong Id { get; } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public abstract DiscordClient Discord { get; } | |||||
public DiscordClient Discord { get; } | |||||
public string Username { get; private set; } | public string Username { get; private set; } | ||||
public ushort Discriminator { get; private set; } | public ushort Discriminator { get; private set; } | ||||
public bool IsBot { get; private set; } | public bool IsBot { get; private set; } | ||||
public string CurrentGame { get; private set; } | |||||
public UserStatus Status { get; private set; } | |||||
public string AvatarUrl => CDN.GetUserAvatarUrl(Id, _avatarId); | public string AvatarUrl => CDN.GetUserAvatarUrl(Id, _avatarId); | ||||
public string Mention => MentionHelper.Mention(this); | public string Mention => MentionHelper.Mention(this); | ||||
internal User(ulong id) | |||||
internal GlobalUser(ulong id, DiscordClient discord) | |||||
{ | { | ||||
Id = id; | Id = id; | ||||
Discord = discord; | |||||
} | } | ||||
internal virtual void Update(Model model) | internal virtual void Update(Model model) | ||||
{ | { | ||||
@@ -34,6 +38,18 @@ namespace Discord | |||||
public virtual Task Update() { throw new NotSupportedException(); } | public virtual Task Update() { throw new NotSupportedException(); } | ||||
public async Task<DMChannel> CreateDMChannel() => await Discord.GetOrCreateDMChannel(Id); //TODO: We dont want both this and .Channel to appear on DMUser | |||||
public async Task<DMChannel> CreateDMChannel() => await Discord.GetOrCreateDMChannel(Id); | |||||
internal void Attach(IUser user) | |||||
{ | |||||
//Only ever called from the gateway thread | |||||
_refCount++; | |||||
} | |||||
internal void Detach(IUser user) | |||||
{ | |||||
//Only ever called from the gateway thread | |||||
if (--_refCount == 0) | |||||
Discord.RemoveUser(this); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,48 +1,81 @@ | |||||
using Discord.API.Rest; | using Discord.API.Rest; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Model = Discord.API.GuildMember; | using Model = Discord.API.GuildMember; | ||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public class GuildUser : User, IMentionable | |||||
public class GuildUser : IUser | |||||
{ | { | ||||
private readonly GlobalUser _user; | |||||
public Guild Guild { get; } | public Guild Guild { get; } | ||||
public GuildPresence Presence { get; } | |||||
public VoiceState VoiceState { get; } | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public DateTime JoinedAt { get; private set; } | |||||
public GuildPermissions GuildPermissions { get; internal set; } | |||||
public string CurrentGame { get; private set; } | |||||
/// <inheritdoc /> | |||||
public UserStatus Status { get; private set; } | |||||
public VoiceChannel VoiceChannel { get; private set; } | |||||
public override DiscordClient Discord => Guild.Discord; | |||||
public IEnumerable<TextChannel> TextChannels => Guild.TextChannels.Where(x => GetPermissions(x).ReadMessages); | |||||
/// <inheritdoc /> | |||||
public DiscordClient Discord => _user.Discord; | |||||
/// <inheritdoc /> | |||||
public ulong Id => _user.Id; | |||||
/// <inheritdoc /> | |||||
public string Username => _user.Username; | |||||
/// <inheritdoc /> | |||||
public ushort Discriminator => _user.Discriminator; | |||||
/// <inheritdoc /> | |||||
public bool IsBot => _user.IsBot; | |||||
/// <inheritdoc /> | |||||
public string AvatarUrl => _user.AvatarUrl; | |||||
/// <inheritdoc /> | |||||
public string Mention => _user.Mention; | |||||
internal GuildUser(ulong id, Guild guild, GuildPresence presence, VoiceState voiceState) | |||||
: base(id) | |||||
/// <inheritdoc /> | |||||
public IReadOnlyList<Role> Roles { get; private set; } | |||||
internal GuildUser(GlobalUser user, Guild guild) | |||||
{ | { | ||||
_user = user; | |||||
Guild = guild; | Guild = guild; | ||||
Presence = presence; | |||||
VoiceState = voiceState; | |||||
} | } | ||||
internal void Update(Model model) | internal void Update(Model model) | ||||
{ | { | ||||
base.Update(model.User); | |||||
JoinedAt = model.JoinedAt.Value; | JoinedAt = model.JoinedAt.Value; | ||||
Roles = model.Roles.Select(x => Guild.GetRole(x)).ToImmutableArray(); | |||||
} | } | ||||
public bool HasRole(Role role) => false; //TODO: Implement | |||||
public Task Kick() => Discord.RestClient.Send(new RemoveGuildMemberRequest(Guild.Id, Id)); | |||||
public Task Ban(int pruneDays = 0) => Discord.RestClient.Send(new CreateGuildBanRequest(Guild.Id, Id) { PruneDays = pruneDays }); | |||||
public Task Unban() => Discord.RestClient.Send(new RemoveGuildBanRequest(Guild.Id, Id)); | |||||
/// <inheritdoc /> | |||||
public DateTime JoinedAt { get; private set; } | |||||
public GuildPermissions GuildPermissions { get; internal set; } | |||||
public Task<DMChannel> CreateDMChannel() => _user.CreateDMChannel(); | |||||
/// <inheritdoc /> | |||||
public Task Update() { throw new NotSupportedException(); } //TODO: Not supported | |||||
public ChannelPermissions GetPermissions(GuildChannel channel) | public ChannelPermissions GetPermissions(GuildChannel channel) | ||||
{ | { | ||||
if (channel == null) throw new ArgumentNullException(nameof(channel)); | if (channel == null) throw new ArgumentNullException(nameof(channel)); | ||||
return channel.GetPermissions(this); | return channel.GetPermissions(this); | ||||
} | } | ||||
/// <inheritdoc /> | |||||
public override Task Update() { throw new NotSupportedException(); } //TODO: Not supported yet | |||||
public Task Kick() => Discord.RestClient.Send(new RemoveGuildMemberRequest(Guild.Id, Id)); | |||||
public Task Ban(int pruneDays = 0) => Discord.RestClient.Send(new CreateGuildBanRequest(Guild.Id, Id) { PruneDays = pruneDays }); | |||||
public Task Unban() => Discord.RestClient.Send(new RemoveGuildBanRequest(Guild.Id, Id)); | |||||
public async Task Modify(Action<ModifyGuildMemberRequest> func) | |||||
{ | |||||
if (func != null) throw new NullReferenceException(nameof(func)); | |||||
var req = new ModifyGuildMemberRequest(Guild.Id, Id); | |||||
func(req); | |||||
await Discord.RestClient.Send(req).ConfigureAwait(false); | |||||
} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,14 @@ | |||||
namespace Discord | |||||
{ | |||||
public interface IUser : IEntity<ulong> | |||||
{ | |||||
string Username { get; } | |||||
ushort Discriminator { get; } | |||||
bool IsBot { get; } | |||||
string AvatarUrl { get; } | |||||
string Mention { get; } | |||||
string CurrentGame { get; } | |||||
UserStatus Status { get; } | |||||
} | |||||
} |
@@ -1,13 +0,0 @@ | |||||
namespace Discord | |||||
{ | |||||
public class PublicUser : User | |||||
{ | |||||
public override DiscordClient Discord { get; } | |||||
internal PublicUser(ulong id, DiscordClient discord) | |||||
: base(id) | |||||
{ | |||||
Discord = discord; | |||||
} | |||||
} | |||||
} |
@@ -2,17 +2,14 @@ | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public class SelfUser : User | |||||
public class SelfUser : GlobalUser | |||||
{ | { | ||||
public override DiscordClient Discord { get; } | |||||
public string Email { get; private set; } | public string Email { get; private set; } | ||||
public bool IsVerified { get; private set; } | public bool IsVerified { get; private set; } | ||||
internal SelfUser(ulong id, DiscordClient discord) | internal SelfUser(ulong id, DiscordClient discord) | ||||
: base(id) | |||||
: base(id, discord) | |||||
{ | { | ||||
Discord = discord; | |||||
} | } | ||||
internal override void Update(Model model) | internal override void Update(Model model) | ||||
@@ -1,8 +1,4 @@ | |||||
using Discord.API.Rest; | |||||
using System; | |||||
using System.Collections.Immutable; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
/*using System; | |||||
using Model = Discord.API.MemberVoiceState; | using Model = Discord.API.MemberVoiceState; | ||||
namespace Discord | namespace Discord | ||||
@@ -63,4 +59,4 @@ namespace Discord | |||||
_voiceStates &= ~VoiceStates.Suppressed; | _voiceStates &= ~VoiceStates.Suppressed; | ||||
} | } | ||||
} | } | ||||
} | |||||
}*/ |
@@ -26,6 +26,6 @@ | |||||
MuteMembers = 22, | MuteMembers = 22, | ||||
DeafenMembers = 23, | DeafenMembers = 23, | ||||
MoveMembers = 24, | MoveMembers = 24, | ||||
UseVoiceActivation = 25 | |||||
UseVAD = 25 | |||||
} | } | ||||
} | } |
@@ -2,6 +2,7 @@ | |||||
{ | { | ||||
public enum UserStatus | public enum UserStatus | ||||
{ | { | ||||
Unknown, | |||||
Online, | Online, | ||||
Idle, | Idle, | ||||
Offline | Offline | ||||
@@ -5,9 +5,9 @@ namespace Discord | |||||
public class TypingEventArgs : EventArgs | public class TypingEventArgs : EventArgs | ||||
{ | { | ||||
public IMessageChannel Channel { get; } | public IMessageChannel Channel { get; } | ||||
public User User { get; } | |||||
public IUser User { get; } | |||||
public TypingEventArgs(IMessageChannel channel, User user) | |||||
public TypingEventArgs(IMessageChannel channel, IUser user) | |||||
{ | { | ||||
Channel = channel; | Channel = channel; | ||||
User = user; | User = user; | ||||
@@ -4,9 +4,9 @@ namespace Discord | |||||
{ | { | ||||
public class UserEventArgs : EventArgs | public class UserEventArgs : EventArgs | ||||
{ | { | ||||
public User User { get; } | |||||
public IUser User { get; } | |||||
public UserEventArgs(User user) | |||||
public UserEventArgs(IUser user) | |||||
{ | { | ||||
User = user; | User = user; | ||||
} | } | ||||
@@ -2,10 +2,10 @@ | |||||
{ | { | ||||
public class UserUpdatedEventArgs : UserEventArgs | public class UserUpdatedEventArgs : UserEventArgs | ||||
{ | { | ||||
public User Before { get; } | |||||
public User After => User; | |||||
public IUser Before { get; } | |||||
public IUser After => User; | |||||
public UserUpdatedEventArgs(User before, User after) | |||||
public UserUpdatedEventArgs(IUser before, IUser after) | |||||
: base(after) | : base(after) | ||||
{ | { | ||||
Before = before; | Before = before; | ||||
@@ -2,7 +2,7 @@ | |||||
{ | { | ||||
internal static class InternalExtensions | internal static class InternalExtensions | ||||
{ | { | ||||
public static User GetCurrentUser(this IChannel channel) | |||||
public static IUser GetCurrentUser(this IChannel channel) | |||||
{ | { | ||||
switch (channel.Type) | switch (channel.Type) | ||||
{ | { | ||||
@@ -197,7 +197,7 @@ namespace Discord | |||||
//{ | //{ | ||||
try | try | ||||
{ | { | ||||
var request = new UpdateMessageRequest(msg.Channel.Id, msg.Id) | |||||
var request = new ModifyMessageRequest(msg.Channel.Id, msg.Id) | |||||
{ | { | ||||
Content = item.NewText | Content = item.NewText | ||||
}; | }; | ||||
@@ -242,7 +242,7 @@ namespace Discord.Tests | |||||
"MessageUpdated event never received", | "MessageUpdated event never received", | ||||
async () => await message.Modify(x => | async () => await message.Modify(x => | ||||
{ | { | ||||
x.Text = text + " updated"; | |||||
x.Content = text + " updated"; | |||||
}), | }), | ||||
x => _targetBot.MessageUpdated += x, | x => _targetBot.MessageUpdated += x, | ||||
x => _targetBot.MessageUpdated -= x, | x => _targetBot.MessageUpdated -= x, | ||||
@@ -293,7 +293,11 @@ namespace Discord.Tests | |||||
var user = _testGuild.GetUser(_targetBot.CurrentUser.Id); | var user = _testGuild.GetUser(_targetBot.CurrentUser.Id); | ||||
AssertEvent<UserUpdatedEventArgs>( | AssertEvent<UserUpdatedEventArgs>( | ||||
"UserUpdated never fired", | "UserUpdated never fired", | ||||
async () => await user.Modify(true, true, null, null), | |||||
async () => await user.Modify(x => | |||||
{ | |||||
x.Deaf = true; | |||||
x.Mute = true; | |||||
}), | |||||
x => _targetBot.UserUpdated += x, | x => _targetBot.UserUpdated += x, | ||||
x => _targetBot.UserUpdated -= x); | x => _targetBot.UserUpdated -= x); | ||||
} | } | ||||
@@ -319,7 +323,7 @@ namespace Discord.Tests | |||||
x => _observerBot.UserUpdated -= x, | x => _observerBot.UserUpdated -= x, | ||||
(s, e) => e.After.Status == UserStatus.Idle); | (s, e) => e.After.Status == UserStatus.Idle); | ||||
} | } | ||||
private async Task SetStatus(DiscordClient _client, UserStatus status) | |||||
private Task SetStatus(DiscordClient _client, UserStatus status) | |||||
{ | { | ||||
throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
/*_client.SetStatus(status); | /*_client.SetStatus(status); | ||||
@@ -336,7 +340,7 @@ namespace Discord.Tests | |||||
(s, e) => _targetBot.CurrentUser.CurrentGame == "test game"); | (s, e) => _targetBot.CurrentUser.CurrentGame == "test game"); | ||||
} | } | ||||
private async Task SetGame(DiscordClient _client, string game) | |||||
private Task SetGame(DiscordClient _client, string game) | |||||
{ | { | ||||
throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
//_client.SetGame(game); | //_client.SetGame(game); | ||||