@@ -30,6 +30,26 @@ public string State
3030
3131 /// <summary>Inernal inner state string</summary>
3232 protected internal string _state ;
33+
34+ /// <summary>
35+ /// URL that is linked to when clicking on the details text in the activity card.
36+ /// <para>Max 256 characters</para>
37+ /// </summary>
38+ [ JsonProperty ( "state_url" , NullValueHandling = NullValueHandling . Ignore ) ]
39+ public string StateUrl
40+ {
41+ get { return _stateUrl ; }
42+ set
43+ {
44+ if ( ! ValidateString ( value , out _stateUrl , false , 256 ) )
45+ throw new StringOutOfRangeException ( 256 ) ;
46+
47+ if ( ! ValidateUrl ( _stateUrl ) )
48+ throw new ArgumentException ( "Url must be a valid URI" ) ;
49+ }
50+ }
51+ /// <summary>Inernal inner state URL string</summary>
52+ protected internal string _stateUrl ;
3353
3454 /// <summary>
3555 /// What the user is currently doing. For example, "Competitive - Total Mayhem".
@@ -47,6 +67,26 @@ public string Details
4767 }
4868 /// <summary>Inernal inner detail string</summary>
4969 protected internal string _details ;
70+
71+ /// <summary>
72+ /// URL that is linked to when clicking on the details text in the activity card.
73+ /// <para>Max 256 characters</para>
74+ /// </summary>
75+ [ JsonProperty ( "details_url" , NullValueHandling = NullValueHandling . Ignore ) ]
76+ public string DetailsUrl
77+ {
78+ get { return _detailsUrl ; }
79+ set
80+ {
81+ if ( ! ValidateString ( value , out _detailsUrl , false , 256 ) )
82+ throw new StringOutOfRangeException ( 256 ) ;
83+
84+ if ( ! ValidateUrl ( _detailsUrl ) )
85+ throw new ArgumentException ( "Url must be a valid URI" ) ;
86+ }
87+ }
88+ /// <summary>Inernal inner detail URL string</summary>
89+ protected internal string _detailsUrl ;
5090
5191 /// <summary>
5292 /// The time elapsed / remaining time data.
@@ -163,6 +203,23 @@ internal static bool ValidateString(string str, out string result, bool useBytes
163203 result = s . GetNullOrString ( ) ;
164204 return true ;
165205 }
206+
207+ /// <summary>
208+ /// Validates URLs.
209+ /// </summary>
210+ /// <param name="url">The URL to check</param>
211+ /// <returns>True if the URL is valid</returns>
212+ internal static bool ValidateUrl ( string url )
213+ {
214+ if ( string . IsNullOrEmpty ( url ) )
215+ return true ;
216+
217+ //Check if the URL is valid
218+ if ( ! Uri . TryCreate ( url , UriKind . Absolute , out _ ) )
219+ return false ;
220+
221+ return true ;
222+ }
166223
167224 /// <summary>
168225 /// Operator that converts a presence into a boolean for null checks.
@@ -184,7 +241,11 @@ internal virtual bool Matches(RichPresence other)
184241 if ( other == null )
185242 return false ;
186243
187- if ( State != other . State || Details != other . Details || Type != other . Type )
244+ if ( State != other . State ||
245+ StateUrl != other . StateUrl ||
246+ Details != other . Details ||
247+ DetailsUrl != other . DetailsUrl ||
248+ Type != other . Type )
188249 return false ;
189250
190251 //Checks if the timestamps are different
@@ -235,8 +296,10 @@ internal virtual bool Matches(RichPresence other)
235296 if ( other . Assets == null ||
236297 other . Assets . LargeImageKey != Assets . LargeImageKey ||
237298 other . Assets . LargeImageText != Assets . LargeImageText ||
299+ other . Assets . LargeImageUrl != Assets . LargeImageUrl ||
238300 other . Assets . SmallImageKey != Assets . SmallImageKey ||
239- other . Assets . SmallImageText != Assets . SmallImageText )
301+ other . Assets . SmallImageText != Assets . SmallImageText ||
302+ other . Assets . SmallImageUrl != Assets . SmallImageUrl )
240303 return false ;
241304 }
242305 else if ( other . Assets != null )
@@ -256,7 +319,9 @@ public RichPresence ToRichPresence()
256319 {
257320 var presence = new RichPresence ( ) ;
258321 presence . State = State ;
322+ presence . StateUrl = StateUrl ;
259323 presence . Details = Details ;
324+ presence . DetailsUrl = DetailsUrl ;
260325 presence . Type = Type ;
261326 presence . StatusDisplay = StatusDisplay ;
262327
@@ -269,9 +334,11 @@ public RichPresence ToRichPresence()
269334 {
270335 SmallImageKey = Assets . SmallImageKey ,
271336 SmallImageText = Assets . SmallImageText ,
337+ SmallImageUrl = Assets . SmallImageUrl ,
272338
273339 LargeImageKey = Assets . LargeImageKey ,
274- LargeImageText = Assets . LargeImageText
340+ LargeImageText = Assets . LargeImageText ,
341+ LargeImageUrl = Assets . LargeImageUrl
275342 } ;
276343 }
277344
@@ -453,7 +520,25 @@ public string LargeImageText
453520 }
454521 }
455522 private string _largeimagetext ;
456-
523+
524+ /// <summary>
525+ /// URL that is linked to when clicking on the large image in the activity card.
526+ /// <para>Max 256 characters.</para>
527+ /// </summary>
528+ [ JsonProperty ( "large_url" , NullValueHandling = NullValueHandling . Ignore ) ]
529+ public string LargeImageUrl
530+ {
531+ get { return _largeimageurl ; }
532+ set
533+ {
534+ if ( ! BaseRichPresence . ValidateString ( value , out _largeimageurl , false , 256 ) )
535+ throw new StringOutOfRangeException ( 256 ) ;
536+
537+ if ( ! BaseRichPresence . ValidateUrl ( _largeimageurl ) )
538+ throw new ArgumentException ( "Url must be a valid URI" ) ;
539+ }
540+ }
541+ private string _largeimageurl ;
457542
458543 /// <summary>
459544 /// Name of the uploaded image for the small profile artwork.
@@ -503,6 +588,25 @@ public string SmallImageText
503588 }
504589 }
505590 private string _smallimagetext ;
591+
592+ /// <summary>
593+ /// URL that is linked to when clicking on the small image in the activity card.
594+ /// <para>Max 256 characters.</para>
595+ /// </summary>
596+ [ JsonProperty ( "small_url" , NullValueHandling = NullValueHandling . Ignore ) ]
597+ public string SmallImageUrl
598+ {
599+ get { return _smallimageurl ; }
600+ set
601+ {
602+ if ( ! BaseRichPresence . ValidateString ( value , out _smallimageurl , false , 256 ) )
603+ throw new StringOutOfRangeException ( 256 ) ;
604+
605+ if ( ! BaseRichPresence . ValidateUrl ( _smallimageurl ) )
606+ throw new ArgumentException ( "Url must be a valid URI" ) ;
607+ }
608+ }
609+ private string _smallimageurl ;
506610
507611 /// <summary>
508612 /// The ID of the large image. This is only set after Update Presence and will automatically become null when <see cref="LargeImageKey"/> is changed.
@@ -526,7 +630,9 @@ internal void Merge(Assets other)
526630 {
527631 //Copy over the names
528632 _smallimagetext = other . _smallimagetext ;
633+ _smallimageurl = other . _smallimageurl ;
529634 _largeimagetext = other . _largeimagetext ;
635+ _largeimageurl = other . _largeimageurl ;
530636
531637 //Convert large ID
532638 ulong largeID ;
@@ -796,7 +902,7 @@ public string Url
796902 if ( ! BaseRichPresence . ValidateString ( value , out _url , false , 512 ) )
797903 throw new StringOutOfRangeException ( 512 ) ;
798904
799- if ( ! Uri . TryCreate ( _url , UriKind . Absolute , out var uriResult ) ) // || !(uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps ))
905+ if ( ! BaseRichPresence . ValidateUrl ( _url ) )
800906 throw new ArgumentException ( "Url must be a valid URI" ) ;
801907 }
802908 }
@@ -880,6 +986,17 @@ public RichPresence WithState(string state)
880986 State = state ;
881987 return this ;
882988 }
989+
990+ /// <summary>
991+ /// Sets the state URL of the Rich Presence. See also <seealso cref="BaseRichPresence.StateUrl"/>.
992+ /// </summary>
993+ /// <param name="stateUrl">State URL when clicking on the state text.</param>
994+ /// <returns>The modified Rich Presence.</returns>
995+ public RichPresence WithStateUrl ( string stateUrl )
996+ {
997+ StateUrl = stateUrl ;
998+ return this ;
999+ }
8831000
8841001 /// <summary>
8851002 /// Sets the details of the Rich Presence. See also <seealso cref="BaseRichPresence.Details"/>.
@@ -891,6 +1008,17 @@ public RichPresence WithDetails(string details)
8911008 Details = details ;
8921009 return this ;
8931010 }
1011+
1012+ /// <summary>
1013+ /// Sets the details URL of the Rich Presence. See also <seealso cref="BaseRichPresence.DetailsUrl"/>.
1014+ /// </summary>
1015+ /// <param name="detailsUrl">Details URL when clicking on the details text.</param>
1016+ /// <returns>The modified Rich Presence.</returns>
1017+ public RichPresence WithDetailsUrl ( string detailsUrl )
1018+ {
1019+ DetailsUrl = detailsUrl ;
1020+ return this ;
1021+ }
8941022
8951023 /// <summary>
8961024 /// Sets the type of the Rich Presence. See also <seealso cref="ActivityType"/>.
@@ -970,7 +1098,9 @@ public RichPresence Clone()
9701098 return new RichPresence
9711099 {
9721100 State = this . _state != null ? _state . Clone ( ) as string : null ,
1101+ StateUrl = this . _stateUrl != null ? _stateUrl . Clone ( ) as string : null ,
9731102 Details = this . _details != null ? _details . Clone ( ) as string : null ,
1103+ DetailsUrl = this . _detailsUrl != null ? _detailsUrl . Clone ( ) as string : null ,
9741104 Type = this . Type ,
9751105 StatusDisplay = this . StatusDisplay ,
9761106
@@ -992,8 +1122,10 @@ public RichPresence Clone()
9921122 {
9931123 LargeImageKey = this . Assets . LargeImageKey != null ? this . Assets . LargeImageKey . Clone ( ) as string : null ,
9941124 LargeImageText = this . Assets . LargeImageText != null ? this . Assets . LargeImageText . Clone ( ) as string : null ,
1125+ LargeImageUrl = this . Assets . LargeImageUrl != null ? this . Assets . LargeImageUrl . Clone ( ) as string : null ,
9951126 SmallImageKey = this . Assets . SmallImageKey != null ? this . Assets . SmallImageKey . Clone ( ) as string : null ,
996- SmallImageText = this . Assets . SmallImageText != null ? this . Assets . SmallImageText . Clone ( ) as string : null
1127+ SmallImageText = this . Assets . SmallImageText != null ? this . Assets . SmallImageText . Clone ( ) as string : null ,
1128+ SmallImageUrl = this . Assets . SmallImageUrl != null ? this . Assets . SmallImageUrl . Clone ( ) as string : null ,
9971129 } ,
9981130
9991131 Party = ! HasParty ( ) ? null : new Party
@@ -1014,7 +1146,9 @@ public RichPresence Clone()
10141146 internal RichPresence Merge ( BaseRichPresence presence )
10151147 {
10161148 this . _state = presence . State ;
1149+ this . _stateUrl = presence . StateUrl ;
10171150 this . _details = presence . Details ;
1151+ this . _detailsUrl = presence . DetailsUrl ;
10181152 this . Type = presence . Type ;
10191153 this . StatusDisplay = presence . StatusDisplay ;
10201154 this . Party = presence . Party ;
0 commit comments