Refactor Games, support reading Rich Presences (#877)

* Add API-level support for Rich Presences

* Add library-level support for Game presences

* Add model conversions for outgoing+incoming rich presences

* Refactored Game into Activities

* Integrated Activities with user entities

rebase hell from 5f3cb947a92f4fd01cc4df47ca548180036b47f3

* Fix JSON converters for Activities

* Finish rebase, activity should be set on BaseSocketClient

* Use ApplicationId to define a rich presence

* Added SetActivityAsync to Base and Sharded Socket clients

* Remove public parameterless Game constructor

* Remove GameAssets, refactored to GameAsset

* Hide constructors for types that should be read-only

* Revert changes to Discord.Net.sln

got damned visual studio caching

* Refactor GameParty to use dedicated current/capacity values

Per feedback from @khionu
This commit is contained in:
Christopher F
2017-12-23 14:58:35 -05:00
committed by GitHub
parent 678a7238e6
commit 34b4e5a6d2
28 changed files with 376 additions and 58 deletions

View File

@@ -22,6 +22,12 @@ namespace Discord
public static string GetEmojiUrl(ulong emojiId)
=> $"{DiscordConfig.CDNUrl}emojis/{emojiId}.png";
public static string GetRichAssetUrl(ulong appId, string assetId, ushort size, ImageFormat format)
{
string extension = FormatToExtension(format, "");
return $"{DiscordConfig.CDNUrl}app-assets/{appId}/{assetId}.{extension}?size={size}";
}
private static string FormatToExtension(ImageFormat format, string imageId)
{
if (format == ImageFormat.Auto)

View File

@@ -0,0 +1,19 @@
using System.Diagnostics;
namespace Discord
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class Game : IActivity
{
public string Name { get; internal set; }
internal Game() { }
public Game(string name)
{
Name = name;
}
public override string ToString() => Name;
private string DebuggerDisplay => Name;
}
}

View File

@@ -0,0 +1,15 @@
namespace Discord
{
public class GameAsset
{
internal GameAsset() { }
internal ulong ApplicationId { get; set; }
public string Text { get; internal set; }
public string ImageId { get; internal set; }
public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetRichAssetUrl(ApplicationId, ImageId, size, format);
}
}

View File

@@ -0,0 +1,11 @@
namespace Discord
{
public class GameParty
{
internal GameParty() { }
public string Id { get; internal set; }
public int Members { get; internal set; }
public int Capacity { get; internal set; }
}
}

View File

@@ -0,0 +1,16 @@
namespace Discord
{
public class GameSecrets
{
public string Match { get; }
public string Join { get; }
public string Spectate { get; }
internal GameSecrets(string match, string join, string spectate)
{
Match = match;
Join = join;
Spectate = spectate;
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace Discord
{
public class GameTimestamps
{
public DateTimeOffset? Start { get; }
public DateTimeOffset? End { get; }
internal GameTimestamps(DateTimeOffset? start, DateTimeOffset? end)
{
Start = start;
End = end;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Discord
{
public interface IActivity
{
string Name { get; }
}
}

View File

@@ -0,0 +1,22 @@
using System.Diagnostics;
namespace Discord
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RichGame : Game
{
internal RichGame() { }
public string Details { get; internal set;}
public string State { get; internal set;}
public ulong ApplicationId { get; internal set; }
public GameAsset SmallAsset { get; internal set; }
public GameAsset LargeAsset { get; internal set; }
public GameParty Party { get; internal set; }
public GameSecrets Secrets { get; internal set; }
public GameTimestamps Timestamps { get; internal set; }
public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} (Rich)";
}
}

View File

@@ -0,0 +1,21 @@
using System.Diagnostics;
namespace Discord
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class StreamingGame : Game
{
public string Url { get; internal set; }
public StreamType StreamType { get; internal set; }
public StreamingGame(string name, string url, StreamType streamType)
{
Name = name;
Url = url;
StreamType = streamType;
}
public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Url})";
}
}

View File

@@ -1,24 +0,0 @@
using System.Diagnostics;
namespace Discord
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public struct Game
{
public string Name { get; }
public string StreamUrl { get; }
public StreamType StreamType { get; }
public Game(string name, string streamUrl, StreamType type)
{
Name = name;
StreamUrl = streamUrl;
StreamType = type;
}
private Game(string name)
: this(name, null, StreamType.NotStreaming) { }
public override string ToString() => Name;
private string DebuggerDisplay => StreamUrl != null ? $"{Name} ({StreamUrl})" : Name;
}
}

View File

@@ -2,8 +2,8 @@
{
public interface IPresence
{
/// <summary> Gets the game this user is currently playing, if any. </summary>
Game? Game { get; }
/// <summary> Gets the activity this user is currently doing. </summary>
IActivity Activity { get; }
/// <summary> Gets the current status of this user. </summary>
UserStatus Status { get; }
}