Browse Source

Added missing files

tags/docs-0.9
RogueException 9 years ago
parent
commit
21ac5c5d74
9 changed files with 97 additions and 460 deletions
  1. +26
    -12
      src/Discord.Net/API/Converters.cs
  2. +0
    -37
      src/Discord.Net/API/Converters/LongStringConverter.cs
  3. +0
    -54
      src/Discord.Net/API/Endpoints.cs
  4. +0
    -293
      src/Discord.Net/DiscordAPIClient.cs
  5. +52
    -49
      src/Discord.Net/DiscordClient.cs
  6. +18
    -7
      src/Discord.Net/DiscordConfig.cs
  7. +0
    -0
      src/Discord.Net/ImageType.cs
  8. +1
    -7
      src/Discord.Net/Net/WebSockets/WS4NetEngine.cs
  9. +0
    -1
      src/Discord.Net/Settings.StyleCop

src/Discord.Net/API/Converters/LongStringCollectionConverter.cs → src/Discord.Net/API/Converters.cs View File

@@ -1,15 +1,32 @@
using Newtonsoft.Json;
using System;
using System;
using Newtonsoft.Json;
using System.Collections.Generic;

namespace Discord.API.Converters
{
public class LongStringEnumerableConverter : JsonConverter
public class LongStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IEnumerable<ulong>);
}
public override bool CanConvert(Type objectType)
=> objectType == typeof(ulong);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
=> IdConvert.ToLong((string)reader.Value);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
=> writer.WriteValue(IdConvert.ToString((ulong)value));
}

public class NullableLongStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
=> objectType == typeof(ulong?);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
=> IdConvert.ToNullableLong((string)reader.Value);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
=> writer.WriteValue(IdConvert.ToString((ulong?)value));
}

/*public class LongStringEnumerableConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong>);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
List<ulong> result = new List<ulong>();
@@ -36,14 +53,11 @@ namespace Discord.API.Converters
writer.WriteEndArray();
}
}
}
}*/

internal class LongStringArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IEnumerable<ulong[]>);
}
public override bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong[]>);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var result = new List<ulong>();

+ 0
- 37
src/Discord.Net/API/Converters/LongStringConverter.cs View File

@@ -1,37 +0,0 @@
using System;
using Newtonsoft.Json;

namespace Discord.API.Converters
{
public class LongStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ulong);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return IdConvert.ToLong((string)reader.Value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(IdConvert.ToString((ulong)value));
}
}

public class NullableLongStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ulong?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return IdConvert.ToNullableLong((string)reader.Value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(IdConvert.ToString((ulong?)value));
}
}
}

+ 0
- 54
src/Discord.Net/API/Endpoints.cs View File

@@ -1,54 +0,0 @@
namespace Discord.API
{
public static class Endpoints
{
public const string BaseStatusApi = "https://status.discordapp.com/api/v2/";
public const string BaseApi = "https://discordapp.com/api/";
public const string BaseCdn = "https://cdn.discordapp.com/";

public const string Gateway = "gateway";

public const string Auth = "auth";
public const string AuthLogin = "auth/login";
public const string AuthLogout = "auth/logout";
public const string Channels = "channels";
public static string Channel(ulong channelId) => $"channels/{channelId}";
public static string ChannelInvites(ulong channelId) => $"channels/{channelId}/invites";
public static string ChannelMessages(ulong channelId) => $"channels/{channelId}/messages";
public static string ChannelMessages(ulong channelId, int limit) => $"channels/{channelId}/messages?limit={limit}";
public static string ChannelMessages(ulong channelId, int limit, ulong relativeId, string relativeDir) => $"channels/{channelId}/messages?limit={limit}&{relativeDir}={relativeId}";
public static string ChannelMessage(ulong channelId, ulong msgId) => $"channels/{channelId}/messages/{msgId}";
public static string ChannelMessageAck(ulong channelId, ulong msgId) => $"channels/{channelId}/messages/{msgId}/ack";
public static string ChannelPermission(ulong channelId, ulong userOrRoleId) => $"channels/{channelId}/permissions/{userOrRoleId}";
public static string ChannelTyping(ulong channelId) => $"channels/{channelId}/typing";

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

public const string Invites = "invite";
public static string Invite(ulong inviteId) => $"invite/{inviteId}";
public static string Invite(string inviteIdOrXkcd) => $"invite/{inviteIdOrXkcd}";
public static string InviteUrl(ulong inviteId) => $"https://discord.gg/{inviteId}";
public static string InviteUrl(string inviteIdOrXkcd) => $"https://discord.gg/{inviteIdOrXkcd}";

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

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

public const string StatusActiveMaintenance = "scheduled-maintenances/active.json";
public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json";
}
}

+ 0
- 293
src/Discord.Net/DiscordAPIClient.cs View File

@@ -1,293 +0,0 @@
using Discord.API;
using Discord.Net.Rest;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Discord
{
public enum RelativeDirection { Before, After }

/// <summary> A lightweight wrapper around the Discord API. </summary>
public class DiscordAPIClient
{
public static readonly string Version = DiscordClient.Version;

private readonly DiscordConfig _config;

internal RestClient RestClient => _rest;
private readonly RestClient _rest;

public DiscordAPIClient(DiscordConfig config = null, Logger logger = null)
{
_config = config ?? new DiscordConfig();
_rest = new RestClient(_config, logger);
}

private string _token;
public string Token
{
get { return _token; }
set { _token = value; _rest.SetToken(value); }
}
private CancellationToken _cancelToken;
public CancellationToken CancelToken
{
get { return _cancelToken; }
set { _cancelToken = value; _rest.SetCancelToken(value); }
}

//Auth
public Task<GatewayResponse> Gateway()
=> _rest.Get<GatewayResponse>(Endpoints.Gateway);
public async Task<LoginResponse> Login(string email, string password)
{
if (email == null) throw new ArgumentNullException(nameof(email));
if (password == null) throw new ArgumentNullException(nameof(password));

var request = new LoginRequest { Email = email, Password = password };
return await _rest.Post<LoginResponse>(Endpoints.AuthLogin, request).ConfigureAwait(false);
}
public Task Logout()
=> _rest.Post(Endpoints.AuthLogout);

//Channels
public Task<CreateChannelResponse> CreateChannel(ulong serverId, string name, string channelType)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (channelType == null) throw new ArgumentNullException(nameof(channelType));

var request = new CreateChannelRequest { Name = name, Type = channelType };
return _rest.Post<CreateChannelResponse>(Endpoints.ServerChannels(serverId), request);
}
public Task<CreateChannelResponse> CreatePMChannel(ulong myId, ulong recipientId)
{
var request = new CreatePMChannelRequest { RecipientId = recipientId };
return _rest.Post<CreateChannelResponse>(Endpoints.UserChannels(myId), request);
}
public Task<DestroyChannelResponse> DestroyChannel(ulong channelId)
{
return _rest.Delete<DestroyChannelResponse>(Endpoints.Channel(channelId));
}
public Task<EditChannelResponse> EditChannel(ulong channelId, string name = null, string topic = null)
{
var request = new EditChannelRequest { Name = name, Topic = topic };
return _rest.Patch<EditChannelResponse>(Endpoints.Channel(channelId), request);
}
public Task ReorderChannels(ulong serverId, IEnumerable<ulong> channelIds, int startPos = 0)
{
if (channelIds == null) throw new ArgumentNullException(nameof(channelIds));
if (startPos < 0) throw new ArgumentOutOfRangeException(nameof(startPos), "startPos must be a positive integer.");

uint pos = (uint)startPos;
var channels = channelIds.Select(x => new ReorderChannelsRequest.Channel { Id = x, Position = pos++ });
var request = new ReorderChannelsRequest(channels);
return _rest.Patch(Endpoints.ServerChannels(serverId), request);
}
public Task<GetMessagesResponse> GetMessages(ulong channelId, int count, ulong? relativeMessageId = null, RelativeDirection relativeDir = RelativeDirection.Before)
{
if (relativeMessageId != null)
return _rest.Get<GetMessagesResponse>(Endpoints.ChannelMessages(channelId, count, relativeMessageId.Value, relativeDir == RelativeDirection.Before ? "before" : "after"));
else
return _rest.Get<GetMessagesResponse>(Endpoints.ChannelMessages(channelId, count));
}

//Incidents
public Task<GetIncidentsResponse> GetActiveIncidents()
{
return _rest.Get<GetIncidentsResponse>(Endpoints.StatusActiveMaintenance);
}
public Task<GetIncidentsResponse> GetUpcomingIncidents()
{
return _rest.Get<GetIncidentsResponse>(Endpoints.StatusUpcomingMaintenance);
}

//Invites
public Task<CreateInviteResponse> CreateInvite(ulong channelId, int maxAge, int maxUses, bool tempMembership, bool hasXkcd)
{
var request = new CreateInviteRequest { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = tempMembership, WithXkcdPass = hasXkcd };
return _rest.Post<CreateInviteResponse>(Endpoints.ChannelInvites(channelId), request);
}
public Task<GetInviteResponse> GetInvite(string inviteIdOrXkcd)
{
if (inviteIdOrXkcd == null) throw new ArgumentNullException(nameof(inviteIdOrXkcd));

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

return _rest.Post<AcceptInviteResponse>(Endpoints.Invite(inviteId));
}
public Task DeleteInvite(string inviteId)
{
if (inviteId == null) throw new ArgumentNullException(nameof(inviteId));

return _rest.Delete(Endpoints.Invite(inviteId));
}

//Users
public Task EditUser(ulong serverId, ulong userId, bool? mute = null, bool? deaf = null, ulong? voiceChannelId = null, IEnumerable<ulong> roleIds = null)
{
var request = new EditMemberRequest { Mute = mute, Deaf = deaf, ChannelId = voiceChannelId, Roles = roleIds };
return _rest.Patch(Endpoints.ServerMember(serverId, userId), request);
}
public Task KickUser(ulong serverId, ulong userId)
{
return _rest.Delete(Endpoints.ServerMember(serverId, userId));
}
public Task BanUser(ulong serverId, ulong userId)
{
return _rest.Put(Endpoints.ServerBan(serverId, userId));
}
public Task UnbanUser(ulong serverId, ulong userId)
{
return _rest.Delete(Endpoints.ServerBan(serverId, userId));
}
public Task<PruneUsersResponse> PruneUsers(ulong serverId, int days, bool simulate)
{
if (simulate)
return _rest.Get<PruneUsersResponse>(Endpoints.ServerPrune(serverId, days));
else
return _rest.Post<PruneUsersResponse>(Endpoints.ServerPrune(serverId, days));
}

//Messages
public Task<SendMessageResponse> SendMessage(ulong channelId, string message, IEnumerable<ulong> mentionedUserIds = null, string nonce = null, bool isTTS = false)
{
if (message == null) throw new ArgumentNullException(nameof(message));

var request = new SendMessageRequest { Content = message, Mentions = mentionedUserIds ?? new ulong[0], Nonce = nonce, IsTTS = isTTS ? true : false };
return _rest.Post<SendMessageResponse>(Endpoints.ChannelMessages(channelId), request);
}
public Task<SendMessageResponse> SendFile(ulong channelId, string filename, Stream stream)
{
if (filename == null) throw new ArgumentNullException(nameof(filename));
if (stream == null) throw new ArgumentNullException(nameof(stream));

return _rest.PostFile<SendMessageResponse>(Endpoints.ChannelMessages(channelId), filename, stream);
}
public Task DeleteMessage(ulong messageId, ulong channelId)
{
return _rest.Delete(Endpoints.ChannelMessage(channelId, messageId));
}
public Task<EditMessageResponse> EditMessage(ulong messageId, ulong channelId, string message = null, IEnumerable<ulong> mentionedUserIds = null)
{
var request = new EditMessageRequest { Content = message, Mentions = mentionedUserIds };
return _rest.Patch<EditMessageResponse>(Endpoints.ChannelMessage(channelId, messageId), request);
}
public Task AckMessage(ulong messageId, ulong channelId)
{
return _rest.Post(Endpoints.ChannelMessageAck(channelId, messageId));
}
public Task SendIsTyping(ulong channelId)
{
return _rest.Post(Endpoints.ChannelTyping(channelId));
}

//Permissions
public Task SetChannelPermissions(ulong channelId, ulong userOrRoleId, string idType, uint allow = 0, uint deny = 0)
{
if (idType == null) throw new ArgumentNullException(nameof(idType));

var request = new SetChannelPermissionsRequest { Id = userOrRoleId, Type = idType, Allow = allow, Deny = deny };
return _rest.Put(Endpoints.ChannelPermission(channelId, userOrRoleId), request);
}
public Task DeleteChannelPermissions(ulong channelId, ulong userOrRoleId)
{
return _rest.Delete(Endpoints.ChannelPermission(channelId, userOrRoleId), null);
}

//Roles
public Task<RoleInfo> CreateRole(ulong serverId)
{
return _rest.Post<RoleInfo>(Endpoints.ServerRoles(serverId));
}
public Task DeleteRole(ulong serverId, ulong roleId)
{
return _rest.Delete(Endpoints.ServerRole(serverId, roleId));
}
public Task<RoleInfo> EditRole(ulong serverId, ulong roleId, string name = null, uint? permissions = null, uint? color = null, bool? hoist = null)
{
var request = new EditRoleRequest { Name = name, Permissions = permissions, Hoist = hoist, Color = color };
return _rest.Patch<RoleInfo>(Endpoints.ServerRole(serverId, roleId), request);
}
public Task ReorderRoles(ulong serverId, IEnumerable<ulong> roleIds, int startPos = 0)
{
if (roleIds == null) throw new ArgumentNullException(nameof(roleIds));
if (startPos < 0) throw new ArgumentOutOfRangeException(nameof(startPos), "startPos must be a positive integer.");

uint pos = (uint)startPos;
var roles = roleIds.Select(x => new ReorderRolesRequest.Role { Id = x, Position = pos++ });
var request = new ReorderRolesRequest(roles);
return _rest.Patch(Endpoints.ServerRoles(serverId), request);
}

//Servers
public Task<CreateServerResponse> CreateServer(string name, string region)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (region == null) throw new ArgumentNullException(nameof(region));

var request = new CreateServerRequest { Name = name, Region = region };
return _rest.Post<CreateServerResponse>(Endpoints.Servers, request);
}
public Task LeaveServer(ulong serverId)
{
return _rest.Delete<DeleteServerResponse>(Endpoints.Server(serverId));
}
public Task<EditServerResponse> EditServer(ulong serverId, string name, string region,
Stream icon, ImageType iconType, string existingIcon,
ulong? afkChannelId, int afkTimeout)
{
var request = new EditServerRequest {
Name = name,
Region = region,
Icon = Base64Picture(icon, iconType, existingIcon),
AFKChannelId = afkChannelId,
AFKTimeout = afkTimeout
};
return _rest.Patch<EditServerResponse>(Endpoints.Server(serverId), request);
}

//User
public Task<EditUserResponse> EditProfile(string currentPassword,
string username, string email, string password,
Stream avatar, ImageType avatarType, string existingAvatar)
{
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
var request = new EditUserRequest { CurrentPassword = currentPassword, Username = username,
Email = email, Password = password, Avatar = Base64Picture(avatar, avatarType, existingAvatar) };
return _rest.Patch<EditUserResponse>(Endpoints.UserMe, request);
}

//Voice
public Task<GetRegionsResponse> GetVoiceRegions()
=> _rest.Get<GetRegionsResponse>(Endpoints.VoiceRegions);

private string Base64Picture(Stream stream, ImageType type, string existingId)
{
if (type == ImageType.None)
return null;
else if (stream != null)
{
byte[] bytes = new byte[stream.Length - stream.Position];
stream.Read(bytes, 0, bytes.Length);

string base64 = Convert.ToBase64String(bytes);
string imageType = type == ImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64";
return $"data:{imageType},{base64}";
}
return existingId;
}
}
}

+ 52
- 49
src/Discord.Net/DiscordClient.cs View File

@@ -1,13 +1,13 @@
using Discord.API;
using Discord.API.Client.GatewaySocket;
using Discord.API.Client.Rest;
using Discord.Net;
using Discord.Net.Rest;
using Discord.Net.WebSockets;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
@@ -53,8 +53,6 @@ namespace Discord
/// <summary> Provides a connection to the DiscordApp service. </summary>
public partial class DiscordClient
{
public static readonly string Version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(3);

private readonly LogService _log;
private readonly Logger _logger, _restLogger, _cacheLogger;
private readonly Dictionary<Type, object> _singletons;
@@ -63,7 +61,6 @@ namespace Discord
private readonly ManualResetEvent _disconnectedEvent;
private readonly ManualResetEventSlim _connectedEvent;
private readonly TaskManager _taskManager;
private bool _sentInitialLog;
private UserStatus _status;
private int? _gameId;

@@ -76,8 +73,8 @@ namespace Discord
private ConnectionState _state;

/// <summary> Gives direct access to the underlying DiscordAPIClient. This can be used to modify objects not in cache. </summary>
public DiscordAPIClient APIClient => _api;
private readonly DiscordAPIClient _api;
public RestClient Rest => _rest;
private readonly RestClient _rest;

/// <summary> Returns the internal websocket object. </summary>
public GatewaySocket WebSocket => _webSocket;
@@ -145,8 +142,11 @@ namespace Discord
_cacheLogger = CreateCacheLogger();

//Networking
_webSocket = new GatewaySocket(this, _log.CreateLogger("WebSocket"));
var settings = new JsonSerializerSettings();
_restLogger = CreateRestLogger();
_rest = new RestClient(_config, _restLogger);

var webSocketLogger = _log.CreateLogger("WebSocket");
_webSocket = new GatewaySocket(this, webSocketLogger);
_webSocket.Connected += (s, e) =>
{
if (_state == ConnectionState.Connecting)
@@ -156,18 +156,15 @@ namespace Discord
{
RaiseDisconnected(e);
};

_webSocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e);

_api = new DiscordAPIClient(_config);
if (Config.UseMessageQueue)
_pendingMessages = new ConcurrentQueue<MessageQueueItem>();
Connected += async (s, e) =>
{
_api.CancelToken = _cancelToken;
_rest.SetCancelToken(_cancelToken);
await SendStatus().ConfigureAwait(false);
};
_restLogger = CreateRestLogger();

//Import/Export
_messageImporter = new JsonSerializer();
@@ -216,7 +213,7 @@ namespace Discord
if (_log.Level >= LogSeverity.Verbose)
{
logger = _log.CreateLogger("Rest");
_api.RestClient.OnRequest += (s, e) =>
_rest.OnRequest += (s, e) =>
{
if (e.Payload != null)
logger.Verbose( $"{e.Method} {e.Path}: {Math.Round(e.ElapsedMilliseconds, 2)} ms ({e.Payload})");
@@ -280,9 +277,6 @@ namespace Discord
_lock.WaitOne();
try
{
if (!_sentInitialLog)
SendInitialLog();

if (State != ConnectionState.Disconnected)
await Disconnect().ConfigureAwait(false);
await _taskManager.Stop().ConfigureAwait(false);
@@ -347,7 +341,8 @@ namespace Discord
token = LoadToken(tokenPath, key);
if (token == null)
{
var response = await _api.Login(email, password).ConfigureAwait(false);
var request = new LoginRequest() { Email = email, Password = password };
var response = await _rest.Send(request).ConfigureAwait(false);
token = response.Token;
SaveToken(tokenPath, key, token);
useCache = false;
@@ -355,17 +350,18 @@ namespace Discord
}
else
{
var response = await _api.Login(email, password).ConfigureAwait(false);
var request = new LoginRequest() { Email = email, Password = password };
var response = await _rest.Send(request).ConfigureAwait(false);
token = response.Token;
}
}
_token = token;
_api.Token = token;
_rest.SetToken(token);

//Get gateway and check token
try
{
var gatewayResponse = await _api.Gateway().ConfigureAwait(false);
var gatewayResponse = await _rest.Send(new GatewayRequest()).ConfigureAwait(false);
var gateway = gatewayResponse.Url;
_gateway = gateway;
if (_config.LogLevel >= LogSeverity.Verbose)
@@ -399,7 +395,7 @@ namespace Discord
while (_pendingMessages.TryDequeue(out ignored)) { }
}

await _api.Logout().ConfigureAwait(false);
await _rest.Send(new LogoutRequest()).ConfigureAwait(false);

_channels.Clear();
_users.Clear();
@@ -528,7 +524,7 @@ namespace Discord
//Members
case "GUILD_MEMBER_ADD":
{
var data = e.Payload.ToObject<MemberAddEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildMemberAddEvent>(_webSocket.Serializer);
var user = _users.GetOrAdd(data.User.Id, data.GuildId);
user.Update(data);
user.UpdateActivity();
@@ -537,7 +533,7 @@ namespace Discord
break;
case "GUILD_MEMBER_UPDATE":
{
var data = e.Payload.ToObject<MemberUpdateEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildMemberUpdateEvent>(_webSocket.Serializer);
var user = _users[data.User.Id, data.GuildId];
if (user != null)
{
@@ -548,7 +544,7 @@ namespace Discord
break;
case "GUILD_MEMBER_REMOVE":
{
var data = e.Payload.ToObject<MemberRemoveEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildMemberRemoveEvent>(_webSocket.Serializer);
var user = _users.TryRemove(data.User.Id, data.GuildId);
if (user != null)
RaiseUserLeft(user);
@@ -556,7 +552,7 @@ namespace Discord
break;
case "GUILD_MEMBERS_CHUNK":
{
var data = e.Payload.ToObject<MembersChunkEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildMembersChunkEvent>(_webSocket.Serializer);
foreach (var memberData in data.Members)
{
var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId);
@@ -569,7 +565,7 @@ namespace Discord
//Roles
case "GUILD_ROLE_CREATE":
{
var data = e.Payload.ToObject<RoleCreateEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildRoleCreateEvent>(_webSocket.Serializer);
var role = _roles.GetOrAdd(data.Data.Id, data.GuildId);
role.Update(data.Data);
var server = _servers[data.GuildId];
@@ -580,7 +576,7 @@ namespace Discord
break;
case "GUILD_ROLE_UPDATE":
{
var data = e.Payload.ToObject<RoleUpdateEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildRoleUpdateEvent>(_webSocket.Serializer);
var role = _roles[data.Data.Id];
if (role != null)
{
@@ -591,7 +587,7 @@ namespace Discord
break;
case "GUILD_ROLE_DELETE":
{
var data = e.Payload.ToObject<RoleDeleteEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildRoleDeleteEvent>(_webSocket.Serializer);
var role = _roles.TryRemove(data.RoleId);
if (role != null)
{
@@ -606,25 +602,23 @@ namespace Discord
//Bans
case "GUILD_BAN_ADD":
{
var data = e.Payload.ToObject<BanAddEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildBanAddEvent>(_webSocket.Serializer);
var server = _servers[data.GuildId];
if (server != null)
{
var id = data.User?.Id ?? data.UserId;
server.AddBan(id);
RaiseUserBanned(id, server);
server.AddBan(data.UserId);
RaiseUserBanned(data.UserId, server);
}
}
break;
case "GUILD_BAN_REMOVE":
{
var data = e.Payload.ToObject<BanRemoveEvent>(_webSocket.Serializer);
var data = e.Payload.ToObject<GuildBanRemoveEvent>(_webSocket.Serializer);
var server = _servers[data.GuildId];
if (server != null)
{
var id = data.User?.Id ?? data.UserId;
if (server.RemoveBan(id))
RaiseUserUnbanned(id, server);
if (server.RemoveBan(data.UserId))
RaiseUserUnbanned(data.UserId, server);
}
}
break;
@@ -689,7 +683,7 @@ namespace Discord
case "MESSAGE_ACK":
{
var data = e.Payload.ToObject<MessageAckEvent>(_webSocket.Serializer);
var msg = GetMessage(data.MessageId);
var msg = _messages[data.MessageId];
if (msg != null)
RaiseMessageAcknowledged(msg);
}
@@ -727,8 +721,8 @@ namespace Discord
//Voice
case "VOICE_STATE_UPDATE":
{
var data = e.Payload.ToObject<MemberVoiceStateUpdateEvent>(_webSocket.Serializer);
var user = _users[data.UserId, data.GuildId];
var data = e.Payload.ToObject<VoiceStateUpdateEvent>(_webSocket.Serializer);
var user = _users[data.User.Id, data.GuildId];
if (user != null)
{
/*var voiceChannel = user.VoiceChannel;
@@ -779,13 +773,6 @@ namespace Discord
}
}

private void SendInitialLog()
{
if (_config.LogLevel >= LogSeverity.Verbose)
_logger.Verbose( $"Config: {JsonConvert.SerializeObject(_config)}");
_sentInitialLog = true;
}

#region Async Wrapper
/// <summary> Blocking call that will not return until client has been stopped. This is mainly intended for use in console applications. </summary>
public void Run(Func<Task> asyncAction)
@@ -946,5 +933,21 @@ namespace Discord
_logger.Warning("Failed to cache token", ex);
}
}

private static string Base64Image(ImageType type, Stream stream, string existingId)
{
if (type == ImageType.None)
return null;
else if (stream != null)
{
byte[] bytes = new byte[stream.Length - stream.Position];
stream.Read(bytes, 0, bytes.Length);

string base64 = Convert.ToBase64String(bytes);
string imageType = type == ImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64";
return $"data:{imageType},{base64}";
}
return existingId;
}
}
}

+ 18
- 7
src/Discord.Net/DiscordConfig.cs View File

@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Reflection;
using System.Text;

namespace Discord
@@ -35,18 +36,28 @@ namespace Discord
public class DiscordConfig : BaseConfig<DiscordConfig>
{
//Global
public static string LibName => "Discord.Net";
public static string LibVersion => typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(3);
public static string LibUrl => "https://github.com/RogueException/Discord.Net";

/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogSeverity _logLevel = LogSeverity.Info;
public static string ClientAPIUrl => "https://discordapp.com/api/";
public static string StatusAPIUrl => "https://status.discordapp.com/api/v2/";
public static string CDNUrl => "https://cdn.discordapp.com/";
public static string InviteUrl => "https://discord.gg/";

/// <summary> Name of your application. </summary>
public string AppName { get { return _appName; } set { SetValue(ref _appName, value); UpdateUserAgent(); } }
//Global

/// <summary> Name of your application. </summary>
public string AppName { get { return _appName; } set { SetValue(ref _appName, value); UpdateUserAgent(); } }
private string _appName = null;
/// <summary> Version of your application. </summary>
public string AppVersion { get { return _appVersion; } set { SetValue(ref _appVersion, value); UpdateUserAgent(); } }
private string _appVersion = null;

/// <summary> Specifies the minimum log level severity that will be sent to the LogMessage event. Warning: setting this to debug will really hurt performance but should help investigate any internal issues. </summary>
public LogSeverity LogLevel { get { return _logLevel; } set { SetValue(ref _logLevel, value); } }
private LogSeverity _logLevel = LogSeverity.Info;

/// <summary> User Agent string to use when connecting to Discord. </summary>
[JsonIgnore]
public string UserAgent { get { return _userAgent; } }
@@ -114,7 +125,7 @@ namespace Discord
}
builder.Append(' ');
}
builder.Append($"DiscordBot (https://github.com/RogueException/Discord.Net, v{DiscordClient.Version})");
builder.Append($"DiscordBot ({LibUrl}, v{LibVersion})");
_userAgent = builder.ToString();
}
}


src/Discord.Net/API/Enums/ImageType.cs → src/Discord.Net/ImageType.cs View File


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

@@ -106,13 +106,7 @@ namespace Discord.Net.WebSockets
RaiseBinaryMessage(e.Data);
}

public IEnumerable<Task> GetTasks(CancellationToken cancelToken)
{
return new Task[]
{
SendAsync(cancelToken)
};
}
public IEnumerable<Task> GetTasks(CancellationToken cancelToken) => new Task[] { SendAsync(cancelToken) };

private Task SendAsync(CancellationToken cancelToken)
{


+ 0
- 1
src/Discord.Net/Settings.StyleCop View File

@@ -1 +0,0 @@
<StyleCopSettings Version="105" />

Loading…
Cancel
Save