Major cleanup, added message and role caches, added a few events, added test placeholder
This commit is contained in:
48
Discord.Net.Tests/ChannelTests.cs
Normal file
48
Discord.Net.Tests/ChannelTests.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using Discord.Models;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord.Net.Tests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class ChannelTests
|
||||||
|
{
|
||||||
|
private DiscordClient _bot1, _bot2;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
_bot1 = new DiscordClient();
|
||||||
|
_bot2 = new DiscordClient();
|
||||||
|
|
||||||
|
_bot1.Connect(Settings.Test1_Username, Settings.Test1_Password).Wait();
|
||||||
|
_bot2.Connect(Settings.Test2_Username, Settings.Test2_Password).Wait();
|
||||||
|
|
||||||
|
//Cleanup existing servers
|
||||||
|
Task.WaitAll(_bot1.Servers.Select(x => _bot1.LeaveServer(x)).ToArray());
|
||||||
|
Task.WaitAll(_bot2.Servers.Select(x => _bot2.LeaveServer(x)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task DoNothing()
|
||||||
|
{
|
||||||
|
Server server = await _bot1.CreateServer("Discord.Net Testbed", Region.US_East);
|
||||||
|
Invite invite = await _bot1.CreateInvite(server, 60, 1, false, false);
|
||||||
|
await _bot2.AcceptInvite(invite);
|
||||||
|
await _bot2.LeaveServer(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCleanup]
|
||||||
|
public void Cleanup()
|
||||||
|
{
|
||||||
|
if (_bot1.IsConnected)
|
||||||
|
Task.WaitAll(_bot1.Servers.Select(x => _bot1.LeaveServer(x)).ToArray());
|
||||||
|
if (_bot2.IsConnected)
|
||||||
|
Task.WaitAll(_bot2.Servers.Select(x => _bot2.LeaveServer(x)).ToArray());
|
||||||
|
|
||||||
|
_bot1.Disconnect().Wait();
|
||||||
|
_bot2.Disconnect().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
90
Discord.Net.Tests/Discord.Net.Tests.csproj
Normal file
90
Discord.Net.Tests/Discord.Net.Tests.csproj
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{855D6B1D-847B-42DA-BE6A-23683EA89511}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Discord.Net.Tests</RootNamespace>
|
||||||
|
<AssemblyName>Discord.Net.Tests</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
|
<TestProjectType>UnitTest</TestProjectType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Choose>
|
||||||
|
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||||
|
</ItemGroup>
|
||||||
|
</When>
|
||||||
|
<Otherwise>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Otherwise>
|
||||||
|
</Choose>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="ChannelTests.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Settings.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Discord.Net\Discord.Net.csproj">
|
||||||
|
<Project>{8d23f61b-723c-4966-859d-1119b28bcf19}</Project>
|
||||||
|
<Name>Discord.Net</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Choose>
|
||||||
|
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
</When>
|
||||||
|
</Choose>
|
||||||
|
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||||
|
<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>
|
||||||
36
Discord.Net.Tests/Properties/AssemblyInfo.cs
Normal file
36
Discord.Net.Tests/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Discord.Net.Tests")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Discord.Net.Tests")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("855d6b1d-847b-42da-be6a-23683ea89511")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
LICENSE = LICENSE
|
LICENSE = LICENSE
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Tests", "Discord.Net.Tests\Discord.Net.Tests.csproj", "{855D6B1D-847B-42DA-BE6A-23683EA89511}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -21,6 +23,10 @@ Global
|
|||||||
{8D23F61B-723C-4966-859D-1119B28BCF19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8D23F61B-723C-4966-859D-1119B28BCF19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8D23F61B-723C-4966-859D-1119B28BCF19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8D23F61B-723C-4966-859D-1119B28BCF19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8D23F61B-723C-4966-859D-1119B28BCF19}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8D23F61B-723C-4966-859D-1119B28BCF19}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{855D6B1D-847B-42DA-BE6A-23683EA89511}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -6,17 +6,18 @@ namespace Discord.API
|
|||||||
{
|
{
|
||||||
internal static class DiscordAPI
|
internal static class DiscordAPI
|
||||||
{
|
{
|
||||||
public static async Task<AuthRegisterResponse> LoginAnonymous(string username, HttpOptions options)
|
//Auth
|
||||||
|
public static async Task<APIResponses.AuthRegister> LoginAnonymous(string username, HttpOptions options)
|
||||||
{
|
{
|
||||||
var fingerprintResponse = await Http.Post<AuthFingerprintResponse>(Endpoints.AuthFingerprint, options);
|
var fingerprintResponse = await Http.Post<APIResponses.AuthFingerprint>(Endpoints.AuthFingerprint, options);
|
||||||
var registerRequest = new AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username };
|
var registerRequest = new APIRequests.AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username };
|
||||||
var registerResponse = await Http.Post<AuthRegisterResponse>(Endpoints.AuthRegister, registerRequest, options);
|
var registerResponse = await Http.Post<APIResponses.AuthRegister>(Endpoints.AuthRegister, registerRequest, options);
|
||||||
return registerResponse;
|
return registerResponse;
|
||||||
}
|
}
|
||||||
public static async Task<AuthLoginResponse> Login(string email, string password, HttpOptions options)
|
public static async Task<APIResponses.AuthLogin> Login(string email, string password, HttpOptions options)
|
||||||
{
|
{
|
||||||
var request = new AuthLoginRequest { Email = email, Password = password };
|
var request = new APIRequests.AuthLogin { Email = email, Password = password };
|
||||||
var response = await Http.Post<AuthLoginResponse>(Endpoints.AuthLogin, request, options);
|
var response = await Http.Post<APIResponses.AuthLogin>(Endpoints.AuthLogin, request, options);
|
||||||
options.Token = response.Token;
|
options.Token = response.Token;
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -25,37 +26,61 @@ namespace Discord.API
|
|||||||
return Http.Post(Endpoints.AuthLogout, options);
|
return Http.Post(Endpoints.AuthLogout, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task CreateServer(string name, string region, HttpOptions options)
|
//Servers
|
||||||
|
public static Task<APIResponses.CreateServer> CreateServer(string name, string region, HttpOptions options)
|
||||||
{
|
{
|
||||||
var request = new CreateServerRequest { Name = name, Region = region };
|
var request = new APIRequests.CreateServer { Name = name, Region = region };
|
||||||
return Http.Post(Endpoints.Servers, request, options);
|
return Http.Post<APIResponses.CreateServer>(Endpoints.Servers, request, options);
|
||||||
}
|
|
||||||
public static Task DeleteServer(string id, HttpOptions options)
|
|
||||||
{
|
|
||||||
return Http.Delete(Endpoints.Server(id), options);
|
|
||||||
}
|
}
|
||||||
|
public static Task LeaveServer(string id, HttpOptions options)
|
||||||
public static Task<GetInviteResponse> GetInvite(string id, HttpOptions options)
|
|
||||||
{
|
{
|
||||||
return Http.Get<GetInviteResponse>(Endpoints.Invite(id), options);
|
return Http.Delete<APIResponses.DeleteServer>(Endpoints.Server(id), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Channels
|
||||||
|
public static Task<APIResponses.GetMessages[]> GetMessages(string channelId, HttpOptions options)
|
||||||
|
{
|
||||||
|
return Http.Get<APIResponses.GetMessages[]>(Endpoints.ChannelMessages(channelId, 50), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Invites
|
||||||
|
public static Task<APIResponses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass, HttpOptions options)
|
||||||
|
{
|
||||||
|
var request = new APIRequests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, HasXkcdPass = hasXkcdPass };
|
||||||
|
return Http.Post<APIResponses.CreateInvite>(Endpoints.ChannelInvites(channelId), request, options);
|
||||||
|
}
|
||||||
|
public static Task<APIResponses.GetInvite> GetInvite(string id, HttpOptions options)
|
||||||
|
{
|
||||||
|
return Http.Get<APIResponses.GetInvite>(Endpoints.Invite(id), options);
|
||||||
}
|
}
|
||||||
public static Task AcceptInvite(string id, HttpOptions options)
|
public static Task AcceptInvite(string id, HttpOptions options)
|
||||||
{
|
{
|
||||||
return Http.Post(Endpoints.Invite(id), options);
|
return Http.Post<APIResponses.AcceptInvite>(Endpoints.Invite(id), options);
|
||||||
}
|
}
|
||||||
public static Task DeleteInvite(string id, HttpOptions options)
|
public static Task DeleteInvite(string id, HttpOptions options)
|
||||||
{
|
{
|
||||||
return Http.Delete(Endpoints.Invite(id), options);
|
return Http.Delete(Endpoints.Invite(id), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task Typing(string channelId, HttpOptions options)
|
//Chat
|
||||||
|
public static Task SendMessage(string channelId, string message, string[] mentions, HttpOptions options)
|
||||||
|
{
|
||||||
|
var request = new APIRequests.SendMessage { Content = message, Mentions = mentions };
|
||||||
|
return Http.Post(Endpoints.ChannelMessages(channelId), request, options);
|
||||||
|
}
|
||||||
|
public static Task SendIsTyping(string channelId, HttpOptions options)
|
||||||
{
|
{
|
||||||
return Http.Post(Endpoints.ChannelTyping(channelId), options);
|
return Http.Post(Endpoints.ChannelTyping(channelId), options);
|
||||||
}
|
}
|
||||||
public static Task SendMessage(string channelId, string message, string[] mentions, HttpOptions options)
|
|
||||||
|
//Voice
|
||||||
|
public static Task<APIResponses.GetRegions[]> GetVoiceRegions(HttpOptions options)
|
||||||
{
|
{
|
||||||
var request = new SendMessageRequest { Content = message, Mentions = mentions };
|
return Http.Get<APIResponses.GetRegions[]>(Endpoints.VoiceRegions, options);
|
||||||
return Http.Post(Endpoints.ChannelMessages(channelId), request, options);
|
|
||||||
}
|
}
|
||||||
}
|
public static Task<APIResponses.GetIce> GetVoiceIce(HttpOptions options)
|
||||||
|
{
|
||||||
|
return Http.Get<APIResponses.GetIce>(Endpoints.VoiceIce, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,29 +2,43 @@
|
|||||||
{
|
{
|
||||||
internal static class Endpoints
|
internal static class Endpoints
|
||||||
{
|
{
|
||||||
public static readonly string BaseUrl = "discordapp.com/";
|
public static readonly string BaseUrl = "discordapp.com";
|
||||||
public static readonly string BaseHttps = "https://" + BaseUrl;
|
public static readonly string BaseHttps = $"https://{BaseUrl}";
|
||||||
public static readonly string BaseWss = "wss://" + BaseUrl;
|
|
||||||
|
|
||||||
public static readonly string Auth = $"{BaseHttps}/api/auth";
|
// /api
|
||||||
|
public static readonly string BaseApi = $"{BaseHttps}/api";
|
||||||
|
public static readonly string Track = $"{BaseApi}/track";
|
||||||
|
|
||||||
|
// /api/auth
|
||||||
|
public static readonly string Auth = $"{BaseApi}/auth";
|
||||||
public static readonly string AuthFingerprint = $"{Auth}fingerprint";
|
public static readonly string AuthFingerprint = $"{Auth}fingerprint";
|
||||||
public static readonly string AuthRegister = $"{Auth}/register";
|
public static readonly string AuthRegister = $"{Auth}/register";
|
||||||
public static readonly string AuthLogin = $"{Auth}/login";
|
public static readonly string AuthLogin = $"{Auth}/login";
|
||||||
public static readonly string AuthLogout = $"{Auth}/logout";
|
public static readonly string AuthLogout = $"{Auth}/logout";
|
||||||
|
|
||||||
public static readonly string Servers = $"{BaseHttps}/api/guilds";
|
// /api/guilds
|
||||||
|
public static readonly string Servers = $"{BaseApi}/guilds";
|
||||||
public static string Server(string id) { return $"{Servers}/{id}"; }
|
public static string Server(string id) { return $"{Servers}/{id}"; }
|
||||||
public static string ServerMessages(string id) { return $"{Servers}/{id}/messages?limit=50"; }
|
|
||||||
|
|
||||||
public static readonly string Invites = $"{BaseHttps}/api/invite";
|
// /api/guilds
|
||||||
|
public static readonly string Invites = $"{BaseApi}/invite";
|
||||||
public static string Invite(string id) { return $"{Invites}/{id}"; }
|
public static string Invite(string id) { return $"{Invites}/{id}"; }
|
||||||
|
|
||||||
public static readonly string Channels = $"{BaseHttps}/api/channels";
|
// /api/channels
|
||||||
|
public static readonly string Channels = $"{BaseApi}/channels";
|
||||||
public static string Channel(string id) { return $"{Channels}/{id}"; }
|
public static string Channel(string id) { return $"{Channels}/{id}"; }
|
||||||
public static string ChannelTyping(string id) { return $"{Channels}/{id}/typing"; }
|
public static string ChannelTyping(string id) { return $"{Channels}/{id}/typing"; }
|
||||||
public static string ChannelMessages(string id) { return $"{Channels}/{id}/messages"; }
|
public static string ChannelMessages(string id) { return $"{Channels}/{id}/messages"; }
|
||||||
|
public static string ChannelMessages(string id, int limit) { return $"{Channels}/{id}/messages?limit={limit}"; }
|
||||||
|
public static string ChannelInvites(string id) { return $"{Channels}/{id}/invites"; }
|
||||||
|
|
||||||
public static readonly string WebSocket_Hub = BaseWss + "hub";
|
// /api/voice
|
||||||
|
public static readonly string Voice = $"{BaseApi}/voice";
|
||||||
|
public static readonly string VoiceRegions = $"{Voice}/regions";
|
||||||
|
public static readonly string VoiceIce = $"{Voice}/ice";
|
||||||
|
|
||||||
|
//Web Sockets
|
||||||
|
public static readonly string BaseWss = "wss://" + BaseUrl;
|
||||||
|
public static readonly string WebSocket_Hub = $"{BaseWss}/hub";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
91
Discord.Net/API/Models/APIResponses.cs
Normal file
91
Discord.Net/API/Models/APIResponses.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
//Ignore unused/unassigned variable warnings
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Discord.API.Models
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static class APIResponses
|
||||||
|
{
|
||||||
|
public class AuthFingerprint
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "fingerprint")]
|
||||||
|
public string Fingerprint;
|
||||||
|
}
|
||||||
|
public class AuthRegister : AuthLogin { }
|
||||||
|
public class AuthLogin
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "token")]
|
||||||
|
public string Token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateServer : ServerInfo { }
|
||||||
|
public class DeleteServer : ServerInfo { }
|
||||||
|
|
||||||
|
public class CreateInvite : GetInvite
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "max_age")]
|
||||||
|
public int MaxAge;
|
||||||
|
[JsonProperty(PropertyName = "max_uses")]
|
||||||
|
public int MaxUses;
|
||||||
|
[JsonProperty(PropertyName = "revoked")]
|
||||||
|
public bool IsRevoked;
|
||||||
|
[JsonProperty(PropertyName = "temporary")]
|
||||||
|
public bool IsTemporary;
|
||||||
|
[JsonProperty(PropertyName = "uses")]
|
||||||
|
public int Uses;
|
||||||
|
[JsonProperty(PropertyName = "created_at")]
|
||||||
|
public DateTime CreatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetInvite
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "inviter")]
|
||||||
|
public UserReference Inviter;
|
||||||
|
[JsonProperty(PropertyName = "guild")]
|
||||||
|
public ServerReference Server;
|
||||||
|
[JsonProperty(PropertyName = "channel")]
|
||||||
|
public ChannelReference Channel;
|
||||||
|
[JsonProperty(PropertyName = "code")]
|
||||||
|
public string Code;
|
||||||
|
[JsonProperty(PropertyName = "xkcdpass")]
|
||||||
|
public string XkcdPass;
|
||||||
|
}
|
||||||
|
public class AcceptInvite : GetInvite { }
|
||||||
|
|
||||||
|
public class GetMessages : Message { }
|
||||||
|
|
||||||
|
public class GetRegions
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "sample_hostname")]
|
||||||
|
public string Hostname;
|
||||||
|
[JsonProperty(PropertyName = "sample_port")]
|
||||||
|
public int Port;
|
||||||
|
[JsonProperty(PropertyName = "id")]
|
||||||
|
public string Id;
|
||||||
|
[JsonProperty(PropertyName = "name")]
|
||||||
|
public string Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetIce
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "ttl")]
|
||||||
|
public string TTL;
|
||||||
|
[JsonProperty(PropertyName = "servers")]
|
||||||
|
public Server[] Servers;
|
||||||
|
|
||||||
|
public class Server
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string URL;
|
||||||
|
[JsonProperty(PropertyName = "username")]
|
||||||
|
public string Username;
|
||||||
|
[JsonProperty(PropertyName = "credential")]
|
||||||
|
public string Credential;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,61 +6,49 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Discord.API.Models
|
namespace Discord.API.Models
|
||||||
{
|
{
|
||||||
public class AuthFingerprintResponse
|
internal static class APIRequests
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "fingerprint")]
|
public class AuthRegisterRequest
|
||||||
public string Fingerprint;
|
{
|
||||||
}
|
[JsonProperty(PropertyName = "fingerprint")]
|
||||||
|
public string Fingerprint;
|
||||||
|
[JsonProperty(PropertyName = "username")]
|
||||||
|
public string Username;
|
||||||
|
}
|
||||||
|
public class AuthLogin
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "email")]
|
||||||
|
public string Email;
|
||||||
|
[JsonProperty(PropertyName = "password")]
|
||||||
|
public string Password;
|
||||||
|
}
|
||||||
|
|
||||||
public class AuthRegisterRequest
|
public class CreateServer
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "fingerprint")]
|
[JsonProperty(PropertyName = "name")]
|
||||||
public string Fingerprint;
|
public string Name;
|
||||||
[JsonProperty(PropertyName = "username")]
|
[JsonProperty(PropertyName = "region")]
|
||||||
public string Username;
|
public string Region;
|
||||||
}
|
}
|
||||||
public class AuthRegisterResponse : AuthLoginResponse { }
|
|
||||||
|
|
||||||
public class AuthLoginRequest
|
public class CreateInvite
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "email")]
|
[JsonProperty(PropertyName = "max_age")]
|
||||||
public string Email;
|
public int MaxAge;
|
||||||
[JsonProperty(PropertyName = "password")]
|
[JsonProperty(PropertyName = "max_uses")]
|
||||||
public string Password;
|
public int MaxUses;
|
||||||
}
|
[JsonProperty(PropertyName = "temporary")]
|
||||||
public class AuthLoginResponse
|
public bool IsTemporary;
|
||||||
{
|
[JsonProperty(PropertyName = "xkcdpass")]
|
||||||
[JsonProperty(PropertyName = "token")]
|
public bool HasXkcdPass;
|
||||||
public string Token;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class CreateServerRequest
|
public class SendMessage
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "name")]
|
[JsonProperty(PropertyName = "content")]
|
||||||
public string Name;
|
public string Content;
|
||||||
[JsonProperty(PropertyName = "region")]
|
[JsonProperty(PropertyName = "mentions")]
|
||||||
public string Region;
|
public string[] Mentions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetInviteResponse
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "inviter")]
|
|
||||||
public UserInfo Inviter;
|
|
||||||
[JsonProperty(PropertyName = "guild")]
|
|
||||||
public ServerInfo Server;
|
|
||||||
[JsonProperty(PropertyName = "channel")]
|
|
||||||
public ChannelInfo Channel;
|
|
||||||
[JsonProperty(PropertyName = "code")]
|
|
||||||
public string Code;
|
|
||||||
[JsonProperty(PropertyName = "xkcdpass")]
|
|
||||||
public string XkcdPass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SendMessageRequest
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "content")]
|
|
||||||
public string Content;
|
|
||||||
[JsonProperty(PropertyName = "mentions")]
|
|
||||||
public string[] Mentions;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ namespace Discord.API.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserInfo
|
//Users
|
||||||
|
internal class UserReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "username")]
|
[JsonProperty(PropertyName = "username")]
|
||||||
public string Username;
|
public string Username;
|
||||||
@@ -43,14 +44,14 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "avatar")]
|
[JsonProperty(PropertyName = "avatar")]
|
||||||
public string Avatar;
|
public string Avatar;
|
||||||
}
|
}
|
||||||
public class SelfUserInfo : UserInfo
|
internal class SelfUserInfo : UserReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "email")]
|
[JsonProperty(PropertyName = "email")]
|
||||||
public string Email;
|
public string Email;
|
||||||
[JsonProperty(PropertyName = "verified")]
|
[JsonProperty(PropertyName = "verified")]
|
||||||
public bool IsVerified;
|
public bool IsVerified;
|
||||||
}
|
}
|
||||||
public class PresenceUserInfo : UserInfo
|
internal class PresenceUserInfo : UserReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "game_id")]
|
[JsonProperty(PropertyName = "game_id")]
|
||||||
public string GameId;
|
public string GameId;
|
||||||
@@ -58,78 +59,115 @@ namespace Discord.API.Models
|
|||||||
public string Status;
|
public string Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MembershipInfo
|
//Channels
|
||||||
{
|
internal class ChannelReference
|
||||||
[JsonProperty(PropertyName = "roles")]
|
|
||||||
public object[] Roles;
|
|
||||||
[JsonProperty(PropertyName = "mute")]
|
|
||||||
public bool IsMuted;
|
|
||||||
[JsonProperty(PropertyName = "deaf")]
|
|
||||||
public bool IsDeaf;
|
|
||||||
[JsonProperty(PropertyName = "joined_at")]
|
|
||||||
public DateTime JoinedAt;
|
|
||||||
[JsonProperty(PropertyName = "user")]
|
|
||||||
public UserInfo User;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChannelInfo
|
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "id")]
|
[JsonProperty(PropertyName = "id")]
|
||||||
public string Id;
|
public string Id;
|
||||||
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
|
public string GuildId;
|
||||||
[JsonProperty(PropertyName = "name")]
|
[JsonProperty(PropertyName = "name")]
|
||||||
public string Name;
|
public string Name;
|
||||||
|
[JsonProperty(PropertyName = "type")]
|
||||||
|
public string Type;
|
||||||
|
}
|
||||||
|
internal class ChannelInfo : ChannelReference
|
||||||
|
{
|
||||||
[JsonProperty(PropertyName = "last_message_id")]
|
[JsonProperty(PropertyName = "last_message_id")]
|
||||||
public string LastMessageId;
|
public string LastMessageId;
|
||||||
[JsonProperty(PropertyName = "is_private")]
|
[JsonProperty(PropertyName = "is_private")]
|
||||||
public bool IsPrivate;
|
public bool IsPrivate;
|
||||||
[JsonProperty(PropertyName = "type")]
|
|
||||||
public string Type;
|
|
||||||
[JsonProperty(PropertyName = "permission_overwrites")]
|
[JsonProperty(PropertyName = "permission_overwrites")]
|
||||||
public object[] PermissionOverwrites;
|
public object[] PermissionOverwrites;
|
||||||
[JsonProperty(PropertyName = "recipient")]
|
[JsonProperty(PropertyName = "recipient")]
|
||||||
public UserInfo Recipient;
|
public UserReference Recipient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerInfo
|
//Servers
|
||||||
|
internal class ServerReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "id")]
|
[JsonProperty(PropertyName = "id")]
|
||||||
public string Id;
|
public string Id;
|
||||||
[JsonProperty(PropertyName = "name")]
|
[JsonProperty(PropertyName = "name")]
|
||||||
public string Name;
|
public string Name;
|
||||||
}
|
}
|
||||||
public class ExtendedServerInfo : ServerInfo
|
internal class ServerInfo : ServerReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "afk_channel_id")]
|
[JsonProperty(PropertyName = "afk_channel_id")]
|
||||||
public string AFKChannelId;
|
public string AFKChannelId;
|
||||||
[JsonProperty(PropertyName = "afk_timeout")]
|
[JsonProperty(PropertyName = "afk_timeout")]
|
||||||
public int AFKTimeout;
|
public int AFKTimeout;
|
||||||
[JsonProperty(PropertyName = "channels")]
|
[JsonProperty(PropertyName = "embed_channel_id")]
|
||||||
public ChannelInfo[] Channels;
|
public string EmbedChannelId;
|
||||||
|
[JsonProperty(PropertyName = "embed_enabled")]
|
||||||
|
public bool EmbedEnabled;
|
||||||
[JsonProperty(PropertyName = "joined_at")]
|
[JsonProperty(PropertyName = "joined_at")]
|
||||||
public DateTime JoinedAt;
|
public DateTime? JoinedAt;
|
||||||
[JsonProperty(PropertyName = "members")]
|
|
||||||
public MembershipInfo[] Members;
|
|
||||||
[JsonProperty(PropertyName = "owner_id")]
|
[JsonProperty(PropertyName = "owner_id")]
|
||||||
public string OwnerId;
|
public string OwnerId;
|
||||||
[JsonProperty(PropertyName = "presence")]
|
|
||||||
public object[] Presence;
|
|
||||||
[JsonProperty(PropertyName = "region")]
|
[JsonProperty(PropertyName = "region")]
|
||||||
public string Region;
|
public string Region;
|
||||||
[JsonProperty(PropertyName = "roles")]
|
[JsonProperty(PropertyName = "roles")]
|
||||||
public object[] Roles;
|
public Role[] Roles;
|
||||||
|
}
|
||||||
|
internal class ExtendedServerInfo : ServerInfo
|
||||||
|
{
|
||||||
|
public class Membership
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "roles")]
|
||||||
|
public object[] Roles;
|
||||||
|
[JsonProperty(PropertyName = "mute")]
|
||||||
|
public bool IsMuted;
|
||||||
|
[JsonProperty(PropertyName = "deaf")]
|
||||||
|
public bool IsDeaf;
|
||||||
|
[JsonProperty(PropertyName = "joined_at")]
|
||||||
|
public DateTime JoinedAt;
|
||||||
|
[JsonProperty(PropertyName = "user")]
|
||||||
|
public UserReference User;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "channels")]
|
||||||
|
public ChannelInfo[] Channels;
|
||||||
|
[JsonProperty(PropertyName = "members")]
|
||||||
|
public Membership[] Members;
|
||||||
|
[JsonProperty(PropertyName = "presence")]
|
||||||
|
public object[] Presence;
|
||||||
[JsonProperty(PropertyName = "voice_states")]
|
[JsonProperty(PropertyName = "voice_states")]
|
||||||
public object[] VoiceStates;
|
public object[] VoiceStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Messages
|
||||||
internal class MessageReference
|
internal class MessageReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "message_id")]
|
[JsonProperty(PropertyName = "id")]
|
||||||
public string MessageId;
|
public string Id;
|
||||||
[JsonProperty(PropertyName = "channel_id")]
|
[JsonProperty(PropertyName = "channel_id")]
|
||||||
public string ChannelId;
|
public string ChannelId;
|
||||||
|
[JsonProperty(PropertyName = "message_id")]
|
||||||
|
public string MessageId { get { return Id; } set { Id = value; } }
|
||||||
|
}
|
||||||
|
internal class Message : MessageReference
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "tts")]
|
||||||
|
public bool IsTextToSpeech;
|
||||||
|
[JsonProperty(PropertyName = "mention_everyone")]
|
||||||
|
public bool IsMentioningEveryone;
|
||||||
|
[JsonProperty(PropertyName = "timestamp")]
|
||||||
|
public DateTime Timestamp;
|
||||||
|
[JsonProperty(PropertyName = "mentions")]
|
||||||
|
public UserReference[] Mentions;
|
||||||
|
[JsonProperty(PropertyName = "embeds")]
|
||||||
|
public object[] Embeds;
|
||||||
|
[JsonProperty(PropertyName = "attachments")]
|
||||||
|
public object[] Attachments;
|
||||||
|
[JsonProperty(PropertyName = "content")]
|
||||||
|
public string Content;
|
||||||
|
[JsonProperty(PropertyName = "author")]
|
||||||
|
public UserReference Author;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Role
|
//Roles
|
||||||
|
internal class Role
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "permissions")]
|
[JsonProperty(PropertyName = "permissions")]
|
||||||
public int Permissions;
|
public int Permissions;
|
||||||
@@ -25,65 +25,72 @@ namespace Discord.API.Models
|
|||||||
public int HeartbeatInterval;
|
public int HeartbeatInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Servers
|
||||||
internal sealed class GuildCreate : ExtendedServerInfo { }
|
internal sealed class GuildCreate : ExtendedServerInfo { }
|
||||||
internal sealed class GuildDelete : ExtendedServerInfo { }
|
internal sealed class GuildDelete : ExtendedServerInfo { }
|
||||||
|
|
||||||
|
//Channels
|
||||||
internal sealed class ChannelCreate : ChannelInfo { }
|
internal sealed class ChannelCreate : ChannelInfo { }
|
||||||
internal sealed class ChannelDelete : ChannelInfo { }
|
internal sealed class ChannelDelete : ChannelInfo { }
|
||||||
internal sealed class ChannelUpdate : ChannelInfo { }
|
internal sealed class ChannelUpdate : ChannelInfo { }
|
||||||
|
|
||||||
internal sealed class GuildMemberAdd : GuildMemberUpdate
|
//Memberships
|
||||||
|
internal abstract class GuildMemberEvent
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "user")]
|
||||||
|
public UserReference User;
|
||||||
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
|
public string GuildId;
|
||||||
|
}
|
||||||
|
internal sealed class GuildMemberAdd : GuildMemberEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "joined_at")]
|
[JsonProperty(PropertyName = "joined_at")]
|
||||||
public DateTime JoinedAt;
|
public DateTime JoinedAt;
|
||||||
}
|
|
||||||
internal class GuildMemberUpdate
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "user")]
|
|
||||||
public UserInfo User;
|
|
||||||
[JsonProperty(PropertyName = "roles")]
|
[JsonProperty(PropertyName = "roles")]
|
||||||
public object[] Roles;
|
public object[] Roles;
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
}
|
}
|
||||||
internal sealed class GuildMemberRemove
|
internal sealed class GuildMemberUpdate : GuildMemberEvent
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "roles")]
|
||||||
|
public object[] Roles;
|
||||||
|
}
|
||||||
|
internal sealed class GuildMemberRemove : GuildMemberEvent { }
|
||||||
|
|
||||||
|
//Roles
|
||||||
|
internal abstract class GuildRoleEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "user")]
|
|
||||||
public UserInfo User;
|
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
public string GuildId;
|
public string GuildId;
|
||||||
}
|
}
|
||||||
|
internal sealed class GuildRoleCreateUpdate : GuildRoleEvent
|
||||||
internal sealed class GuildRoleCreateUpdate
|
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "role")]
|
[JsonProperty(PropertyName = "role")]
|
||||||
public Role Role;
|
public Role Role;
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
}
|
}
|
||||||
internal sealed class GuildRoleDelete
|
internal sealed class GuildRoleDelete : GuildRoleEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "role_id")]
|
[JsonProperty(PropertyName = "role_id")]
|
||||||
public string RoleId;
|
public string RoleId;
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class GuildBanAddRemove
|
//Bans
|
||||||
|
internal abstract class GuildBanEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "user")]
|
|
||||||
public UserInfo User;
|
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
public string GuildId;
|
public string GuildId;
|
||||||
}
|
}
|
||||||
internal sealed class GuildBanRemove
|
internal sealed class GuildBanAddRemove : GuildBanEvent
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "user")]
|
||||||
|
public UserReference User;
|
||||||
|
}
|
||||||
|
internal sealed class GuildBanRemove : GuildBanEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "user_id")]
|
[JsonProperty(PropertyName = "user_id")]
|
||||||
public string UserId;
|
public string UserId;
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//User
|
||||||
internal sealed class UserUpdate : SelfUserInfo { }
|
internal sealed class UserUpdate : SelfUserInfo { }
|
||||||
internal sealed class PresenceUpdate : PresenceUserInfo { }
|
internal sealed class PresenceUpdate : PresenceUserInfo { }
|
||||||
internal sealed class VoiceStateUpdate
|
internal sealed class VoiceStateUpdate
|
||||||
@@ -107,35 +114,11 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "deaf")]
|
[JsonProperty(PropertyName = "deaf")]
|
||||||
public bool IsDeafened;
|
public bool IsDeafened;
|
||||||
}
|
}
|
||||||
internal sealed class MessageCreate
|
|
||||||
|
//Chat
|
||||||
|
internal sealed class MessageCreate : Message { }
|
||||||
|
internal sealed class MessageUpdate : MessageReference
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "id")]
|
|
||||||
public string Id;
|
|
||||||
[JsonProperty(PropertyName = "channel_id")]
|
|
||||||
public string ChannelId;
|
|
||||||
[JsonProperty(PropertyName = "tts")]
|
|
||||||
public bool IsTextToSpeech;
|
|
||||||
[JsonProperty(PropertyName = "mention_everyone")]
|
|
||||||
public bool IsMentioningEveryone;
|
|
||||||
[JsonProperty(PropertyName = "timestamp")]
|
|
||||||
public DateTime Timestamp;
|
|
||||||
[JsonProperty(PropertyName = "mentions")]
|
|
||||||
public UserInfo[] Mentions;
|
|
||||||
[JsonProperty(PropertyName = "embeds")]
|
|
||||||
public object[] Embeds;
|
|
||||||
[JsonProperty(PropertyName = "attachments")]
|
|
||||||
public object[] Attachments;
|
|
||||||
[JsonProperty(PropertyName = "content")]
|
|
||||||
public string Content;
|
|
||||||
[JsonProperty(PropertyName = "author")]
|
|
||||||
public UserInfo Author;
|
|
||||||
}
|
|
||||||
internal sealed class MessageUpdate
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "id")]
|
|
||||||
public string Id;
|
|
||||||
[JsonProperty(PropertyName = "channel_id")]
|
|
||||||
public string ChannelId;
|
|
||||||
[JsonProperty(PropertyName = "embeds")]
|
[JsonProperty(PropertyName = "embeds")]
|
||||||
public object[] Embeds;
|
public object[] Embeds;
|
||||||
}
|
}
|
||||||
@@ -150,5 +133,14 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "timestamp")]
|
[JsonProperty(PropertyName = "timestamp")]
|
||||||
public int Timestamp;
|
public int Timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Voice
|
||||||
|
internal sealed class VoiceServerUpdate
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
|
public string ServerId;
|
||||||
|
[JsonProperty(PropertyName = "endpoint")]
|
||||||
|
public string Endpoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,13 +45,15 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="API\Models\General.cs" />
|
<Compile Include="API\Models\Common.cs" />
|
||||||
<Compile Include="API\Models\ApiRequests.cs" />
|
<Compile Include="API\Models\APIRequests.cs" />
|
||||||
<Compile Include="API\Endpoints.cs" />
|
<Compile Include="API\Endpoints.cs" />
|
||||||
|
<Compile Include="API\Models\APIResponses.cs" />
|
||||||
<Compile Include="API\Models\WebSocketCommands.cs" />
|
<Compile Include="API\Models\WebSocketCommands.cs" />
|
||||||
|
<Compile Include="Helpers\AsyncCache.cs" />
|
||||||
|
<Compile Include="Models\Invite.cs" />
|
||||||
<Compile Include="Models\Role.cs" />
|
<Compile Include="Models\Role.cs" />
|
||||||
<Compile Include="Models\ChatMessageReference.cs" />
|
<Compile Include="Models\Message.cs" />
|
||||||
<Compile Include="Models\ChatMessage.cs" />
|
|
||||||
<Compile Include="Models\Channel.cs" />
|
<Compile Include="Models\Channel.cs" />
|
||||||
<Compile Include="DiscordWebSocket.Events.cs" />
|
<Compile Include="DiscordWebSocket.Events.cs" />
|
||||||
<Compile Include="Helpers\Http.cs" />
|
<Compile Include="Helpers\Http.cs" />
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace Discord
|
|||||||
public readonly string Message;
|
public readonly string Message;
|
||||||
internal LogMessageEventArgs(string msg) { Message = msg; }
|
internal LogMessageEventArgs(string msg) { Message = msg; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<LogMessageEventArgs> DebugMessage;
|
public event EventHandler<LogMessageEventArgs> DebugMessage;
|
||||||
private void RaiseOnDebugMessage(string message)
|
private void RaiseOnDebugMessage(string message)
|
||||||
{
|
{
|
||||||
@@ -26,7 +25,6 @@ namespace Discord
|
|||||||
if (Connected != null)
|
if (Connected != null)
|
||||||
Connected(this, EventArgs.Empty);
|
Connected(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler Disconnected;
|
public event EventHandler Disconnected;
|
||||||
private void RaiseDisconnected()
|
private void RaiseDisconnected()
|
||||||
{
|
{
|
||||||
@@ -34,12 +32,12 @@ namespace Discord
|
|||||||
Disconnected(this, EventArgs.Empty);
|
Disconnected(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler LoggedIn;
|
/*public event EventHandler LoggedIn;
|
||||||
private void RaiseLoggedIn()
|
private void RaiseLoggedIn()
|
||||||
{
|
{
|
||||||
if (LoggedIn != null)
|
if (LoggedIn != null)
|
||||||
LoggedIn(this, EventArgs.Empty);
|
LoggedIn(this, EventArgs.Empty);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//Server
|
//Server
|
||||||
public sealed class ServerEventArgs : EventArgs
|
public sealed class ServerEventArgs : EventArgs
|
||||||
@@ -54,7 +52,6 @@ namespace Discord
|
|||||||
if (ServerCreated != null)
|
if (ServerCreated != null)
|
||||||
ServerCreated(this, new ServerEventArgs(server));
|
ServerCreated(this, new ServerEventArgs(server));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<ServerEventArgs> ServerDestroyed;
|
public event EventHandler<ServerEventArgs> ServerDestroyed;
|
||||||
private void RaiseServerDestroyed(Server server)
|
private void RaiseServerDestroyed(Server server)
|
||||||
{
|
{
|
||||||
@@ -75,14 +72,12 @@ namespace Discord
|
|||||||
if (ChannelCreated != null)
|
if (ChannelCreated != null)
|
||||||
ChannelCreated(this, new ChannelEventArgs(channel));
|
ChannelCreated(this, new ChannelEventArgs(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<ChannelEventArgs> ChannelDestroyed;
|
public event EventHandler<ChannelEventArgs> ChannelDestroyed;
|
||||||
private void RaiseChannelDestroyed(Channel channel)
|
private void RaiseChannelDestroyed(Channel channel)
|
||||||
{
|
{
|
||||||
if (ChannelDestroyed != null)
|
if (ChannelDestroyed != null)
|
||||||
ChannelDestroyed(this, new ChannelEventArgs(channel));
|
ChannelDestroyed(this, new ChannelEventArgs(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<ChannelEventArgs> ChannelUpdated;
|
public event EventHandler<ChannelEventArgs> ChannelUpdated;
|
||||||
private void RaiseChannelUpdated(Channel channel)
|
private void RaiseChannelUpdated(Channel channel)
|
||||||
{
|
{
|
||||||
@@ -98,40 +93,32 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Message
|
//Message
|
||||||
public sealed class MessageCreateEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public readonly ChatMessage Message;
|
|
||||||
internal MessageCreateEventArgs(ChatMessage msg) { Message = msg; }
|
|
||||||
}
|
|
||||||
public sealed class MessageEventArgs : EventArgs
|
public sealed class MessageEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public readonly ChatMessageReference Message;
|
public readonly Message Message;
|
||||||
internal MessageEventArgs(ChatMessageReference msg) { Message = msg; }
|
internal MessageEventArgs(Message msg) { Message = msg; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MessageCreateEventArgs> MessageCreated;
|
public event EventHandler<MessageEventArgs> MessageCreated;
|
||||||
private void RaiseMessageCreated(ChatMessage msg)
|
private void RaiseMessageCreated(Message msg)
|
||||||
{
|
{
|
||||||
if (MessageCreated != null)
|
if (MessageCreated != null)
|
||||||
MessageCreated(this, new MessageCreateEventArgs(msg));
|
MessageCreated(this, new MessageEventArgs(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MessageEventArgs> MessageDeleted;
|
public event EventHandler<MessageEventArgs> MessageDeleted;
|
||||||
private void RaiseMessageDeleted(ChatMessageReference msg)
|
private void RaiseMessageDeleted(Message msg)
|
||||||
{
|
{
|
||||||
if (MessageDeleted != null)
|
if (MessageDeleted != null)
|
||||||
MessageDeleted(this, new MessageEventArgs(msg));
|
MessageDeleted(this, new MessageEventArgs(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MessageEventArgs> MessageUpdated;
|
public event EventHandler<MessageEventArgs> MessageUpdated;
|
||||||
private void RaiseMessageUpdated(ChatMessageReference msg)
|
private void RaiseMessageUpdated(Message msg)
|
||||||
{
|
{
|
||||||
if (MessageUpdated != null)
|
if (MessageUpdated != null)
|
||||||
MessageUpdated(this, new MessageEventArgs(msg));
|
MessageUpdated(this, new MessageEventArgs(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MessageEventArgs> MessageAcknowledged;
|
public event EventHandler<MessageEventArgs> MessageAcknowledged;
|
||||||
private void RaiseMessageAcknowledged(ChatMessageReference msg)
|
private void RaiseMessageAcknowledged(Message msg)
|
||||||
{
|
{
|
||||||
if (MessageAcknowledged != null)
|
if (MessageAcknowledged != null)
|
||||||
MessageAcknowledged(this, new MessageEventArgs(msg));
|
MessageAcknowledged(this, new MessageEventArgs(msg));
|
||||||
@@ -150,14 +137,12 @@ namespace Discord
|
|||||||
if (RoleCreated != null)
|
if (RoleCreated != null)
|
||||||
RoleCreated(this, new RoleEventArgs(role));
|
RoleCreated(this, new RoleEventArgs(role));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<RoleEventArgs> RoleUpdated;
|
public event EventHandler<RoleEventArgs> RoleUpdated;
|
||||||
private void RaiseRoleDeleted(Role role)
|
private void RaiseRoleDeleted(Role role)
|
||||||
{
|
{
|
||||||
if (RoleDeleted != null)
|
if (RoleDeleted != null)
|
||||||
RoleDeleted(this, new RoleEventArgs(role));
|
RoleDeleted(this, new RoleEventArgs(role));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<RoleEventArgs> RoleDeleted;
|
public event EventHandler<RoleEventArgs> RoleDeleted;
|
||||||
private void RaiseRoleUpdated(Role role)
|
private void RaiseRoleUpdated(Role role)
|
||||||
{
|
{
|
||||||
@@ -183,7 +168,6 @@ namespace Discord
|
|||||||
if (BanAdded != null)
|
if (BanAdded != null)
|
||||||
BanAdded(this, new BanEventArgs(user, server));
|
BanAdded(this, new BanEventArgs(user, server));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<BanEventArgs> BanRemoved;
|
public event EventHandler<BanEventArgs> BanRemoved;
|
||||||
private void RaiseBanRemoved(User user, Server server)
|
private void RaiseBanRemoved(User user, Server server)
|
||||||
{
|
{
|
||||||
@@ -209,14 +193,12 @@ namespace Discord
|
|||||||
if (MemberAdded != null)
|
if (MemberAdded != null)
|
||||||
MemberAdded(this, new MemberEventArgs(user, server));
|
MemberAdded(this, new MemberEventArgs(user, server));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MemberEventArgs> MemberRemoved;
|
public event EventHandler<MemberEventArgs> MemberRemoved;
|
||||||
private void RaiseMemberRemoved(User user, Server server)
|
private void RaiseMemberRemoved(User user, Server server)
|
||||||
{
|
{
|
||||||
if (MemberRemoved != null)
|
if (MemberRemoved != null)
|
||||||
MemberRemoved(this, new MemberEventArgs(user, server));
|
MemberRemoved(this, new MemberEventArgs(user, server));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MemberEventArgs> MemberUpdated;
|
public event EventHandler<MemberEventArgs> MemberUpdated;
|
||||||
private void RaiseMemberUpdated(User user, Server server)
|
private void RaiseMemberUpdated(User user, Server server)
|
||||||
{
|
{
|
||||||
@@ -242,19 +224,36 @@ namespace Discord
|
|||||||
if (PresenceUpdated != null)
|
if (PresenceUpdated != null)
|
||||||
PresenceUpdated(this, new UserEventArgs(user));
|
PresenceUpdated(this, new UserEventArgs(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<UserEventArgs> VoiceStateUpdated;
|
public event EventHandler<UserEventArgs> VoiceStateUpdated;
|
||||||
private void RaiseVoiceStateUpdated(User user)
|
private void RaiseVoiceStateUpdated(User user)
|
||||||
{
|
{
|
||||||
if (VoiceStateUpdated != null)
|
if (VoiceStateUpdated != null)
|
||||||
VoiceStateUpdated(this, new UserEventArgs(user));
|
VoiceStateUpdated(this, new UserEventArgs(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<UserTypingEventArgs> UserTyping;
|
public event EventHandler<UserTypingEventArgs> UserTyping;
|
||||||
private void RaiseUserTyping(User user, Channel channel)
|
private void RaiseUserTyping(User user, Channel channel)
|
||||||
{
|
{
|
||||||
if (UserTyping != null)
|
if (UserTyping != null)
|
||||||
UserTyping(this, new UserTypingEventArgs(user, channel));
|
UserTyping(this, new UserTypingEventArgs(user, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Voice
|
||||||
|
public sealed class VoiceServerUpdatedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public readonly Server Server;
|
||||||
|
public readonly string Endpoint;
|
||||||
|
internal VoiceServerUpdatedEventArgs(Server server, string endpoint)
|
||||||
|
{
|
||||||
|
Server = server;
|
||||||
|
Endpoint = endpoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<VoiceServerUpdatedEventArgs> VoiceServerUpdated;
|
||||||
|
private void RaiseVoiceServerUpdated(Server server, string endpoint)
|
||||||
|
{
|
||||||
|
if (VoiceServerUpdated != null)
|
||||||
|
VoiceServerUpdated(this, new VoiceServerUpdatedEventArgs(server, endpoint));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ using Discord.API.Models;
|
|||||||
using Discord.Helpers;
|
using Discord.Helpers;
|
||||||
using Discord.Models;
|
using Discord.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Message = Discord.Models.Message;
|
||||||
using Role = Discord.Models.Role;
|
using Role = Discord.Models.Role;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -19,26 +21,144 @@ namespace Discord
|
|||||||
private HttpOptions _httpOptions;
|
private HttpOptions _httpOptions;
|
||||||
private bool _isClosing, _isReady;
|
private bool _isClosing, _isReady;
|
||||||
|
|
||||||
public string SelfId { get; private set; }
|
public string UserId { get; private set; }
|
||||||
public User Self { get { return GetUser(SelfId); } }
|
public User User { get { return _users[UserId]; } }
|
||||||
|
|
||||||
public IEnumerable<User> Users { get { return _users.Values; } }
|
public IEnumerable<User> Users { get { return _users; } }
|
||||||
private ConcurrentDictionary<string, User> _users;
|
private AsyncCache<User, API.Models.UserReference> _users;
|
||||||
|
|
||||||
public IEnumerable<Server> Servers { get { return _servers.Values; } }
|
public IEnumerable<Server> Servers { get { return _servers; } }
|
||||||
private ConcurrentDictionary<string, Server> _servers;
|
private AsyncCache<Server, API.Models.ServerReference> _servers;
|
||||||
|
|
||||||
public IEnumerable<Channel> Channels { get { return _channels.Values; } }
|
public IEnumerable<Channel> Channels { get { return _channels; } }
|
||||||
private ConcurrentDictionary<string, Channel> _channels;
|
private AsyncCache<Channel, API.Models.ChannelReference> _channels;
|
||||||
|
|
||||||
|
public IEnumerable<Message> Messages { get { return _messages; } }
|
||||||
|
private AsyncCache<Message, API.Models.MessageReference> _messages;
|
||||||
|
|
||||||
|
public IEnumerable<Role> Roles { get { return _roles; } }
|
||||||
|
private AsyncCache<Role, API.Models.Role> _roles;
|
||||||
|
|
||||||
|
public bool IsConnected { get { return _isReady; } }
|
||||||
|
|
||||||
public DiscordClient()
|
public DiscordClient()
|
||||||
{
|
{
|
||||||
string version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(2);
|
string version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(2);
|
||||||
_httpOptions = new HttpOptions { UserAgent = $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)" };
|
_httpOptions = new HttpOptions { UserAgent = $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)" };
|
||||||
|
|
||||||
_users = new ConcurrentDictionary<string, User>();
|
_servers = new AsyncCache<Server, API.Models.ServerReference>(
|
||||||
_servers = new ConcurrentDictionary<string, Server>();
|
(key, parentKey) => new Server(key, this),
|
||||||
_channels = new ConcurrentDictionary<string, Channel>();
|
(server, model) =>
|
||||||
|
{
|
||||||
|
server.Name = model.Name;
|
||||||
|
if (model is ExtendedServerInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as ExtendedServerInfo;
|
||||||
|
server.AFKChannelId = extendedModel.AFKChannelId;
|
||||||
|
server.AFKTimeout = extendedModel.AFKTimeout;
|
||||||
|
server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue;
|
||||||
|
server.OwnerId = extendedModel.OwnerId;
|
||||||
|
server.Presence = extendedModel.Presence;
|
||||||
|
server.Region = extendedModel.Region;
|
||||||
|
server.VoiceStates = extendedModel.VoiceStates;
|
||||||
|
|
||||||
|
foreach (var role in extendedModel.Roles)
|
||||||
|
_roles.Update(role.Id, model.Id, role);
|
||||||
|
foreach (var channel in extendedModel.Channels)
|
||||||
|
{
|
||||||
|
_channels.Update(channel.Id, model.Id, channel);
|
||||||
|
if (channel.Type == "text")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var messages = DiscordAPI.GetMessages(channel.Id, _httpOptions).Result.OrderBy(x => x.Timestamp);
|
||||||
|
foreach (var message in messages)
|
||||||
|
{
|
||||||
|
var msg = _messages.Update(message.Id, message.ChannelId, message);
|
||||||
|
if (msg.User != null)
|
||||||
|
msg.User.UpdateActivity(message.Timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { } //Bad Permissions?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var membership in extendedModel.Members)
|
||||||
|
{
|
||||||
|
_users.Update(membership.User.Id, membership.User);
|
||||||
|
server.AddMember(membership.User.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server => { }
|
||||||
|
);
|
||||||
|
|
||||||
|
_channels = new AsyncCache<Channel, API.Models.ChannelReference>(
|
||||||
|
(key, parentKey) => new Channel(key, parentKey, this),
|
||||||
|
(channel, model) =>
|
||||||
|
{
|
||||||
|
channel.Name = model.Name;
|
||||||
|
channel.Type = model.Type;
|
||||||
|
if (model is ChannelInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as ChannelInfo;
|
||||||
|
channel.PermissionOverwrites = extendedModel.PermissionOverwrites;
|
||||||
|
channel.RecipientId = extendedModel.Recipient?.Id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel => { });
|
||||||
|
_messages = new AsyncCache<Message, API.Models.MessageReference>(
|
||||||
|
(key, parentKey) => new Message(key, parentKey, this),
|
||||||
|
(message, model) =>
|
||||||
|
{
|
||||||
|
if (model is API.Models.Message)
|
||||||
|
{
|
||||||
|
var extendedModel = model as API.Models.Message;
|
||||||
|
message.Attachments = extendedModel.Attachments;
|
||||||
|
message.Text = extendedModel.Content;
|
||||||
|
message.Embeds = extendedModel.Embeds;
|
||||||
|
message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
|
||||||
|
message.IsTTS = extendedModel.IsTextToSpeech;
|
||||||
|
message.UserId = extendedModel.Author.Id;
|
||||||
|
message.Timestamp = extendedModel.Timestamp;
|
||||||
|
}
|
||||||
|
if (model is WebSocketEvents.MessageUpdate)
|
||||||
|
{
|
||||||
|
var extendedModel = model as WebSocketEvents.MessageUpdate;
|
||||||
|
message.Embeds = extendedModel.Embeds;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
message => { }
|
||||||
|
);
|
||||||
|
_roles = new AsyncCache<Role, API.Models.Role>(
|
||||||
|
(key, parentKey) => new Role(key, parentKey, this),
|
||||||
|
(role, model) =>
|
||||||
|
{
|
||||||
|
role.Permissions = model.Permissions;
|
||||||
|
},
|
||||||
|
role => { }
|
||||||
|
);
|
||||||
|
_users = new AsyncCache<User, API.Models.UserReference>(
|
||||||
|
(key, parentKey) => new User(key, this),
|
||||||
|
(user, model) =>
|
||||||
|
{
|
||||||
|
user.Avatar = model.Avatar;
|
||||||
|
user.Discriminator = model.Discriminator;
|
||||||
|
user.Name = model.Username;
|
||||||
|
if (model is SelfUserInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as SelfUserInfo;
|
||||||
|
user.Email = extendedModel.Email;
|
||||||
|
user.IsVerified = extendedModel.IsVerified;
|
||||||
|
}
|
||||||
|
if (model is PresenceUserInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as PresenceUserInfo;
|
||||||
|
user.GameId = extendedModel.GameId;
|
||||||
|
user.Status = extendedModel.Status;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user => { }
|
||||||
|
);
|
||||||
|
|
||||||
_webSocket = new DiscordWebSocket();
|
_webSocket = new DiscordWebSocket();
|
||||||
_webSocket.Connected += (s,e) => RaiseConnected();
|
_webSocket.Connected += (s,e) => RaiseConnected();
|
||||||
@@ -65,14 +185,12 @@ namespace Discord
|
|||||||
_channels.Clear();
|
_channels.Clear();
|
||||||
_users.Clear();
|
_users.Clear();
|
||||||
|
|
||||||
SelfId = data.User.Id;
|
UserId = data.User.Id;
|
||||||
UpdateUser(data.User);
|
_users.Update(data.User.Id, data.User);
|
||||||
foreach (var server in data.Guilds)
|
foreach (var server in data.Guilds)
|
||||||
UpdateServer(server);
|
_servers.Update(server.Id, server);
|
||||||
foreach (var channel in data.PrivateChannels)
|
foreach (var channel in data.PrivateChannels)
|
||||||
UpdateChannel(channel as ChannelInfo, null);
|
_channels.Update(channel.Id, null, channel);
|
||||||
|
|
||||||
RaiseLoggedIn();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -80,15 +198,15 @@ namespace Discord
|
|||||||
case "GUILD_CREATE":
|
case "GUILD_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildCreate>();
|
||||||
var server = UpdateServer(data);
|
var server = _servers.Update(data.Id, data);
|
||||||
RaiseServerCreated(server);
|
RaiseServerCreated(server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_DELETE":
|
case "GUILD_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildDelete>();
|
||||||
Server server;
|
var server = _servers.Remove(data.Id);
|
||||||
if (_servers.TryRemove(data.Id, out server))
|
if (server != null)
|
||||||
RaiseServerDestroyed(server);
|
RaiseServerDestroyed(server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -97,52 +215,53 @@ namespace Discord
|
|||||||
case "CHANNEL_CREATE":
|
case "CHANNEL_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.ChannelCreate>();
|
||||||
var channel = UpdateChannel(data, null);
|
var channel = _channels.Update(data.Id, data.GuildId, data);
|
||||||
RaiseChannelCreated(channel);
|
RaiseChannelCreated(channel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CHANNEL_DELETE":
|
|
||||||
{
|
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelDelete>();
|
|
||||||
var channel = DeleteChannel(data.Id);
|
|
||||||
RaiseChannelDestroyed(channel);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CHANNEL_UPDATE":
|
case "CHANNEL_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.ChannelUpdate>();
|
||||||
var channel = DeleteChannel(data.Id);
|
var channel = _channels.Update(data.Id, data.GuildId, data);
|
||||||
RaiseChannelUpdated(channel);
|
RaiseChannelUpdated(channel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "CHANNEL_DELETE":
|
||||||
|
{
|
||||||
|
var data = e.Event.ToObject<WebSocketEvents.ChannelDelete>();
|
||||||
|
var channel = _channels.Remove(data.Id);
|
||||||
|
if (channel != null)
|
||||||
|
RaiseChannelDestroyed(channel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//Members
|
//Members
|
||||||
case "GUILD_MEMBER_ADD":
|
case "GUILD_MEMBER_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberAdd>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberAdd>();
|
||||||
var user = UpdateUser(data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = GetServer(data.GuildId);
|
var server = _servers[data.GuildId];
|
||||||
server._members[user.Id] = true;
|
server._members[user.Id] = true;
|
||||||
RaiseMemberAdded(user, server);
|
RaiseMemberAdded(user, server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_MEMBER_REMOVE":
|
|
||||||
{
|
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberRemove>();
|
|
||||||
var user = UpdateUser(data.User);
|
|
||||||
var server = GetServer(data.GuildId);
|
|
||||||
server._members[user.Id] = true;
|
|
||||||
RaiseMemberRemoved(user, server);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "GUILD_MEMBER_UPDATE":
|
case "GUILD_MEMBER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberUpdate>();
|
||||||
var user = UpdateUser(data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = GetServer(data.GuildId);
|
var server = _servers[data.GuildId];
|
||||||
RaiseMemberUpdated(user, server);
|
RaiseMemberUpdated(user, server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "GUILD_MEMBER_REMOVE":
|
||||||
|
{
|
||||||
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberRemove>();
|
||||||
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
|
var server = _servers[data.GuildId];
|
||||||
|
if (server != null && server.RemoveMember(user.Id))
|
||||||
|
RaiseMemberRemoved(user, server);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//Roles
|
//Roles
|
||||||
case "GUILD_ROLE_CREATE":
|
case "GUILD_ROLE_CREATE":
|
||||||
@@ -152,13 +271,6 @@ namespace Discord
|
|||||||
RaiseRoleCreated(role);
|
RaiseRoleCreated(role);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_ROLE_DELETE":
|
|
||||||
{
|
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildRoleDelete>();
|
|
||||||
var role = GetRole(data.RoleId, data.GuildId);
|
|
||||||
RaiseRoleDeleted(role);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "GUILD_ROLE_UPDATE":
|
case "GUILD_ROLE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>();
|
||||||
@@ -166,22 +278,31 @@ namespace Discord
|
|||||||
RaiseRoleUpdated(role);
|
RaiseRoleUpdated(role);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "GUILD_ROLE_DELETE":
|
||||||
|
{
|
||||||
|
var data = e.Event.ToObject<WebSocketEvents.GuildRoleDelete>();
|
||||||
|
var role = _roles.Remove(data.RoleId);
|
||||||
|
if (role != null)
|
||||||
|
RaiseRoleDeleted(role);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//Roles
|
//Bans
|
||||||
case "GUILD_BAN_ADD":
|
case "GUILD_BAN_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
||||||
var user = UpdateUser(data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = GetServer(data.GuildId);
|
var server = _servers[data.GuildId];
|
||||||
RaiseBanAdded(user, server);
|
RaiseBanAdded(user, server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_BAN_REMOVE":
|
case "GUILD_BAN_REMOVE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
||||||
var user = UpdateUser(data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = GetServer(data.GuildId);
|
var server = _servers[data.GuildId];
|
||||||
RaiseBanRemoved(user, server);
|
if (server != null && server.RemoveBan(user.Id))
|
||||||
|
RaiseBanRemoved(user, server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -189,7 +310,7 @@ namespace Discord
|
|||||||
case "MESSAGE_CREATE":
|
case "MESSAGE_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageCreate>();
|
||||||
var msg = UpdateMessage(data);
|
var msg = _messages.Update(data.Id, data.ChannelId, data);
|
||||||
msg.User.UpdateActivity(data.Timestamp);
|
msg.User.UpdateActivity(data.Timestamp);
|
||||||
RaiseMessageCreated(msg);
|
RaiseMessageCreated(msg);
|
||||||
}
|
}
|
||||||
@@ -197,21 +318,21 @@ namespace Discord
|
|||||||
case "MESSAGE_UPDATE":
|
case "MESSAGE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageUpdate>();
|
||||||
var msg = GetMessage(data.Id, data.ChannelId);
|
var msg = _messages.Update(data.Id, data);
|
||||||
RaiseMessageUpdated(msg);
|
RaiseMessageUpdated(msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MESSAGE_DELETE":
|
case "MESSAGE_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageDelete>();
|
||||||
var msg = GetMessage(data.MessageId, data.ChannelId);
|
var msg = GetMessage(data.MessageId);
|
||||||
RaiseMessageDeleted(msg);
|
_messages.Remove(msg.Id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MESSAGE_ACK":
|
case "MESSAGE_ACK":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageAck>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageAck>();
|
||||||
var msg = GetMessage(data.MessageId, data.ChannelId);
|
var msg = GetMessage(data.MessageId);
|
||||||
RaiseMessageAcknowledged(msg);
|
RaiseMessageAcknowledged(msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -220,25 +341,36 @@ namespace Discord
|
|||||||
case "PRESENCE_UPDATE":
|
case "PRESENCE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.PresenceUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.PresenceUpdate>();
|
||||||
var user = UpdateUser(data);
|
var user = _users.Update(data.Id, data);
|
||||||
RaisePresenceUpdated(user);
|
RaisePresenceUpdated(user);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "VOICE_STATE_UPDATE":
|
case "VOICE_STATE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.VoiceStateUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.VoiceStateUpdate>();
|
||||||
var user = GetUser(data.UserId); //TODO: Don't ignore this
|
var user = _users[data.UserId]; //TODO: Don't ignore this
|
||||||
RaiseVoiceStateUpdated(user);
|
RaiseVoiceStateUpdated(user);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "TYPING_START":
|
case "TYPING_START":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.TypingStart>();
|
var data = e.Event.ToObject<WebSocketEvents.TypingStart>();
|
||||||
var channel = GetChannel(data.ChannelId);
|
var channel = _channels[data.ChannelId];
|
||||||
var user = GetUser(data.UserId);
|
var user = _users[data.UserId];
|
||||||
RaiseUserTyping(user, channel);
|
RaiseUserTyping(user, channel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//Voice
|
||||||
|
case "VOICE_SERVER_UPDATE":
|
||||||
|
{
|
||||||
|
var data = e.Event.ToObject<WebSocketEvents.VoiceServerUpdate>();
|
||||||
|
var server = _servers[data.ServerId];
|
||||||
|
RaiseVoiceServerUpdated(server, data.Endpoint);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Others
|
||||||
default:
|
default:
|
||||||
RaiseOnDebugMessage("Unknown WebSocket message type: " + e.Type);
|
RaiseOnDebugMessage("Unknown WebSocket message type: " + e.Type);
|
||||||
break;
|
break;
|
||||||
@@ -247,6 +379,7 @@ namespace Discord
|
|||||||
_webSocket.OnDebugMessage += (s, e) => RaiseOnDebugMessage(e.Message);
|
_webSocket.OnDebugMessage += (s, e) => RaiseOnDebugMessage(e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Auth
|
||||||
public async Task Connect(string email, string password)
|
public async Task Connect(string email, string password)
|
||||||
{
|
{
|
||||||
_isClosing = false;
|
_isClosing = false;
|
||||||
@@ -271,21 +404,67 @@ namespace Discord
|
|||||||
_isClosing = false;
|
_isClosing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task CreateServer(string name, string region)
|
//Servers
|
||||||
|
public async Task<Server> CreateServer(string name, string region)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.CreateServer(name, region, _httpOptions);
|
var response = await DiscordAPI.CreateServer(name, region, _httpOptions);
|
||||||
|
return _servers.Update(response.Id, response);
|
||||||
}
|
}
|
||||||
public Task DeleteServer(string id)
|
public Task<Server> LeaveServer(Server server)
|
||||||
|
{
|
||||||
|
return LeaveServer(server.Id);
|
||||||
|
}
|
||||||
|
public async Task<Server> LeaveServer(string id)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.DeleteServer(id, _httpOptions);
|
await DiscordAPI.LeaveServer(id, _httpOptions);
|
||||||
|
return _servers.Remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<GetInviteResponse> GetInvite(string id)
|
//Invites
|
||||||
|
public Task<Invite> CreateInvite(Server server, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
||||||
|
{
|
||||||
|
return CreateInvite(server.DefaultChannelId, maxAge, maxUses, isTemporary, hasXkcdPass);
|
||||||
|
}
|
||||||
|
public Task<Invite> CreateInvite(Channel channel, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
||||||
|
{
|
||||||
|
return CreateInvite(channel, maxAge, maxUses, isTemporary, hasXkcdPass);
|
||||||
|
}
|
||||||
|
public async Task<Invite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.GetInvite(id, _httpOptions);
|
var response = await DiscordAPI.CreateInvite(channelId, maxAge, maxUses, isTemporary, hasXkcdPass, _httpOptions);
|
||||||
|
_channels.Update(response.Channel.Id, response.Server.Id, response.Channel);
|
||||||
|
_servers.Update(response.Server.Id, response.Server);
|
||||||
|
_users.Update(response.Inviter.Id, response.Inviter);
|
||||||
|
return new Invite(response.Code, response.XkcdPass, this)
|
||||||
|
{
|
||||||
|
ChannelId = response.Channel.Id,
|
||||||
|
InviterId = response.Inviter.Id,
|
||||||
|
ServerId = response.Server.Id,
|
||||||
|
IsRevoked = response.IsRevoked,
|
||||||
|
IsTemporary = response.IsTemporary,
|
||||||
|
MaxAge = response.MaxAge,
|
||||||
|
MaxUses = response.MaxUses,
|
||||||
|
Uses = response.Uses
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<Invite> GetInvite(string id)
|
||||||
|
{
|
||||||
|
CheckReady();
|
||||||
|
var response = await DiscordAPI.GetInvite(id, _httpOptions);
|
||||||
|
return new Invite(response.Code, response.XkcdPass, this)
|
||||||
|
{
|
||||||
|
ChannelId = response.Channel.Id,
|
||||||
|
InviterId = response.Inviter.Id,
|
||||||
|
ServerId = response.Server.Id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public Task AcceptInvite(Invite invite)
|
||||||
|
{
|
||||||
|
CheckReady();
|
||||||
|
return DiscordAPI.AcceptInvite(invite.Code, _httpOptions);
|
||||||
}
|
}
|
||||||
public async Task AcceptInvite(string id)
|
public async Task AcceptInvite(string id)
|
||||||
{
|
{
|
||||||
@@ -302,6 +481,7 @@ namespace Discord
|
|||||||
await DiscordAPI.DeleteInvite(response.Code, _httpOptions);
|
await DiscordAPI.DeleteInvite(response.Code, _httpOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Chat
|
||||||
public Task SendMessage(string channelId, string text)
|
public Task SendMessage(string channelId, string text)
|
||||||
{
|
{
|
||||||
return SendMessage(channelId, text, new string[0]);
|
return SendMessage(channelId, text, new string[0]);
|
||||||
@@ -323,136 +503,27 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public User GetUser(string id)
|
|
||||||
{
|
|
||||||
if (id == null) return null;
|
|
||||||
User user = null;
|
|
||||||
_users.TryGetValue(id, out user);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
private User UpdateUser(UserInfo model, bool addNew = true)
|
|
||||||
{
|
|
||||||
var user = GetUser(model.Id) ?? new User(model.Id, this);
|
|
||||||
|
|
||||||
user.Avatar = model.Avatar;
|
|
||||||
user.Discriminator = model.Discriminator;
|
|
||||||
user.Name = model.Username;
|
|
||||||
if (model is SelfUserInfo)
|
|
||||||
{
|
|
||||||
var extendedModel = model as SelfUserInfo;
|
|
||||||
user.Email = extendedModel.Email;
|
|
||||||
user.IsVerified = extendedModel.IsVerified;
|
|
||||||
}
|
|
||||||
if (model is PresenceUserInfo)
|
|
||||||
{
|
|
||||||
var extendedModel = model as PresenceUserInfo;
|
|
||||||
user.GameId = extendedModel.GameId;
|
|
||||||
user.Status = extendedModel.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addNew)
|
|
||||||
_users[model.Id] = user;
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Server GetServer(string id)
|
public Server GetServer(string id)
|
||||||
{
|
{
|
||||||
if (id == null) return null;
|
return _servers[id];
|
||||||
Server server = null;
|
|
||||||
_servers.TryGetValue(id, out server);
|
|
||||||
return server;
|
|
||||||
}
|
}
|
||||||
private Server UpdateServer(ServerInfo model, bool addNew = true)
|
|
||||||
{
|
|
||||||
var server = GetServer(model.Id) ?? new Server(model.Id, this);
|
|
||||||
|
|
||||||
server.Name = model.Name;
|
|
||||||
if (model is ExtendedServerInfo)
|
|
||||||
{
|
|
||||||
var extendedModel = model as ExtendedServerInfo;
|
|
||||||
server.AFKChannelId = extendedModel.AFKChannelId;
|
|
||||||
server.AFKTimeout = extendedModel.AFKTimeout;
|
|
||||||
server.JoinedAt = extendedModel.JoinedAt;
|
|
||||||
server.OwnerId = extendedModel.OwnerId;
|
|
||||||
server.Presence = extendedModel.Presence;
|
|
||||||
server.Region = extendedModel.Region;
|
|
||||||
server.Roles = extendedModel.Roles;
|
|
||||||
server.VoiceStates = extendedModel.VoiceStates;
|
|
||||||
|
|
||||||
foreach (var channel in extendedModel.Channels)
|
|
||||||
{
|
|
||||||
UpdateChannel(channel, model.Id, addNew);
|
|
||||||
server._channels[channel.Id] = true;
|
|
||||||
}
|
|
||||||
foreach (var membership in extendedModel.Members)
|
|
||||||
{
|
|
||||||
UpdateUser(membership.User, addNew);
|
|
||||||
server._members[membership.User.Id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addNew)
|
|
||||||
_servers[model.Id] = server;
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Channel GetChannel(string id)
|
public Channel GetChannel(string id)
|
||||||
{
|
{
|
||||||
if (id == null) return null;
|
return _channels[id];
|
||||||
Channel channel = null;
|
|
||||||
_channels.TryGetValue(id, out channel);
|
|
||||||
return channel;
|
|
||||||
}
|
}
|
||||||
private Channel UpdateChannel(ChannelInfo model, string serverId, bool addNew = true)
|
public User GetUser(string id)
|
||||||
{
|
{
|
||||||
var channel = GetChannel(model.Id) ?? new Channel(model.Id, serverId, this);
|
return _users[id];
|
||||||
|
|
||||||
channel.Name = model.Name;
|
|
||||||
channel.IsPrivate = model.IsPrivate;
|
|
||||||
channel.PermissionOverwrites = model.PermissionOverwrites;
|
|
||||||
channel.RecipientId = model.Recipient?.Id;
|
|
||||||
channel.Type = model.Type;
|
|
||||||
|
|
||||||
if (addNew)
|
|
||||||
_channels[model.Id] = channel;
|
|
||||||
return channel;
|
|
||||||
}
|
}
|
||||||
private Channel DeleteChannel(string id)
|
public Models.Message GetMessage(string id)
|
||||||
{
|
{
|
||||||
Channel channel = null;
|
return _messages[id];
|
||||||
if (_channels.TryRemove(id, out channel))
|
|
||||||
{
|
|
||||||
bool ignored;
|
|
||||||
channel.Server._channels.TryRemove(id, out ignored);
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Temporary measure, unsure if we want to store these or not.
|
|
||||||
private ChatMessageReference GetMessage(string id, string channelId)
|
|
||||||
{
|
|
||||||
if (id == null || channelId == null) return null;
|
|
||||||
return new ChatMessageReference(id, channelId, this);
|
|
||||||
}
|
}
|
||||||
private ChatMessage UpdateMessage(WebSocketEvents.MessageCreate model, bool addNew = true)
|
public Role GetRole(string id)
|
||||||
{
|
{
|
||||||
return new ChatMessage(model.Id, model.ChannelId, this)
|
return _roles[id];
|
||||||
{
|
|
||||||
Attachments = model.Attachments,
|
|
||||||
Text = model.Content,
|
|
||||||
Embeds = model.Embeds,
|
|
||||||
IsMentioningEveryone = model.IsMentioningEveryone,
|
|
||||||
IsTTS = model.IsTextToSpeech,
|
|
||||||
UserId = model.Author.Id,
|
|
||||||
Timestamp = model.Timestamp
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Role GetRole(string id, string serverId)
|
|
||||||
{
|
|
||||||
if (id == null || serverId == null) return null;
|
|
||||||
return new Role(id, serverId, this);
|
|
||||||
}
|
|
||||||
private Role UpdateRole(WebSocketEvents.GuildRoleCreateUpdate role, bool addNew = true)
|
private Role UpdateRole(WebSocketEvents.GuildRoleCreateUpdate role, bool addNew = true)
|
||||||
{
|
{
|
||||||
return new Role(role.Role.Id, role.GuildId, this)
|
return new Role(role.Role.Id, role.GuildId, this)
|
||||||
@@ -467,5 +538,12 @@ namespace Discord
|
|||||||
if (!_isReady)
|
if (!_isReady)
|
||||||
throw new InvalidOperationException("The client is not currently connected to Discord");
|
throw new InvalidOperationException("The client is not currently connected to Discord");
|
||||||
}
|
}
|
||||||
|
public void Block()
|
||||||
|
{
|
||||||
|
//Blocking call for console apps
|
||||||
|
//TODO: Improve this
|
||||||
|
while (!_isClosing)
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,13 @@ namespace Discord
|
|||||||
private ConcurrentQueue<byte[]> _sendQueue;
|
private ConcurrentQueue<byte[]> _sendQueue;
|
||||||
private int _heartbeatInterval;
|
private int _heartbeatInterval;
|
||||||
private DateTime _lastHeartbeat;
|
private DateTime _lastHeartbeat;
|
||||||
|
private AutoResetEvent _connectWaitOnLogin;
|
||||||
|
|
||||||
public async Task ConnectAsync(string url, HttpOptions options)
|
public async Task ConnectAsync(string url, HttpOptions options)
|
||||||
{
|
{
|
||||||
await DisconnectAsync();
|
await DisconnectAsync();
|
||||||
|
|
||||||
|
_connectWaitOnLogin = new AutoResetEvent(false);
|
||||||
_sendQueue = new ConcurrentQueue<byte[]>();
|
_sendQueue = new ConcurrentQueue<byte[]>();
|
||||||
|
|
||||||
_webSocket = new ClientWebSocket();
|
_webSocket = new ClientWebSocket();
|
||||||
@@ -62,7 +64,9 @@ namespace Discord
|
|||||||
msg.Payload.Properties["$referrer"] = "";
|
msg.Payload.Properties["$referrer"] = "";
|
||||||
msg.Payload.Properties["$referring_domain"] = "";
|
msg.Payload.Properties["$referring_domain"] = "";
|
||||||
SendMessage(msg, cancelToken);
|
SendMessage(msg, cancelToken);
|
||||||
}
|
|
||||||
|
_connectWaitOnLogin.WaitOne();
|
||||||
|
}
|
||||||
public async Task DisconnectAsync()
|
public async Task DisconnectAsync()
|
||||||
{
|
{
|
||||||
if (_webSocket != null)
|
if (_webSocket != null)
|
||||||
@@ -112,6 +116,8 @@ namespace Discord
|
|||||||
SendMessage(new WebSocketCommands.KeepAlive(), cancelToken);
|
SendMessage(new WebSocketCommands.KeepAlive(), cancelToken);
|
||||||
}
|
}
|
||||||
RaiseGotEvent(msg.Type, msg.Payload as JToken);
|
RaiseGotEvent(msg.Type, msg.Payload as JToken);
|
||||||
|
if (msg.Type == "READY")
|
||||||
|
_connectWaitOnLogin.Set();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RaiseOnDebugMessage("Unknown WebSocket operation ID: " + msg.Operation);
|
RaiseOnDebugMessage("Unknown WebSocket operation ID: " + msg.Operation);
|
||||||
|
|||||||
90
Discord.Net/Helpers/AsyncCache.cs
Normal file
90
Discord.Net/Helpers/AsyncCache.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Discord.Helpers
|
||||||
|
{
|
||||||
|
public class AsyncCache<TValue, TModel> : IEnumerable<TValue>
|
||||||
|
where TValue : class
|
||||||
|
where TModel : class
|
||||||
|
{
|
||||||
|
protected readonly ConcurrentDictionary<string, TValue> _dictionary;
|
||||||
|
private readonly Func<string, string, TValue> _onCreate;
|
||||||
|
private readonly Action<TValue, TModel> _onUpdate;
|
||||||
|
private readonly Action<TValue> _onRemove;
|
||||||
|
|
||||||
|
public AsyncCache(Func<string, string, TValue> onCreate, Action<TValue, TModel> onUpdate, Action<TValue> onRemove)
|
||||||
|
{
|
||||||
|
_dictionary = new ConcurrentDictionary<string, TValue>();
|
||||||
|
_onCreate = onCreate;
|
||||||
|
_onUpdate = onUpdate;
|
||||||
|
_onRemove = onRemove;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue this[string key]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (key == null)
|
||||||
|
return null;
|
||||||
|
TValue value = null;
|
||||||
|
_dictionary.TryGetValue(key, out value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue Update(string key, TModel model)
|
||||||
|
{
|
||||||
|
return Update(key, null, model);
|
||||||
|
}
|
||||||
|
public TValue Update(string key, string parentKey, TModel model)
|
||||||
|
{
|
||||||
|
if (key == null)
|
||||||
|
return null;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
bool isNew;
|
||||||
|
TValue value;
|
||||||
|
isNew = !_dictionary.TryGetValue(key, out value);
|
||||||
|
if (isNew)
|
||||||
|
value = _onCreate(key, parentKey);
|
||||||
|
_onUpdate(value, model);
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
//If this fails, repeat as an update instead of an add
|
||||||
|
if (_dictionary.TryAdd(key, value))
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dictionary[key] = value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue Remove(string key)
|
||||||
|
{
|
||||||
|
TValue value = null;
|
||||||
|
if (_dictionary.TryRemove(key, out value))
|
||||||
|
return value;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_dictionary.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TValue> GetEnumerator()
|
||||||
|
{
|
||||||
|
return _dictionary.Values.GetEnumerator();
|
||||||
|
}
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return _dictionary.Values.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
@@ -24,47 +25,93 @@ namespace Discord.Helpers
|
|||||||
internal static class Http
|
internal static class Http
|
||||||
{
|
{
|
||||||
private static readonly RequestCachePolicy _cachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
|
private static readonly RequestCachePolicy _cachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
|
||||||
|
#if DEBUG
|
||||||
|
private const bool _isDebug = true;
|
||||||
|
#else
|
||||||
|
private const bool _isDebug = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//GET
|
||||||
internal static async Task<ResponseT> Get<ResponseT>(string path, object data, HttpOptions options)
|
internal static async Task<ResponseT> Get<ResponseT>(string path, object data, HttpOptions options)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string requestJson = JsonConvert.SerializeObject(data);
|
string requestJson = JsonConvert.SerializeObject(data);
|
||||||
string responseJson = await SendRequest("GET", path, requestJson, options, true);
|
string responseJson = await SendRequest("GET", path, requestJson, options, true);
|
||||||
return JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
|
#if DEBUG
|
||||||
|
CheckResponse(responseJson, response);
|
||||||
|
#endif
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
internal static async Task<ResponseT> Get<ResponseT>(string path, HttpOptions options)
|
internal static async Task<ResponseT> Get<ResponseT>(string path, HttpOptions options)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string responseJson = await SendRequest("GET", path, null, options, true);
|
string responseJson = await SendRequest("GET", path, null, options, true);
|
||||||
return JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
|
#if DEBUG
|
||||||
|
CheckResponse(responseJson, response);
|
||||||
|
#endif
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//POST
|
||||||
internal static async Task<ResponseT> Post<ResponseT>(string path, object data, HttpOptions options)
|
internal static async Task<ResponseT> Post<ResponseT>(string path, object data, HttpOptions options)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string requestJson = JsonConvert.SerializeObject(data);
|
string requestJson = JsonConvert.SerializeObject(data);
|
||||||
string responseJson = await SendRequest("POST", path, requestJson, options, true);
|
string responseJson = await SendRequest("POST", path, requestJson, options, true);
|
||||||
return JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
|
#if DEBUG
|
||||||
|
CheckResponse(responseJson, response);
|
||||||
|
#endif
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
internal static Task Post(string path, object data, HttpOptions options)
|
internal static async Task<string> Post(string path, object data, HttpOptions options)
|
||||||
{
|
{
|
||||||
string requestJson = JsonConvert.SerializeObject(data);
|
string requestJson = JsonConvert.SerializeObject(data);
|
||||||
return SendRequest("POST", path, requestJson, options, false);
|
string responseJson = await SendRequest("POST", path, requestJson, options, _isDebug);
|
||||||
|
#if DEBUG
|
||||||
|
CheckEmptyResponse(responseJson);
|
||||||
|
#endif
|
||||||
|
return responseJson;
|
||||||
}
|
}
|
||||||
internal static async Task<ResponseT> Post<ResponseT>(string path, HttpOptions options)
|
internal static async Task<ResponseT> Post<ResponseT>(string path, HttpOptions options)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string responseJson = await SendRequest("POST", path, null, options, true);
|
string responseJson = await SendRequest("POST", path, null, options, true);
|
||||||
return JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
|
#if DEBUG
|
||||||
|
CheckResponse(responseJson, response);
|
||||||
|
#endif
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
internal static Task Post(string path, HttpOptions options)
|
internal static async Task<string> Post(string path, HttpOptions options)
|
||||||
{
|
{
|
||||||
return SendRequest("POST", path, null, options, false);
|
string responseJson = await SendRequest("POST", path, null, options, _isDebug);
|
||||||
|
#if DEBUG
|
||||||
|
CheckEmptyResponse(responseJson);
|
||||||
|
#endif
|
||||||
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Task Delete(string path, HttpOptions options)
|
//DELETE
|
||||||
|
internal static async Task<ResponseT> Delete<ResponseT>(string path, HttpOptions options)
|
||||||
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
return SendRequest("DELETE", path, null, options, false);
|
string responseJson = await SendRequest("DELETE", path, null, options, true);
|
||||||
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
|
#if DEBUG
|
||||||
|
CheckResponse(responseJson, response);
|
||||||
|
#endif
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
internal static async Task<string> Delete(string path, HttpOptions options)
|
||||||
|
{
|
||||||
|
string responseJson = await SendRequest("DELETE", path, null, options, _isDebug);
|
||||||
|
#if DEBUG
|
||||||
|
CheckEmptyResponse(responseJson);
|
||||||
|
#endif
|
||||||
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> SendRequest(string method, string path, string data, HttpOptions options, bool hasResponse)
|
private static async Task<string> SendRequest(string method, string path, string data, HttpOptions options, bool hasResponse)
|
||||||
@@ -124,6 +171,7 @@ namespace Discord.Helpers
|
|||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream GetDecoder(string contentEncoding, MemoryStream encodedStream)
|
private static Stream GetDecoder(string contentEncoding, MemoryStream encodedStream)
|
||||||
@@ -138,5 +186,21 @@ namespace Discord.Helpers
|
|||||||
throw new ArgumentOutOfRangeException("Unknown encoding: " + contentEncoding);
|
throw new ArgumentOutOfRangeException("Unknown encoding: " + contentEncoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
private static void CheckResponse<T>(string json, T obj)
|
||||||
|
{
|
||||||
|
/*JToken token = JToken.Parse(json);
|
||||||
|
JToken token2 = JToken.FromObject(obj);
|
||||||
|
if (!JToken.DeepEquals(token, token2))
|
||||||
|
throw new Exception("API check failed: Objects do not match.");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckEmptyResponse(string json)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
throw new Exception("API check failed: Response is not empty.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Discord.Models
|
namespace Discord.Models
|
||||||
{
|
{
|
||||||
public sealed class Channel
|
public sealed class Channel
|
||||||
{
|
{
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private string _name;
|
|
||||||
|
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
|
|
||||||
|
private string _name;
|
||||||
public string Name { get { return !IsPrivate ? _name : '@' + Recipient.Name; } internal set { _name = value; } }
|
public string Name { get { return !IsPrivate ? _name : '@' + Recipient.Name; } internal set { _name = value; } }
|
||||||
|
|
||||||
public bool IsPrivate { get; internal set; }
|
public bool IsPrivate { get; }
|
||||||
public string Type { get; internal set; }
|
public string Type { get; internal set; }
|
||||||
|
|
||||||
public string ServerId { get; }
|
public string ServerId { get; }
|
||||||
@@ -21,6 +24,8 @@ namespace Discord.Models
|
|||||||
public string RecipientId { get; internal set; }
|
public string RecipientId { get; internal set; }
|
||||||
public User Recipient { get { return _client.GetUser(RecipientId); } }
|
public User Recipient { get { return _client.GetUser(RecipientId); } }
|
||||||
|
|
||||||
|
public IEnumerable<Message> Messages { get { return _client.Messages.Where(x => x.ChannelId == Id); } }
|
||||||
|
|
||||||
//Not Implemented
|
//Not Implemented
|
||||||
public object[] PermissionOverwrites { get; internal set; }
|
public object[] PermissionOverwrites { get; internal set; }
|
||||||
|
|
||||||
@@ -28,6 +33,7 @@ namespace Discord.Models
|
|||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
ServerId = serverId;
|
ServerId = serverId;
|
||||||
|
IsPrivate = serverId == null;
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Discord.Models
|
|
||||||
{
|
|
||||||
public class ChatMessageReference
|
|
||||||
{
|
|
||||||
protected readonly DiscordClient _client;
|
|
||||||
|
|
||||||
public string Id { get; }
|
|
||||||
|
|
||||||
public string ChannelId { get; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public Channel Channel { get { return _client.GetChannel(ChannelId); } }
|
|
||||||
|
|
||||||
internal ChatMessageReference(string id, string channelId, DiscordClient client)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
ChannelId = channelId;
|
|
||||||
_client = client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
32
Discord.Net/Models/Invite.cs
Normal file
32
Discord.Net/Models/Invite.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Discord.Models
|
||||||
|
{
|
||||||
|
public sealed class Invite
|
||||||
|
{
|
||||||
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
|
public int MaxAge, Uses, MaxUses;
|
||||||
|
public bool IsRevoked, IsTemporary;
|
||||||
|
public readonly string Code, XkcdPass;
|
||||||
|
|
||||||
|
public string InviterId { get; internal set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public User Inviter { get { return _client.GetUser(InviterId); } }
|
||||||
|
|
||||||
|
public string ServerId { get; internal set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public Server Server { get { return _client.GetServer(ServerId); } }
|
||||||
|
|
||||||
|
public string ChannelId { get; internal set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public Channel Channel { get { return _client.GetChannel(ChannelId); } }
|
||||||
|
|
||||||
|
internal Invite(string code, string xkcdPass, DiscordClient client)
|
||||||
|
{
|
||||||
|
Code = code;
|
||||||
|
XkcdPass = xkcdPass;
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,13 @@ using System;
|
|||||||
|
|
||||||
namespace Discord.Models
|
namespace Discord.Models
|
||||||
{
|
{
|
||||||
public sealed class ChatMessage : ChatMessageReference
|
public sealed class Message
|
||||||
{
|
{
|
||||||
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
|
public string Id { get; }
|
||||||
|
public string ChannelId { get; }
|
||||||
|
|
||||||
public bool IsMentioningEveryone { get; internal set; }
|
public bool IsMentioningEveryone { get; internal set; }
|
||||||
public bool IsTTS { get; internal set; }
|
public bool IsTTS { get; internal set; }
|
||||||
public string Text { get; internal set; }
|
public string Text { get; internal set; }
|
||||||
@@ -18,10 +23,12 @@ namespace Discord.Models
|
|||||||
public object[] Attachments { get; internal set; }
|
public object[] Attachments { get; internal set; }
|
||||||
public object[] Embeds { get; internal set; }
|
public object[] Embeds { get; internal set; }
|
||||||
|
|
||||||
internal ChatMessage(string id, string channelId, DiscordClient client)
|
internal Message(string id, string channelId, DiscordClient client)
|
||||||
: base(id, channelId, client)
|
|
||||||
{
|
{
|
||||||
}
|
Id = id;
|
||||||
|
ChannelId = channelId;
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Newtonsoft.Json;
|
using Discord.Helpers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -20,20 +21,22 @@ namespace Discord.Models
|
|||||||
|
|
||||||
public string OwnerId { get; internal set; }
|
public string OwnerId { get; internal set; }
|
||||||
public User Owner { get { return _client.GetUser(OwnerId); } }
|
public User Owner { get { return _client.GetUser(OwnerId); } }
|
||||||
|
public bool IsOwner { get { return _client.UserId == OwnerId; } }
|
||||||
|
|
||||||
|
public string DefaultChannelId { get { return Id; } }
|
||||||
|
public Channel DefaultChannel { get { return _client.GetChannel(DefaultChannelId); } }
|
||||||
|
|
||||||
internal ConcurrentDictionary<string, bool> _members;
|
internal ConcurrentDictionary<string, bool> _members;
|
||||||
public IEnumerable<string> MemberIds { get { return _members.Keys; } }
|
|
||||||
[JsonIgnore]
|
|
||||||
public IEnumerable<User> Members { get { return _members.Keys.Select(x => _client.GetUser(x)); } }
|
public IEnumerable<User> Members { get { return _members.Keys.Select(x => _client.GetUser(x)); } }
|
||||||
|
|
||||||
internal ConcurrentDictionary<string, bool> _channels;
|
internal ConcurrentDictionary<string, bool> _bans;
|
||||||
public IEnumerable<string> ChannelIds { get { return _channels.Keys; } }
|
public IEnumerable<User> Bans { get { return _bans.Keys.Select(x => _client.GetUser(x)); } }
|
||||||
[JsonIgnore]
|
|
||||||
public IEnumerable<Channel> Channels { get { return _channels.Keys.Select(x => _client.GetChannel(x)); } }
|
public IEnumerable<Channel> Channels { get { return _client.Channels.Where(x => x.ServerId == Id); } }
|
||||||
|
public IEnumerable<Role> Roles { get { return _client.Roles.Where(x => x.ServerId == Id); } }
|
||||||
|
|
||||||
//Not Implemented
|
//Not Implemented
|
||||||
public object Presence { get; internal set; }
|
public object Presence { get; internal set; }
|
||||||
public object[] Roles { get; internal set; }
|
|
||||||
public object[] VoiceStates { get; internal set; }
|
public object[] VoiceStates { get; internal set; }
|
||||||
|
|
||||||
internal Server(string id, DiscordClient client)
|
internal Server(string id, DiscordClient client)
|
||||||
@@ -41,12 +44,32 @@ namespace Discord.Models
|
|||||||
Id = id;
|
Id = id;
|
||||||
_client = client;
|
_client = client;
|
||||||
_members = new ConcurrentDictionary<string, bool>();
|
_members = new ConcurrentDictionary<string, bool>();
|
||||||
_channels = new ConcurrentDictionary<string, bool>();
|
_bans = new ConcurrentDictionary<string, bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void AddMember(string id)
|
||||||
|
{
|
||||||
|
_members.TryAdd(id, true);
|
||||||
|
}
|
||||||
|
internal bool RemoveMember(string id)
|
||||||
|
{
|
||||||
|
bool ignored;
|
||||||
|
return _members.TryRemove(id, out ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AddBan(string id)
|
||||||
|
{
|
||||||
|
_bans.TryAdd(id, true);
|
||||||
|
}
|
||||||
|
internal bool RemoveBan(string id)
|
||||||
|
{
|
||||||
|
bool ignored;
|
||||||
|
return _bans.TryRemove(id, out ignored);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Discord.Net")]
|
[assembly: AssemblyTitle("Discord.Net")]
|
||||||
[assembly: AssemblyDescription("A .Net API Wrapper for the Discord client")]
|
[assembly: AssemblyDescription("A .Net API wrapper for the Discord client")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("RogueException")]
|
[assembly: AssemblyCompany("RogueException")]
|
||||||
[assembly: AssemblyProduct("Discord.Net")]
|
[assembly: AssemblyProduct("Discord.Net")]
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion("0.1.0.0")]
|
[assembly: AssemblyVersion("0.2.0.0")]
|
||||||
[assembly: AssemblyFileVersion("0.1.0.0")]
|
[assembly: AssemblyFileVersion("0.2.0.0")]
|
||||||
|
|||||||
Reference in New Issue
Block a user