Skip to content

Commit 0ec0da0

Browse files
committed
Made spectating obsolete
1 parent 5a8080f commit 0ec0da0

File tree

9 files changed

+126
-82
lines changed

9 files changed

+126
-82
lines changed

DiscordRPC/DiscordRpcClient.cs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ namespace DiscordRPC
1212
{
1313

1414
/// <summary>
15-
/// A Discord RPC Client which is used to send Rich Presence updates and receive Join / Spectate events.
15+
/// A Discord RPC Client which is used to send Rich Presence updates and receive Join events.
1616
/// </summary>
1717
public sealed class DiscordRpcClient : IDisposable
1818
{
1919
#region Properties
2020

2121

2222
/// <summary>
23-
/// Gets a value indicating if the client has registered a URI Scheme. If this is false, Join / Spectate events will fail.
23+
/// Gets a value indicating if the client has registered a URI Scheme. If this is false, Join events will fail.
2424
/// <para>To register a URI Scheme, call <see cref="RegisterUriScheme(string, string)"/>.</para>
2525
/// </summary>
2626
public bool HasRegisteredUriScheme { get; private set; }
@@ -172,6 +172,7 @@ public bool ShutdownOnly
172172
/// Called when the Discord Client wishes for this process to spectate a game.
173173
/// <para>If <see cref="AutoEvents"/> is true then this event will execute on a different thread. If it is not true however, then this event is not invoked untill <see cref="Invoke"/> and will be on the calling thread.</para>
174174
/// </summary>
175+
[System.Obsolete("Spectating is no longer supported by Discord.")]
175176
public event OnSpectateEvent OnSpectate;
176177

177178
/// <summary>
@@ -201,13 +202,13 @@ public bool ShutdownOnly
201202
#region Initialization
202203

203204
/// <summary>
204-
/// Creates a new Discord RPC Client which can be used to send Rich Presence and receive Join / Spectate events.
205+
/// Creates a new Discord RPC Client which can be used to send Rich Presence and receive Join events.
205206
/// </summary>
206207
/// <param name="applicationID">The ID of the application created at discord's developers portal.</param>
207208
public DiscordRpcClient(string applicationID) : this(applicationID, -1) { }
208209

209210
/// <summary>
210-
/// Creates a new Discord RPC Client which can be used to send Rich Presence and receive Join / Spectate events. This constructor exposes more advance features such as custom NamedPipeClients and Loggers.
211+
/// Creates a new Discord RPC Client which can be used to send Rich Presence and receive Join events. This constructor exposes more advance features such as custom NamedPipeClients and Loggers.
211212
/// </summary>
212213
/// <param name="applicationID">The ID of the application created at discord's developers portal.</param>
213214
/// <param name="pipe">The pipe to connect too. If -1, then the client will scan for the first available instance of Discord.</param>
@@ -420,6 +421,24 @@ private void ProcessMessage(IMessage message)
420421
/// <param name="request">The request that is being responded too.</param>
421422
/// <param name="acceptRequest">Accept the join request.</param>
422423
public void Respond(JoinRequestMessage request, bool acceptRequest)
424+
=> Respond(request.User.ID, acceptRequest);
425+
426+
/// <summary>
427+
/// Respond to a Join Request. All requests will timeout after 30 seconds.
428+
/// <para>Because of the 30 second timeout, it is recommended to call <seealso cref="Invoke"/> faster than every 15 seconds to give your users adequate time to respond to the request.</para>
429+
/// </summary>
430+
/// <param name="user">The user to respond to.</param>
431+
/// <param name="acceptRequest">Accept the join request.</param>
432+
public void Respond(User user, bool acceptRequest)
433+
=> Respond(user.ID, acceptRequest);
434+
435+
/// <summary>
436+
/// Respond to a Join Request. All requests will timeout after 30 seconds.
437+
/// <para>Because of the 30 second timeout, it is recommended to call <seealso cref="Invoke"/> faster than every 15 seconds to give your users adequate time to respond to the request.</para>
438+
/// </summary>
439+
/// <param name="userID">The ID of the user to respond to.</param>
440+
/// <param name="acceptRequest">Accept the join request.</param>
441+
public void Respond(ulong userID, bool acceptRequest)
423442
{
424443
if (IsDisposed)
425444
throw new ObjectDisposedException("Discord IPC Client");
@@ -430,7 +449,11 @@ public void Respond(JoinRequestMessage request, bool acceptRequest)
430449
if (!IsInitialized)
431450
throw new UninitializedException();
432451

433-
connection.EnqueueCommand(new RespondCommand() { Accept = acceptRequest, UserID = request.User.ID.ToString() });
452+
connection.EnqueueCommand(new RespondCommand()
453+
{
454+
Accept = acceptRequest,
455+
UserID = userID.ToString()
456+
});
434457
}
435458

436459
/// <summary>
@@ -692,7 +715,7 @@ public void ClearPresence()
692715

693716
/// <summary>
694717
/// Registers the application executable to a custom URI Scheme.
695-
/// <para>This is required for the Join and Spectate features. Discord will run this custom URI Scheme to launch your application when a user presses either of the buttons.</para>
718+
/// <para>This is required for the Join feature. Discord will run this custom URI Scheme to launch your application when a user presses either of the buttons.</para>
696719
/// </summary>
697720
/// <param name="steamAppID">Optional Steam ID. If supplied, Discord will launch the game through steam instead of directly calling it.</param>
698721
/// <param name="executable">The path to the executable. If null, the path to the current executable will be used instead.</param>
@@ -710,14 +733,14 @@ public bool RegisterUriScheme(string steamAppID = null, string executable = null
710733
}
711734

712735
/// <summary>
713-
/// Subscribes to an event sent from discord. Used for Join / Spectate feature.
736+
/// Subscribes to an event sent from discord. Used for Join feature.
714737
/// <para>Requires the UriScheme to be registered.</para>
715738
/// </summary>
716739
/// <param name="type">The event type to subscribe to</param>
717740
public void Subscribe(EventType type) { SetSubscription(Subscription | type); }
718741

719742
/// <summary>
720-
/// Unsubscribe from the event sent by discord. Used for Join / Spectate feature.
743+
/// Unsubscribe from the event sent by discord. Used for Join feature.
721744
/// <para>Requires the UriScheme to be registered.</para>
722745
/// </summary>
723746
/// <param name="type">The event type to unsubscribe from</param>
@@ -773,8 +796,10 @@ private void SubscribeToTypes(EventType type, bool isUnsubscribe)
773796
throw new InvalidConfigurationException("Cannot subscribe/unsubscribe to an event as this application has not registered a URI Scheme. Call RegisterUriScheme().");
774797

775798
//Add the subscribe command to be sent when the connection is able too
799+
#pragma warning disable CS0618 // Type or member is obsolete
776800
if ((type & EventType.Spectate) == EventType.Spectate)
777801
connection.EnqueueCommand(new SubscribeCommand() { Event = RPC.Payload.ServerEvent.ActivitySpectate, IsUnsubscribe = isUnsubscribe });
802+
#pragma warning restore CS0618 // Type or member is obsolete
778803

779804
if ((type & EventType.Join) == EventType.Join)
780805
connection.EnqueueCommand(new SubscribeCommand() { Event = RPC.Payload.ServerEvent.ActivityJoin, IsUnsubscribe = isUnsubscribe });

DiscordRPC/Entities/RichPresence.cs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public string State
3030

3131
/// <summary>Inernal inner state string</summary>
3232
protected internal string _state;
33-
33+
3434
/// <summary>
3535
/// URL that is linked to when clicking on the details text in the activity card.
3636
/// <para>Max 256 characters</para>
@@ -67,7 +67,7 @@ public string Details
6767
}
6868
/// <summary>Inernal inner detail string</summary>
6969
protected internal string _details;
70-
70+
7171
/// <summary>
7272
/// URL that is linked to when clicking on the details text in the activity card.
7373
/// <para>Max 256 characters</para>
@@ -107,7 +107,7 @@ public string DetailsUrl
107107
public Party Party { get; set; }
108108

109109
/// <summary>
110-
/// The secrets used for Join / Spectate. Secrets are obfuscated data of your choosing. They could be match ids, player ids, lobby ids, etc. Make this object null if you do not wish too / unable too implement the Join / Request feature.
110+
/// The secrets used for Joining. Secrets are obfuscated data of your choosing. They could be match ids, player ids, lobby ids, etc. Make this object null if you do not wish too / unable too implement the Join / Request feature.
111111
/// <para>To keep security on the up and up, Discord requires that you properly hash/encode/encrypt/put-a-padlock-on-and-swallow-the-key-but-wait-then-how-would-you-open-it your secrets.</para>
112112
/// <para>Visit the <see href="https://discordapp.com/developers/docs/rich-presence/how-to#secrets">Rich Presence How-To</see> for more information.</para>
113113
/// </summary>
@@ -119,7 +119,7 @@ public string DetailsUrl
119119
/// </summary>
120120
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
121121
public ActivityType Type { get; set; }
122-
122+
123123
/// <summary>
124124
/// The display type for the status
125125
/// </summary>
@@ -160,7 +160,9 @@ public bool HasParty()
160160
/// <returns></returns>
161161
public bool HasSecrets()
162162
{
163-
return Secrets != null && (Secrets.JoinSecret != null || Secrets.SpectateSecret != null);
163+
#pragma warning disable CS0618 // Type or member is obsolete
164+
return Secrets != null && (Secrets.Join != null || Secrets.SpectateSecret != null);
165+
#pragma warning restore CS0618 // Type or member is obsolete
164166
}
165167

166168
#endregion
@@ -191,7 +193,7 @@ internal static bool ValidateString(string str, out string result, bool useBytes
191193
result = s.GetNullOrString();
192194
return true;
193195
}
194-
196+
195197
/// <summary>
196198
/// Validates URLs.
197199
/// </summary>
@@ -251,10 +253,12 @@ internal virtual bool Matches(RichPresence other)
251253
//Checks if the secrets are different
252254
if (Secrets != null)
253255
{
256+
#pragma warning disable CS0618 // Type or member is obsolete
254257
if (other.Secrets == null ||
255-
other.Secrets.JoinSecret != Secrets.JoinSecret ||
258+
other.Secrets.Join != Secrets.Join ||
256259
other.Secrets.SpectateSecret != Secrets.SpectateSecret)
257260
return false;
261+
#pragma warning restore CS0618 // Type or member is obsolete
258262
}
259263
else if (other.Secrets != null)
260264
{
@@ -372,7 +376,7 @@ public RichPresence WithState(string state)
372376
State = state;
373377
return this;
374378
}
375-
379+
376380
/// <summary>
377381
/// Sets the state URL of the Rich Presence. See also <seealso cref="BaseRichPresence.StateUrl"/>.
378382
/// </summary>
@@ -394,7 +398,7 @@ public RichPresence WithDetails(string details)
394398
Details = details;
395399
return this;
396400
}
397-
401+
398402
/// <summary>
399403
/// Sets the details URL of the Rich Presence. See also <seealso cref="BaseRichPresence.DetailsUrl"/>.
400404
/// </summary>
@@ -463,21 +467,21 @@ public RichPresence WithParty(Party party)
463467
/// <summary>
464468
/// Sets the Rich Presence's secrets. See also <seealso cref="Secrets"/>.
465469
/// </summary>
466-
/// <param name="secrets">The secrets used for Join / Spectate.</param>
470+
/// <param name="secrets">The secrets used for Joining.</param>
467471
/// <returns>The modified Rich Presence.</returns>
468472
public RichPresence WithSecrets(Secrets secrets)
469473
{
470474
Secrets = secrets;
471475
return this;
472476
}
473477

474-
/// <summary>
475-
/// Sets the Rich Presence's buttons.
476-
/// </summary>
477-
/// <param name="topButton">The top button to display</param>
478-
/// <param name="bottomButton">The optional bottom button to display</param>
479-
/// <returns>The modified Rich Presence.</returns>
480-
public RichPresence WithButtons(Button topButton, Button bottomButton = null)
478+
/// <summary>
479+
/// Sets the Rich Presence's buttons.
480+
/// </summary>
481+
/// <param name="topButton">The top button to display</param>
482+
/// <param name="bottomButton">The optional bottom button to display</param>
483+
/// <returns>The modified Rich Presence.</returns>
484+
public RichPresence WithButtons(Button topButton, Button bottomButton = null)
481485
{
482486
if (topButton != null && bottomButton != null)
483487
{
@@ -486,9 +490,9 @@ public RichPresence WithButtons(Button topButton, Button bottomButton = null)
486490
else if (topButton == null && bottomButton == null)
487491
{
488492
Buttons = default;
489-
}
490-
else
491-
{
493+
}
494+
else
495+
{
492496
Buttons = new Button[] { topButton ?? bottomButton };
493497
}
494498

@@ -513,14 +517,16 @@ public RichPresence Clone()
513517
DetailsUrl = this._detailsUrl != null ? _detailsUrl.Clone() as string : null,
514518
Type = this.Type,
515519
StatusDisplay = this.StatusDisplay,
516-
517520
Buttons = !HasButtons() ? null : this.Buttons.Clone() as Button[],
521+
522+
#pragma warning disable CS0618 // Type or member is obsolete
518523
Secrets = !HasSecrets() ? null : new Secrets
519524
{
520525
//MatchSecret = this.Secrets.MatchSecret?.Clone() as string,
521-
JoinSecret = this.Secrets.JoinSecret != null ? this.Secrets.JoinSecret.Clone() as string : null,
526+
Join = this.Secrets.Join != null ? this.Secrets.Join.Clone() as string : null,
522527
SpectateSecret = this.Secrets.SpectateSecret != null ? this.Secrets.SpectateSecret.Clone() as string : null
523528
},
529+
#pragma warning restore CS0618 // Type or member is obsolete
524530

525531
Timestamps = !HasTimestamps() ? null : new Timestamps
526532
{

DiscordRPC/Entities/Secrets.cs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
namespace DiscordRPC
77
{
88
/// <summary>
9-
/// The secrets used for Join / Spectate. Secrets are obfuscated data of your choosing. They could be match ids, player ids, lobby ids, etc.
9+
/// The secrets used for Joining. Secrets are obfuscated data of your choosing. They could be match ids, player ids, lobby ids, etc.
1010
/// <para>To keep security on the up and up, Discord requires that you properly hash/encode/encrypt/put-a-padlock-on-and-swallow-the-key-but-wait-then-how-would-you-open-it your secrets.</para>
11-
/// <para>You should send discord data that someone else's game client would need to join or spectate their friend. If you can't or don't want to support those actions, you don't need to send secrets.</para>
11+
/// <para>You should send discord data that someone else's game client would need to join their friend. If you can't or don't want to support those actions, you don't need to send secrets.</para>
1212
/// <para>Visit the <see href="https://discordapp.com/developers/docs/rich-presence/how-to#secrets">Rich Presence How-To</see> for more information.</para>
1313
/// </summary>
1414
[Serializable]
@@ -20,6 +20,7 @@ public class Secrets
2020
/// <para>Max Length of 128 characters</para>
2121
/// </summary>
2222
[Obsolete("This feature has been deprecated my Mason in issue #152 on the offical library. Was originally used as a Notify Me feature, it has been replaced with Join / Spectate.", true)]
23+
[JsonIgnore]
2324
public string MatchSecret;
2425

2526
/// <summary>
@@ -44,6 +45,7 @@ public string Join
4445
/// <summary>Alias of Join</summary>
4546
/// <remarks>This was made obsolete as the property name contains redundant information.</remarks>
4647
[System.Obsolete("Property name is redundant and replaced with Join.")]
48+
[JsonIgnore]
4749
public string JoinSecret
4850
{
4951
get => Join;
@@ -57,28 +59,9 @@ public string JoinSecret
5759
/// </para>
5860
/// <para>Max Length of 128 characters</para>
5961
/// </summary>
60-
[JsonProperty("spectate", NullValueHandling = NullValueHandling.Ignore)]
61-
public string Spectate
62-
{
63-
get => _spectateSecret;
64-
set
65-
{
66-
if (!BaseRichPresence.ValidateString(value, out _spectateSecret, false, 128))
67-
throw new StringOutOfRangeException(128);
68-
}
69-
}
70-
private string _spectateSecret;
71-
72-
73-
/// <summary>Alias of Spectate</summary>
74-
/// <remarks>This was made obsolete as the property name contains redundant information.</remarks>
75-
[System.Obsolete("Property name is redundant and replaced with Spectate.")]
76-
public string SpectateSecret
77-
{
78-
get => Spectate;
79-
set => Spectate = value;
80-
}
81-
62+
[System.Obsolete("Spectating is no longer supported by Discord.")]
63+
[JsonIgnore]
64+
public string SpectateSecret { get; set; }
8265
#region Statics
8366

8467
/// <summary>
@@ -89,18 +72,22 @@ public string SpectateSecret
8972
/// <summary>
9073
/// The length of a secret in bytes.
9174
/// </summary>
92-
public static int SecretLength => 128;
75+
public const int SecretLength = 128;
9376

9477
/// <summary>
9578
/// Creates a new secret. This is NOT a cryptographic function and should NOT be used for sensitive information. This is mainly provided as a way to generate quick IDs.
9679
/// </summary>
9780
/// <param name="random">The random to use</param>
98-
/// <returns>Returns a <see cref="SecretLength"/> sized string with random characters from <see cref="Encoding"/></returns>
99-
public static string CreateSecret(Random random)
81+
/// <param name="length">The length of the secret to generate. Defaults to <see cref="SecretLength"/>.</param>
82+
/// <returns>Returns a string with random characters from <see cref="Encoding"/></returns>
83+
public static string CreateSecret(Random random, int length = SecretLength)
10084
{
85+
if (length < 1 || length > SecretLength)
86+
throw new ArgumentOutOfRangeException(nameof(length), "Secret length must be between 1 and 128 characters.");
87+
10188
//Prepare an array and fill it with random bytes
10289
// THIS IS NOT SECURE! DO NOT USE THIS FOR PASSWORDS!
103-
byte[] bytes = new byte[SecretLength];
90+
byte[] bytes = new byte[length];
10491
random.NextBytes(bytes);
10592

10693
//Return the encoding. Probably should remove invalid characters but cannot be fucked.
@@ -112,13 +99,18 @@ public static string CreateSecret(Random random)
11299
/// Creates a secret word using more readable friendly characters. Useful for debugging purposes. This is not a cryptographic function and should NOT be used for sensitive information.
113100
/// </summary>
114101
/// <param name="random">The random used to generate the characters</param>
115-
/// <returns></returns>
116-
public static string CreateFriendlySecret(Random random)
102+
/// <param name="length">The length of the secret to generate. Defaults to <see cref="SecretLength"/>.</param>
103+
/// <returns>Returns a string with random alphanumeric characters</returns>
104+
public static string CreateFriendlySecret(Random random, int length = SecretLength)
117105
{
106+
if (length < 1 || length > SecretLength)
107+
throw new ArgumentOutOfRangeException(nameof(length), "Secret length must be between 1 and 128 characters.");
108+
109+
//Characters to use in the secret
118110
string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
119111

120112
StringBuilder builder = new StringBuilder();
121-
for (int i = 0; i < SecretLength; i++)
113+
for (int i = 0; i < length; i++)
122114
builder.Append(charset[random.Next(charset.Length)]);
123115

124116
return builder.ToString();

DiscordRPC/EventType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public enum EventType
1919
/// <summary>
2020
/// Called when the Discord Client wishes to enter a game to spectate
2121
/// </summary>
22-
Spectate = 0x1,
22+
[System.Obsolete("Spectating is no longer supported by Discord.")]
23+
Spectate = 0x1,
2324

2425
/// <summary>
2526
/// Called when the Discord Client wishes to enter a game to play.

DiscordRPC/Events.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ namespace DiscordRPC.Events
6060
/// </summary>
6161
/// <param name="sender">The Discord client handler that sent this event</param>
6262
/// <param name="args">The arguments supplied with the event</param>
63+
[System.Obsolete("Spectating is no longer supported by Discord.")]
6364
public delegate void OnSpectateEvent(object sender, SpectateMessage args);
6465

6566
/// <summary>

0 commit comments

Comments
 (0)