| @@ -29,7 +29,8 @@ | |||
| <PackageReference Update="Microsoft.Extensions.Hosting" Version="5.0.0" /> | |||
| <PackageReference Update="Microsoft.Extensions.Options" Version="5.0.0" /> | |||
| <PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" /> | |||
| <PackageReference Update="System.IO.Pipelines" Version="5.0.0" /> | |||
| <PackageReference Update="System.IO.Pipelines" Version="5.0.1" /> | |||
| <PackageReference Update="System.Text.Json" Version="5.0.2" /> | |||
| <PackageReference Update="xunit" Version="2.4.1" /> | |||
| <PackageReference Update="xunit.runner.visualstudio" Version="2.4.3" /> | |||
| </ItemGroup> | |||
| @@ -1,19 +1,21 @@ | |||
| | |||
| Microsoft Visual Studio Solution File, Format Version 12.00 | |||
| # Visual Studio 15 | |||
| VisualStudioVersion = 15.0.26124.0 | |||
| # Visual Studio Version 16 | |||
| VisualStudioVersion = 16.0.31229.75 | |||
| MinimumVisualStudioVersion = 15.0.26124.0 | |||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CD5CFA4B-143E-4495-8BFD-AF419226CBE5}" | |||
| EndProject | |||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Gateway", "src\Gateway\Discord.Net.Gateway.csproj", "{DAF502E3-CFE6-4243-8049-9A6157F42111}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Gateway", "src\Gateway\Discord.Net.Gateway.csproj", "{DAF502E3-CFE6-4243-8049-9A6157F42111}" | |||
| EndProject | |||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6D7B7A29-83FE-44F2-85E1-7D44B061EA27}" | |||
| EndProject | |||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PingPong", "samples\PingPong\PingPong.csproj", "{54A6E396-5186-4D79-893B-6EFD1CF658CB}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PingPong", "samples\PingPong\PingPong.csproj", "{54A6E396-5186-4D79-893B-6EFD1CF658CB}" | |||
| EndProject | |||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A47FC28E-1835-46C3-AFD5-7C048A43C157}" | |||
| EndProject | |||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Gateway.UnitTests", "test\Gateway\Discord.Net.Gateway.UnitTests.csproj", "{7EC53EB6-6C15-4FD7-9B83-95F96025C14D}" | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Gateway.UnitTests", "test\Gateway\Discord.Net.Gateway.UnitTests.csproj", "{7EC53EB6-6C15-4FD7-9B83-95F96025C14D}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Models", "src\Models\Discord.Net.Models.csproj", "{564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}" | |||
| EndProject | |||
| Global | |||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
| @@ -24,9 +26,6 @@ Global | |||
| Release|x64 = Release|x64 | |||
| Release|x86 = Release|x86 | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| EndGlobalSection | |||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
| {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| @@ -64,10 +63,29 @@ Global | |||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x64.Build.0 = Release|Any CPU | |||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.ActiveCfg = Release|Any CPU | |||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.Build.0 = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x86.Build.0 = Debug|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x64.Build.0 = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x86.ActiveCfg = Release|Any CPU | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x86.Build.0 = Release|Any CPU | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| EndGlobalSection | |||
| GlobalSection(NestedProjects) = preSolution | |||
| {DAF502E3-CFE6-4243-8049-9A6157F42111} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | |||
| {54A6E396-5186-4D79-893B-6EFD1CF658CB} = {6D7B7A29-83FE-44F2-85E1-7D44B061EA27} | |||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D} = {A47FC28E-1835-46C3-AFD5-7C048A43C157} | |||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | |||
| EndGlobalSection | |||
| GlobalSection(ExtensibilityGlobals) = postSolution | |||
| SolutionGuid = {36B0BFC9-AF79-4D25-89D4-2EE3C961612B} | |||
| EndGlobalSection | |||
| EndGlobal | |||
| @@ -0,0 +1,58 @@ | |||
| using System.Text.Json.Serialization; | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Represents an audit entry info object. | |||
| /// </summary> | |||
| public record AuditEntryInfo | |||
| { | |||
| /// <summary> | |||
| /// Number of days after which inactive members were kicked. | |||
| /// </summary> | |||
| [JsonPropertyName("delete_member_days")] | |||
| public Optional<int> DeleteMemberDays { get; init; } // actually sent as Optional<string> | |||
| /// <summary> | |||
| /// Number of members removed by the prune. | |||
| /// </summary> | |||
| [JsonPropertyName("members_removed")] | |||
| public Optional<int> MembersRemoved { get; init; } // actually sent as Optional<string> | |||
| /// <summary> | |||
| /// Channel in which the entities were targeted. | |||
| /// </summary> | |||
| [JsonPropertyName("channel_id")] | |||
| public Optional<Snowflake> ChannelId { get; init; } | |||
| /// <summary> | |||
| /// Id of the message that was targeted. | |||
| /// </summary> | |||
| [JsonPropertyName("message_id")] | |||
| public Optional<Snowflake> MessageId { get; init; } | |||
| /// <summary> | |||
| /// Number of entities that were targeted. | |||
| /// </summary> | |||
| [JsonPropertyName("count")] | |||
| public Optional<int> Count { get; init; } // actually sent as Optional<string> | |||
| /// <summary> | |||
| /// Id of the overwritten entity. | |||
| /// </summary> | |||
| [JsonPropertyName("id")] | |||
| public Optional<Snowflake> Id { get; init; } | |||
| /// <summary> | |||
| /// Type of overwritten entity - "0" for "role" or "1" for "member". | |||
| /// </summary> | |||
| [JsonPropertyName("type")] | |||
| public Optional<AuditEntryInfo> Type { get; init; } // actually sent as Optional<string> | |||
| /// <summary> | |||
| /// Name of the role if type is "0" (not present if type is "1"). | |||
| /// </summary> | |||
| [JsonPropertyName("role_name")] | |||
| public Optional<string> RoleName { get; init; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Represents type of the overwritten entity for an audit entry info. | |||
| /// </summary> | |||
| public enum AuditEntryInfoType | |||
| { | |||
| /// <summary> | |||
| /// The type of the overwritten entity is a role. | |||
| /// </summary> | |||
| Role = 0, | |||
| /// <summary> | |||
| /// The type of the overwritten entity is a member. | |||
| /// </summary> | |||
| Member = 1, | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| using System.Text.Json.Serialization; | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Represents a discord audit log object. | |||
| /// </summary> | |||
| public record AuditLog | |||
| { | |||
| /// <summary> | |||
| /// Gets an array of <see cref="Webhook"/>s. | |||
| /// </summary> | |||
| /*[JsonPropertyName("webhooks")] | |||
| public Optional<Webhook[]> Webhooks { get; init; }*/ //TODO Add Webhook | |||
| /// <summary> | |||
| /// Gets an array of <see cref="User"/>s. | |||
| /// </summary> | |||
| /*[JsonPropertyName("users")] | |||
| public Optional<User[]> Users { get; init; }*/ //TODO Add User | |||
| /// <summary> | |||
| /// Gets an array of <see cref="AuditLogEntry"/>s. | |||
| /// </summary> | |||
| [JsonPropertyName("audit_log_entries")] | |||
| public Optional<AuditLogEntry[]> AuditLogEntries { get; init; } | |||
| /// <summary> | |||
| /// Gets an array of <see cref="Integration"/>s. | |||
| /// </summary> | |||
| /*[JsonPropertyName("integrations")] | |||
| public Optional<Integration[]> Integrations { get; init; }*/ //TODO Add Integration | |||
| } | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| using System.Text.Json.Serialization; | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Represents an audit log change object. | |||
| /// </summary> | |||
| public record AuditLogChange | |||
| { | |||
| /// <summary> | |||
| /// New value of the key. | |||
| /// </summary> | |||
| [JsonPropertyName("new_value")] | |||
| public Optional<object> NewValue { get; init; } | |||
| /// <summary> | |||
| /// Old value of the key. | |||
| /// </summary> | |||
| [JsonPropertyName("old_value")] | |||
| public Optional<object> OldValue { get; init; } | |||
| /// <summary> | |||
| /// Name of the audit log change key. | |||
| /// </summary> | |||
| [JsonPropertyName("key")] | |||
| public string? Key { get; init; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,52 @@ | |||
| using System.Text.Json.Serialization; | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Represents an audit log entry object. | |||
| /// </summary> | |||
| public record AuditLogEntry | |||
| { | |||
| /// <summary> | |||
| /// Id of the affected entity (webhook, user, role, etc.). | |||
| /// </summary> | |||
| [JsonPropertyName("target_id")] | |||
| public Snowflake? TargetId { get; init; } | |||
| /// <summary> | |||
| /// Changes made to the <see cref="TargetId"/>. | |||
| /// </summary> | |||
| [JsonPropertyName("changes")] | |||
| public Optional<AuditLogChange[]> Changes { get; init; } | |||
| /// <summary> | |||
| /// The user who made the changes. | |||
| /// </summary> | |||
| [JsonPropertyName("user_id")] | |||
| public Snowflake? UserId { get; init; } | |||
| /// <summary> | |||
| /// Id of the entry. | |||
| /// </summary> | |||
| [JsonPropertyName("id")] | |||
| public Snowflake Id { get; init; } | |||
| /// <summary> | |||
| /// Type of action that occurred. | |||
| /// </summary> | |||
| [JsonPropertyName("action_type")] | |||
| public AuditLogEvent ActionType { get; init; } | |||
| /// <summary> | |||
| /// Additional info for certain action types. | |||
| /// </summary> | |||
| [JsonPropertyName("options")] | |||
| public Optional<AuditEntryInfo> Options { get; init; } | |||
| /// <summary> | |||
| /// The reason for the change (0-512 characters). | |||
| /// </summary> | |||
| [JsonPropertyName("reason")] | |||
| public Optional<string> Reason { get; init; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,153 @@ | |||
| namespace Discord.Net.Models | |||
| { | |||
| /// <summary> | |||
| /// Specifies the type of audit log event. | |||
| /// </summary> | |||
| public enum AuditLogEvent : int | |||
| { | |||
| /// <summary> | |||
| /// Default value of this type. | |||
| /// </summary> | |||
| None = 0, | |||
| /// <summary> | |||
| /// The guild was updated. | |||
| /// </summary> | |||
| GuildUpdate = 1, | |||
| /// <summary> | |||
| /// A channel was created. | |||
| /// </summary> | |||
| ChannelCreate = 10, | |||
| /// <summary> | |||
| /// A channel was updated. | |||
| /// </summary> | |||
| ChannelUpdate = 11, | |||
| /// <summary> | |||
| /// A channel was deleted. | |||
| /// </summary> | |||
| ChannelDelete = 12, | |||
| /// <summary> | |||
| /// A channel overwrite was created. | |||
| /// </summary> | |||
| ChannelOverwriteCreate = 13, | |||
| /// <summary> | |||
| /// A channel overwrite was updated. | |||
| /// </summary> | |||
| ChannelOverwriteUpdate = 14, | |||
| /// <summary> | |||
| /// A channel overwrite was deleted. | |||
| /// </summary> | |||
| ChannelOverwriteDelete = 15, | |||
| /// <summary> | |||
| /// A guild member was kicked. | |||
| /// </summary> | |||
| MemberKick = 20, | |||
| /// <summary> | |||
| /// A guild member was pruned. | |||
| /// </summary> | |||
| MemberPrune = 21, | |||
| /// <summary> | |||
| /// A guild member was banned. | |||
| /// </summary> | |||
| MemberBanAdd = 22, | |||
| /// <summary> | |||
| /// A guild member was unbanned. | |||
| /// </summary> | |||
| MemberBanRemove = 23, | |||
| /// <summary> | |||
| /// A guild member was updated. | |||
| /// </summary> | |||
| MemberUpdate = 24, | |||
| /// <summary> | |||
| /// A guild role was updated. | |||
| /// </summary> | |||
| MemberRoleUpdate = 25, | |||
| /// <summary> | |||
| /// A guild member was moved. | |||
| /// </summary> | |||
| MemberMove = 26, | |||
| /// <summary> | |||
| /// A guild member was disconnected. | |||
| /// </summary> | |||
| MemberDisconnect = 27, | |||
| /// <summary> | |||
| /// A bot was added. | |||
| /// </summary> | |||
| BotAdd = 28, | |||
| /// <summary> | |||
| /// A role was created. | |||
| /// </summary> | |||
| RoleCreate = 30, | |||
| /// <summary> | |||
| /// A role was updated. | |||
| /// </summary> | |||
| RoleUpdate = 31, | |||
| /// <summary> | |||
| /// A role was deleted. | |||
| /// </summary> | |||
| RoleDelete = 32, | |||
| /// <summary> | |||
| /// An invite was created. | |||
| /// </summary> | |||
| InviteCreate = 40, | |||
| /// <summary> | |||
| /// An invite was updated. | |||
| /// </summary> | |||
| InviteUpdate = 41, | |||
| /// <summary> | |||
| /// An invite was deleted. | |||
| /// </summary> | |||
| InviteDelete = 42, | |||
| /// <summary> | |||
| /// A webhook was created. | |||
| /// </summary> | |||
| WebhookCreate = 50, | |||
| /// <summary> | |||
| /// A webhook was updated. | |||
| /// </summary> | |||
| WebhookUpdate = 51, | |||
| /// <summary> | |||
| /// A webhook was deleted. | |||
| /// </summary> | |||
| WebhookDelete = 52, | |||
| /// <summary> | |||
| /// An emoji was created. | |||
| /// </summary> | |||
| EmojiCreate = 60, | |||
| /// <summary> | |||
| /// An emoji was updated. | |||
| /// </summary> | |||
| EmojiUpdate = 61, | |||
| /// <summary> | |||
| /// An emoji was deleted. | |||
| /// </summary> | |||
| EmojiDelete = 62, | |||
| /// <summary> | |||
| /// A message was deleted. | |||
| /// </summary> | |||
| MessageDelete = 72, | |||
| /// <summary> | |||
| /// Message were deleted in bulk. | |||
| /// </summary> | |||
| MessageBulkDelete = 73, | |||
| /// <summary> | |||
| /// A message was pinned. | |||
| /// </summary> | |||
| MessagePin = 74, | |||
| /// <summary> | |||
| /// A message was unpinned. | |||
| /// </summary> | |||
| MessageUnpin = 75, | |||
| /// <summary> | |||
| /// An integration was created. | |||
| /// </summary> | |||
| IntegrationCreate = 80, | |||
| /// <summary> | |||
| /// An integration was updated. | |||
| /// </summary> | |||
| IntegrationUpdate = 81, | |||
| /// <summary> | |||
| /// An integration was deleted. | |||
| /// </summary> | |||
| IntegrationDelete = 82, | |||
| } | |||
| } | |||
| @@ -8,5 +8,9 @@ | |||
| Shared models between the Discord REST API and Gateway. | |||
| </Description> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="System.Text.Json" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -0,0 +1,98 @@ | |||
| using System; | |||
| namespace Discord.Net | |||
| { | |||
| /// <summary> | |||
| /// Container to keep a type that might not be present. | |||
| /// </summary> | |||
| /// <typeparam name="T">Inner type</typeparam> | |||
| public struct Optional<T> | |||
| { | |||
| private readonly T _value; | |||
| /// <summary> | |||
| /// Gets the inner value of this <see cref="Optional{T}"/> if present. | |||
| /// </summary> | |||
| /// <returns>The value inside this <see cref="Optional{T}"/>.</returns> | |||
| /// <exception cref="InvalidOperationException">This <see cref="Optional{T}"/> has no inner value.</exception> | |||
| public T Value => !IsSpecified ? throw new InvalidOperationException("This property has no value set.") : _value; | |||
| /// <summary> | |||
| /// Gets if this <see cref="Optional{T}"/> has an inner value. | |||
| /// </summary> | |||
| /// <returns>A boolean that determines if this <see cref="Optional{T}"/> has a <see cref="Value"/>.</returns> | |||
| public bool IsSpecified { get; } | |||
| private Optional(T value) | |||
| { | |||
| _value = value; | |||
| IsSpecified = true; | |||
| } | |||
| /// <summary> | |||
| /// Creates a new unspecified <see cref="Optional{T}"/>. | |||
| /// </summary> | |||
| /// <returns>An unspecified <see cref="Optional{T}"/>.</returns> | |||
| public static Optional<T> Create() | |||
| => default; | |||
| /// <summary> | |||
| /// Creates a new <see cref="Optional{T}"/> with the specified <paramref name="value"/>. | |||
| /// </summary> | |||
| /// <param name="value">Value that will be specified for this <see cref="Optional{T}"/>.</param> | |||
| /// <returns>A specified <see cref="Optional{T}"/> with the provided value inside.</returns> | |||
| public static Optional<T> Create(T value) | |||
| => new(value); | |||
| /// <summary> | |||
| /// Gets the <see cref="Value"/> or their <see langword="default"/> value. | |||
| /// </summary> | |||
| /// <returns>The value inside this <see cref="Optional{T}"/> or their <see langword="default"/> value.</returns> | |||
| public T GetValueOrDefault() | |||
| => _value; | |||
| /// <summary> | |||
| /// Gets the <see cref="Value"/> or the default value provided. | |||
| /// </summary> | |||
| /// <returns>The value inside this <see cref="Optional{T}"/> or default value provided.</returns> | |||
| public T GetValueOrDefault(T defaultValue) | |||
| => IsSpecified ? _value : defaultValue; | |||
| /// <inheritdoc/> | |||
| public override bool Equals(object? other) | |||
| { | |||
| if (!IsSpecified) | |||
| return other == null; | |||
| if (other == null || _value == null) | |||
| return false; | |||
| return _value.Equals(other); | |||
| } | |||
| /// <inheritdoc/> | |||
| public override int GetHashCode() | |||
| => IsSpecified ? _value?.GetHashCode() ?? default : default; | |||
| /// <summary> | |||
| /// Returns the inner value ToString value or this type fully qualified name. | |||
| /// </summary> | |||
| /// <returns>The inner value string value or this type fully qualified name.</returns> | |||
| public override string? ToString() | |||
| => IsSpecified ? _value?.ToString() : default; | |||
| /// <summary> | |||
| /// Creates a new <see cref="Optional{T}"/> with the specified <paramref name="value"/>. | |||
| /// </summary> | |||
| /// <param name="value">Value to convert</param> | |||
| /// <returns>A new <see cref="Optional{T}"/> with the specified <paramref name="value"/></returns> | |||
| public static implicit operator Optional<T>(T value) | |||
| => new(value); | |||
| /// <summary> | |||
| /// Gets the inner value. | |||
| /// </summary> | |||
| /// <param name="value">Value to convert</param> | |||
| /// <returns>The inner value</returns> | |||
| public static explicit operator T(Optional<T> value) | |||
| => value.Value; | |||
| } | |||
| } | |||
| @@ -0,0 +1,76 @@ | |||
| using System; | |||
| namespace Discord.Net | |||
| { | |||
| /// <summary> | |||
| /// Represents a discord snowflake. | |||
| /// </summary> | |||
| public struct Snowflake | |||
| { | |||
| private const ulong DiscordEpoch = 1420070400000UL; | |||
| /// <summary> | |||
| /// Gets the raw value of this snowflake. | |||
| /// </summary> | |||
| /// <returns>A <see cref="ulong"/> with the rae value.</returns> | |||
| public ulong RawValue { get; } | |||
| /// <summary> | |||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="value"/> provided. | |||
| /// </summary> | |||
| /// <param name="value">Raw value of the snowflake.</param> | |||
| public Snowflake(ulong value) | |||
| { | |||
| RawValue = value; | |||
| } | |||
| /// <summary> | |||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="dateTimeOffset"/> provided. | |||
| /// </summary> | |||
| /// <param name="dateTimeOffset">DateTimeOffset of this snowflake.</param> | |||
| public Snowflake(DateTimeOffset dateTimeOffset) | |||
| { | |||
| RawValue = ((ulong)dateTimeOffset.ToUniversalTime().ToUnixTimeMilliseconds() - DiscordEpoch) << 22; | |||
| } | |||
| /// <summary> | |||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="dateTime"/> provided. | |||
| /// </summary> | |||
| /// <param name="dateTime">DateTime of this snowflake.</param> | |||
| public Snowflake(DateTime dateTime) | |||
| : this(new DateTimeOffset(dateTime)) { } | |||
| /// <summary> | |||
| /// Converts this <see cref="Snowflake"/> to a <see cref="DateTimeOffset"/>. | |||
| /// </summary> | |||
| /// <returns>A <see cref="DateTimeOffset"/> of this snowflake.</returns> | |||
| public DateTimeOffset ToDateTimeOffset() => DateTimeOffset.FromUnixTimeMilliseconds((long)((RawValue >> 22) + DiscordEpoch)); | |||
| /// <summary> | |||
| /// Converts this <see cref="Snowflake"/> to a <see cref="DateTime"/>. | |||
| /// </summary> | |||
| /// <returns>A <see cref="DateTime"/> of this snowflake.</returns> | |||
| public DateTimeOffset ToDateTime() => ToDateTimeOffset().UtcDateTime; | |||
| /// <summary> | |||
| /// Converts this <see cref="Snowflake"/> to a <see cref="ulong"/>. | |||
| /// </summary> | |||
| /// <param name="snowflake">Value that will be converted</param> | |||
| /// <returns>A <see cref="ulong"/> with the raw value.</returns> | |||
| public static implicit operator ulong(Snowflake snowflake) => snowflake.RawValue; | |||
| /// <summary> | |||
| /// Converts this <see cref="ulong"/> to a <see cref="Snowflake"/>. | |||
| /// </summary> | |||
| /// <param name="value">Value that will be converted</param> | |||
| /// <returns>A <see cref="Snowflake"/> with <paramref name="value"/> as the raw value.</returns> | |||
| public static implicit operator Snowflake(ulong value) => new Snowflake(value); | |||
| /// <summary> | |||
| /// Returns the raw value as <see cref="string"/>. | |||
| /// </summary> | |||
| /// <returns>A <see cref="string"/> that is the raw value.</returns> | |||
| public override string ToString() | |||
| => RawValue.ToString(); | |||
| } | |||
| } | |||