diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 3056d678a..cea87d328 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -82,8 +82,8 @@ API\Enums\AvatarImageType.cs - - API\Enums\ChannelTypes.cs + + API\Enums\ChannelType.cs API\Enums\PermissionTarget.cs @@ -91,6 +91,9 @@ API\Enums\Regions.cs + + API\Enums\StringEnum.cs + API\Enums\UserStatus.cs diff --git a/src/Discord.Net/API/Enums/ChannelType.cs b/src/Discord.Net/API/Enums/ChannelType.cs new file mode 100644 index 000000000..066d12565 --- /dev/null +++ b/src/Discord.Net/API/Enums/ChannelType.cs @@ -0,0 +1,28 @@ +namespace Discord +{ + public class ChannelType : StringEnum + { + /// A text-only channel. + public static readonly ChannelType Text = new ChannelType("text"); + /// A voice-only channel. + public static readonly ChannelType Voice = new ChannelType("voice"); + + private ChannelType(string value) + : base(value) { } + + public static ChannelType FromString(string value) + { + switch (value) + { + case null: + return null; + case "text": + return ChannelType.Text; + case "voice": + return ChannelType.Voice; + default: + return new ChannelType(value); + } + } + } +} diff --git a/src/Discord.Net/API/Enums/ChannelTypes.cs b/src/Discord.Net/API/Enums/ChannelTypes.cs deleted file mode 100644 index caa118c73..000000000 --- a/src/Discord.Net/API/Enums/ChannelTypes.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Discord -{ - public static class ChannelTypes - { - /// A text-only channel. - public const string Text = "text"; - /// A voice-only channel. - public const string Voice = "voice"; - } -} diff --git a/src/Discord.Net/API/Enums/PermissionTarget.cs b/src/Discord.Net/API/Enums/PermissionTarget.cs index 4e53e64ab..63672f3b5 100644 --- a/src/Discord.Net/API/Enums/PermissionTarget.cs +++ b/src/Discord.Net/API/Enums/PermissionTarget.cs @@ -1,8 +1,28 @@ namespace Discord { - public static class PermissionTarget - { - public const string Role = "role"; - public const string Member = "member"; + public class PermissionTarget : StringEnum + { + /// A text-only channel. + public static readonly PermissionTarget Role = new PermissionTarget("role"); + /// A voice-only channel. + public static readonly PermissionTarget Member = new PermissionTarget("member"); + + private PermissionTarget(string value) + : base(value) { } + + public static PermissionTarget FromString(string value) + { + switch (value) + { + case null: + return null; + case "role": + return PermissionTarget.Role; + case "member": + return PermissionTarget.Member; + default: + return new PermissionTarget(value); + } + } } } diff --git a/src/Discord.Net/API/Enums/Regions.cs b/src/Discord.Net/API/Enums/Regions.cs index ea38a6bd7..505778ad5 100644 --- a/src/Discord.Net/API/Enums/Regions.cs +++ b/src/Discord.Net/API/Enums/Regions.cs @@ -1,12 +1,38 @@ namespace Discord { - public static class Regions + public class Region : StringEnum { - public const string US_West = "us-west"; - public const string US_East = "us-east"; - public const string Singapore = "singapore"; - public const string London = "london"; - public const string Sydney = "sydney"; - public const string Amsterdam = "amsterdam"; + public static readonly Region USWest = new Region("us-west"); + public static readonly Region USEast = new Region("us-east"); + public static readonly Region Singapore = new Region("singapore"); + public static readonly Region London = new Region("london"); + public static readonly Region Sydney = new Region("sydney"); + public static readonly Region Amsterdam = new Region("amsterdam"); + + private Region(string value) + : base(value) { } + + public static Region FromString(string value) + { + switch (value) + { + case null: + return null; + case "us-west": + return Region.USWest; + case "us-east": + return Region.USEast; + case "singapore": + return Region.Singapore; + case "london": + return Region.London; + case "sydney": + return Region.Sydney; + case "amsterdam": + return Region.Amsterdam; + default: + return new Region(value); + } + } } } diff --git a/src/Discord.Net/API/Enums/StringEnum.cs b/src/Discord.Net/API/Enums/StringEnum.cs new file mode 100644 index 000000000..88a527dd2 --- /dev/null +++ b/src/Discord.Net/API/Enums/StringEnum.cs @@ -0,0 +1,52 @@ +namespace Discord +{ + public abstract class StringEnum + { + private string _value; + protected StringEnum(string value) + { + _value = value; + } + + public string Value => _value; + public override string ToString() => _value; + + public override bool Equals(object obj) + { + var enum2 = obj as StringEnum; + if (enum2 == (StringEnum)null) + return false; + else + return _value == enum2._value; + } + public override int GetHashCode() + { + return _value.GetHashCode(); + } + + public static bool operator ==(StringEnum a, StringEnum b) + { + return a?._value == b?._value; + } + public static bool operator !=(StringEnum a, StringEnum b) + { + return a?._value != b?._value; + } + public static bool operator ==(StringEnum a, string b) + { + return a?._value == b; + } + public static bool operator !=(StringEnum a, string b) + { + return a?._value != b; + } + public static bool operator ==(string a, StringEnum b) + { + return a == b?._value; + } + public static bool operator !=(string a, StringEnum b) + { + return a != b?._value; + } + } +} diff --git a/src/Discord.Net/API/Enums/UserStatus.cs b/src/Discord.Net/API/Enums/UserStatus.cs index 4a4a5d8c3..493c9ec50 100644 --- a/src/Discord.Net/API/Enums/UserStatus.cs +++ b/src/Discord.Net/API/Enums/UserStatus.cs @@ -1,12 +1,32 @@ namespace Discord { - public static class UserStatus + public class UserStatus : StringEnum { /// User is currently online and active. - public const string Online = "online"; + public static readonly UserStatus Online = new UserStatus("online"); /// User is currently online but inactive. - public const string Idle = "idle"; + public static readonly UserStatus Idle = new UserStatus("idle"); /// User is offline. - public const string Offline = "offline"; + public static readonly UserStatus Offline = new UserStatus("offline"); + + private UserStatus(string value) + : base(value) { } + + public static UserStatus FromString(string value) + { + switch (value) + { + case null: + return null; + case "online": + return UserStatus.Online; + case "idle": + return UserStatus.Idle; + case "offline": + return UserStatus.Offline; + default: + return new UserStatus(value); + } + } } } diff --git a/src/Discord.Net/DiscordClient.Bans.cs b/src/Discord.Net/DiscordClient.Bans.cs index 3d1d631b3..b9fa351aa 100644 --- a/src/Discord.Net/DiscordClient.Bans.cs +++ b/src/Discord.Net/DiscordClient.Bans.cs @@ -35,8 +35,8 @@ namespace Discord /// Bans a user from the provided server. public Task Ban(Member member) { - CheckReady(); if (member == null) throw new ArgumentNullException(nameof(member)); + CheckReady(); return _api.Ban(member.ServerId, member.Id); } @@ -44,8 +44,8 @@ namespace Discord /// Unbans a user from the provided server. public async Task Unban(Member member) { - CheckReady(); if (member == null) throw new ArgumentNullException(nameof(member)); + CheckReady(); try { await _api.Unban(member.ServerId, member.Id).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } diff --git a/src/Discord.Net/DiscordClient.Channels.cs b/src/Discord.Net/DiscordClient.Channels.cs index 0d69cdb63..1b15a2d2f 100644 --- a/src/Discord.Net/DiscordClient.Channels.cs +++ b/src/Discord.Net/DiscordClient.Channels.cs @@ -56,7 +56,7 @@ namespace Discord /// Returns all channels with the specified server and name. /// Name formats supported: Name and #Name. Search is case-insensitive. - public IEnumerable FindChannels(Server server, string name, string type = null) + public IEnumerable FindChannels(Server server, string name, ChannelType type = null) { if (server == null) throw new ArgumentNullException(nameof(server)); @@ -74,21 +74,21 @@ namespace Discord string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); } - if (type != null) + if (type != (string)null) result = result.Where(x => x.Type == type); return result; } - /// Creates a new channel with the provided name and type (see ChannelTypes). - public async Task CreateChannel(Server server, string name, string type = ChannelTypes.Text) + /// Creates a new channel with the provided name and type. + public async Task CreateChannel(Server server, string name, ChannelType type) { if (server == null) throw new ArgumentNullException(nameof(server)); if (name == null) throw new ArgumentNullException(nameof(name)); - if (type == null) throw new ArgumentNullException(nameof(type)); + if (type == (string)null) throw new ArgumentNullException(nameof(type)); CheckReady(); - var response = await _api.CreateChannel(server.Id, name, type).ConfigureAwait(false); + var response = await _api.CreateChannel(server.Id, name, type.Value).ConfigureAwait(false); var channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id); channel.Update(response); return channel; @@ -153,15 +153,16 @@ namespace Discord { if (server == null) throw new ArgumentNullException(nameof(server)); if (channels == null) throw new ArgumentNullException(nameof(channels)); - + CheckReady(); + return _api.ReorderChannels(server.Id, channels.Select(x => x.Id), after.Position); } /// Destroys the provided channel. public async Task DestroyChannel(Channel channel) { - CheckReady(); if (channel == null) throw new ArgumentNullException(nameof(channel)); + CheckReady(); try { await _api.DestroyChannel(channel.Id).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } diff --git a/src/Discord.Net/DiscordClient.Invites.cs b/src/Discord.Net/DiscordClient.Invites.cs index d2aed4501..8637243f1 100644 --- a/src/Discord.Net/DiscordClient.Invites.cs +++ b/src/Discord.Net/DiscordClient.Invites.cs @@ -10,8 +10,8 @@ namespace Discord /// Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode public async Task GetInvite(string inviteIdOrXkcd) { - CheckReady(); if (inviteIdOrXkcd == null) throw new ArgumentNullException(nameof(inviteIdOrXkcd)); + CheckReady(); //Remove trailing slash if (inviteIdOrXkcd.Length > 0 && inviteIdOrXkcd[inviteIdOrXkcd.Length - 1] == '/') @@ -35,6 +35,8 @@ namespace Discord public Task CreateInvite(Server server, int maxAge = 1800, int maxUses = 0, bool tempMembership = false, bool hasXkcd = false) { if (server == null) throw new ArgumentNullException(nameof(server)); + CheckReady(); + return CreateInvite(server.DefaultChannel, maxAge, maxUses, tempMembership, hasXkcd); } /// Creates a new invite to the provided channel. @@ -59,8 +61,8 @@ namespace Discord /// Deletes the provided invite. public async Task DestroyInvite(Invite invite) { - CheckReady(); if (invite == null) throw new ArgumentNullException(nameof(invite)); + CheckReady(); try { await _api.DeleteInvite(invite.Id).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } @@ -69,8 +71,8 @@ namespace Discord /// Accepts the provided invite. public Task AcceptInvite(Invite invite) { - CheckReady(); if (invite == null) throw new ArgumentNullException(nameof(invite)); + CheckReady(); return _api.AcceptInvite(invite.Id); } diff --git a/src/Discord.Net/DiscordClient.Messages.cs b/src/Discord.Net/DiscordClient.Messages.cs index 4c59b374c..e97ef97c9 100644 --- a/src/Discord.Net/DiscordClient.Messages.cs +++ b/src/Discord.Net/DiscordClient.Messages.cs @@ -190,7 +190,7 @@ namespace Discord CheckReady(); if (count == 0) return new Message[0]; - if (channel != null && channel.Type == ChannelTypes.Text) + if (channel != null && channel.Type == ChannelType.Text) { try { diff --git a/src/Discord.Net/DiscordClient.Permissions.cs b/src/Discord.Net/DiscordClient.Permissions.cs index b67bacac3..29010c607 100644 --- a/src/Discord.Net/DiscordClient.Permissions.cs +++ b/src/Discord.Net/DiscordClient.Permissions.cs @@ -8,20 +8,39 @@ namespace Discord public partial class DiscordClient { public Task SetChannelUserPermissions(Channel channel, Member member, ChannelPermissions allow = null, ChannelPermissions deny = null) - => SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, allow, deny); + { + if (channel == null) throw new ArgumentNullException(nameof(channel)); + if (member == null) throw new ArgumentNullException(nameof(member)); + CheckReady(); + + return SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, allow, deny); + } public Task SetChannelUserPermissions(Channel channel, Member member, DualChannelPermissions permissions = null) - => SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, permissions?.Allow, permissions?.Deny); + { + if (channel == null) throw new ArgumentNullException(nameof(channel)); + if (member == null) throw new ArgumentNullException(nameof(member)); + CheckReady(); + + return SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, permissions?.Allow, permissions?.Deny); + } public Task SetChannelRolePermissions(Channel channel, Role role, ChannelPermissions allow = null, ChannelPermissions deny = null) - => SetChannelPermissions(channel, role?.Id, PermissionTarget.Role, allow, deny); - public Task SetChannelRolePermissions(Channel channel, Role role, DualChannelPermissions permissions = null) - => SetChannelPermissions(channel, role?.Id, PermissionTarget.Role, permissions?.Allow, permissions?.Deny); - private async Task SetChannelPermissions(Channel channel, string targetId, string targetType, ChannelPermissions allow = null, ChannelPermissions deny = null) { + if (channel == null) throw new ArgumentNullException(nameof(channel)); + if (role == null) throw new ArgumentNullException(nameof(role)); CheckReady(); + + return SetChannelPermissions(channel, role?.Id, PermissionTarget.Role, allow, deny); + } + public Task SetChannelRolePermissions(Channel channel, Role role, DualChannelPermissions permissions = null) + { if (channel == null) throw new ArgumentNullException(nameof(channel)); - if (targetId == null) throw new ArgumentNullException(nameof(targetId)); - if (targetType == null) throw new ArgumentNullException(nameof(targetType)); + if (role == null) throw new ArgumentNullException(nameof(role)); + CheckReady(); + return SetChannelPermissions(channel, role?.Id, PermissionTarget.Role, permissions?.Allow, permissions?.Deny); + } + private async Task SetChannelPermissions(Channel channel, string targetId, PermissionTarget targetType, ChannelPermissions allow = null, ChannelPermissions deny = null) + { uint allowValue = allow?.RawValue ?? 0; uint denyValue = deny?.RawValue ?? 0; bool changed = false; @@ -29,7 +48,7 @@ namespace Discord var perms = channel.PermissionOverwrites.Where(x => x.TargetType != targetType || x.TargetId != targetId).FirstOrDefault(); if (allowValue != 0 || denyValue != 0) { - await _api.SetChannelPermissions(channel.Id, targetId, targetType, allowValue, denyValue); + await _api.SetChannelPermissions(channel.Id, targetId, targetType.Value, allowValue, denyValue); if (perms != null) { perms.Allow.SetRawValueInternal(allowValue); @@ -84,19 +103,19 @@ namespace Discord return RemoveChannelPermissions(channel, role?.Id, PermissionTarget.Role); } - private async Task RemoveChannelPermissions(Channel channel, string userOrRoleId, string idType) + private async Task RemoveChannelPermissions(Channel channel, string userOrRoleId, PermissionTarget targetType) { try { - var perms = channel.PermissionOverwrites.Where(x => x.TargetType != idType || x.TargetId != userOrRoleId).FirstOrDefault(); + var perms = channel.PermissionOverwrites.Where(x => x.TargetType != targetType || x.TargetId != userOrRoleId).FirstOrDefault(); await _api.DeleteChannelPermissions(channel.Id, userOrRoleId).ConfigureAwait(false); if (perms != null) { - channel.PermissionOverwrites.Where(x => x.TargetType != idType || x.TargetId != userOrRoleId).ToArray(); + channel.PermissionOverwrites.Where(x => x.TargetType != targetType || x.TargetId != userOrRoleId).ToArray(); - if (idType == PermissionTarget.Role) + if (targetType == PermissionTarget.Role) channel.InvalidatePermissionsCache(); - else if (idType == PermissionTarget.Member) + else if (targetType == PermissionTarget.Member) channel.InvalidatePermissionsCache(userOrRoleId); } } diff --git a/src/Discord.Net/DiscordClient.Roles.cs b/src/Discord.Net/DiscordClient.Roles.cs index 2248baed9..866852061 100644 --- a/src/Discord.Net/DiscordClient.Roles.cs +++ b/src/Discord.Net/DiscordClient.Roles.cs @@ -63,13 +63,20 @@ namespace Discord private readonly Roles _roles; /// Returns the role with the specified id, or null if none was found. - public Role GetRole(string id) => _roles[id]; + public Role GetRole(string id) + { + if (id == null) throw new ArgumentNullException(nameof(id)); + CheckReady(); + + return _roles[id]; + } /// Returns all roles with the specified server and name. /// Name formats supported: Name and @Name. Search is case-insensitive. public IEnumerable FindRoles(Server server, string name) { if (server == null) throw new ArgumentNullException(nameof(server)); if (name == null) throw new ArgumentNullException(nameof(name)); + CheckReady(); if (name.StartsWith("@")) { @@ -83,18 +90,16 @@ namespace Discord string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); } } - - /// Note: due to current API limitations, the created role cannot be returned. - public Task CreateRole(Server server, string name) - => CreateRole(server?.Id, name); + /// Note: due to current API limitations, the created role cannot be returned. - public async Task CreateRole(string serverId, string name) + public async Task CreateRole(Server server, string name) { + if (server == null) throw new ArgumentNullException(nameof(server)); + if (name == null) throw new ArgumentNullException(nameof(name)); CheckReady(); - if (serverId == null) throw new ArgumentNullException(nameof(serverId)); - var response = await _api.CreateRole(serverId).ConfigureAwait(false); - var role = _roles.GetOrAdd(response.Id, serverId); + var response = await _api.CreateRole(server.Id).ConfigureAwait(false); + var role = _roles.GetOrAdd(response.Id, server.Id); role.Update(response); await EditRole(role, name: name); diff --git a/src/Discord.Net/DiscordClient.Servers.cs b/src/Discord.Net/DiscordClient.Servers.cs index 15ac58476..0e053f3e4 100644 --- a/src/Discord.Net/DiscordClient.Servers.cs +++ b/src/Discord.Net/DiscordClient.Servers.cs @@ -98,48 +98,43 @@ namespace Discord public IEnumerable FindServers(string name) { if (name == null) throw new ArgumentNullException(nameof(name)); + CheckReady(); return _servers.Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); } /// Creates a new server with the provided name and region (see Regions). - public async Task CreateServer(string name, string region) + public async Task CreateServer(string name, Region region) { - CheckReady(); if (name == null) throw new ArgumentNullException(nameof(name)); - if (region == null) throw new ArgumentNullException(nameof(region)); + if (region == (string)null) throw new ArgumentNullException(nameof(region)); + CheckReady(); - var response = await _api.CreateServer(name, region).ConfigureAwait(false); + var response = await _api.CreateServer(name, region.Value).ConfigureAwait(false); var server = _servers.GetOrAdd(response.Id); server.Update(response); return server; } - - /// Edits the provided server, changing only non-null attributes. - public Task EditServer(string serverId, string name = null, string region = null, ImageType iconType = ImageType.Png, byte[] icon = null) - => EditServer(_servers[serverId], name: name, region: region, iconType: iconType, icon: icon); + /// Edits the provided server, changing only non-null attributes. - public async Task EditServer(Server server, string name = null, string region = null, ImageType iconType = ImageType.Png, byte[] icon = null) + public async Task EditServer(Server server, string name = null, Region region = null, ImageType iconType = ImageType.Png, byte[] icon = null) { - CheckReady(); if (server == null) throw new ArgumentNullException(nameof(server)); + CheckReady(); - var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region, iconType: iconType, icon: icon); + var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region.Value, iconType: iconType, icon: icon); server.Update(response); } - + /// Leaves the provided server, destroying it if you are the owner. - public Task LeaveServer(Server server) - => LeaveServer(server?.Id); - /// Leaves the provided server, destroying it if you are the owner. - public async Task LeaveServer(string serverId) + public async Task LeaveServer(Server server) { + if (server == null) throw new ArgumentNullException(nameof(server)); CheckReady(); - if (serverId == null) throw new ArgumentNullException(nameof(serverId)); - try { await _api.LeaveServer(serverId).ConfigureAwait(false); } + try { await _api.LeaveServer(server.Id).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } - return _servers.TryRemove(serverId); + return _servers.TryRemove(server.Id); } } } \ No newline at end of file diff --git a/src/Discord.Net/DiscordClient.Users.cs b/src/Discord.Net/DiscordClient.Users.cs index 6b4bdcf66..3daa0592e 100644 --- a/src/Discord.Net/DiscordClient.Users.cs +++ b/src/Discord.Net/DiscordClient.Users.cs @@ -62,14 +62,18 @@ namespace Discord ImageType avatarType = ImageType.Png, byte[] avatar = null) { if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); + CheckReady(); return _api.EditUser(currentPassword: currentPassword, username: username ?? _currentUser?.Name, email: email ?? _currentUser?.GlobalUser.Email, password: password, avatarType: avatarType, avatar: avatar); } - public Task SetStatus(string status) + public Task SetStatus(UserStatus status) { + if (status == (string)null) throw new ArgumentNullException(nameof(status)); + CheckReady(); + if (status != UserStatus.Online && status != UserStatus.Idle) throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Idle}"); _status = status; @@ -77,6 +81,8 @@ namespace Discord } public Task SetGame(int? gameId) { + CheckReady(); + _gameId = gameId; return SendStatus(); } diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index bdc6e5172..d212398d5 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -19,7 +19,7 @@ namespace Discord private readonly ConcurrentDictionary _voiceClients; private bool _sentInitialLog; private uint _nextVoiceClientId; - private string _status; + private UserStatus _status; private int? _gameId; public new DiscordClientConfig Config => _config as DiscordClientConfig; diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index 3044507cf..73e290aaf 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -11,12 +11,12 @@ namespace Discord { public sealed class PermissionOverwrite { - public string TargetType { get; } + public PermissionTarget TargetType { get; } public string TargetId { get; } public ChannelPermissions Allow { get; } public ChannelPermissions Deny { get; } - internal PermissionOverwrite(string targetType, string targetId, uint allow, uint deny) + internal PermissionOverwrite(PermissionTarget targetType, string targetId, uint allow, uint deny) { TargetType = targetType; TargetId = targetId; @@ -138,7 +138,7 @@ namespace Discord if (model.PermissionOverwrites != null) { _permissionOverwrites = model.PermissionOverwrites - .Select(x => new PermissionOverwrite(x.Type, x.Id, x.Allow, x.Deny)) + .Select(x => new PermissionOverwrite(PermissionTarget.FromString(x.Type), x.Id, x.Allow, x.Deny)) .ToArray(); InvalidatePermissionsCache(); } diff --git a/src/Discord.Net/Models/Permissions.cs b/src/Discord.Net/Models/Permissions.cs index 741cae5b1..dd7b29a53 100644 --- a/src/Discord.Net/Models/Permissions.cs +++ b/src/Discord.Net/Models/Permissions.cs @@ -62,8 +62,8 @@ namespace Discord public static ChannelPermissions All(string channelType, bool isPrivate) { if (isPrivate) return PrivateOnly; - else if (channelType == ChannelTypes.Text) return TextOnly; - else if (channelType == ChannelTypes.Voice) return VoiceOnly; + else if (channelType == ChannelType.Text) return TextOnly; + else if (channelType == ChannelType.Voice) return VoiceOnly; else return None; } diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index bad0e3503..ac2861031 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -8,7 +8,6 @@ namespace Discord public sealed class Role : CachedObject { private readonly string _serverId; - private Server _server; /// Returns the name of this role. public string Name { get; private set; } @@ -26,7 +25,7 @@ namespace Discord /// Returns the server this role is a member of. [JsonIgnore] - public Server Server => _server; + public Server Server { get; private set; } /// Returns true if this is the role representing all users in a server. public bool IsEveryone => Id == _serverId; @@ -48,14 +47,16 @@ namespace Discord } internal override void OnCached() { - _server = _client.Servers[_serverId]; - _server.AddRole(this); + var server = _client.Servers[_serverId]; + server.AddRole(this); + Server = server; } internal override void OnUncached() { - if (_server != null) - _server.RemoveRole(this); - _server = null; + var server = Server; + if (server != null) + server.RemoveRole(this); + Server = null; } internal void Update(RoleInfo model) diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index 606e4df01..4c8e12960 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -60,10 +60,10 @@ namespace Discord public IEnumerable Channels => _channels.Select(x => _client.Channels[x.Key]); /// Returns a collection of all channels within this server. [JsonIgnore] - public IEnumerable TextChannels => _channels.Select(x => _client.Channels[x.Key]).Where(x => x.Type == ChannelTypes.Text); + public IEnumerable TextChannels => _channels.Select(x => _client.Channels[x.Key]).Where(x => x.Type == ChannelType.Text); /// Returns a collection of all channels within this server. [JsonIgnore] - public IEnumerable VoiceChannels => _channels.Select(x => _client.Channels[x.Key]).Where(x => x.Type == ChannelTypes.Voice); + public IEnumerable VoiceChannels => _channels.Select(x => _client.Channels[x.Key]).Where(x => x.Type == ChannelType.Voice); /// Returns a collection of all invites to this server. [JsonIgnore] diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index cef5a07af..d143ecf19 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -40,7 +40,7 @@ namespace Discord /// Returns the id for the game this user is currently playing. public string GameId { get; private set; } /// Returns the current status for this user. - public string Status { get; private set; } + public UserStatus Status { get; private set; } /// Returns the time this user last sent/edited a message, started typing or sent voice data in this server. public DateTime? LastActivityAt { get; private set; } /// Returns the time this user was last seen online in this server. @@ -152,7 +152,7 @@ namespace Discord UpdateRoles(model.Roles); if (model.Status != null && Status != model.Status) { - Status = model.Status; + Status = UserStatus.FromString(model.Status); if (Status == UserStatus.Offline) _lastOnline = DateTime.UtcNow; } diff --git a/src/Discord.Net/Net/Rest/SharpRestEngine.cs b/src/Discord.Net/Net/Rest/SharpRestEngine.cs index 553746f14..ff15fbff5 100644 --- a/src/Discord.Net/Net/Rest/SharpRestEngine.cs +++ b/src/Discord.Net/Net/Rest/SharpRestEngine.cs @@ -19,11 +19,14 @@ namespace Discord.Net.Rest _client = new RestSharp.RestClient(Endpoints.BaseApi) { PreAuthenticate = false, - Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials), ReadWriteTimeout = _config.APITimeout, UserAgent = _config.UserAgent }; - _client.RemoveDefaultParameter("Accept"); + if (_config.ProxyUrl != null) + _client.Proxy = new WebProxy(_config.ProxyUrl, true, new string[0], _config.ProxyCredentials); + else + _client.Proxy = null; + _client.RemoveDefaultParameter("Accept"); _client.AddDefaultHeader("accept", "*/*"); _client.AddDefaultHeader("accept-encoding", "gzip,deflate"); } diff --git a/test/Discord.Net.Tests/Tests.cs b/test/Discord.Net.Tests/Tests.cs index 81515ffd9..56cf7e15f 100644 --- a/test/Discord.Net.Tests/Tests.cs +++ b/test/Discord.Net.Tests/Tests.cs @@ -38,7 +38,7 @@ namespace Discord.Tests _observerBot.AllServers.Select(x => _observerBot.LeaveServer(x))); //Create new server and invite the other bots to it - _testServer = _hostClient.CreateServer("Discord.Net Testing", Regions.US_East).Result; + _testServer = _hostClient.CreateServer("Discord.Net Testing", Region.USEast).Result; _testServerChannel = _testServer.DefaultChannel; Invite invite = _hostClient.CreateInvite(_testServer, 60, 1, false, false).Result; WaitAll( @@ -49,11 +49,11 @@ namespace Discord.Tests //Channels [TestMethod] public void TestCreateTextChannel() - => TestCreateChannel(ChannelTypes.Text); + => TestCreateChannel(ChannelType.Text); [TestMethod] public void TestCreateVoiceChannel() - => TestCreateChannel(ChannelTypes.Voice); - private void TestCreateChannel(string type) + => TestCreateChannel(ChannelType.Voice); + private void TestCreateChannel(ChannelType type) { Channel channel = null; string name = $"#test_{_random.Next()}"; @@ -76,21 +76,21 @@ namespace Discord.Tests [ExpectedException(typeof(InvalidOperationException))] public async Task TestCreateChannel_NoName() { - await _hostClient.CreateChannel(_testServer, $"", ChannelTypes.Text); + await _hostClient.CreateChannel(_testServer, $"", ChannelType.Text); } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public async Task TestCreateChannel_NoType() { string name = $"#test_{_random.Next()}"; - await _hostClient.CreateChannel(_testServer, $"", ""); + await _hostClient.CreateChannel(_testServer, $"", ChannelType.FromString("")); } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public async Task TestCreateChannel_BadType() { string name = $"#test_{_random.Next()}"; - await _hostClient.CreateChannel(_testServer, $"", "badtype"); + await _hostClient.CreateChannel(_testServer, $"", ChannelType.FromString("badtype")); } //Messages