Browse Source

Merge pull request #1 from RogueException/dev

Dev
tags/docs-0.9
Googie2149 9 years ago
parent
commit
affcc806db
24 changed files with 375 additions and 76 deletions
  1. +18
    -0
      Discord.Net.sln
  2. +2
    -2
      src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs
  3. +2
    -2
      src/Discord.Net.Commands/project.json
  4. +56
    -0
      src/Discord.Net.Modules.Net45/Discord.Net.Modules.csproj
  5. +18
    -0
      src/Discord.Net.Modules.Net45/Properties/AssemblyInfo.cs
  6. +21
    -0
      src/Discord.Net.Modules/Discord.Net.Modules.xproj
  7. +22
    -0
      src/Discord.Net.Modules/project.json
  8. +2
    -2
      src/Discord.Net.Net45/Properties/AssemblyInfo.cs
  9. +9
    -6
      src/Discord.Net/API/Endpoints.cs
  10. +2
    -0
      src/Discord.Net/API/Invites.cs
  11. +12
    -1
      src/Discord.Net/API/Members.cs
  12. +15
    -0
      src/Discord.Net/API/Messages.cs
  13. +25
    -6
      src/Discord.Net/DiscordAPIClient.cs
  14. +2
    -2
      src/Discord.Net/DiscordClient.Bans.cs
  15. +19
    -3
      src/Discord.Net/DiscordClient.Invites.cs
  16. +8
    -3
      src/Discord.Net/DiscordClient.Messages.cs
  17. +45
    -5
      src/Discord.Net/DiscordClient.Users.cs
  18. +23
    -12
      src/Discord.Net/DiscordClient.cs
  19. +1
    -1
      src/Discord.Net/Helpers/Reference.cs
  20. +47
    -6
      src/Discord.Net/Models/Invite.cs
  21. +9
    -17
      src/Discord.Net/Models/Server.cs
  22. +9
    -6
      src/Discord.Net/Models/User.cs
  23. +7
    -1
      src/Discord.Net/Net/WebSockets/DataWebSocket.cs
  24. +1
    -1
      src/Discord.Net/project.json

+ 18
- 0
Discord.Net.sln View File

@@ -26,6 +26,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net", "src\Discord.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Commands", "src\Discord.Net.Commands.Net45\Discord.Net.Commands.csproj", "{1B5603B4-6F8F-4289-B945-7BAAE523D740}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Modules", "src\Discord.Net.Modules\Discord.Net.Modules.xproj", "{01584E8A-78DA-486F-9EF9-A894E435841B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Modules", "src\Discord.Net.Modules.Net45\Discord.Net.Modules.csproj", "{3091164F-66AE-4543-A63D-167C1116241D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -63,6 +67,18 @@ Global
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01584E8A-78DA-486F-9EF9-A894E435841B}.Release|Any CPU.Build.0 = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -75,5 +91,7 @@ Global
{855D6B1D-847B-42DA-BE6A-23683EA89511} = {6317A2E6-8E36-4C3E-949B-3F10EC888AB9}
{8D71A857-879A-4A10-859E-5FF824ED6688} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
{1B5603B4-6F8F-4289-B945-7BAAE523D740} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
{01584E8A-78DA-486F-9EF9-A894E435841B} = {EA68EBE2-51C8-4440-9EF7-D633C90A5D35}
{3091164F-66AE-4543-A63D-167C1116241D} = {DF03D4E8-38F6-4FE1-BC52-E38124BE8AFD}
EndGlobalSection
EndGlobal

+ 2
- 2
src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs View File

@@ -13,6 +13,6 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")]

[assembly: AssemblyVersion("0.8.0.0")]
[assembly: AssemblyFileVersion("0.8.0.0")]
[assembly: AssemblyVersion("0.8.1.0")]
[assembly: AssemblyFileVersion("0.8.1.0")]


+ 2
- 2
src/Discord.Net.Commands/project.json View File

@@ -1,5 +1,5 @@
{
"version": "0.8.0-beta1",
"version": "0.8.1-beta1",
"description": "A Discord.Net extension adding basic command support.",
"authors": [ "RogueException" ],
"tags": [ "discord", "discordapp" ],
@@ -13,7 +13,7 @@
"warningsAsErrors": true
},
"dependencies": {
"Discord.Net": "0.8.0-beta1"
"Discord.Net": "0.8.1-beta1"
},
"frameworks": {
"net45": { },


+ 56
- 0
src/Discord.Net.Modules.Net45/Discord.Net.Modules.csproj View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3091164F-66AE-4543-A63D-167C1116241D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Discord</RootNamespace>
<AssemblyName>Discord.Net.Commands</AssemblyName>
<FileAlignment>512</FileAlignment>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<UseMSBuildEngine>False</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;NET45</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>6</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NET45</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>6</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Discord.Net.Net45\Discord.Net.csproj">
<Project>{8d71a857-879a-4a10-859e-5ff824ed6688}</Project>
<Name>Discord.Net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 18
- 0
src/Discord.Net.Modules.Net45/Properties/AssemblyInfo.cs View File

@@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("Discord.Net.Modules")]
[assembly: AssemblyDescription("A Discord.Net extension adding basic plugin support.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("RogueException")]
[assembly: AssemblyProduct("Discord.Net.Modules")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")]

[assembly: AssemblyVersion("0.8.1.0")]
[assembly: AssemblyFileVersion("0.8.1.0")]


+ 21
- 0
src/Discord.Net.Modules/Discord.Net.Modules.xproj View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>01584e8a-78da-486f-9ef9-a894e435841b</ProjectGuid>
<RootNamespace>Discord</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

+ 22
- 0
src/Discord.Net.Modules/project.json View File

@@ -0,0 +1,22 @@
{
"version": "0.8.1-beta1",
"description": "A Discord.Net extension adding basic plugin support.",
"authors": [ "RogueException" ],
"tags": [ "discord", "discordapp" ],
"projectUrl": "https://github.com/RogueException/Discord.Net",
"licenseUrl": "http://opensource.org/licenses/MIT",
"repository": {
"type": "git",
"url": "git://github.com/RogueException/Discord.Net"
},
"compilationOptions": {
"warningsAsErrors": true
},
"dependencies": {
"Discord.Net": "0.8.1-beta1"
},
"frameworks": {
"net45": { },
"dnx451": { }
}
}

+ 2
- 2
src/Discord.Net.Net45/Properties/AssemblyInfo.cs View File

@@ -13,5 +13,5 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")]

[assembly: AssemblyVersion("0.8.0")]
[assembly: AssemblyFileVersion("0.8.0")]
[assembly: AssemblyVersion("0.8.1.0")]
[assembly: AssemblyFileVersion("0.8.1.0")]

+ 9
- 6
src/Discord.Net/API/Endpoints.cs View File

@@ -13,19 +13,22 @@
public const string Channels = "channels";
public static string Channel(string channelId) => $"channels/{channelId}";
public static string ChannelTyping(string channelId) => $"channels/{channelId}/typing";
public static string ChannelInvites(string channelId) => $"channels/{channelId}/invites";
public static string ChannelMessages(string channelId) => $"channels/{channelId}/messages";
public static string ChannelMessages(string channelId, int limit) => $"channels/{channelId}/messages?limit={limit}";
public static string ChannelMessages(string channelId, int limit, string beforeId) => $"channels/{channelId}/messages?limit={limit}&before={beforeId}";
public static string ChannelMessage(string channelId, string msgId) => $"channels/{channelId}/messages/{msgId}";
public static string ChannelMessageAck(string channelId, string msgId) => $"channels/{channelId}/messages/{msgId}/ack";
public static string ChannelInvites(string channelId) => $"channels/{channelId}/invites";
public static string ChannelPermission(string channelId, string userOrRoleId) => $"channels/{channelId}/permissions/{userOrRoleId}";
public static string ChannelTyping(string channelId) => $"channels/{channelId}/typing";

public const string Servers = "guilds";
public static string Server(string serverId) => $"guilds/{serverId}";
public static string ServerBan(string serverId, string userId) => $"guilds/{serverId}/bans/{userId}";
public static string ServerChannels(string serverId) => $"guilds/{serverId}/channels";
public static string ServerInvites(string serverId) => $"guilds/{serverId}/invites";
public static string ServerMember(string serverId, string userId) => $"guilds/{serverId}/members/{userId}";
public static string ServerBan(string serverId, string userId) => $"guilds/{serverId}/bans/{userId}";
public static string ServerPrune(string serverId, int days) => $"guilds/{serverId}/prune?days={days}";
public static string ServerRoles(string serverId) => $"guilds/{serverId}/roles";
public static string ServerRole(string serverId, string roleId) => $"guilds/{serverId}/roles/{roleId}";

@@ -34,10 +37,10 @@
public static string InviteUrl(string inviteId) => $"https://discord.gg/{inviteId}";

public const string Users = "users";
public static string UserMe => $"users/@me";
public static string UserChannels(string userId) => $"users/{userId}/channels";
public static string UserAvatar(string userId, string avatarId) => $"users/{userId}/avatars/{avatarId}.jpg";
public static string UserChannels(string userId) => $"users/{userId}/channels";
public static string UserMe => $"users/@me";

public const string Voice = "voice";
public const string VoiceRegions = "voice/regions";
//public const string VoiceIce = "voice/ice";


+ 2
- 0
src/Discord.Net/API/Invites.cs View File

@@ -4,6 +4,7 @@

using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace Discord.API
{
@@ -53,6 +54,7 @@ namespace Discord.API

//Get
public class GetInviteResponse : InviteReference { }
public class GetInvitesResponse : List<InviteReference> { }

//Accept
public class AcceptInviteResponse : InviteReference { }


+ 12
- 1
src/Discord.Net/API/Members.cs View File

@@ -82,9 +82,20 @@ namespace Discord.API
public IEnumerable<string> Roles;
}

public class PruneUsersResponse
{
[JsonProperty("pruned")]
public int? Pruned;
}

//Events
internal sealed class MemberAddEvent : MemberInfo { }
internal sealed class MemberUpdateEvent : MemberInfo { }
internal sealed class MemberRemoveEvent : MemberInfo { }
internal sealed class MemberVoiceStateUpdateEvent : VoiceMemberInfo { }
internal sealed class MemberVoiceStateUpdateEvent : VoiceMemberInfo { }
internal sealed class MembersChunkEvent
{
[JsonProperty("members")]
public MemberInfo[] Members;
}
}

+ 15
- 0
src/Discord.Net/API/Messages.cs View File

@@ -125,6 +125,21 @@ namespace Discord.API
//Get
public sealed class GetMessagesResponse : List<MessageInfo> { }

//Commands
internal sealed class GetUsersCommand : WebSocketMessage<GetUsersCommand.Data>
{
public GetUsersCommand() : base(8) { }
public class Data
{
[JsonProperty("guild_id")]
public string ServerId;
[JsonProperty("query")]
public string Query;
[JsonProperty("limit")]
public int Limit;
}
}

//Events
internal sealed class MessageCreateEvent : MessageInfo { }
internal sealed class MessageUpdateEvent : MessageInfo { }


+ 25
- 6
src/Discord.Net/DiscordAPIClient.cs View File

@@ -92,11 +92,14 @@ namespace Discord
var request = new ReorderChannelsRequest(channels);
return _rest.Patch(Endpoints.ServerChannels(serverId), request);
}
public Task<GetMessagesResponse> GetMessages(string channelId, int count)
public Task<GetMessagesResponse> GetMessages(string channelId, int count, string beforeMessageId = null)
{
if (channelId == null) throw new ArgumentNullException(nameof(channelId));

return _rest.Get<GetMessagesResponse>(Endpoints.ChannelMessages(channelId, count));
if (beforeMessageId != null)
return _rest.Get<GetMessagesResponse>(Endpoints.ChannelMessages(channelId, count, beforeMessageId));
else
return _rest.Get<GetMessagesResponse>(Endpoints.ChannelMessages(channelId, count));
}

//Incidents
@@ -123,6 +126,12 @@ namespace Discord

return _rest.Get<GetInviteResponse>(Endpoints.Invite(inviteIdOrXkcd));
}
public Task<GetInvitesResponse> GetInvites(string serverId)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));

return _rest.Get<GetInvitesResponse>(Endpoints.ServerInvites(serverId));
}
public Task<AcceptInviteResponse> AcceptInvite(string inviteId)
{
if (inviteId == null) throw new ArgumentNullException(nameof(inviteId));
@@ -136,7 +145,7 @@ namespace Discord
return _rest.Delete(Endpoints.Invite(inviteId));
}

//Members
//Users
public Task EditUser(string serverId, string userId, bool? mute = null, bool? deaf = null, IEnumerable<string> roles = null)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
@@ -145,27 +154,37 @@ namespace Discord
var request = new EditMemberRequest { Mute = mute, Deaf = deaf, Roles = roles };
return _rest.Patch(Endpoints.ServerMember(serverId, userId), request);
}
public Task Kick(string serverId, string userId)
public Task KickUser(string serverId, string userId)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
if (userId == null) throw new ArgumentNullException(nameof(userId));

return _rest.Delete(Endpoints.ServerMember(serverId, userId));
}
public Task Ban(string serverId, string userId)
public Task BanUser(string serverId, string userId)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
if (userId == null) throw new ArgumentNullException(nameof(userId));

return _rest.Put(Endpoints.ServerBan(serverId, userId));
}
public Task Unban(string serverId, string userId)
public Task UnbanUser(string serverId, string userId)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
if (userId == null) throw new ArgumentNullException(nameof(userId));

return _rest.Delete(Endpoints.ServerBan(serverId, userId));
}
public Task<PruneUsersResponse> PruneUsers(string serverId, int days, bool simulate)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
if (days <= 0) throw new ArgumentOutOfRangeException(nameof(days));
if (simulate)
return _rest.Get<PruneUsersResponse>(Endpoints.ServerPrune(serverId, days));
else
return _rest.Post<PruneUsersResponse>(Endpoints.ServerPrune(serverId, days));
}

//Messages
public Task<SendMessageResponse> SendMessage(string channelId, string message, IEnumerable<string> mentionedUserIds = null, string nonce = null, bool isTTS = false)


+ 2
- 2
src/Discord.Net/DiscordClient.Bans.cs View File

@@ -38,7 +38,7 @@ namespace Discord
if (user.Server == null) throw new ArgumentException("Unable to ban a user in a private chat.");
CheckReady();

return _api.Ban(user.Server.Id, user.Id);
return _api.BanUser(user.Server.Id, user.Id);
}

/// <summary> Unbans a user from the provided server. </summary>
@@ -48,7 +48,7 @@ namespace Discord
if (userId == null) throw new ArgumentNullException(nameof(userId));
CheckReady();

try { await _api.Unban(server.Id, userId).ConfigureAwait(false); }
try { await _api.UnbanUser(server.Id, userId).ConfigureAwait(false); }
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
}
}

+ 19
- 3
src/Discord.Net/DiscordClient.Invites.cs View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

@@ -10,8 +11,6 @@ namespace Discord
/// <remarks> Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode </remarks>
public async Task<Invite> GetInvite(string inviteIdOrXkcd)
{
//This doesn't work well if it's an invite to a different server!

if (inviteIdOrXkcd == null) throw new ArgumentNullException(nameof(inviteIdOrXkcd));
CheckReady();

@@ -26,7 +25,24 @@ namespace Discord
var response = await _api.GetInvite(inviteIdOrXkcd).ConfigureAwait(false);
var invite = new Invite(this, response.Code, response.XkcdPass, response.Guild.Id, response.Inviter?.Id, response.Channel?.Id);
invite.Cache(); //Builds references
return invite;
invite.Update(response);
return invite;
}

/// <summary> Gets all active (non-expired) invites to a provided server. </summary>
public async Task<Invite[]> GetInvites(Server server)
{
if (server == null) throw new ArgumentNullException(nameof(server));
CheckReady();

var response = await _api.GetInvites(server.Id).ConfigureAwait(false);
return response.Select(x =>
{
var invite = new Invite(this, x.Code, x.XkcdPass, x.Guild.Id, x.Inviter?.Id, x.Channel?.Id);
invite.Cache(); //Builds references
invite.Update(x);
return invite;
}).ToArray();
}

/// <summary> Creates a new invite to the default channel of the provided server. </summary>


+ 8
- 3
src/Discord.Net/DiscordClient.Messages.cs View File

@@ -46,7 +46,7 @@ namespace Discord
public const int MaxMessageSize = 2000;

public event EventHandler<MessageEventArgs> MessageReceived;
private void RaiseMessageCreated(Message msg)
private void RaiseMessageReceived(Message msg)
{
if (MessageReceived != null)
RaiseEvent(nameof(MessageReceived), () => MessageReceived(this, new MessageEventArgs(msg)));
@@ -93,6 +93,7 @@ namespace Discord
{
if (channel == null) throw new ArgumentNullException(nameof(channel));
if (text == null) throw new ArgumentNullException(nameof(text));
if (text.Length > MaxMessageSize) throw new ArgumentOutOfRangeException(nameof(text), $"Message must be {MaxMessageSize} characters or less.");
CheckReady();

return SendMessage(channel, text, false);
@@ -102,6 +103,7 @@ namespace Discord
{
if (channel == null) throw new ArgumentNullException(nameof(channel));
if (text == null) throw new ArgumentNullException(nameof(text));
if (text.Length > MaxMessageSize) throw new ArgumentOutOfRangeException(nameof(text), $"Message must be {MaxMessageSize} characters or less.");
CheckReady();

return SendMessage(channel, text, false);
@@ -111,7 +113,8 @@ namespace Discord
{
if (user == null) throw new ArgumentNullException(nameof(user));
if (text == null) throw new ArgumentNullException(nameof(text));
CheckReady();
if (text.Length > MaxMessageSize) throw new ArgumentOutOfRangeException(nameof(text), $"Message must be {MaxMessageSize} characters or less.");
CheckReady();

var channel = await CreatePMChannel(user).ConfigureAwait(false);
return await SendMessage(channel, text).ConfigureAwait(false);
@@ -164,6 +167,8 @@ namespace Discord
public Task EditMessage(Message message, string text)
{
if (message == null) throw new ArgumentNullException(nameof(message));
if (text == null) throw new ArgumentNullException(nameof(text));
if (text.Length > MaxMessageSize) throw new ArgumentOutOfRangeException(nameof(text), $"Message must be {MaxMessageSize} characters or less.");
CheckReady();

if (text != null && text.Length > MaxMessageSize)
@@ -210,7 +215,7 @@ namespace Discord
{
try
{
var msgs = await _api.GetMessages(channel.Id, count).ConfigureAwait(false);
var msgs = await _api.GetMessages(channel.Id, count, beforeMessageId).ConfigureAwait(false);
return msgs.Select(x =>
{
Message msg = null;


+ 45
- 5
src/Discord.Net/DiscordClient.Users.cs View File

@@ -1,5 +1,4 @@
using Discord.API;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -85,7 +84,7 @@ namespace Discord
RaiseEvent(nameof(UserRemoved), () => UserRemoved(this, new UserEventArgs(user)));
}
public event EventHandler<UserEventArgs> UserUpdated;
private void RaiseMemberUpdated(User user)
private void RaiseUserUpdated(User user)
{
if (UserUpdated != null)
RaiseEvent(nameof(UserUpdated), () => UserUpdated(this, new UserEventArgs(user)));
@@ -170,10 +169,51 @@ namespace Discord
if (user == null) throw new ArgumentNullException(nameof(user));
CheckReady();

return _api.EditUser(user.Server?.Id, user.Id, mute: mute, deaf: deaf, roles: roles.Select(x => x.Id));
var serverId = user.Server?.Id;
return _api.EditUser(serverId, user.Id,
mute: mute, deaf: deaf,
roles: roles.Select(x => x.Id).Where(x => x != serverId));
}

public Task<EditUserResponse> EditProfile(string currentPassword = "",
public Task KickUser(User user)
{
if (user == null) throw new ArgumentNullException(nameof(user));

return _api.KickUser(user.Server?.Id, user.Id);
}
public Task BanUser(User user)
{
if (user == null) throw new ArgumentNullException(nameof(user));

return _api.BanUser(user.Server?.Id, user.Id);
}
public Task UnbanUser(Server server, string userId)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (userId == null) throw new ArgumentNullException(nameof(userId));

return _api.UnbanUser(server.Id, userId);
}

public async Task<int> PruneUsers(string serverId, int days, bool simulate = false)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
if (days <= 0) throw new ArgumentOutOfRangeException(nameof(days));
CheckReady();

var response = await _api.PruneUsers(serverId, days, simulate);
return response.Pruned ?? 0;
}

/// <summary>When Config.UseLargeThreshold is enabled, running this command will request the Discord server to provide you with all offline users for a particular server.</summary>
public void RequestOfflineUsers(string serverId)
{
if (serverId == null) throw new ArgumentNullException(nameof(serverId));

_dataSocket.SendGetUsers(serverId);
}

public Task EditProfile(string currentPassword = "",
string username = null, string email = null, string password = null,
ImageType avatarType = ImageType.Png, byte[] avatar = null)
{


+ 23
- 12
src/Discord.Net/DiscordClient.cs View File

@@ -90,7 +90,7 @@ namespace Discord
ChannelUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"Channel Updated: {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}");
MessageReceived += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"Message Created: {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.Message?.Id}");
$"Message Received: {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.Message?.Id}");
MessageDeleted += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"Message Deleted: {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.Message?.Id}");
MessageUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
@@ -106,26 +106,26 @@ namespace Discord
UserUnbanned += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"Unbanned User: {e.Server?.Name ?? "[Private]"}/{e.UserId}");
UserAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"User Joined: {e.Server?.Name ?? "[Private]"}/{e.User.Id}");
$"User Joined: {e.Server?.Name ?? "[Private]"}/{e.User.Name}");
UserRemoved += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"User Left: {e.Server?.Name ?? "[Private]"}/{e.User.Id}");
$"User Left: {e.Server?.Name ?? "[Private]"}/{e.User.Name}");
UserUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"User Updated: {e.Server?.Name ?? "[Private]"}/{e.User.Id}");
$"User Updated: {e.Server?.Name ?? "[Private]"}/{e.User.Name}");
UserVoiceStateUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"User Updated (Voice State): {e.Server?.Name ?? "[Private]"}/{e.User.Id}");
$"User Updated (Voice State): {e.Server?.Name ?? "[Private]"}/{e.User.Name}");
ProfileUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
"Profile Updated");
}
if (_config.LogLevel >= LogMessageSeverity.Verbose)
{
UserIsTypingUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client,
$"Updated User (Is Typing): {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.User?.Name}");
$"User Updated (Is Typing): {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.User?.Name}");
MessageReadRemotely += (s, e) => RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client,
$"Read Message (Remotely): {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.Message?.Id}");
MessageSent += (s, e) => RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client,
$"Sent Message: {e.Server?.Name ?? "[Private]"}/{e.Channel?.Name}/{e.Message?.Id}");
UserPresenceUpdated += (s, e) => RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client,
$"Updated Member (Presence): {e.Server?.Name ?? "[Private]"}/{e.User?.Name}");
$"User Updated (Presence): {e.Server?.Name ?? "[Private]"}/{e.User?.Name}");
_api.RestClient.OnRequest += (s, e) =>
{
@@ -140,9 +140,9 @@ namespace Discord
_channels.ItemCreated += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Created Channel {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_channels.ItemDestroyed += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Destroyed Channel {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_channels.Cleared += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Cleared Channels");
_users.ItemCreated += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Created Member {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_users.ItemDestroyed += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Destroyed Member {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_users.Cleared += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Cleared Members");
_users.ItemCreated += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Created User {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_users.ItemDestroyed += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Destroyed User {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Id}");
_users.Cleared += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Cleared Users");
_messages.ItemCreated += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Created Message {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Channel.Id}/{e.Item.Id}");
_messages.ItemDestroyed += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Destroyed Message {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Channel.Id}/{e.Item.Id}");
_messages.ItemRemapped += (s, e) => RaiseOnLog(LogMessageSeverity.Debug, LogMessageSource.Cache, $"Remapped Message {e.Item.Server?.Id ?? "[Private]"}/{e.Item.Channel.Id}/[{e.OldId} -> {e.NewId}]");
@@ -406,7 +406,7 @@ namespace Discord
if (user != null)
{
user.Update(data);
RaiseMemberUpdated(user);
RaiseUserUpdated(user);
}
}
break;
@@ -418,6 +418,17 @@ namespace Discord
RaiseUserRemoved(user);
}
break;
case "GUILD_MEMBERS_CHUNK":
{
var data = e.Payload.ToObject<MembersChunkEvent>(_serializer);
foreach (var memberData in data.Members)
{
var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId);
user.Update(memberData);
//RaiseUserAdded(user);
}
}
break;

//Roles
case "GUILD_ROLE_CREATE":
@@ -499,7 +510,7 @@ namespace Discord
}
}

RaiseMessageCreated(msg);
RaiseMessageReceived(msg);

if (Config.AckMessages && !isAuthor)
await _api.AckMessage(data.Id, data.ChannelId).ConfigureAwait(false);


+ 1
- 1
src/Discord.Net/Helpers/Reference.cs View File

@@ -63,6 +63,6 @@ namespace Discord
_getItem = getItem;
_onCache = onCache;
_onUncache = onUncache;
}
}
}
}

+ 47
- 6
src/Discord.Net/Models/Invite.cs View File

@@ -26,24 +26,54 @@ namespace Discord
[JsonIgnore]
public User Inviter => _inviter.Value;
private readonly Reference<User> _inviter;
private User _generatedInviter;

/// <summary> Returns the server this invite is to. </summary>
[JsonIgnore]
public Server Server => _server.Value;
private readonly Reference<Server> _server;
private Server _generatedServer;

/// <summary> Returns the channel this invite is to. </summary>
[JsonIgnore]
public Channel Channel => _channel.Value;
private readonly Reference<Channel> _channel;
private Channel _generatedChannel;

internal Invite(DiscordClient client, string code, string xkcdPass, string serverId, string inviterId, string channelId)
: base(client, code)
{
XkcdCode = xkcdPass;
_server = new Reference<Server>(serverId, x => _client.Servers[x] ?? new Server(client, x));
_inviter = new Reference<User>(serverId, x => _client.Users[x, _server.Id] ?? new User(client, x, _server.Id));
_channel = new Reference<Channel>(serverId, x => _client.Channels[x] ?? new Channel(client, x, _server.Id, null));
_server = new Reference<Server>(serverId, x =>
{
var server = _client.Servers[x];
if (server == null)
{
server = _generatedServer = new Server(client, x);
server.Cache();
}
return server;
});
_inviter = new Reference<User>(serverId, x =>
{
var inviter = _client.Users[x, _server.Id];
if (inviter == null)
{
inviter = _generatedInviter = new User(client, x, _server.Id);
inviter.Cache();
}
return inviter;
});
_channel = new Reference<Channel>(serverId, x =>
{
var channel = _client.Channels[x];
if (channel == null)
{
channel = _generatedChannel = new Channel(client, x, _server.Id, null);
channel.Cache();
}
return channel;
});
}
internal override void LoadReferences()
{
@@ -54,10 +84,21 @@ namespace Discord
internal override void UnloadReferences() { }

public override string ToString() => XkcdCode ?? Id;

internal void Update(InviteInfo model)

internal void Update(InviteReference model)
{
if (model.Guild != null && _generatedServer != null)
_generatedServer.Update(model.Guild);
if (model.Inviter != null && _generatedInviter != null)
_generatedInviter.Update(model.Inviter);
if (model.Channel != null && _generatedChannel != null)
_generatedChannel.Update(model.Channel);
}
internal void Update(InviteInfo model)
{
Update(model as InviteReference);

if (model.IsRevoked != null)
IsRevoked = model.IsRevoked.Value;
if (model.IsTemporary != null)
@@ -68,6 +109,6 @@ namespace Discord
MaxUses = model.MaxUses.Value;
if (model.Uses != null)
Uses = model.Uses.Value;
}
}
}
}

+ 9
- 17
src/Discord.Net/Models/Server.cs View File

@@ -55,11 +55,6 @@ namespace Discord
public IEnumerable<Channel> VoiceChannels => _channels.Select(x => x.Value).Where(x => x.Type == ChannelType.Voice);
private ConcurrentDictionary<string, Channel> _channels;

/// <summary> Returns a collection of all invites to this server. </summary>
[JsonIgnore]
public IEnumerable<Invite> Invites => _invites.Values;
private ConcurrentDictionary<string, Invite> _invites;

/// <summary> Returns a collection of all users within this server with their server-specific data. </summary>
[JsonIgnore]
public IEnumerable<User> Members => _members.Select(x => x.Value);
@@ -85,7 +80,6 @@ namespace Discord

//Local Cache
_bans = new ConcurrentDictionary<string, bool>();
_invites = new ConcurrentDictionary<string, Invite>();
}
internal override void LoadReferences()
{
@@ -113,25 +107,26 @@ namespace Discord
roles.Clear();

//Local Cache
var invites = _invites;
foreach (var invite in invites)
invite.Value.Uncache();
invites.Clear();

_bans.Clear();

_afkChannel.Unload();
}

internal void Update(GuildInfo model)
internal void Update(GuildReference model)
{
if (model.Name != null)
Name = model.Name;
}

internal void Update(GuildInfo model)
{
Update(model as GuildReference);

if (model.AFKTimeout != null)
AFKTimeout = model.AFKTimeout.Value;
if (model.AFKChannelId != null)
if (model.JoinedAt != null)
JoinedAt = model.JoinedAt.Value;
if (model.Name != null)
Name = model.Name;
if (model.OwnerId != null && _ownerId != model.OwnerId)
{
_ownerId = model.OwnerId;
@@ -212,9 +207,6 @@ namespace Discord
_channels.TryRemove(channel.Id, out channel);
}

internal void AddInvite(Invite invite) => _invites.TryAdd(invite.Id, invite);
internal void RemoveInvite(Invite invite) => _invites.TryRemove(invite.Id, out invite);

internal void AddMember(User user)
{
if (_members.TryAdd(user.Id, user))


+ 9
- 6
src/Discord.Net/Models/User.cs View File

@@ -24,7 +24,7 @@ namespace Discord
/// <summary> Returns the unique identifier for this user's current avatar. </summary>
public string AvatarId { get; private set; }
/// <summary> Returns the URL to this user's current avatar. </summary>
public string AvatarUrl => API.Endpoints.UserAvatar(Id, AvatarId);
public string AvatarUrl => AvatarId != null ? API.Endpoints.UserAvatar(Id, AvatarId) : null;
/// <summary> Returns the datetime that this user joined this server. </summary>
public DateTime JoinedAt { get; private set; }

@@ -61,7 +61,8 @@ namespace Discord
private readonly Reference<Server> _server;

[JsonIgnore]
public Channel VoiceChannel { get; private set; }
public Channel VoiceChannel => _voiceChannel.Value;
private Reference<Channel> _voiceChannel;

[JsonIgnore]
public IEnumerable<Role> Roles => _roles.Select(x => x.Value);
@@ -130,6 +131,8 @@ namespace Discord
if (Id == _client.CurrentUserId)
x.CurrentUser = null;
});
_voiceChannel = new Reference<Channel>(x => _client.Channels[x]);

Status = UserStatus.Offline;
_channels = new ConcurrentDictionary<string, Channel>();
if (serverId != null)
@@ -210,16 +213,16 @@ namespace Discord
SessionId = model.SessionId;
if (model.Token != null)
Token = model.Token;

if (model.ChannelId != null)
VoiceChannel = _client.Channels[model.ChannelId];
if (model.IsSelfDeafened != null)
IsSelfDeafened = model.IsSelfDeafened.Value;
if (model.IsSelfMuted != null)
IsSelfMuted = model.IsSelfMuted.Value;
if (model.IsServerSuppressed != null)
IsServerSuppressed = model.IsServerSuppressed.Value;
}

_voiceChannel.Id = model.ChannelId; //Can be null
}
private void UpdateRoles(IEnumerable<Role> roles)
{
if (_server.Id != null)


+ 7
- 1
src/Discord.Net/Net/WebSockets/DataWebSocket.cs View File

@@ -27,7 +27,7 @@ namespace Discord.Net.WebSockets
msg.Payload.Token = token;
msg.Payload.Properties["$device"] = "Discord.Net";
if (_client.Config.UseLargeThreshold)
msg.Payload.LargeThreshold = 50;
msg.Payload.LargeThreshold = 100;
msg.Payload.Compress = true;
QueueMessage(msg);
}
@@ -141,5 +141,11 @@ namespace Discord.Net.WebSockets
leaveVoice.Payload.ServerId = serverId;
QueueMessage(leaveVoice);
}
public void SendGetUsers(string serverId, string query = "", int limit = 0)
{
var getOfflineUsers = new GetUsersCommand();
getOfflineUsers.Payload.ServerId = serverId;
QueueMessage(getOfflineUsers);
}
}
}

+ 1
- 1
src/Discord.Net/project.json View File

@@ -1,5 +1,5 @@
{
"version": "0.8.0-beta1",
"version": "0.8.1-beta1",
"description": "An unofficial .Net API wrapper for the Discord client.",
"authors": [
"RogueException"


Loading…
Cancel
Save