Browse Source

port: started stubbing guild interface/model

pull/1253/head
Christopher Felegy 6 years ago
parent
commit
30e5cbcd4a
15 changed files with 434 additions and 14 deletions
  1. +9
    -0
      src/Discord.Net/Discord.Net.csproj
  2. +19
    -0
      src/Discord.Net/Entities/Guilds/DefaultMessageNotifications.cs
  3. +13
    -0
      src/Discord.Net/Entities/Guilds/ExplicitContentFilterLevel.cs
  4. +146
    -0
      src/Discord.Net/Entities/Guilds/IGuild.cs
  5. +17
    -0
      src/Discord.Net/Entities/Guilds/MfaLevel.cs
  6. +29
    -0
      src/Discord.Net/Entities/Guilds/VerificationLevel.cs
  7. +16
    -0
      src/Discord.Net/Entities/IDeletable.cs
  8. +18
    -0
      src/Discord.Net/Entities/IEntity.cs
  9. +16
    -0
      src/Discord.Net/Entities/ISnowflakeEntity.cs
  10. +66
    -0
      src/Discord.Net/Models/Guilds/Guild.cs
  11. +28
    -0
      src/Discord.Net/Models/SnowflakeEntity.cs
  12. +31
    -0
      src/Discord.Net/Utilities/SnowflakeUtilities.cs
  13. +4
    -0
      test/Discord.Tests.Unit/Discord.Tests.Unit.csproj
  14. +0
    -14
      test/Discord.Tests.Unit/UnitTest1.cs
  15. +22
    -0
      test/Discord.Tests.Unit/Utilities/SnowflakeTests.cs

+ 9
- 0
src/Discord.Net/Discord.Net.csproj View File

@@ -4,4 +4,13 @@
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>


<ItemGroup>
<PackageReference Include="Wumpus.Net.Gateway" Version="0.2.2-build-00031" />
<PackageReference Include="Wumpus.Net.Rest" Version="0.2.2-build-00031" />
</ItemGroup>

<ItemGroup>
<Folder Include="Models\Guilds\" />
</ItemGroup>

</Project> </Project>

+ 19
- 0
src/Discord.Net/Entities/Guilds/DefaultMessageNotifications.cs View File

@@ -0,0 +1,19 @@
using Model = Wumpus.Entities.DefaultMessageNotifications;

namespace Discord
{
/// <summary>
/// Specifies the default message notification behavior the guild uses.
/// </summary>
public enum DefaultMessageNotifications
{
/// <summary>
/// By default, all messages will trigger notifications.
/// </summary>
AllMessages = 0,
/// <summary>
/// By default, only mentions will trigger notifications.
/// </summary>
MentionsOnly = 1
}
}

+ 13
- 0
src/Discord.Net/Entities/Guilds/ExplicitContentFilterLevel.cs View File

@@ -0,0 +1,13 @@
namespace Discord
{
public enum ExplicitContentFilterLevel
{
/// <summary> No messages will be scanned. </summary>
Disabled = 0,
/// <summary> Scans messages from all guild members that do not have a role. </summary>
/// <remarks> Recommented option for servers that use roles for trusted membership. </remarks>
MembersWithoutRoles = 1,
/// <summary> Scan messages sent by all guild members. </summary>
AllMembers = 2
}
}

+ 146
- 0
src/Discord.Net/Entities/Guilds/IGuild.cs View File

@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Discord
{
public interface IGuild : IDeletable, ISnowflakeEntity
{
/// <summary>
/// Gets the name of this guild.
/// </summary>
/// <returns>
/// A string containing the name of this guild.
/// </returns>
string Name { get; }
/// <summary>
/// Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are
/// automatically moved to the AFK voice channel.
/// </summary>
/// <returns>
/// An <see cref="int"/> representing the amount of time in seconds for a user to be marked as inactive
/// and moved into the AFK voice channel.
/// </returns>
int AFKTimeout { get; }
/// <summary>
/// Gets a value that indicates whether this guild is embeddable (i.e. can use widget).
/// </summary>
/// <returns>
/// <c>true</c> if this guild can be embedded via widgets; otherwise <c>false</c>.
/// </returns>
bool IsEmbeddable { get; }
/// <summary>
/// Gets the default message notifications for users who haven't explicitly set their notification settings.
/// </summary>
DefaultMessageNotifications DefaultMessageNotifications { get; }
/// <summary>
/// Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to
/// perform administrative actions in this guild.
/// </summary>
/// <returns>
/// The level of MFA requirement.
/// </returns>
MfaLevel MfaLevel { get; }
/// <summary>
/// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild.
/// </summary>
/// <returns>
/// The level of requirements.
/// </returns>
VerificationLevel VerificationLevel { get; }
/// <summary>
/// Gets the level of content filtering applied to user's content in a Guild.
/// </summary>
/// <returns>
/// The level of explicit content filtering.
/// </returns>
ExplicitContentFilterLevel ExplicitContentFilter { get; }
/// <summary>
/// Gets the ID of this guild's icon.
/// </summary>
/// <returns>
/// An identifier for the splash image; <c>null</c> if none is set.
/// </returns>
string IconId { get; }
/// <summary>
/// Gets the URL of this guild's icon.
/// </summary>
/// <returns>
/// A URL pointing to the guild's icon; <c>null</c> if none is set.
/// </returns>
string IconUrl { get; }
/// <summary>
/// Gets the ID of this guild's splash image.
/// </summary>
/// <returns>
/// An identifier for the splash image; <c>null</c> if none is set.
/// </returns>
string SplashId { get; }
/// <summary>
/// Gets the URL of this guild's splash image.
/// </summary>
/// <returns>
/// A URL pointing to the guild's splash image; <c>null</c> if none is set.
/// </returns>
string SplashUrl { get; }
/// <summary>
/// Determines if this guild is currently connected and ready to be used.
/// </summary>
/// <remarks>
/// <note>
/// This property only applies to a guild fetched via the gateway; it will always return false on guilds fetched via REST.
/// </note>
/// This boolean is used to determine if the guild is currently connected to the WebSocket and is ready to be used/accessed.
/// </remarks>
/// <returns>
/// <c>true</c> if this guild is currently connected and ready to be used; otherwise <c>false</c>.
/// </returns>
bool Available { get; }

/// <summary>
/// Gets the ID of the AFK voice channel for this guild.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the AFK voice channel; <c>null</c> if
/// none is set.
/// </returns>
ulong? AFKChannelId { get; }
/// <summary>
/// Gets the ID of the widget embed channel of this guild.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the embedded channel found within the
/// widget settings of this guild; <c>null</c> if none is set.
/// </returns>
ulong? EmbedChannelId { get; }
/// <summary>
/// Gets the ID of the channel where randomized welcome messages are sent.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the system channel where randomized
/// welcome messages are sent; <c>null</c> if none is set.
/// </returns>
ulong? SystemChannelId { get; }
/// <summary>
/// Gets the ID of the user that owns this guild.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the user that owns this guild.
/// </returns>
ulong OwnerId { get; }
/// <summary>
/// Gets the application ID of the guild creator if it is bot-created.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the application ID that created this guild, or <c>null</c> if it was not bot-created.
/// </returns>
ulong? ApplicationId { get; }
/// <summary>
/// Gets the ID of the region hosting this guild's voice channels.
/// </summary>
/// <returns>
/// A string containing the identifier for the voice region that this guild uses (e.g. <c>eu-central</c>).
/// </returns>
string VoiceRegionId { get; }
}
}

+ 17
- 0
src/Discord.Net/Entities/Guilds/MfaLevel.cs View File

@@ -0,0 +1,17 @@
namespace Discord
{
/// <summary>
/// Specifies the guild's Multi-Factor Authentication (MFA) level requirement.
/// </summary>
public enum MfaLevel
{
/// <summary>
/// Users have no additional MFA restriction on this guild.
/// </summary>
Disabled = 0,
/// <summary>
/// Users must have MFA enabled on their account to perform administrative actions.
/// </summary>
Enabled = 1
}
}

+ 29
- 0
src/Discord.Net/Entities/Guilds/VerificationLevel.cs View File

@@ -0,0 +1,29 @@
namespace Discord
{
/// <summary>
/// Specifies the verification level the guild uses.
/// </summary>
public enum VerificationLevel
{
/// <summary>
/// Users have no additional restrictions on sending messages to this guild.
/// </summary>
None = 0,
/// <summary>
/// Users must have a verified email on their account.
/// </summary>
Low = 1,
/// <summary>
/// Users must fulfill the requirements of Low and be registered on Discord for at least 5 minutes.
/// </summary>
Medium = 2,
/// <summary>
/// Users must fulfill the requirements of Medium and be a member of this guild for at least 10 minutes.
/// </summary>
High = 3,
/// <summary>
/// Users must fulfill the requirements of High and must have a verified phone on their Discord account.
/// </summary>
Extreme = 4
}
}

+ 16
- 0
src/Discord.Net/Entities/IDeletable.cs View File

@@ -0,0 +1,16 @@
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Determines whether the object is deletable or not.
/// </summary>
public interface IDeletable
{
/// <summary>
/// Deletes this object and all its children.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
Task DeleteAsync(/*RequestOptions options = null*/);
}
}

+ 18
- 0
src/Discord.Net/Entities/IEntity.cs View File

@@ -0,0 +1,18 @@
using System;

namespace Discord
{
public interface IEntity<TId>
where TId : IEquatable<TId>
{
/// <summary>
/// Gets the <see cref="IDiscordClient"/> that created this object.
/// </summary>
IDiscordClient Discord { get; }

/// <summary>
/// Gets the unique identifier for this object.
/// </summary>
TId Id { get; }
}
}

+ 16
- 0
src/Discord.Net/Entities/ISnowflakeEntity.cs View File

@@ -0,0 +1,16 @@
using System;

namespace Discord
{
/// <summary> Represents a Discord snowflake entity. </summary>
public interface ISnowflakeEntity : IEntity<ulong>
{
/// <summary>
/// Gets when the snowflake was created.
/// </summary>
/// <returns>
/// A <see cref="DateTimeOffset"/> representing when the entity was first created.
/// </returns>
DateTimeOffset CreatedAt { get; }
}
}

+ 66
- 0
src/Discord.Net/Models/Guilds/Guild.cs View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Wumpus.Entities;
using Model = Wumpus.Entities.Guild;

namespace Discord
{
internal class Guild : SnowflakeEntity, IGuild
{
public Guild(Model model, IDiscordClient client) : base(client)
{
Name = model.Name.ToString();
AFKTimeout = model.AfkTimeout;
IsEmbeddable = model.EmbedEnabled.GetValueOrDefault(false);

// FYI: when casting these, make sure Wumpus is using the same schema as us, otherwise these values will not match up.
DefaultMessageNotifications = (DefaultMessageNotifications)model.DefaultMessageNotifications;
MfaLevel = (MfaLevel)model.MfaLevel;
VerificationLevel = (VerificationLevel)model.VerificationLevel;
ExplicitContentFilter = (ExplicitContentFilterLevel)model.ExplicitContentFilter;

IconId = model.Icon?.Hash.ToString();
IconUrl = null; // TODO: port CDN
SplashId = model.Splash?.Hash.ToString();
SplashUrl = null; // TODO: port CDN

Available = model is GatewayGuild;

AFKChannelId = model.AfkChannelId;
EmbedChannelId = model.EmbedChannelId.IsSpecified ? model.EmbedChannelId.Value : null;
SystemChannelId = model.SystemChannelId;

OwnerId = model.OwnerId;
ApplicationId = model.ApplicationId;
VoiceRegionId = null; // TODO?
}

public string Name { get; set; }
public int AFKTimeout { get; set; }
public bool IsEmbeddable { get; set; }

public DefaultMessageNotifications DefaultMessageNotifications { get; set; }
public MfaLevel MfaLevel { get; set; }
public VerificationLevel VerificationLevel { get; set; }
public ExplicitContentFilterLevel ExplicitContentFilter { get; set; }

public string IconId { get; set; }
public string IconUrl { get; set; }
public string SplashId { get; set; }
public string SplashUrl { get; set; }

public bool Available { get; set; }

public ulong? AFKChannelId { get; set; }
public ulong? EmbedChannelId { get; set; }
public ulong? SystemChannelId { get; set; }

public ulong OwnerId { get; set; }
public ulong? ApplicationId { get; set; }
public string VoiceRegionId { get; set; }

public Task DeleteAsync() => throw new NotImplementedException();
}
}

+ 28
- 0
src/Discord.Net/Models/SnowflakeEntity.cs View File

@@ -0,0 +1,28 @@
using System;

namespace Discord
{
internal abstract class SnowflakeEntity : ISnowflakeEntity
{
private DateTimeOffset? _createdAt;

public SnowflakeEntity(IDiscordClient discord)
{
Discord = discord;
}

public IDiscordClient Discord { get; set; }
public ulong Id { get; set; }

public DateTimeOffset CreatedAt
{
get
{
if (_createdAt.HasValue)
return _createdAt.Value;
_createdAt = SnowflakeUtilities.FromSnowflake(Id);
return _createdAt.Value;
}
}
}
}

+ 31
- 0
src/Discord.Net/Utilities/SnowflakeUtilities.cs View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Discord
{
/// <summary>
/// Provides a series of helper methods for handling snowflake identifiers.
/// </summary>
public static class SnowflakeUtilities
{
/// <summary>
/// Resolves the time of which the snowflake is generated.
/// </summary>
/// <param name="value">The snowflake identifier to resolve.</param>
/// <returns>
/// A <see cref="DateTimeOffset" /> representing the time for when the object is geenrated.
/// </returns>
public static DateTimeOffset FromSnowflake(ulong value)
=> DateTimeOffset.FromUnixTimeMilliseconds((long)((value >> 22) + 1420070400000UL));
/// <summary>
/// Generates a pseudo-snowflake identifier with a <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="value">The time to be used in the new snowflake.</param>
/// <returns>
/// A <see cref="UInt64" /> representing the newly generated snowflake identifier.
/// </returns>
public static ulong ToSnowflake(DateTimeOffset value)
=> ((ulong)value.ToUnixTimeMilliseconds() - 1420070400000UL) << 22;
}
}

+ 4
- 0
test/Discord.Tests.Unit/Discord.Tests.Unit.csproj View File

@@ -12,4 +12,8 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup> </ItemGroup>


<ItemGroup>
<ProjectReference Include="..\..\src\Discord.Net\Discord.Net.csproj" />
</ItemGroup>

</Project> </Project>

+ 0
- 14
test/Discord.Tests.Unit/UnitTest1.cs View File

@@ -1,14 +0,0 @@
using System;
using Xunit;

namespace Discord.Tests.Unit
{
public class UnitTest1
{
[Fact]
public void Test1()
{

}
}
}

+ 22
- 0
test/Discord.Tests.Unit/Utilities/SnowflakeTests.cs View File

@@ -0,0 +1,22 @@
using System;
using Xunit;

namespace Discord.Tests.Unit
{
public class SnowflakeTests
{
[Fact]
public void FromSnowflake()
{
Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1420070400000), SnowflakeUtilities.FromSnowflake(0));
Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1439474045698), SnowflakeUtilities.FromSnowflake(81384788765712384));
}

[Fact]
public void ToSnowflake()
{
Assert.Equal(0UL, SnowflakeUtilities.ToSnowflake(DateTimeOffset.FromUnixTimeMilliseconds(1420070400000)));
Assert.Equal(81384788765704192UL, SnowflakeUtilities.ToSnowflake(DateTimeOffset.FromUnixTimeMilliseconds(1439474045698)));
}
}
}

Loading…
Cancel
Save