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
{
///
/// Handles HTTP Rich Presence Requests
///
[System.Obsolete("Rich Presence over HTTP is no longer supported by Discord. See offical Rich Presence github for more information.")]
public static class WebRPC
{
///
/// Sets the Rich Presence over the HTTP protocol. Does not support Join / Spectate and by default is blocking.
///
/// The presence to send to discord
/// The ID of the application
/// The port the discord client is currently on. Specify this for testing. Will start scanning from supplied port.
/// 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.
[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;
}
}
///
/// Attempts to set the Rich Presence over the HTTP protocol. Does not support Join / Specate and by default is blocking.
///
/// The presence to send to discord
/// The response object from the client
/// The ID of the application
/// The port the discord client is currently on. Specify this for testing. Will start scanning from supplied port.
/// True if the response was valid from the server, otherwise false.
[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;
}
///
/// Attempts to parse the response of a Web Request to a rich presence
///
/// The json data received by the client
/// The parsed rich presence
/// True if the parse was succesfull
public static bool TryParseResponse(string json, out RichPresence response)
{
try
{
//Try to parse the JSON into a event
EventPayload ev = JsonConvert.DeserializeObject(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();
return true;
}
}catch(Exception) { }
//We failed.
response = null;
return false;
}
///
/// Prepares a struct containing data requried to make a succesful web client request to set the rich presence.
///
/// The rich presence to set.
/// The ID of the application the presence belongs too.
/// 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.
/// Returns a web request containing nessary data to make a POST request
[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);
}
}
///
/// Details of a HTTP Post request that will set the rich presence.
///
[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 _headers;
///
/// The URL to send the POST request too
///
public string URL { get { return _url; } }
///
/// The JSON formatted body to send with the POST request
///
public string Data { get { return _json; } }
///
/// The headers to send with the body
///
public Dictionary Headers { get { return _headers; } }
internal WebRequest(string url, string json)
{
_url = url;
_json = json;
_headers = new Dictionary();
_headers.Add("content-type", "application/json");
}
}
}
#endif