Compare commits
2 Commits
ad7597379a
...
e925e541fd
| Author | SHA1 | Date | |
|---|---|---|---|
| e925e541fd | |||
| 79dda056b1 |
@ -150,6 +150,7 @@ public class JsonTests
|
|||||||
"user": {
|
"user": {
|
||||||
"id": "80351110224678912",
|
"id": "80351110224678912",
|
||||||
"username": "Nelly",
|
"username": "Nelly",
|
||||||
|
"global_name": null,
|
||||||
"discriminator": "1337",
|
"discriminator": "1337",
|
||||||
"avatar": "8342729096ea3675442027381ff50dfe",
|
"avatar": "8342729096ea3675442027381ff50dfe",
|
||||||
"verified": true,
|
"verified": true,
|
||||||
|
|||||||
@ -6,13 +6,5 @@ public class ChannelData
|
|||||||
{
|
{
|
||||||
public required ulong Id { get; init; }
|
public required ulong Id { get; init; }
|
||||||
public required int Type { get; init; }
|
public required int Type { get; init; }
|
||||||
public ulong? GuildId { get; init; }
|
|
||||||
public int? Position { get; init; }
|
|
||||||
public string? Name { get; init; }
|
|
||||||
public string? Topic { get; init; }
|
|
||||||
public bool? Nsfw { get; init; }
|
|
||||||
public ulong? LastMessageId { get; init; }
|
|
||||||
public int? Bitrate { get; init; }
|
|
||||||
public ulong? ParentId { get; init; }
|
|
||||||
//TODO: Missing fields
|
//TODO: Missing fields
|
||||||
}
|
}
|
||||||
11
Discord.API/DataTypes/GuildChannelData.cs
Normal file
11
Discord.API/DataTypes/GuildChannelData.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
public class GuildChannelData : ChannelData
|
||||||
|
{
|
||||||
|
public ulong? GuildId { get; init; }
|
||||||
|
public int? Position { get; init; }
|
||||||
|
public required string Name { get; init; }
|
||||||
|
public ulong? ParentId { get; init; }
|
||||||
|
public int? Bitrate { get; init; }
|
||||||
|
public bool? Nsfw { get; init; }
|
||||||
|
}
|
||||||
@ -5,6 +5,14 @@ public class GuildCreateData : GuildData{
|
|||||||
public required bool Large { get; init; }
|
public required bool Large { get; init; }
|
||||||
public required uint MemberCount { get; init; }
|
public required uint MemberCount { get; init; }
|
||||||
public required VoiceStateData[] VoiceStates { get; init; }
|
public required VoiceStateData[] VoiceStates { get; init; }
|
||||||
public required GuildMemberData[] Members { get; init; }
|
public required GuildMemberDataWithUser[] Members { get; init; }
|
||||||
public required ChannelData[] Channels { get; init; }
|
public required ChannelData[] Channels { get; init; }
|
||||||
|
|
||||||
|
public override void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(VoiceStates);
|
||||||
|
ArgumentNullException.ThrowIfNull(Members);
|
||||||
|
ArgumentNullException.ThrowIfNull(Channels);
|
||||||
|
base.OnDeserialized();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -17,4 +17,11 @@ public abstract class GuildData : UnavailableGuildData
|
|||||||
public required uint SystemChannelFlags { get; init; }
|
public required uint SystemChannelFlags { get; init; }
|
||||||
public required string? Description { get; init; }
|
public required string? Description { get; init; }
|
||||||
public required int NsfwLevel { get; init; }
|
public required int NsfwLevel { get; init; }
|
||||||
|
|
||||||
|
public override void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(Name);
|
||||||
|
ArgumentNullException.ThrowIfNull(Roles);
|
||||||
|
base.OnDeserialized();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,13 +2,21 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
|
|
||||||
public class GuildMemberData
|
[JsonPolymorphic]
|
||||||
|
[JsonDerivedType(typeof(GuildMemberDataWithUser))]
|
||||||
|
public class GuildMemberData : IJsonOnDeserialized
|
||||||
{
|
{
|
||||||
public UserData? User { get; init; }
|
|
||||||
public string? Nick { get; init; }
|
public string? Nick { get; init; }
|
||||||
public ulong[]? Roles { get; init; }
|
public required ulong[] Roles { get; init; }
|
||||||
public DateTime? JoinedAt { get; init; }
|
public required DateTime JoinedAt { get; init; }
|
||||||
public bool? Deaf { get; init; }
|
public required bool Deaf { get; init; }
|
||||||
public bool? Mute { get; init; }
|
public required bool Mute { get; init; }
|
||||||
|
|
||||||
|
public virtual void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(Roles);
|
||||||
|
}
|
||||||
//TODO: More fields
|
//TODO: More fields
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
12
Discord.API/DataTypes/GuildMemberDataWithUser.cs
Normal file
12
Discord.API/DataTypes/GuildMemberDataWithUser.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
public class GuildMemberDataWithUser : GuildMemberData
|
||||||
|
{
|
||||||
|
public required UserData User { get; init; }
|
||||||
|
|
||||||
|
public override void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(User);
|
||||||
|
base.OnDeserialized();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,14 +2,18 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
|
|
||||||
public class RoleData
|
public class RoleData : IJsonOnDeserialized
|
||||||
{
|
{
|
||||||
[JsonRequired]
|
public required ulong Id { get; init; }
|
||||||
public ulong Id { get; init; }
|
public required string Name { get; init; }
|
||||||
public string? Name { get; init; }
|
public required uint Color { get; init; }
|
||||||
public uint? Color { get; init; }
|
public required bool Hoist { get; init; }
|
||||||
public bool? Hoist { get; init; }
|
public required int Position { get; init; }
|
||||||
public int? Position { get; init; }
|
public required bool Managed { get; init; }
|
||||||
public bool? Managed { get; init; }
|
public required bool Mentionable { get; init; }
|
||||||
public bool? Mentionable { get; init; }
|
|
||||||
|
public void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,8 +4,12 @@ namespace Discord.API;
|
|||||||
|
|
||||||
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
|
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
|
||||||
[JsonDerivedType(typeof(GuildData))]
|
[JsonDerivedType(typeof(GuildData))]
|
||||||
public class UnavailableGuildData
|
public class UnavailableGuildData : IJsonOnDeserialized
|
||||||
{
|
{
|
||||||
public required ulong Id { get; init; }
|
public required ulong Id { get; init; }
|
||||||
public virtual bool Unavailable => true;
|
public virtual bool Unavailable => true;
|
||||||
|
|
||||||
|
public virtual void OnDeserialized()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,13 +1,20 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
|
||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
|
|
||||||
public sealed class UserData
|
public sealed class UserData : IJsonOnDeserialized
|
||||||
{
|
{
|
||||||
public required ulong Id { get; init; }
|
public required ulong Id { get; init; }
|
||||||
public string? Username { get; init; }
|
public required string Username { get; init; }
|
||||||
public string? Discriminator { get; init; }
|
public required string Discriminator { get; init; }
|
||||||
public string? GlobalName { get; init; }
|
public string? GlobalName { get; init; }
|
||||||
|
|
||||||
|
public void OnDeserialized()
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(Username);
|
||||||
|
ArgumentNullException.ThrowIfNull(Discriminator);
|
||||||
|
}
|
||||||
//TODO More fields
|
//TODO More fields
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,18 +4,15 @@ namespace Discord.API;
|
|||||||
|
|
||||||
public class VoiceStateData
|
public class VoiceStateData
|
||||||
{
|
{
|
||||||
public ulong? GuildId { get; init; }
|
public required ulong? ChannelId { get; init; }
|
||||||
public ulong? ChannelId { get; init; }
|
|
||||||
[JsonRequired]
|
|
||||||
public required ulong UserId { get; init; }
|
public required ulong UserId { get; init; }
|
||||||
public GuildMemberData? Member { get; init; }
|
|
||||||
public string? SessionId { get; init; }
|
public string? SessionId { get; init; }
|
||||||
public bool? Mute { get; init; }
|
public required bool Mute { get; init; }
|
||||||
public bool? Deaf { get; init; }
|
public required bool Deaf { get; init; }
|
||||||
public bool? SelfMute { get; init; }
|
public required bool SelfMute { get; init; }
|
||||||
public bool? SelfDeaf { get; init; }
|
public required bool SelfDeaf { get; init; }
|
||||||
public bool? SelfStream { get; init; }
|
public bool? SelfStream { get; init; }
|
||||||
public bool? SelfVideo { get; init; }
|
public bool? SelfVideo { get; init; }
|
||||||
public bool? Suppress { get; init; }
|
public required bool Suppress { get; init; }
|
||||||
public DateTime? RequestToSpeakTimestamp { get; init; }
|
public DateTime? RequestToSpeakTimestamp { get; init; }
|
||||||
}
|
}
|
||||||
6
Discord.API/DataTypes/VoiceStateDataWithGuildId.cs
Normal file
6
Discord.API/DataTypes/VoiceStateDataWithGuildId.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
public class VoiceStateDataWithGuildId : VoiceStateData
|
||||||
|
{
|
||||||
|
public required ulong GuildId {get; init;}
|
||||||
|
}
|
||||||
@ -96,6 +96,10 @@ public abstract class AbstractGateway {
|
|||||||
InstantHeartbeatCts?.Cancel();
|
InstantHeartbeatCts?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void ImmediateHeartbeat(){
|
||||||
|
InstantHeartbeatCts?.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public virtual async Task Close(){
|
public virtual async Task Close(){
|
||||||
|
|||||||
@ -59,6 +59,7 @@ public class GatewayClient : AbstractGateway {
|
|||||||
}
|
}
|
||||||
protected override void MessageReceivedHandler(ResponseMessage msg){
|
protected override void MessageReceivedHandler(ResponseMessage msg){
|
||||||
if(msg.MessageType != System.Net.WebSockets.WebSocketMessageType.Text) return;
|
if(msg.MessageType != System.Net.WebSockets.WebSocketMessageType.Text) return;
|
||||||
|
Log.Debug("GATEWAY PACKET: {packet}", msg);
|
||||||
try{
|
try{
|
||||||
GatewayPacket packet = JsonSerializer.Deserialize(msg.Text!, SourceGenerationContext.Default.GatewayPacket)
|
GatewayPacket packet = JsonSerializer.Deserialize(msg.Text!, SourceGenerationContext.Default.GatewayPacket)
|
||||||
?? throw new Exception("Failed to deserialize packet"); // This can be optimized //TODO
|
?? throw new Exception("Failed to deserialize packet"); // This can be optimized //TODO
|
||||||
@ -78,6 +79,9 @@ public class GatewayClient : AbstractGateway {
|
|||||||
case InvalidSessionPacket invalidSessionPacket:
|
case InvalidSessionPacket invalidSessionPacket:
|
||||||
InvalidSessionHandler(invalidSessionPacket);
|
InvalidSessionHandler(invalidSessionPacket);
|
||||||
break;
|
break;
|
||||||
|
case HeartbeatPacket:
|
||||||
|
HeartbeatPacketHandler();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Log.Debug("GATEWAY: Packet not handled {opcode}", packet.Op);
|
Log.Debug("GATEWAY: Packet not handled {opcode}", packet.Op);
|
||||||
break;
|
break;
|
||||||
@ -126,6 +130,11 @@ public class GatewayClient : AbstractGateway {
|
|||||||
Log.Debug("GATEWAY: Resume url: {url}", packet.Data.ResumeGatewayUrl);
|
Log.Debug("GATEWAY: Resume url: {url}", packet.Data.ResumeGatewayUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HeartbeatPacketHandler(){
|
||||||
|
ImmediateHeartbeat();
|
||||||
|
Log.Debug("GATEWAY: Remote requested immediate heartbeat");
|
||||||
|
}
|
||||||
|
|
||||||
protected override Task SendHeartbeat()
|
protected override Task SendHeartbeat()
|
||||||
{
|
{
|
||||||
HeartbeatPacket packet = new(){
|
HeartbeatPacket packet = new(){
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Discord.API\Discord.API.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
22
Discord.Model/DiscordModel.cs
Normal file
22
Discord.Model/DiscordModel.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public sealed class DiscordModel
|
||||||
|
{
|
||||||
|
public DiscordClient DiscordClient {get;}
|
||||||
|
private IDisposable Subscription;
|
||||||
|
public DiscordModel(string api_key, Intents intents){
|
||||||
|
DiscordClient = new DiscordClient(api_key, intents);
|
||||||
|
Subscription = DiscordClient.PacketReceived.Subscribe(PacketHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PacketHandler(GatewayPacket packet){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close(){
|
||||||
|
Subscription.Dispose();
|
||||||
|
DiscordClient.Close().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Discord.Model/Types/Channel.cs
Normal file
38
Discord.Model/Types/Channel.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class Channel
|
||||||
|
{
|
||||||
|
public enum ChannelType {
|
||||||
|
GuildText = 0,
|
||||||
|
DM = 1,
|
||||||
|
GuildVoice = 2,
|
||||||
|
GroupDM = 3,
|
||||||
|
GuildCategory = 4,
|
||||||
|
GuildAnnouncement = 5,
|
||||||
|
AnnouncementThread = 10,
|
||||||
|
PublicThread = 11,
|
||||||
|
PrivateThread = 12,
|
||||||
|
GuildStageVoice = 13,
|
||||||
|
GuildDirectory = 14,
|
||||||
|
GuildForum = 15,
|
||||||
|
GuildMedia = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
public Snowflake Id { get; }
|
||||||
|
public ChannelType Type { get; protected set; }
|
||||||
|
|
||||||
|
public Channel(ChannelData data){
|
||||||
|
Id = data.Id;
|
||||||
|
Update(data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Update(ChannelData data, bool call_base_update){
|
||||||
|
Type = (ChannelType)data.Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Update(ChannelData data){
|
||||||
|
Update(data, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Discord.Model/Types/GuildChannel.cs
Normal file
47
Discord.Model/Types/GuildChannel.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Discord.API;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class GuildChannel : Channel
|
||||||
|
{
|
||||||
|
public string Name {get; protected set;}
|
||||||
|
public Snowflake? ParentId {get; protected set;}
|
||||||
|
|
||||||
|
internal GuildChannel(GuildChannelData data) : base(data){
|
||||||
|
Update(data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemberNotNull(nameof(Name))]
|
||||||
|
protected void Update(GuildChannelData data, bool call_base_update)
|
||||||
|
{
|
||||||
|
if((ChannelType)data.Type is not ChannelType.GuildText or
|
||||||
|
ChannelType.GuildVoice or
|
||||||
|
ChannelType.GuildCategory or
|
||||||
|
ChannelType.GuildAnnouncement or
|
||||||
|
ChannelType.AnnouncementThread or
|
||||||
|
ChannelType.PublicThread or
|
||||||
|
ChannelType.PrivateThread or
|
||||||
|
ChannelType.GuildStageVoice or
|
||||||
|
ChannelType.GuildForum or
|
||||||
|
ChannelType.GuildMedia)
|
||||||
|
{
|
||||||
|
Log.Warning("GuildChannel has type {type} that is not compatible", (ChannelType)data.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Name = data.Name;
|
||||||
|
ParentId = data.ParentId;
|
||||||
|
|
||||||
|
if(call_base_update) base.Update(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(ChannelData data)
|
||||||
|
{
|
||||||
|
if(data is GuildChannelData guild_data){
|
||||||
|
Update(guild_data, true);
|
||||||
|
}else{
|
||||||
|
throw new ArgumentException("data must be GuildChannelData", nameof(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Discord.Model/Types/GuildMember.cs
Normal file
29
Discord.Model/Types/GuildMember.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class GuildMember
|
||||||
|
{
|
||||||
|
public 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; }
|
||||||
|
|
||||||
|
internal GuildMember(GuildMemberData data, User user){
|
||||||
|
User = user;
|
||||||
|
Update(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemberNotNull(nameof(Roles))]
|
||||||
|
public void Update(GuildMemberData data){
|
||||||
|
Nick = data.Nick;
|
||||||
|
Roles = data.Roles.Select(num => (Snowflake)num).ToArray();
|
||||||
|
JoinedAt = data.JoinedAt;
|
||||||
|
Deaf = data.Deaf;
|
||||||
|
Mute = data.Mute;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Discord.Model/Types/GuildTextChannel.cs
Normal file
12
Discord.Model/Types/GuildTextChannel.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class GuildTextChannel : GuildChannel
|
||||||
|
{
|
||||||
|
|
||||||
|
internal GuildTextChannel(GuildChannelData data) : base(data){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
Discord.Model/Types/Role.cs
Normal file
30
Discord.Model/Types/Role.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public sealed class Role
|
||||||
|
{
|
||||||
|
public Snowflake Id { get; private set; }
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public uint Color { get; private set; }
|
||||||
|
public bool Hoist { get; private set; }
|
||||||
|
public int Position { get; private set; }
|
||||||
|
public bool Managed { get; private set; }
|
||||||
|
public bool Mentionable { get; private set; }
|
||||||
|
|
||||||
|
public Role(RoleData data){
|
||||||
|
this.Id = data.Id;
|
||||||
|
Update(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemberNotNull(nameof(Name))]
|
||||||
|
private void Update(RoleData data){
|
||||||
|
this.Name = data.Name;
|
||||||
|
this.Color = data.Color;
|
||||||
|
this.Hoist = data.Hoist;
|
||||||
|
this.Position = data.Position;
|
||||||
|
this.Managed = data.Managed;
|
||||||
|
this.Mentionable = data.Mentionable;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Discord.Model/Types/Snowflake.cs
Normal file
39
Discord.Model/Types/Snowflake.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public readonly struct Snowflake
|
||||||
|
{
|
||||||
|
public readonly ulong Number;
|
||||||
|
public Snowflake(ulong number){
|
||||||
|
this.Number=number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Snowflake left, Snowflake right){
|
||||||
|
return left.Number == right.Number;
|
||||||
|
}
|
||||||
|
public static bool operator !=(Snowflake left, Snowflake right){
|
||||||
|
return left.Number != right.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Snowflake(ulong num){
|
||||||
|
return new Snowflake(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||||
|
{
|
||||||
|
if(obj is ulong num) return this.Number == num;
|
||||||
|
if(obj is Snowflake other) return this == other;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Number.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Discord.Model/Types/User.cs
Normal file
25
Discord.Model/Types/User.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
Update(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemberNotNull(nameof(Username))]
|
||||||
|
[MemberNotNull(nameof(Discriminator))]
|
||||||
|
internal void Update(UserData data){
|
||||||
|
this.Username = data.Username;
|
||||||
|
this.Discriminator = data.Discriminator;
|
||||||
|
this.GlobalName = data.GlobalName;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Discord.Model/Types/VoiceState.cs
Normal file
36
Discord.Model/Types/VoiceState.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Discord.API;
|
||||||
|
|
||||||
|
namespace Discord.Model;
|
||||||
|
|
||||||
|
public class VoiceState
|
||||||
|
{
|
||||||
|
public ulong? ChannelId { get; private set; }
|
||||||
|
public ulong UserId { get; private set; }
|
||||||
|
public string? SessionId { get; private set; }
|
||||||
|
public bool Mute { get; private set; }
|
||||||
|
public bool Deaf { get; private set; }
|
||||||
|
public bool SelfMute { get; private set; }
|
||||||
|
public bool SelfDeaf { get; private set; }
|
||||||
|
public bool? SelfStream { get; private set; }
|
||||||
|
public bool? SelfVideo { get; private set; }
|
||||||
|
public bool Suppress { get; private set; }
|
||||||
|
public DateTime? RequestToSpeakTimestamp { get; private set; }
|
||||||
|
|
||||||
|
public VoiceState(VoiceStateData data){
|
||||||
|
UserId = data.UserId;
|
||||||
|
Update(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(VoiceStateData data){
|
||||||
|
ChannelId = data.ChannelId;
|
||||||
|
SessionId = data.SessionId;
|
||||||
|
Mute = data.Mute;
|
||||||
|
Deaf = data.Deaf;
|
||||||
|
SelfMute = data.SelfMute;
|
||||||
|
SelfDeaf = data.SelfDeaf;
|
||||||
|
SelfStream = data.SelfStream;
|
||||||
|
SelfVideo = data.SelfVideo;
|
||||||
|
Suppress = data.Suppress;
|
||||||
|
RequestToSpeakTimestamp = data.RequestToSpeakTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.0.31903.59
|
VisualStudioVersion = 17.0.31903.59
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Model", "model\Discord.Model.csproj", "{2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Model", "Discord.Model\Discord.Model.csproj", "{2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.API", "Discord.API\Discord.API.csproj", "{5C77661B-670F-400B-AF77-E3EC062B673D}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.API", "Discord.API\Discord.API.csproj", "{5C77661B-670F-400B-AF77-E3EC062B673D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
namespace model;
|
|
||||||
|
|
||||||
public class Class1
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user