diff --git a/Discord.API/DataTypes/GuildCreateData.cs b/Discord.API/DataTypes/GuildCreateData.cs index 489599d..90c5ca3 100644 --- a/Discord.API/DataTypes/GuildCreateData.cs +++ b/Discord.API/DataTypes/GuildCreateData.cs @@ -6,7 +6,7 @@ public class GuildCreateData : GuildData{ public required uint MemberCount { get; init; } public required VoiceStateData[] VoiceStates { get; init; } public required GuildMemberDataWithUser[] Members { get; init; } - public required ChannelData[] Channels { get; init; } + public required GuildChannelData[] Channels { get; init; } public override void OnDeserialized() { diff --git a/Discord.API/DataTypes/GuildMemberDataWithUser.cs b/Discord.API/DataTypes/GuildMemberDataWithUser.cs index 4dcc702..5c7f21a 100644 --- a/Discord.API/DataTypes/GuildMemberDataWithUser.cs +++ b/Discord.API/DataTypes/GuildMemberDataWithUser.cs @@ -1,7 +1,11 @@ -namespace Discord.API; +using System.Text.Json.Serialization; -public class GuildMemberDataWithUser : GuildMemberData +namespace Discord.API; + +public class GuildMemberDataWithUser : GuildMemberData, IId { + [JsonIgnore] + public ulong Id => User.Id; public required UserData User { get; init; } public override void OnDeserialized() diff --git a/Discord.API/DataTypes/UserData.cs b/Discord.API/DataTypes/UserData.cs index fb72b33..8d83488 100644 --- a/Discord.API/DataTypes/UserData.cs +++ b/Discord.API/DataTypes/UserData.cs @@ -2,7 +2,7 @@ using System.Text.Json.Serialization; namespace Discord.API; -public sealed class UserData : IJsonOnDeserialized +public sealed class UserData : IJsonOnDeserialized, IId { public required ulong Id { get; init; } public required string Username { get; init; } diff --git a/Discord.Model/Types/DiscordCollection.cs b/Discord.Model/Types/DiscordCollection.cs index f4fe8ea..bf5fed4 100644 --- a/Discord.Model/Types/DiscordCollection.cs +++ b/Discord.Model/Types/DiscordCollection.cs @@ -40,12 +40,15 @@ public abstract class DiscordCollection : IReadOnlyDictionary { + private UserCollection Users {get; } + public string Name { get; private set; } public ulong? AfkChannelId { get; private set; } public int AfkTimeout { get; private set; } @@ -15,8 +17,19 @@ public class Guild : BaseType public string? Description { get; private set; } public int NsfwLevel { get; private set; } - internal Guild(GuildData data) : base(data.Id){ + public GuildChannelCollection Channels {get; } + public GuildMemberCollection Members {get; } + + internal Guild(GuildCreateData data, UserCollection users) : base(data.Id){ Roles = new(data.Roles.Length); + Users = users; + Channels = new(data.Channels.Length); + Channels.Update(data.Channels); + Members = new GuildMemberCollection(data.Members.Length, users); + Members.Update(data.Members); + foreach(VoiceStateData vt_data in data.VoiceStates){ + Members[vt_data.UserId].UpdateVoiceState(vt_data); + } Update(data); } diff --git a/Discord.Model/Types/GuildChannel.cs b/Discord.Model/Types/GuildChannel.cs index 5b0e742..d75efe8 100644 --- a/Discord.Model/Types/GuildChannel.cs +++ b/Discord.Model/Types/GuildChannel.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Reflection.Metadata.Ecma335; using Discord.API; using Serilog; @@ -37,4 +38,19 @@ public class GuildChannel : BaseType ParentId = data.ParentId; Type = (ChannelType) data.Type; } + + public static GuildChannel Create(GuildChannelData data) + => (ChannelType)data.Type switch { + ChannelType.GuildText + or ChannelType.GuildAnnouncement + or ChannelType.GuildForum + => new GuildTextChannel(data), + ChannelType.GuildVoice + or ChannelType.GuildMedia + or ChannelType.GuildStageVoice + => new GuildVoiceChannel(data), + ChannelType.GuildCategory + => new GuildChannel(data), + _ => throw new ArgumentException("Invalid channel type", nameof(data)) + }; } diff --git a/Discord.Model/Types/GuildChannelCollection.cs b/Discord.Model/Types/GuildChannelCollection.cs new file mode 100644 index 0000000..792614a --- /dev/null +++ b/Discord.Model/Types/GuildChannelCollection.cs @@ -0,0 +1,13 @@ +using Discord.API; + +namespace Discord.Model; + +public class GuildChannelCollection : DiscordCollection +{ + public GuildChannelCollection(int capacity) : base(capacity) + { + } + + protected override GuildChannel CreateInstance(GuildChannelData data) + => GuildChannel.Create(data); +} diff --git a/Discord.Model/Types/GuildMember.cs b/Discord.Model/Types/GuildMember.cs index e9a7ada..71e1e23 100644 --- a/Discord.Model/Types/GuildMember.cs +++ b/Discord.Model/Types/GuildMember.cs @@ -3,27 +3,37 @@ using Discord.API; namespace Discord.Model; -public class GuildMember +public class GuildMember : BaseType { - public Snowflake Id => User.Id; + public override Snowflake Id => User.Id; public User User {get; } public string? Nick { get; private set; } public Snowflake[] Roles { get; private set; } public DateTime JoinedAt { get; private set; } public bool Deaf { get; private set; } public bool Mute { get; private set; } + public VoiceState? VoiceState {get; private set; } - internal GuildMember(GuildMemberData data, User user){ + internal GuildMember(GuildMemberDataWithUser data, User user){ User = user; - Update(data); + Update(data); // This double-updates in some cases, but it's mostly fine //TODO } [MemberNotNull(nameof(Roles))] - public void Update(GuildMemberData data){ + internal override void Update(GuildMemberDataWithUser data){ + User.Update(data.User); Nick = data.Nick; Roles = data.Roles.Select(num => (Snowflake)num).ToArray(); JoinedAt = data.JoinedAt; Deaf = data.Deaf; Mute = data.Mute; } + + internal void UpdateVoiceState(VoiceStateData data){ + if(VoiceState is null){ + VoiceState = new VoiceState(data); + }else{ + VoiceState.Update(data); + } + } } diff --git a/Discord.Model/Types/GuildMemberCollection.cs b/Discord.Model/Types/GuildMemberCollection.cs new file mode 100644 index 0000000..f60624e --- /dev/null +++ b/Discord.Model/Types/GuildMemberCollection.cs @@ -0,0 +1,15 @@ +using Discord.API; + +namespace Discord.Model; + +public class GuildMemberCollection : DiscordCollection +{ + private UserCollection Users {get; } + public GuildMemberCollection(int capacity, UserCollection users) : base(capacity) + { + this.Users = users; + } + + protected override GuildMember CreateInstance(GuildMemberDataWithUser data) + => new GuildMember(data, Users.UpdateSingle(data.User)); +} diff --git a/Discord.Model/Types/User.cs b/Discord.Model/Types/User.cs index d95faea..9c92422 100644 --- a/Discord.Model/Types/User.cs +++ b/Discord.Model/Types/User.cs @@ -3,21 +3,19 @@ using Discord.API; namespace Discord.Model; -public class User +public class User : BaseType { - public Snowflake Id {get;} public string Username {get; private set;} public string Discriminator {get; private set;} public string? GlobalName {get; private set;} - internal User(UserData data){ - this.Id = data.Id; + internal User(UserData data) : base(data.Id) { Update(data); } [MemberNotNull(nameof(Username))] [MemberNotNull(nameof(Discriminator))] - internal void Update(UserData data){ + internal override void Update(UserData data){ this.Username = data.Username; this.Discriminator = data.Discriminator; this.GlobalName = data.GlobalName; diff --git a/Discord.Model/Types/UserCollection.cs b/Discord.Model/Types/UserCollection.cs new file mode 100644 index 0000000..92eb30e --- /dev/null +++ b/Discord.Model/Types/UserCollection.cs @@ -0,0 +1,13 @@ +using Discord.API; + +namespace Discord.Model; + +public class UserCollection : DiscordCollection +{ + public UserCollection(int capacity) : base(capacity) + { + } + + protected override User CreateInstance(UserData data) + => new User(data); +} diff --git a/Discord.Model/Types/VoiceState.cs b/Discord.Model/Types/VoiceState.cs index 2b5c4c8..ce55efb 100644 --- a/Discord.Model/Types/VoiceState.cs +++ b/Discord.Model/Types/VoiceState.cs @@ -2,10 +2,11 @@ namespace Discord.Model; -public class VoiceState +public class VoiceState : BaseType { + public override Snowflake Id => UserId; public ulong? ChannelId { get; private set; } - public ulong UserId { get; private set; } + public Snowflake UserId { get; private set; } public string? SessionId { get; private set; } public bool Mute { get; private set; } public bool Deaf { get; private set; } @@ -21,7 +22,7 @@ public class VoiceState Update(data); } - public void Update(VoiceStateData data){ + internal override void Update(VoiceStateData data){ ChannelId = data.ChannelId; SessionId = data.SessionId; Mute = data.Mute;