| @@ -107,8 +107,8 @@ | |||||
| <Compile Include="..\Discord.Net\Helpers\AsyncCache.cs"> | <Compile Include="..\Discord.Net\Helpers\AsyncCache.cs"> | ||||
| <Link>Helpers\AsyncCache.cs</Link> | <Link>Helpers\AsyncCache.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Helpers\Http.cs"> | |||||
| <Link>Helpers\Http.cs</Link> | |||||
| <Compile Include="..\Discord.Net\Helpers\JsonHttpClient.cs"> | |||||
| <Link>Helpers\JsonHttpClient.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\HttpException.cs"> | <Compile Include="..\Discord.Net\HttpException.cs"> | ||||
| <Link>HttpException.cs</Link> | <Link>HttpException.cs</Link> | ||||
| @@ -6,141 +6,147 @@ using System.Threading.Tasks; | |||||
| namespace Discord.API | namespace Discord.API | ||||
| { | { | ||||
| internal static class DiscordAPI | |||||
| internal class DiscordAPI | |||||
| { | { | ||||
| public const int MaxMessageSize = 2000; | public const int MaxMessageSize = 2000; | ||||
| private readonly JsonHttpClient _http; | |||||
| public DiscordAPI(JsonHttpClient http) | |||||
| { | |||||
| _http = http; | |||||
| } | |||||
| //Auth | //Auth | ||||
| public static Task<APIResponses.Gateway> GetWebSocket() | |||||
| => Http.Get<APIResponses.Gateway>(Endpoints.Gateway); | |||||
| public static async Task<APIResponses.AuthRegister> LoginAnonymous(string username) | |||||
| public Task<APIResponses.Gateway> GetWebSocket() | |||||
| => _http.Get<APIResponses.Gateway>(Endpoints.Gateway); | |||||
| public async Task<APIResponses.AuthRegister> LoginAnonymous(string username) | |||||
| { | { | ||||
| var fingerprintResponse = await Http.Post<APIResponses.AuthFingerprint>(Endpoints.AuthFingerprint); | |||||
| var fingerprintResponse = await _http.Post<APIResponses.AuthFingerprint>(Endpoints.AuthFingerprint); | |||||
| var registerRequest = new APIRequests.AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username }; | var registerRequest = new APIRequests.AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username }; | ||||
| var registerResponse = await Http.Post<APIResponses.AuthRegister>(Endpoints.AuthRegister, registerRequest); | |||||
| var registerResponse = await _http.Post<APIResponses.AuthRegister>(Endpoints.AuthRegister, registerRequest); | |||||
| return registerResponse; | return registerResponse; | ||||
| } | } | ||||
| public static async Task<APIResponses.AuthLogin> Login(string email, string password) | |||||
| public async Task<APIResponses.AuthLogin> Login(string email, string password) | |||||
| { | { | ||||
| var request = new APIRequests.AuthLogin { Email = email, Password = password }; | var request = new APIRequests.AuthLogin { Email = email, Password = password }; | ||||
| var response = await Http.Post<APIResponses.AuthLogin>(Endpoints.AuthLogin, request); | |||||
| var response = await _http.Post<APIResponses.AuthLogin>(Endpoints.AuthLogin, request); | |||||
| return response; | return response; | ||||
| } | } | ||||
| public static Task Logout() | |||||
| => Http.Post(Endpoints.AuthLogout); | |||||
| public Task Logout() | |||||
| => _http.Post(Endpoints.AuthLogout); | |||||
| //Servers | //Servers | ||||
| public static Task<APIResponses.CreateServer> CreateServer(string name, string region) | |||||
| public Task<APIResponses.CreateServer> CreateServer(string name, string region) | |||||
| { | { | ||||
| var request = new APIRequests.CreateServer { Name = name, Region = region }; | var request = new APIRequests.CreateServer { Name = name, Region = region }; | ||||
| return Http.Post<APIResponses.CreateServer>(Endpoints.Servers, request); | |||||
| return _http.Post<APIResponses.CreateServer>(Endpoints.Servers, request); | |||||
| } | } | ||||
| public static Task LeaveServer(string id) | |||||
| => Http.Delete<APIResponses.DeleteServer>(Endpoints.Server(id)); | |||||
| public Task LeaveServer(string id) | |||||
| => _http.Delete<APIResponses.DeleteServer>(Endpoints.Server(id)); | |||||
| //Channels | //Channels | ||||
| public static Task<APIResponses.CreateChannel> CreateChannel(string serverId, string name, string channelType) | |||||
| public Task<APIResponses.CreateChannel> CreateChannel(string serverId, string name, string channelType) | |||||
| { | { | ||||
| var request = new APIRequests.CreateChannel { Name = name, Type = channelType }; | var request = new APIRequests.CreateChannel { Name = name, Type = channelType }; | ||||
| return Http.Post<APIResponses.CreateChannel>(Endpoints.ServerChannels(serverId), request); | |||||
| return _http.Post<APIResponses.CreateChannel>(Endpoints.ServerChannels(serverId), request); | |||||
| } | } | ||||
| public static Task<APIResponses.CreateChannel> CreatePMChannel(string myId, string recipientId) | |||||
| public Task<APIResponses.CreateChannel> CreatePMChannel(string myId, string recipientId) | |||||
| { | { | ||||
| var request = new APIRequests.CreatePMChannel { RecipientId = recipientId }; | var request = new APIRequests.CreatePMChannel { RecipientId = recipientId }; | ||||
| return Http.Post<APIResponses.CreateChannel>(Endpoints.UserChannels(myId), request); | |||||
| return _http.Post<APIResponses.CreateChannel>(Endpoints.UserChannels(myId), request); | |||||
| } | } | ||||
| public static Task<APIResponses.DestroyChannel> DestroyChannel(string channelId) | |||||
| => Http.Delete<APIResponses.DestroyChannel>(Endpoints.Channel(channelId)); | |||||
| public static Task<APIResponses.GetMessages[]> GetMessages(string channelId, int count) | |||||
| => Http.Get<APIResponses.GetMessages[]>(Endpoints.ChannelMessages(channelId, count)); | |||||
| public Task<APIResponses.DestroyChannel> DestroyChannel(string channelId) | |||||
| => _http.Delete<APIResponses.DestroyChannel>(Endpoints.Channel(channelId)); | |||||
| public Task<APIResponses.GetMessages[]> GetMessages(string channelId, int count) | |||||
| => _http.Get<APIResponses.GetMessages[]>(Endpoints.ChannelMessages(channelId, count)); | |||||
| //Members | //Members | ||||
| public static Task Kick(string serverId, string memberId) | |||||
| => Http.Delete(Endpoints.ServerMember(serverId, memberId)); | |||||
| public static Task Ban(string serverId, string memberId) | |||||
| => Http.Put(Endpoints.ServerBan(serverId, memberId)); | |||||
| public static Task Unban(string serverId, string memberId) | |||||
| => Http.Delete(Endpoints.ServerBan(serverId, memberId)); | |||||
| public Task Kick(string serverId, string memberId) | |||||
| => _http.Delete(Endpoints.ServerMember(serverId, memberId)); | |||||
| public Task Ban(string serverId, string memberId) | |||||
| => _http.Put(Endpoints.ServerBan(serverId, memberId)); | |||||
| public Task Unban(string serverId, string memberId) | |||||
| => _http.Delete(Endpoints.ServerBan(serverId, memberId)); | |||||
| //Invites | //Invites | ||||
| public static Task<APIResponses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass) | |||||
| public Task<APIResponses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass) | |||||
| { | { | ||||
| var request = new APIRequests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, HasXkcdPass = hasXkcdPass }; | var request = new APIRequests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, HasXkcdPass = hasXkcdPass }; | ||||
| return Http.Post<APIResponses.CreateInvite>(Endpoints.ChannelInvites(channelId), request); | |||||
| return _http.Post<APIResponses.CreateInvite>(Endpoints.ChannelInvites(channelId), request); | |||||
| } | } | ||||
| public static Task<APIResponses.GetInvite> GetInvite(string id) | |||||
| => Http.Get<APIResponses.GetInvite>(Endpoints.Invite(id)); | |||||
| public static Task AcceptInvite(string id) | |||||
| => Http.Post<APIResponses.AcceptInvite>(Endpoints.Invite(id)); | |||||
| public static Task DeleteInvite(string id) | |||||
| => Http.Delete(Endpoints.Invite(id)); | |||||
| public Task<APIResponses.GetInvite> GetInvite(string id) | |||||
| => _http.Get<APIResponses.GetInvite>(Endpoints.Invite(id)); | |||||
| public Task AcceptInvite(string id) | |||||
| => _http.Post<APIResponses.AcceptInvite>(Endpoints.Invite(id)); | |||||
| public Task DeleteInvite(string id) | |||||
| => _http.Delete(Endpoints.Invite(id)); | |||||
| //Chat | //Chat | ||||
| public static Task<APIResponses.SendMessage> SendMessage(string channelId, string message, string[] mentions, string nonce) | |||||
| public Task<APIResponses.SendMessage> SendMessage(string channelId, string message, string[] mentions, string nonce) | |||||
| { | { | ||||
| var request = new APIRequests.SendMessage { Content = message, Mentions = mentions, Nonce = nonce }; | var request = new APIRequests.SendMessage { Content = message, Mentions = mentions, Nonce = nonce }; | ||||
| return Http.Post<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), request); | |||||
| return _http.Post<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), request); | |||||
| } | } | ||||
| public static Task<APIResponses.EditMessage> EditMessage(string channelId, string messageId, string message, string[] mentions) | |||||
| public Task<APIResponses.EditMessage> EditMessage(string channelId, string messageId, string message, string[] mentions) | |||||
| { | { | ||||
| var request = new APIRequests.EditMessage { Content = message, Mentions = mentions }; | var request = new APIRequests.EditMessage { Content = message, Mentions = mentions }; | ||||
| return Http.Patch<APIResponses.EditMessage>(Endpoints.ChannelMessage(channelId, messageId), request); | |||||
| return _http.Patch<APIResponses.EditMessage>(Endpoints.ChannelMessage(channelId, messageId), request); | |||||
| } | } | ||||
| public static Task SendIsTyping(string channelId) | |||||
| => Http.Post(Endpoints.ChannelTyping(channelId)); | |||||
| public static Task DeleteMessage(string channelId, string msgId) | |||||
| => Http.Delete(Endpoints.ChannelMessage(channelId, msgId)); | |||||
| public static Task SendFile(string channelId, Stream stream, string filename = null) | |||||
| => Http.File<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), stream, filename); | |||||
| public Task SendIsTyping(string channelId) | |||||
| => _http.Post(Endpoints.ChannelTyping(channelId)); | |||||
| public Task DeleteMessage(string channelId, string msgId) | |||||
| => _http.Delete(Endpoints.ChannelMessage(channelId, msgId)); | |||||
| public Task SendFile(string channelId, Stream stream, string filename = null) | |||||
| => _http.File<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), stream, filename); | |||||
| //Voice | //Voice | ||||
| public static Task<APIResponses.GetRegions[]> GetVoiceRegions() | |||||
| => Http.Get<APIResponses.GetRegions[]>(Endpoints.VoiceRegions); | |||||
| public static Task<APIResponses.GetIce> GetVoiceIce() | |||||
| => Http.Get<APIResponses.GetIce>(Endpoints.VoiceIce); | |||||
| public static Task Mute(string serverId, string memberId) | |||||
| public Task<APIResponses.GetRegions[]> GetVoiceRegions() | |||||
| => _http.Get<APIResponses.GetRegions[]>(Endpoints.VoiceRegions); | |||||
| public Task<APIResponses.GetIce> GetVoiceIce() | |||||
| => _http.Get<APIResponses.GetIce>(Endpoints.VoiceIce); | |||||
| public Task Mute(string serverId, string memberId) | |||||
| { | { | ||||
| var request = new APIRequests.SetMemberMute { Mute = true }; | var request = new APIRequests.SetMemberMute { Mute = true }; | ||||
| return Http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| return _http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | } | ||||
| public static Task Unmute(string serverId, string memberId) | |||||
| public Task Unmute(string serverId, string memberId) | |||||
| { | { | ||||
| var request = new APIRequests.SetMemberMute { Mute = false }; | var request = new APIRequests.SetMemberMute { Mute = false }; | ||||
| return Http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| return _http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | } | ||||
| public static Task Deafen(string serverId, string memberId) | |||||
| public Task Deafen(string serverId, string memberId) | |||||
| { | { | ||||
| var request = new APIRequests.SetMemberDeaf { Deaf = true }; | var request = new APIRequests.SetMemberDeaf { Deaf = true }; | ||||
| return Http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| return _http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | } | ||||
| public static Task Undeafen(string serverId, string memberId) | |||||
| public Task Undeafen(string serverId, string memberId) | |||||
| { | { | ||||
| var request = new APIRequests.SetMemberDeaf { Deaf = false }; | var request = new APIRequests.SetMemberDeaf { Deaf = false }; | ||||
| return Http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| return _http.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | } | ||||
| //Profile | //Profile | ||||
| public static Task<SelfUserInfo> ChangeUsername(string newUsername, string currentEmail, string currentPassword) | |||||
| public Task<SelfUserInfo> ChangeUsername(string newUsername, string currentEmail, string currentPassword) | |||||
| { | { | ||||
| var request = new APIRequests.ChangeUsername { Username = newUsername, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | var request = new APIRequests.ChangeUsername { Username = newUsername, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | ||||
| return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| return _http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| } | } | ||||
| public static Task<SelfUserInfo> ChangeEmail(string newEmail, string currentPassword) | |||||
| public Task<SelfUserInfo> ChangeEmail(string newEmail, string currentPassword) | |||||
| { | { | ||||
| var request = new APIRequests.ChangeEmail { NewEmail = newEmail, CurrentPassword = currentPassword }; | var request = new APIRequests.ChangeEmail { NewEmail = newEmail, CurrentPassword = currentPassword }; | ||||
| return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| return _http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| } | } | ||||
| public static Task<SelfUserInfo> ChangePassword(string newPassword, string currentEmail, string currentPassword) | |||||
| public Task<SelfUserInfo> ChangePassword(string newPassword, string currentEmail, string currentPassword) | |||||
| { | { | ||||
| var request = new APIRequests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | var request = new APIRequests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | ||||
| return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| return _http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| } | } | ||||
| public static Task<SelfUserInfo> ChangeAvatar(DiscordClient.AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||||
| public Task<SelfUserInfo> ChangeAvatar(DiscordClient.AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||||
| { | { | ||||
| string base64 = Convert.ToBase64String(bytes); | string base64 = Convert.ToBase64String(bytes); | ||||
| string type = imageType == DiscordClient.AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | string type = imageType == DiscordClient.AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | ||||
| var request = new APIRequests.ChangeAvatar { Avatar = $"data:{type},/9j/{base64}", CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | var request = new APIRequests.ChangeAvatar { Avatar = $"data:{type},/9j/{base64}", CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | ||||
| return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| return _http.Patch<SelfUserInfo>(Endpoints.UserMe, request); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -8,8 +8,7 @@ namespace Discord | |||||
| Event, | Event, | ||||
| Cache, | Cache, | ||||
| WebSocketRawInput, //TODO: Make Http instanced and add a rawoutput event | WebSocketRawInput, //TODO: Make Http instanced and add a rawoutput event | ||||
| WebSocketUnknownInput, | |||||
| WebSocketEvent, | |||||
| WebSocketUnknownOpCode, | |||||
| WebSocketUnknownEvent, | WebSocketUnknownEvent, | ||||
| VoiceOutput | VoiceOutput | ||||
| } | } | ||||
| @@ -17,6 +17,8 @@ namespace Discord | |||||
| /// <summary> Provides a connection to the DiscordApp service. </summary> | /// <summary> Provides a connection to the DiscordApp service. </summary> | ||||
| public partial class DiscordClient | public partial class DiscordClient | ||||
| { | { | ||||
| private readonly JsonHttpClient _http; | |||||
| private readonly DiscordAPI _api; | |||||
| private readonly DiscordDataSocket _webSocket; | private readonly DiscordDataSocket _webSocket; | ||||
| #if !DNXCORE50 | #if !DNXCORE50 | ||||
| private readonly DiscordVoiceSocket _voiceWebSocket; | private readonly DiscordVoiceSocket _voiceWebSocket; | ||||
| @@ -27,7 +29,7 @@ namespace Discord | |||||
| private readonly JsonSerializer _serializer; | private readonly JsonSerializer _serializer; | ||||
| private readonly Random _rand; | private readonly Random _rand; | ||||
| private volatile Task _tasks; | |||||
| private volatile Task _tasks; | |||||
| /// <summary> Returns the User object for the current logged in user. </summary> | /// <summary> Returns the User object for the current logged in user. </summary> | ||||
| public User User { get; private set; } | public User User { get; private set; } | ||||
| @@ -86,9 +88,10 @@ namespace Discord | |||||
| public DiscordClient(DiscordClientConfig config = null) | public DiscordClient(DiscordClientConfig config = null) | ||||
| { | { | ||||
| _blockEvent = new ManualResetEventSlim(true); | _blockEvent = new ManualResetEventSlim(true); | ||||
| _config = config ?? new DiscordClientConfig(); | _config = config ?? new DiscordClientConfig(); | ||||
| _rand = new Random(); | _rand = new Random(); | ||||
| _http = new JsonHttpClient(); | |||||
| _api = new DiscordAPI(_http); | |||||
| _serializer = new JsonSerializer(); | _serializer = new JsonSerializer(); | ||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| @@ -381,9 +384,12 @@ namespace Discord | |||||
| await _webSocket.ReconnectAsync(); | await _webSocket.ReconnectAsync(); | ||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | ||||
| await _webSocket.Login(); | |||||
| if (_config.EnableDebug) | |||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | |||||
| if (_http.Token != null) | |||||
| { | |||||
| await _webSocket.Login(_http.Token); | |||||
| if (_config.EnableDebug) | |||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | |||||
| } | |||||
| break; | break; | ||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| @@ -439,8 +445,6 @@ namespace Discord | |||||
| _webSocket.GotEvent += (s, e) => | _webSocket.GotEvent += (s, e) => | ||||
| #endif | #endif | ||||
| { | { | ||||
| if (_config.EnableDebug) | |||||
| RaiseOnDebugMessage(DebugMessageType.WebSocketEvent, $"{e.Type}: {e.Event}"); | |||||
| switch (e.Type) | switch (e.Type) | ||||
| { | { | ||||
| //Global | //Global | ||||
| @@ -741,7 +745,7 @@ namespace Discord | |||||
| APIResponses.SendMessage apiMsg = null; | APIResponses.SendMessage apiMsg = null; | ||||
| try | try | ||||
| { | { | ||||
| apiMsg = await DiscordAPI.SendMessage(msg.ChannelId, msg.RawText, msg.MentionIds, msg.Nonce); | |||||
| apiMsg = await _api.SendMessage(msg.ChannelId, msg.RawText, msg.MentionIds, msg.Nonce); | |||||
| } | } | ||||
| catch (WebException) { break; } | catch (WebException) { break; } | ||||
| catch (HttpException) { hasFailed = true; } | catch (HttpException) { hasFailed = true; } | ||||
| @@ -929,7 +933,7 @@ namespace Discord | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| var msgs = await DiscordAPI.GetMessages(channel.Id, count); | |||||
| var msgs = await _api.GetMessages(channel.Id, count); | |||||
| return msgs.OrderBy(x => x.Timestamp) | return msgs.OrderBy(x => x.Timestamp) | ||||
| .Select(x => | .Select(x => | ||||
| { | { | ||||
| @@ -969,7 +973,7 @@ namespace Discord | |||||
| _blockEvent.Reset(); | _blockEvent.Reset(); | ||||
| _disconnectToken = new CancellationTokenSource(); | _disconnectToken = new CancellationTokenSource(); | ||||
| string url = (await DiscordAPI.GetWebSocket()).Url; | |||||
| string url = (await _api.GetWebSocket()).Url; | |||||
| //Connect by Token | //Connect by Token | ||||
| if (token != null) | if (token != null) | ||||
| @@ -979,9 +983,9 @@ namespace Discord | |||||
| await _webSocket.ConnectAsync(url); | await _webSocket.ConnectAsync(url); | ||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | ||||
| Http.Token = token; | |||||
| _http.Token = token; | |||||
| await _webSocket.Login(); | |||||
| await _webSocket.Login(_http.Token); | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); | ||||
| success = true; | success = true; | ||||
| @@ -1001,7 +1005,7 @@ namespace Discord | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | ||||
| var response = await DiscordAPI.Login(emailOrUsername, password); | |||||
| var response = await _api.Login(emailOrUsername, password); | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); | ||||
| @@ -1009,8 +1013,8 @@ namespace Discord | |||||
| //Wait for websocket to finish connecting, then send token | //Wait for websocket to finish connecting, then send token | ||||
| token = response.Token; | token = response.Token; | ||||
| Http.Token = token; | |||||
| await _webSocket.Login(); | |||||
| _http.Token = token; | |||||
| await _webSocket.Login(_http.Token); | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | ||||
| success = true; | success = true; | ||||
| @@ -1022,7 +1026,7 @@ namespace Discord | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); | ||||
| var response = await DiscordAPI.LoginAnonymous(emailOrUsername); | |||||
| var response = await _api.LoginAnonymous(emailOrUsername); | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket generated anonymous token."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket generated anonymous token."); | ||||
| @@ -1030,8 +1034,8 @@ namespace Discord | |||||
| //Wait for websocket to finish connecting, then send token | //Wait for websocket to finish connecting, then send token | ||||
| token = response.Token; | token = response.Token; | ||||
| Http.Token = token; | |||||
| await _webSocket.Login(); | |||||
| _http.Token = token; | |||||
| await _webSocket.Login(_http.Token); | |||||
| if (_config.EnableDebug) | if (_config.EnableDebug) | ||||
| RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); | ||||
| success = true; | success = true; | ||||
| @@ -1085,7 +1089,7 @@ namespace Discord | |||||
| public async Task<Server> CreateServer(string name, string region) | public async Task<Server> CreateServer(string name, string region) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.CreateServer(name, region); | |||||
| var response = await _api.CreateServer(name, region); | |||||
| return _servers.Update(response.Id, response); | return _servers.Update(response.Id, response); | ||||
| } | } | ||||
| /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | ||||
| @@ -1097,7 +1101,7 @@ namespace Discord | |||||
| CheckReady(); | CheckReady(); | ||||
| try | try | ||||
| { | { | ||||
| await DiscordAPI.LeaveServer(serverId); | |||||
| await _api.LeaveServer(serverId); | |||||
| } | } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) {} | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) {} | ||||
| return _servers.Remove(serverId); | return _servers.Remove(serverId); | ||||
| @@ -1111,7 +1115,7 @@ namespace Discord | |||||
| public async Task<Channel> CreateChannel(string serverId, string name, string type) | public async Task<Channel> CreateChannel(string serverId, string name, string type) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.CreateChannel(serverId, name, type); | |||||
| var response = await _api.CreateChannel(serverId, name, type); | |||||
| return _channels.Update(response.Id, serverId, response); | return _channels.Update(response.Id, serverId, response); | ||||
| } | } | ||||
| /// <summary> Creates a new private channel with the provided user. </summary> | /// <summary> Creates a new private channel with the provided user. </summary> | ||||
| @@ -1121,7 +1125,7 @@ namespace Discord | |||||
| public async Task<Channel> CreatePMChannel(string userId) | public async Task<Channel> CreatePMChannel(string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.CreatePMChannel(UserId, userId); | |||||
| var response = await _api.CreatePMChannel(UserId, userId); | |||||
| return _channels.Update(response.Id, response); | return _channels.Update(response.Id, response); | ||||
| } | } | ||||
| /// <summary> Destroys the provided channel. </summary> | /// <summary> Destroys the provided channel. </summary> | ||||
| @@ -1133,7 +1137,7 @@ namespace Discord | |||||
| CheckReady(); | CheckReady(); | ||||
| try | try | ||||
| { | { | ||||
| var response = await DiscordAPI.DestroyChannel(channelId); | |||||
| var response = await _api.DestroyChannel(channelId); | |||||
| } | } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| return _channels.Remove(channelId); | return _channels.Remove(channelId); | ||||
| @@ -1153,7 +1157,7 @@ namespace Discord | |||||
| public Task Ban(string serverId, string userId) | public Task Ban(string serverId, string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.Ban(serverId, userId); | |||||
| return _api.Ban(serverId, userId); | |||||
| } | } | ||||
| /// <summary> Unbans a user from the provided server. </summary> | /// <summary> Unbans a user from the provided server. </summary> | ||||
| public Task Unban(Server server, User user) | public Task Unban(Server server, User user) | ||||
| @@ -1170,7 +1174,7 @@ namespace Discord | |||||
| CheckReady(); | CheckReady(); | ||||
| try | try | ||||
| { | { | ||||
| await DiscordAPI.Unban(serverId, userId); | |||||
| await _api.Unban(serverId, userId); | |||||
| } | } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| } | } | ||||
| @@ -1202,7 +1206,7 @@ namespace Discord | |||||
| public async Task<Invite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass) | public async Task<Invite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.CreateInvite(channelId, maxAge, maxUses, isTemporary, hasXkcdPass); | |||||
| var response = await _api.CreateInvite(channelId, maxAge, maxUses, isTemporary, hasXkcdPass); | |||||
| _channels.Update(response.Channel.Id, response.Server.Id, response.Channel); | _channels.Update(response.Channel.Id, response.Server.Id, response.Channel); | ||||
| _servers.Update(response.Server.Id, response.Server); | _servers.Update(response.Server.Id, response.Server); | ||||
| _users.Update(response.Inviter.Id, response.Inviter); | _users.Update(response.Inviter.Id, response.Inviter); | ||||
| @@ -1223,7 +1227,7 @@ namespace Discord | |||||
| public async Task<Invite> GetInvite(string id) | public async Task<Invite> GetInvite(string id) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.GetInvite(id); | |||||
| var response = await _api.GetInvite(id); | |||||
| return new Invite(response.Code, response.XkcdPass, this) | return new Invite(response.Code, response.XkcdPass, this) | ||||
| { | { | ||||
| ChannelId = response.Channel.Id, | ChannelId = response.Channel.Id, | ||||
| @@ -1235,7 +1239,7 @@ namespace Discord | |||||
| public Task AcceptInvite(Invite invite) | public Task AcceptInvite(Invite invite) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.AcceptInvite(invite.Id); | |||||
| return _api.AcceptInvite(invite.Id); | |||||
| } | } | ||||
| /// <summary> Accepts the provided invite. </summary> | /// <summary> Accepts the provided invite. </summary> | ||||
| public async Task AcceptInvite(string id) | public async Task AcceptInvite(string id) | ||||
| @@ -1251,8 +1255,8 @@ namespace Discord | |||||
| id = id.Substring(0, id.Length - 1); | id = id.Substring(0, id.Length - 1); | ||||
| //Check if this is a human-readable link and get its ID | //Check if this is a human-readable link and get its ID | ||||
| var response = await DiscordAPI.GetInvite(id); | |||||
| await DiscordAPI.AcceptInvite(response.Code); | |||||
| var response = await _api.GetInvite(id); | |||||
| await _api.AcceptInvite(response.Code); | |||||
| } | } | ||||
| /// <summary> Deletes the provided invite. </summary> | /// <summary> Deletes the provided invite. </summary> | ||||
| public async Task DeleteInvite(string id) | public async Task DeleteInvite(string id) | ||||
| @@ -1261,8 +1265,8 @@ namespace Discord | |||||
| try | try | ||||
| { | { | ||||
| //Check if this is a human-readable link and get its ID | //Check if this is a human-readable link and get its ID | ||||
| var response = await DiscordAPI.GetInvite(id); | |||||
| await DiscordAPI.DeleteInvite(response.Code); | |||||
| var response = await _api.GetInvite(id); | |||||
| await _api.DeleteInvite(response.Code); | |||||
| } | } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| } | } | ||||
| @@ -1307,7 +1311,7 @@ namespace Discord | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| var msg = await DiscordAPI.SendMessage(channelId, blockText, mentions, nonce); | |||||
| var msg = await _api.SendMessage(channelId, blockText, mentions, nonce); | |||||
| result[i] = _messages.Update(msg.Id, channelId, msg); | result[i] = _messages.Update(msg.Id, channelId, msg); | ||||
| result[i].Nonce = nonce; | result[i].Nonce = nonce; | ||||
| try { RaiseMessageSent(result[i]); } catch { } | try { RaiseMessageSent(result[i]); } catch { } | ||||
| @@ -1342,7 +1346,7 @@ namespace Discord | |||||
| if (text.Length > DiscordAPI.MaxMessageSize) | if (text.Length > DiscordAPI.MaxMessageSize) | ||||
| text = text.Substring(0, DiscordAPI.MaxMessageSize); | text = text.Substring(0, DiscordAPI.MaxMessageSize); | ||||
| var msg = await DiscordAPI.EditMessage(channelId, messageId, text, mentions); | |||||
| var msg = await _api.EditMessage(channelId, messageId, text, mentions); | |||||
| _messages.Update(msg.Id, channelId, msg); | _messages.Update(msg.Id, channelId, msg); | ||||
| } | } | ||||
| @@ -1354,7 +1358,7 @@ namespace Discord | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| await DiscordAPI.DeleteMessage(channelId, msgId); | |||||
| await _api.DeleteMessage(channelId, msgId); | |||||
| return _messages.Remove(msgId); | return _messages.Remove(msgId); | ||||
| } | } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| @@ -1376,7 +1380,7 @@ namespace Discord | |||||
| /// <remarks> It is highly recommended that this stream be cached in memory or on disk, or the request may time out. </remarks> | /// <remarks> It is highly recommended that this stream be cached in memory or on disk, or the request may time out. </remarks> | ||||
| public Task SendFile(string channelId, Stream stream, string filename = null) | public Task SendFile(string channelId, Stream stream, string filename = null) | ||||
| { | { | ||||
| return DiscordAPI.SendFile(channelId, stream, filename); | |||||
| return _api.SendFile(channelId, stream, filename); | |||||
| } | } | ||||
| @@ -1394,7 +1398,7 @@ namespace Discord | |||||
| public Task Mute(string serverId, string userId) | public Task Mute(string serverId, string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.Mute(serverId, userId); | |||||
| return _api.Mute(serverId, userId); | |||||
| } | } | ||||
| /// <summary> Unmutes a user on the provided server. </summary> | /// <summary> Unmutes a user on the provided server. </summary> | ||||
| @@ -1410,7 +1414,7 @@ namespace Discord | |||||
| public Task Unmute(string serverId, string userId) | public Task Unmute(string serverId, string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.Unmute(serverId, userId); | |||||
| return _api.Unmute(serverId, userId); | |||||
| } | } | ||||
| /// <summary> Deafens a user on the provided server. </summary> | /// <summary> Deafens a user on the provided server. </summary> | ||||
| @@ -1426,7 +1430,7 @@ namespace Discord | |||||
| public Task Deafen(string serverId, string userId) | public Task Deafen(string serverId, string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.Deafen(serverId, userId); | |||||
| return _api.Deafen(serverId, userId); | |||||
| } | } | ||||
| /// <summary> Undeafens a user on the provided server. </summary> | /// <summary> Undeafens a user on the provided server. </summary> | ||||
| @@ -1442,7 +1446,7 @@ namespace Discord | |||||
| public Task Undeafen(string serverId, string userId) | public Task Undeafen(string serverId, string userId) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| return DiscordAPI.Undeafen(serverId, userId); | |||||
| return _api.Undeafen(serverId, userId); | |||||
| } | } | ||||
| #if !DNXCORE50 | #if !DNXCORE50 | ||||
| @@ -1506,21 +1510,21 @@ namespace Discord | |||||
| public async Task ChangeUsername(string newName, string currentEmail, string currentPassword) | public async Task ChangeUsername(string newName, string currentEmail, string currentPassword) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.ChangeUsername(newName, currentEmail, currentPassword); | |||||
| var response = await _api.ChangeUsername(newName, currentEmail, currentPassword); | |||||
| _users.Update(response.Id, response); | _users.Update(response.Id, response); | ||||
| } | } | ||||
| /// <summary> Changes your email to newEmail. </summary> | /// <summary> Changes your email to newEmail. </summary> | ||||
| public async Task ChangeEmail(string newEmail, string currentPassword) | public async Task ChangeEmail(string newEmail, string currentPassword) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.ChangeEmail(newEmail, currentPassword); | |||||
| var response = await _api.ChangeEmail(newEmail, currentPassword); | |||||
| _users.Update(response.Id, response); | _users.Update(response.Id, response); | ||||
| } | } | ||||
| /// <summary> Changes your password to newPassword. </summary> | /// <summary> Changes your password to newPassword. </summary> | ||||
| public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword) | public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.ChangePassword(newPassword, currentEmail, currentPassword); | |||||
| var response = await _api.ChangePassword(newPassword, currentEmail, currentPassword); | |||||
| _users.Update(response.Id, response); | _users.Update(response.Id, response); | ||||
| } | } | ||||
| @@ -1534,7 +1538,7 @@ namespace Discord | |||||
| public async Task ChangeAvatar(AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | public async Task ChangeAvatar(AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | ||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await DiscordAPI.ChangeAvatar(imageType, bytes, currentEmail, currentPassword); | |||||
| var response = await _api.ChangeAvatar(imageType, bytes, currentEmail, currentPassword); | |||||
| _users.Update(response.Id, response); | _users.Update(response.Id, response); | ||||
| } | } | ||||
| @@ -11,16 +11,16 @@ namespace Discord | |||||
| { | { | ||||
| internal sealed partial class DiscordDataSocket : DiscordWebSocket | internal sealed partial class DiscordDataSocket : DiscordWebSocket | ||||
| { | { | ||||
| private ManualResetEventSlim _connectWaitOnLogin, _connectWaitOnLogin2; | |||||
| private readonly ManualResetEventSlim _connectWaitOnLogin, _connectWaitOnLogin2; | |||||
| public DiscordDataSocket(DiscordClient client, int timeout, int interval) | public DiscordDataSocket(DiscordClient client, int timeout, int interval) | ||||
| : base(client, timeout, interval) | : base(client, timeout, interval) | ||||
| { | { | ||||
| _connectWaitOnLogin = new ManualResetEventSlim(false); | _connectWaitOnLogin = new ManualResetEventSlim(false); | ||||
| _connectWaitOnLogin2 = new ManualResetEventSlim(false); | _connectWaitOnLogin2 = new ManualResetEventSlim(false); | ||||
| } | |||||
| } | |||||
| public async Task Login() | |||||
| public async Task Login(string token) | |||||
| { | { | ||||
| var cancelToken = _disconnectToken.Token; | var cancelToken = _disconnectToken.Token; | ||||
| @@ -28,7 +28,7 @@ namespace Discord | |||||
| _connectWaitOnLogin2.Reset(); | _connectWaitOnLogin2.Reset(); | ||||
| TextWebSocketCommands.Login msg = new TextWebSocketCommands.Login(); | TextWebSocketCommands.Login msg = new TextWebSocketCommands.Login(); | ||||
| msg.Payload.Token = Http.Token; | |||||
| msg.Payload.Token = token; | |||||
| msg.Payload.Properties["$os"] = ""; | msg.Payload.Properties["$os"] = ""; | ||||
| msg.Payload.Properties["$browser"] = ""; | msg.Payload.Properties["$browser"] = ""; | ||||
| msg.Payload.Properties["$device"] = "Discord.Net"; | msg.Payload.Properties["$device"] = "Discord.Net"; | ||||
| @@ -72,7 +72,7 @@ namespace Discord | |||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownInput, "Unknown DataSocket op: " + msg.Operation); | |||||
| RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown DataSocket op: " + msg.Operation); | |||||
| break; | break; | ||||
| } | } | ||||
| #if DNXCORE | #if DNXCORE | ||||
| @@ -287,7 +287,7 @@ namespace Discord | |||||
| break; | break; | ||||
| #endif | #endif | ||||
| default: | default: | ||||
| RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownInput, "Unknown VoiceSocket op: " + msg.Operation); | |||||
| RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown VoiceSocket op: " + msg.Operation); | |||||
| break; | break; | ||||
| } | } | ||||
| #if DNXCORE50 | #if DNXCORE50 | ||||
| @@ -12,20 +12,20 @@ using System.Threading.Tasks; | |||||
| namespace Discord.Helpers | namespace Discord.Helpers | ||||
| { | { | ||||
| internal static class Http | |||||
| internal class JsonHttpClient | |||||
| { | { | ||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| private const bool _isDebug = true; | private const bool _isDebug = true; | ||||
| #else | #else | ||||
| private const bool _isDebug = false; | private const bool _isDebug = false; | ||||
| #endif | #endif | ||||
| private static readonly HttpClient _client; | |||||
| private static readonly HttpMethod _patch; | |||||
| private readonly HttpClient _client; | |||||
| private readonly HttpMethod _patch; | |||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| private static readonly JsonSerializerSettings _settings; | |||||
| private readonly JsonSerializerSettings _settings; | |||||
| #endif | #endif | ||||
| static Http() | |||||
| public JsonHttpClient() | |||||
| { | { | ||||
| _patch = new HttpMethod("PATCH"); //Not sure why this isn't a default... | _patch = new HttpMethod("PATCH"); //Not sure why this isn't a default... | ||||
| @@ -38,7 +38,7 @@ namespace Discord.Helpers | |||||
| _client.DefaultRequestHeaders.Add("accept", "*/*"); | _client.DefaultRequestHeaders.Add("accept", "*/*"); | ||||
| _client.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate"); | _client.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate"); | ||||
| string version = typeof(Http).GetTypeInfo().Assembly.GetName().Version.ToString(2); | |||||
| string version = typeof(JsonHttpClient).GetTypeInfo().Assembly.GetName().Version.ToString(2); | |||||
| _client.DefaultRequestHeaders.Add("user-agent", $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)"); | _client.DefaultRequestHeaders.Add("user-agent", $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)"); | ||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| @@ -48,8 +48,8 @@ namespace Discord.Helpers | |||||
| #endif | #endif | ||||
| } | } | ||||
| private static string _token; | |||||
| public static string Token | |||||
| private string _token; | |||||
| public string Token | |||||
| { | { | ||||
| get { return _token; } | get { return _token; } | ||||
| set | set | ||||
| @@ -61,63 +61,63 @@ namespace Discord.Helpers | |||||
| } | } | ||||
| } | } | ||||
| internal static Task<ResponseT> Get<ResponseT>(string path) | |||||
| internal Task<ResponseT> Get<ResponseT>(string path) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Get, path, null); | => Send<ResponseT>(HttpMethod.Get, path, null); | ||||
| internal static Task<string> Get(string path) | |||||
| internal Task<string> Get(string path) | |||||
| => Send(HttpMethod.Get, path, null); | => Send(HttpMethod.Get, path, null); | ||||
| internal static Task<ResponseT> Post<ResponseT>(string path, object data) | |||||
| internal Task<ResponseT> Post<ResponseT>(string path, object data) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Post, path, AsJson(data)); | => Send<ResponseT>(HttpMethod.Post, path, AsJson(data)); | ||||
| internal static Task<string> Post(string path, object data) | |||||
| internal Task<string> Post(string path, object data) | |||||
| => Send(HttpMethod.Post, path, AsJson(data)); | => Send(HttpMethod.Post, path, AsJson(data)); | ||||
| internal static Task<ResponseT> Post<ResponseT>(string path) | |||||
| internal Task<ResponseT> Post<ResponseT>(string path) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Post, path, null); | => Send<ResponseT>(HttpMethod.Post, path, null); | ||||
| internal static Task<string> Post(string path) | |||||
| internal Task<string> Post(string path) | |||||
| => Send(HttpMethod.Post, path, null); | => Send(HttpMethod.Post, path, null); | ||||
| internal static Task<ResponseT> Put<ResponseT>(string path, object data) | |||||
| internal Task<ResponseT> Put<ResponseT>(string path, object data) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Put, path, AsJson(data)); | => Send<ResponseT>(HttpMethod.Put, path, AsJson(data)); | ||||
| internal static Task<string> Put(string path, object data) | |||||
| internal Task<string> Put(string path, object data) | |||||
| => Send(HttpMethod.Put, path, AsJson(data)); | => Send(HttpMethod.Put, path, AsJson(data)); | ||||
| internal static Task<ResponseT> Put<ResponseT>(string path) | |||||
| internal Task<ResponseT> Put<ResponseT>(string path) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Put, path, null); | => Send<ResponseT>(HttpMethod.Put, path, null); | ||||
| internal static Task<string> Put(string path) | |||||
| internal Task<string> Put(string path) | |||||
| => Send(HttpMethod.Put, path, null); | => Send(HttpMethod.Put, path, null); | ||||
| internal static Task<ResponseT> Patch<ResponseT>(string path, object data) | |||||
| internal Task<ResponseT> Patch<ResponseT>(string path, object data) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(_patch, path, AsJson(data)); | => Send<ResponseT>(_patch, path, AsJson(data)); | ||||
| internal static Task<string> Patch(string path, object data) | |||||
| internal Task<string> Patch(string path, object data) | |||||
| => Send(_patch, path, AsJson(data)); | => Send(_patch, path, AsJson(data)); | ||||
| internal static Task<ResponseT> Patch<ResponseT>(string path) | |||||
| internal Task<ResponseT> Patch<ResponseT>(string path) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(_patch, path, null); | => Send<ResponseT>(_patch, path, null); | ||||
| internal static Task<string> Patch(string path) | |||||
| internal Task<string> Patch(string path) | |||||
| => Send(_patch, path, null); | => Send(_patch, path, null); | ||||
| internal static Task<ResponseT> Delete<ResponseT>(string path, object data) | |||||
| internal Task<ResponseT> Delete<ResponseT>(string path, object data) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Delete, path, AsJson(data)); | => Send<ResponseT>(HttpMethod.Delete, path, AsJson(data)); | ||||
| internal static Task<string> Delete(string path, object data) | |||||
| internal Task<string> Delete(string path, object data) | |||||
| => Send(HttpMethod.Delete, path, AsJson(data)); | => Send(HttpMethod.Delete, path, AsJson(data)); | ||||
| internal static Task<ResponseT> Delete<ResponseT>(string path) | |||||
| internal Task<ResponseT> Delete<ResponseT>(string path) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Delete, path, null); | => Send<ResponseT>(HttpMethod.Delete, path, null); | ||||
| internal static Task<string> Delete(string path) | |||||
| internal Task<string> Delete(string path) | |||||
| => Send(HttpMethod.Delete, path, null); | => Send(HttpMethod.Delete, path, null); | ||||
| internal static Task<ResponseT> File<ResponseT>(string path, Stream stream, string filename = null) | |||||
| internal Task<ResponseT> File<ResponseT>(string path, Stream stream, string filename = null) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| => Send<ResponseT>(HttpMethod.Post, path, AsFormData(stream, filename)); | => Send<ResponseT>(HttpMethod.Post, path, AsFormData(stream, filename)); | ||||
| internal static Task<string> File(string path, Stream stream, string filename = null) | |||||
| internal Task<string> File(string path, Stream stream, string filename = null) | |||||
| => Send(HttpMethod.Post, path, AsFormData(stream, filename)); | => Send(HttpMethod.Post, path, AsFormData(stream, filename)); | ||||
| private static async Task<ResponseT> Send<ResponseT>(HttpMethod method, string path, HttpContent content) | |||||
| private async Task<ResponseT> Send<ResponseT>(HttpMethod method, string path, HttpContent content) | |||||
| where ResponseT : class | where ResponseT : class | ||||
| { | { | ||||
| string responseJson = await SendRequest(method, path, content, true); | string responseJson = await SendRequest(method, path, content, true); | ||||
| @@ -127,17 +127,20 @@ namespace Discord.Helpers | |||||
| #endif | #endif | ||||
| return JsonConvert.DeserializeObject<ResponseT>(responseJson); | return JsonConvert.DeserializeObject<ResponseT>(responseJson); | ||||
| } | } | ||||
| private static async Task<string> Send(HttpMethod method, string path, HttpContent content) | |||||
| { | |||||
| string responseJson = await SendRequest(method, path, content, _isDebug); | |||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| private async Task<string> Send(HttpMethod method, string path, HttpContent content) | |||||
| { | |||||
| string responseJson = await SendRequest(method, path, content, true); | |||||
| if (path.StartsWith(Endpoints.BaseApi)) | if (path.StartsWith(Endpoints.BaseApi)) | ||||
| CheckEmptyResponse(responseJson); | CheckEmptyResponse(responseJson); | ||||
| #endif | |||||
| return responseJson; | return responseJson; | ||||
| } | } | ||||
| #else | |||||
| private Task<string> Send(HttpMethod method, string path, HttpContent content) | |||||
| => SendRequest(method, path, content, false); | |||||
| #endif | |||||
| private static async Task<string> SendRequest(HttpMethod method, string path, HttpContent content, bool hasResponse) | |||||
| private async Task<string> SendRequest(HttpMethod method, string path, HttpContent content, bool hasResponse) | |||||
| { | { | ||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| Stopwatch stopwatch = Stopwatch.StartNew(); | Stopwatch stopwatch = Stopwatch.StartNew(); | ||||
| @@ -173,18 +176,18 @@ namespace Discord.Helpers | |||||
| } | } | ||||
| #if TEST_RESPONSES | #if TEST_RESPONSES | ||||
| private static void CheckEmptyResponse(string json) | |||||
| private void CheckEmptyResponse(string json) | |||||
| { | { | ||||
| if (!string.IsNullOrEmpty(json)) | if (!string.IsNullOrEmpty(json)) | ||||
| throw new Exception("API check failed: Response is not empty."); | throw new Exception("API check failed: Response is not empty."); | ||||
| } | } | ||||
| #endif | #endif | ||||
| private static StringContent AsJson(object obj) | |||||
| private StringContent AsJson(object obj) | |||||
| { | { | ||||
| return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"); | return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"); | ||||
| } | } | ||||
| private static MultipartFormDataContent AsFormData(Stream stream, string filename) | |||||
| private MultipartFormDataContent AsFormData(Stream stream, string filename) | |||||
| { | { | ||||
| var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); | var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); | ||||
| content.Add(new StreamContent(stream), "file", filename); | content.Add(new StreamContent(stream), "file", filename); | ||||