diff --git a/Maki/Discord.cs b/Maki/Discord.cs
index 66e2407..877f0ae 100644
--- a/Maki/Discord.cs
+++ b/Maki/Discord.cs
@@ -182,7 +182,7 @@ namespace Maki
///
/// Someone started typing, fired again after 8 seconds
///
- public event Action OnTypingStart;
+ public event Action OnTypingStart;
///
/// Someone's status and/or game updated
@@ -383,24 +383,25 @@ namespace Maki
DiscordChannel chan = channels.Find(x => x.Id == channel.Id);
chan.Name = channel.Name;
- /*existing.Type = channel.Type;
- existing.LastMessageId = channel.LastMessageId;
- if (existing.Type == ChannelType.Private)
- existing.Recipients = channel.Recipients;
- else
+ if (chan.Type == DiscordChannelType.Private)
{
- existing.GuildId = channel.GuildId;
- existing.Topic = channel.Topic;
- existing.PermissionOverwrites = channel.PermissionOverwrites;
- existing.Position = channel.Position;
+ // update recipients
+ } else
+ {
+ // update permissions too
+ chan.Position = channel.Position ?? 0;
}
- if (existing.Type == ChannelType.Voice)
+ if (chan.Type == DiscordChannelType.Voice)
{
- existing.Bitrate = channel.Bitrate;
- existing.UserLimit = channel.UserLimit;
- }*/
+ chan.Bitrate = channel.Bitrate ?? 0;
+ chan.UserLimit = channel.UserLimit ?? 0;
+ } else
+ {
+ chan.Topic = channel.Topic;
+ chan.LastMessageId = channel.LastMessageId ?? 0;
+ }
OnChannelUpdate?.Invoke(chan);
}
@@ -408,27 +409,6 @@ namespace Maki
private void ShardManager_OnChannelDelete(GatewayShard shard, Channel channel)
{
DiscordChannel chan = channels.Find(x => x.Id == channel.Id);
-
- chan.Name = channel.Name;
- /*chan.Type = channel.Type;
- chan.LastMessageId = channel.LastMessageId;
-
- if (chan.Type == ChannelType.Private)
- chan.Recipients = channel.Recipients;
- else
- {
- chan.GuildId = channel.GuildId;
- chan.Topic = channel.Topic;
- chan.PermissionOverwrites = channel.PermissionOverwrites;
- chan.Position = channel.Position;
- }
-
- if (chan.Type == ChannelType.Voice)
- {
- chan.Bitrate = channel.Bitrate;
- chan.UserLimit = channel.UserLimit;
- }*/
-
channels.Remove(chan);
OnChannelDelete?.Invoke(chan);
}
@@ -480,7 +460,6 @@ namespace Maki
}
else
{
- // should this explode instead if the guild isn't unavailable?
server = servers.Find(x => x.Id == guild.Id);
server.Name = guild.Name;
}
@@ -594,12 +573,11 @@ namespace Maki
private void ShardManager_OnGuildMemberUpdate(GatewayShard shard, GuildMember sMember)
{
DiscordMember member = members.Find(x => x.User.Id == sMember.User.Id && x.Server.Id == sMember.GuildId);
-
- /*existing.IsDeafened = member.IsDeafened;
- existing.IsMuted = member.IsMuted;
- existing.JoinedAt = member.JoinedAt;
- existing.Roles = member.Roles;*/
+
member.Nickname = sMember.Nickname;
+ member.IsDeaf = sMember.IsDeafened == true;
+ member.IsMute = sMember.IsMuted == true;
+ member.roles = new List(sMember.Roles);
OnMemberUpdate?.Invoke(member);
}
@@ -624,14 +602,24 @@ namespace Maki
$"Permissions: {role.Role.Value.Permissions}"*/
DiscordServer server = servers.Find(x => x.Id == sRole.Guild);
- DiscordRole role = new DiscordRole(this, sRole.Role.Value, server);
- roles.Add(role);
+ DiscordRole role = roles.Where(x => x.Id == sRole.Role.Value.Id).FirstOrDefault();
+
+ if (role == default(DiscordRole))
+ {
+ role = new DiscordRole(this, sRole.Role.Value, server);
+ roles.Add(role);
+ } else
+ {
+ role.Colour.Raw = sRole.Role.Value.Colour.Value;
+ }
+
OnRoleCreate?.Invoke(role);
}
private void ShardManager_OnGuildRoleDelete(GatewayShard shard, GuildRole sRole)
{
DiscordRole role = roles.Find(x => x.Id == sRole.RoleId && x.Server.Id == sRole.Guild);
+ members.Where(x => x.roles.Contains(role.Id)).ToList().ForEach(x => x.roles.RemoveAll(y => y == role.Id));
roles.Remove(role);
OnRoleDelete?.Invoke(role);
}
@@ -663,9 +651,6 @@ namespace Maki
private void ShardManager_OnGuildMembersChunk(GatewayShard shard, GuildMembersChunk membersChunk)
{
- /*$"Guild Id: {membersChunk.Guild}",
- $"Members {string.Join(", ", membersChunk.Members.Select(x => x.User.Id).ToArray())}"*/
-
for (int i = 0; i < membersChunk.Members.Length; i++)
{
GuildMember member = membersChunk.Members[i];
@@ -692,59 +677,88 @@ namespace Maki
private void ShardManager_OnMessageUpdate(GatewayShard shard, Message message)
{
- DiscordMessage msg = messages.Find(x => x.Id == message.Id);
+ DiscordMessage msg = messages.Where(x => x.Id == message.Id).FirstOrDefault();
+
+ if (msg == null)
+ {
+ RestResponse getMsg = RestClient.Request(RestRequestMethod.GET, RestEndpoints.ChannelMessage(message.ChannelId, message.Id));
+ DiscordChannel channel = channels.Where(x => x.Id == getMsg.Response.ChannelId).FirstOrDefault();
+ DiscordMember member = members.Where(x => x.User.Id == getMsg.Response.User.Id && (channel.Server == null || channel.Server == x.Server)).FirstOrDefault();
+ msg = new DiscordMessage(this, getMsg.Response, member, channel);
+ messages.Add(msg);
+ }
msg.Edited = DateTime.Now;
if (!string.IsNullOrEmpty(message.Content))
msg.Text = message.Content;
- /*existing.IsTTS = message.IsTTS == true;
- existing.IsPinned = message.IsPinned == true;*/
+ msg.IsPinned = message.IsPinned == true;
OnMessageUpdate?.Invoke(msg);
}
- // TODO: account for DMs
private void ShardManager_OnTypingStart(GatewayShard shard, TypingStart typing)
{
DiscordChannel channel = channels.Find(x => x.Id == typing.Channel);
- DiscordMember member = members.Find(x => x.User.Id == typing.User && x.Server.Id == channel.Server.Id);
- OnTypingStart?.Invoke(member, channel);
+ DiscordUser user = users.Find(x => x.Id == typing.User);
+ OnTypingStart?.Invoke(user, channel);
}
private void ShardManager_OnPresenceUpdate(GatewayShard shard, Presence presence)
{
- /*$"User Id: {presence.User.Id}",
- $"Roles: " + (presence.Roles != null ? string.Join(", ", presence.Roles) : string.Empty),
- "Game: " + (presence.Game.HasValue ? presence.Game.Value.Name : string.Empty),
- $"Guild Id: {presence.Guild}",
- $"Status: {presence.Status}"*/
-
DiscordMember member = members.Find(x => x.User.Id == presence.User.Id && x.Server.Id == presence.Guild);
- // update user presence
+ member.User.Game = presence.Game.HasValue ? new DiscordGame(presence.Game.Value) : null;
+
+ if (presence.Roles != null)
+ member.roles = new List(presence.Roles);
+
+ switch (presence.Status.ToLower())
+ {
+ case @"online":
+ member.User.Status = DiscordUserStatus.Online;
+ break;
+
+ case @"away":
+ member.User.Status = DiscordUserStatus.Away;
+ break;
+
+ case @"dnd":
+ member.User.Status = DiscordUserStatus.DoNotDisturb;
+ break;
+
+ case @"offline":
+ default:
+ member.User.Status = DiscordUserStatus.Offline;
+ break;
+ }
OnPresenceUpdate?.Invoke(member);
}
private void ShardManager_OnReady(GatewayShard shard, GatewayReady ready)
{
+ foreach (Channel chan in ready.PrivateChannels)
+ {
+ DiscordChannel channel = new DiscordChannel(this, chan);
+
+ // this shouldn't ever happen but just in case
+ if (channels.Where(x => x.Id == channel.Id).Count() > 0)
+ continue;
+
+ channels.Add(channel);
+ }
+
foreach (Guild guild in ready.UnavailableGuilds)
- // should this call an event handler?
- ShardManager_OnGuildCreate(shard, guild);
+ {
+ DiscordServer server = new DiscordServer(this, guild);
- /* not ready for these yet
- foreach (Channel channel in ready.PrivateChannels)
- ShardManager_OnChannelCreate(shard, channel);*/
+ if (servers.Where(x => x.Id == server.Id).Count() > 0)
+ continue;
- // keep track of self
-
- /*$"Version: {ready.Version}",
- $"User: {ready.User.Id}, {ready.User.Username}, {ready.User.EMail}",
- $"Private Channels: {string.Join(", ", ready.PrivateChannels.Select(x => x.Id).ToArray())}",
- $"Unavailable Guilds: {string.Join(", ", ready.UnavailableGuilds.Select(x => x.Id).ToArray())}",
- $"Session: {ready.Session}"*/
+ servers.Add(server);
+ }
DiscordUser user = new DiscordUser(this, ready.User);
users.Add(user);
@@ -810,12 +824,12 @@ namespace Maki
#region IDisposable
- private bool IsDisposed = false;
+ private bool isDisposed = false;
private void Dispose(bool disposing)
{
- if (!IsDisposed) {
- IsDisposed = true;
+ if (!isDisposed) {
+ isDisposed = true;
Disconnect();
}
}
diff --git a/Maki/DiscordChannel.cs b/Maki/DiscordChannel.cs
index ef589cf..2f2c8b3 100644
--- a/Maki/DiscordChannel.cs
+++ b/Maki/DiscordChannel.cs
@@ -14,12 +14,27 @@ namespace Maki
public string Name { get; internal set; }
public DiscordChannelType Type { get; internal set; }
- internal DiscordChannel(Discord discord, Channel channel, DiscordServer server)
+ public int Position { get; internal set; }
+
+ public string Topic { get; internal set; }
+ public ulong LastMessageId { get; internal set; }
+
+ public int Bitrate { get; internal set; }
+ public int UserLimit { get; internal set; }
+
+ public override string ToString() => $@"<#{Id}>";
+
+ internal DiscordChannel(Discord discord, Channel channel, DiscordServer server = null)
{
client = discord;
Id = channel.Id;
Name = channel.Name;
Type = (DiscordChannelType)channel.Type;
+ Position = channel.Position ?? 0;
+ Topic = channel.Topic;
+ LastMessageId = channel.LastMessageId ?? 0;
+ Bitrate = channel.Bitrate ?? 0;
+ UserLimit = channel.UserLimit ?? 0;
Server = server;
}
diff --git a/Maki/DiscordGame.cs b/Maki/DiscordGame.cs
new file mode 100644
index 0000000..9deae01
--- /dev/null
+++ b/Maki/DiscordGame.cs
@@ -0,0 +1,21 @@
+using Maki.Structures.Presences;
+using System;
+
+namespace Maki
+{
+ public class DiscordGame
+ {
+ public string Name { get; internal set; }
+ public bool IsStreaming { get; internal set; }
+ public Uri Url { get; internal set; }
+
+ internal DiscordGame(Game game)
+ {
+ Name = game.Name;
+ IsStreaming = game.Type == GameType.Streaming;
+
+ if (!string.IsNullOrEmpty(game.Url))
+ Url = new Uri(game.Url);
+ }
+ }
+}
diff --git a/Maki/DiscordMember.cs b/Maki/DiscordMember.cs
index 5c3f561..79684a4 100644
--- a/Maki/DiscordMember.cs
+++ b/Maki/DiscordMember.cs
@@ -16,11 +16,15 @@ namespace Maki
public DateTime Joined { get; internal set; }
public string Nickname { get; internal set; }
+ public bool IsDeaf { get; internal set; }
+ public bool IsMute { get; internal set; }
+
public string Name => string.IsNullOrEmpty(Nickname) ? User.Username : Nickname;
public string NameWithTag => $"{Name}#{User.Tag:0000}";
- public override string ToString() => User.ToString();
- private List roles = new List();
+ public override string ToString() => $@"<@!{User.Id}>";
+
+ internal List roles = new List();
internal DiscordMember(Discord discord, GuildMember member, DiscordUser user, DiscordServer server)
{
@@ -29,6 +33,8 @@ namespace Maki
Server = server;
Nickname = member.Nickname;
Joined = member.JoinedAt ?? DateTime.MinValue;
+ IsDeaf = member.IsDeafened == true;
+ IsMute = member.IsMuted == true;
roles.AddRange(member.Roles);
}
diff --git a/Maki/DiscordMessage.cs b/Maki/DiscordMessage.cs
index 91f6bb5..7b17646 100644
--- a/Maki/DiscordMessage.cs
+++ b/Maki/DiscordMessage.cs
@@ -17,10 +17,11 @@ namespace Maki
public DiscordMember[] MentionsUsers { get; internal set; }
public DiscordRole[] MentionsRoles { get; internal set; }
public bool MentionsEveryone { get; internal set; }
+ public bool IsPinned { get; internal set; }
public bool MentionsMe(bool everyone = false, bool roles = true) =>
(everyone && MentionsEveryone)
- || (roles && client.members.Where(x => x.User == client.Me && x.Server == Channel.Server).First().Roles.Where(x => MentionsRoles.Contains(x)).Count() > 0)
+ || (Channel.Type != DiscordChannelType.Private && roles && client.members.Where(x => x.User == client.Me && x.Server == Channel.Server).First().Roles.Where(x => MentionsRoles.Contains(x)).Count() > 0)
|| MentionsUsers.Select(x => x.User).Contains(client.Me);
public bool IsMe => client.Me == Sender.User;
@@ -36,6 +37,7 @@ namespace Maki
MentionsUsers = client.members.Where(x => x.Server == channel.Server && msg.Mentions.Select(y => y.Id).Contains(x.User.Id)).ToArray();
MentionsRoles = client.roles.Where(x => x.Server == channel.Server && msg.MentionsRoles.Contains(x.Id)).ToArray();
MentionsEveryone = msg.MentioningEveryone;
+ IsPinned = msg.IsPinned == true;
}
public DiscordMessage Edit(string text)
diff --git a/Maki/DiscordRole.cs b/Maki/DiscordRole.cs
index 671fa2a..a33826d 100644
--- a/Maki/DiscordRole.cs
+++ b/Maki/DiscordRole.cs
@@ -17,6 +17,8 @@ namespace Maki
public bool IsHoisted { get; internal set; }
public bool IsMentionable { get; internal set; }
+ public override string ToString() => $@"<@&{Id}>";
+
internal DiscordRole(Discord discord, Role role, DiscordServer server)
{
client = discord;
diff --git a/Maki/DiscordServer.cs b/Maki/DiscordServer.cs
index 12a66e6..f3f06b1 100644
--- a/Maki/DiscordServer.cs
+++ b/Maki/DiscordServer.cs
@@ -41,8 +41,14 @@ namespace Maki
if (roleResp.ErrorCode != RestErrorCode.Ok)
throw new Exception($"{roleResp.ErrorCode}: {roleResp.ErrorMessage}");
- DiscordRole role = new DiscordRole(client, roleResp.Response, this);
- client.roles.Add(role);
+ DiscordRole role = client.roles.Where(x => x.Id == roleResp.Response.Id).FirstOrDefault();
+
+ if (role == default(DiscordRole))
+ {
+ role = new DiscordRole(client, roleResp.Response, this);
+ client.roles.Add(role);
+ }
+
return role;
}
}
diff --git a/Maki/DiscordUser.cs b/Maki/DiscordUser.cs
index c4722f6..7e52869 100644
--- a/Maki/DiscordUser.cs
+++ b/Maki/DiscordUser.cs
@@ -17,10 +17,11 @@ namespace Maki
public bool HasMFA { get; internal set; }
public bool IsVerified { get; internal set; }
public string EMail { get; internal set; }
+ public DiscordUserStatus Status { get; internal set; }
+ public DiscordGame Game { get; internal set; }
public string NameWithTag => $"{Username}#{Tag:0000}";
- public string At => $"<@{Id}>";
- public override string ToString() => At;
+ public override string ToString() => $"<@{Id}>";
private string avatarHash;
diff --git a/Maki/DiscordUserStatus.cs b/Maki/DiscordUserStatus.cs
new file mode 100644
index 0000000..11ac896
--- /dev/null
+++ b/Maki/DiscordUserStatus.cs
@@ -0,0 +1,10 @@
+namespace Maki
+{
+ public enum DiscordUserStatus
+ {
+ Online,
+ Offline,
+ Away,
+ DoNotDisturb,
+ }
+}
diff --git a/Maki/Maki.csproj b/Maki/Maki.csproj
index f91521d..396304e 100644
--- a/Maki/Maki.csproj
+++ b/Maki/Maki.csproj
@@ -59,10 +59,12 @@
+
+
diff --git a/Maki/Rest/RestClient.cs b/Maki/Rest/RestClient.cs
index 84658b6..00227f9 100644
--- a/Maki/Rest/RestClient.cs
+++ b/Maki/Rest/RestClient.cs
@@ -17,7 +17,7 @@ namespace Maki.Rest
///
/// User agent that is send alongside requests
///
- private const string USER_AGENT = @"DiscordBot (https://github.com/flashwave/nicobot)";
+ private const string USER_AGENT = @"DiscordBot (https://github.com/flashwave/maki, 1.0.0.0)";
///
/// Container for parent DiscordClient instance