-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWebRPC.cs
More file actions
191 lines (169 loc) · 7.05 KB
/
WebRPC.cs
File metadata and controls
191 lines (169 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
using DiscordRPC.Exceptions;
using DiscordRPC.RPC;
using DiscordRPC.RPC.Commands;
using DiscordRPC.RPC.Payload;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
#if INCLUDE_WEB_RPC
namespace DiscordRPC.Web
{
/// <summary>
/// Handles HTTP Rich Presence Requests
/// </summary>
[System.Obsolete("Rich Presence over HTTP is no longer supported by Discord. See offical Rich Presence github for more information.")]
public static class WebRPC
{
/// <summary>
/// Sets the Rich Presence over the HTTP protocol. Does not support Join / Spectate and by default is blocking.
/// </summary>
/// <param name="presence">The presence to send to discord</param>
/// <param name="applicationID">The ID of the application</param>
/// <param name="port">The port the discord client is currently on. Specify this for testing. Will start scanning from supplied port.</param>
/// <returns>Returns the rich presence result from the server. This can be null if presence was set to be null, or if there was no valid response from the client.</returns>
[System.Obsolete("Setting Rich Presence over HTTP is no longer supported by Discord. See offical Rich Presence github for more information.")]
public static RichPresence SetRichPresence(RichPresence presence, string applicationID, int port = 6463)
{
try
{
RichPresence response;
if (TrySetRichPresence(presence, out response, applicationID, port))
return response;
return null;
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Attempts to set the Rich Presence over the HTTP protocol. Does not support Join / Specate and by default is blocking.
/// </summary>
/// <param name="presence">The presence to send to discord</param>
/// <param name="response">The response object from the client</param>
/// <param name="applicationID">The ID of the application</param>
/// <param name="port">The port the discord client is currently on. Specify this for testing. Will start scanning from supplied port.</param>
/// <returns>True if the response was valid from the server, otherwise false.</returns>
[System.Obsolete("Setting Rich Presence over HTTP is no longer supported by Discord. See offical Rich Presence github for more information.")]
public static bool TrySetRichPresence(RichPresence presence, out RichPresence response, string applicationID, int port = 6463)
{
//Validate the presence
if (presence != null)
{
//Send valid presence
//Validate the presence with our settings
if (presence.HasSecrets())
throw new BadPresenceException("Cannot send a presence with secrets as HTTP endpoint does not suppport events.");
if (presence.HasParty() && presence.Party.Max < presence.Party.Size)
throw new BadPresenceException("Presence maximum party size cannot be smaller than the current size.");
}
//Iterate over the ports until the first succesfull one
for (int p = port; p < 6472; p++)
{
//Prepare the url and json
using (WebClient client = new WebClient())
{
try
{
WebRequest request = PrepareRequest(presence, applicationID, p);
client.Headers.Add("content-type", "application/json");
var result = client.UploadString(request.URL, request.Data);
if (TryParseResponse(result, out response))
return true;
}
catch (Exception)
{
//Something went wrong, but we are just going to ignore it and try the next port.
}
}
}
//we failed, return null
response = null;
return false;
}
/// <summary>
/// Attempts to parse the response of a Web Request to a rich presence
/// </summary>
/// <param name="json">The json data received by the client</param>
/// <param name="response">The parsed rich presence</param>
/// <returns>True if the parse was succesfull</returns>
public static bool TryParseResponse(string json, out RichPresence response)
{
try
{
//Try to parse the JSON into a event
EventPayload ev = JsonConvert.DeserializeObject<EventPayload>(json);
//We have a result, so parse the rich presence response and return it.
if (ev != null)
{
//Parse the response into a rich presence response
response = ev.GetObject<RichPresenceResponse>();
return true;
}
}catch(Exception) { }
//We failed.
response = null;
return false;
}
/// <summary>
/// Prepares a struct containing data requried to make a succesful web client request to set the rich presence.
/// </summary>
/// <param name="presence">The rich presence to set.</param>
/// <param name="applicationID">The ID of the application the presence belongs too.</param>
/// <param name="port">The port the client is located on. The default port for the discord client is 6463, but it may move iteratively upto 6473 if the ports are unavailable.</param>
/// <returns>Returns a web request containing nessary data to make a POST request</returns>
[System.Obsolete("WebRequests are no longer supported because of the removed HTTP functionality by Discord. See offical Rich Presence github for more information.")]
public static WebRequest PrepareRequest(RichPresence presence, string applicationID, int port = 6463)
{
//Validate the presence
if (presence != null)
{
//Send valid presence
//Validate the presence with our settings
if (presence.HasSecrets())
throw new BadPresenceException("Cannot send a presence with secrets as HTTP endpoint does not suppport events.");
if (presence.HasParty() && presence.Party.Max < presence.Party.Size)
throw new BadPresenceException("Presence maximum party size cannot be smaller than the current size.");
}
//Prepare some params
int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
//Prepare the payload
PresenceCommand command = new PresenceCommand() { PID = pid, Presence = presence };
var payload = command.PreparePayload(DateTime.UtcNow.ToFileTime());
string json = JsonConvert.SerializeObject(payload);
string url = "http://127.0.0.1:" + port + "/rpc?v=" + RpcConnection.VERSION + "&client_id=" + applicationID;
return new WebRequest(url, json);
}
}
/// <summary>
/// Details of a HTTP Post request that will set the rich presence.
/// </summary>
[System.Obsolete("Web Requests is no longer supported as Discord removed HTTP Rich Presence support. See offical Rich Presence github for more information.")]
public struct WebRequest
{
private string _url;
private string _json;
private Dictionary<string, string> _headers;
/// <summary>
/// The URL to send the POST request too
/// </summary>
public string URL { get { return _url; } }
/// <summary>
/// The JSON formatted body to send with the POST request
/// </summary>
public string Data { get { return _json; } }
/// <summary>
/// The headers to send with the body
/// </summary>
public Dictionary<string, string> Headers { get { return _headers; } }
internal WebRequest(string url, string json)
{
_url = url;
_json = json;
_headers = new Dictionary<string, string>();
_headers.Add("content-type", "application/json");
}
}
}
#endif