diff --git a/.gitignore b/.gitignore index 9f0c6927..7736c0d3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /_ReSharper.Caches/ /.idea/.idea.ProjectLighthouse/.idea/workspace.xml /.idea/.idea.ProjectLighthouse/.idea/dataSources/ +/.idea/.idea.ProjectLighthouse/.idea/dataSources.xml /.idea/.idea.ProjectLighthouse/.idea/dataSources.local.xml /ProjectLighthouse/ProjectLighthouse.csproj.user *.sln.DotSettings.user diff --git a/.idea/.idea.ProjectLighthouse/.idea/dataSources.xml b/.idea/.idea.ProjectLighthouse/.idea/dataSources.xml deleted file mode 100644 index c8fd1969..00000000 --- a/.idea/.idea.ProjectLighthouse/.idea/dataSources.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - mysql.8 - true - com.mysql.cj.jdbc.NonRegisteringDriver - jdbc:mysql://localhost:3306/lighthouse - $ProjectFileDir$ - - - mariadb - true - org.mariadb.jdbc.Driver - jdbc:mariadb://localhost:3306 - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/Documentation/RPC.md b/Documentation/RPC.md new file mode 100644 index 00000000..6f220c50 --- /dev/null +++ b/Documentation/RPC.md @@ -0,0 +1,38 @@ +# RPC (Rich Presence) + +Lighthouse supports Discord's [Rich Presence](https://discordapp.com/rich-presence) feature, which allows you +to display your current activity in Lighthouse to your Discord friends. + +This can be done by utilizing a pre-existing RPC client, such as [this one](https://github.com/LBPUnion/PLRPC), +or by creating your own. This page will explain how to utilize the `/api/v1/rpc` endpoint to access the +required information. + +## Authentication + +This endpoint does not require any form of authentication and is available to use without restriction, aside +from any server admin imposed rate limiting. + +## Endpoints + +### GET `/api/v1/rpc` + +Returns a JSON object containing the following information: + +- `applicationId`: The ID of the Discord application. +- `partyIdPrefix`: The prefix to use for the party ID. This is used to prevent collisions between + multiple instances of Lighthouse running on the same Discord application. +- `usernameType`: Some compatible APIs require usernames instead of user IDs. A return value of `0` + indicates that usernames should be used, while a return value of `1` indicates that user + IDs should be used. +- `assets`: A JSON object containing the following information: + - `podAsset`: Asset used when in the Pod. + - `moonAsset`: Asset used when creating on the Moon. + - `remoteMoonAsset`: Asset used when creating on a remote Moon. + - `developerAsset`: Asset used when playing a story mode level. + - `developerAdventureAsset`: Asset used when playing an adventure level. + - `dlcAsset`: Asset used when playing a DLC level. + - `fallbackAsset`: Asset used when client can't determine the slot type. + +> **Warning** +> All `assets` properties are nullable and will return `null` if not set in configuration. Be sure to account +> for this when using the returned data. \ No newline at end of file diff --git a/ProjectLighthouse.Servers.API/Controllers/RpcController.cs b/ProjectLighthouse.Servers.API/Controllers/RpcController.cs new file mode 100644 index 00000000..566782d3 --- /dev/null +++ b/ProjectLighthouse.Servers.API/Controllers/RpcController.cs @@ -0,0 +1,18 @@ +using LBPUnion.ProjectLighthouse.Configuration; +using LBPUnion.ProjectLighthouse.Servers.API.Responses; +using Microsoft.AspNetCore.Mvc; + +namespace LBPUnion.ProjectLighthouse.Servers.API.Controllers; + +public class RpcController : ApiEndpointController +{ + /// + /// Returns basic information that Discord RPC clients can use for self-configuration. + /// + /// RpcResponse + /// The RPC configuration. + [HttpGet("rpc")] + [ProducesResponseType(typeof(RpcResponse), StatusCodes.Status200OK)] + public IActionResult GetRpcConfiguration() => + this.Ok(RpcResponse.CreateFromConfiguration(ServerConfiguration.Instance.RichPresenceConfiguration)); +} \ No newline at end of file diff --git a/ProjectLighthouse.Servers.API/Responses/RpcResponse.cs b/ProjectLighthouse.Servers.API/Responses/RpcResponse.cs new file mode 100644 index 00000000..a87a03a5 --- /dev/null +++ b/ProjectLighthouse.Servers.API/Responses/RpcResponse.cs @@ -0,0 +1,33 @@ +#nullable disable + +using LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories; + +namespace LBPUnion.ProjectLighthouse.Servers.API.Responses; + +public class RpcResponse +{ + public string ApplicationId { get; set; } + public string PartyIdPrefix { get; set; } + public UsernameType UsernameType { get; set; } + public RpcAssets Assets { get; set; } + + public static RpcResponse CreateFromConfiguration(RichPresenceConfiguration configuration) => + new() + { + ApplicationId = configuration.ApplicationId, + PartyIdPrefix = configuration.PartyIdPrefix, + UsernameType = configuration.UsernameType, + Assets = new RpcAssets + { + PodAsset = AssetConvertNull(configuration.Assets.PodAsset), + MoonAsset = AssetConvertNull(configuration.Assets.MoonAsset), + RemoteMoonAsset = AssetConvertNull(configuration.Assets.RemoteMoonAsset), + DeveloperAsset = AssetConvertNull(configuration.Assets.DeveloperAsset), + DeveloperAdventureAsset = AssetConvertNull(configuration.Assets.DeveloperAdventureAsset), + DlcAsset = AssetConvertNull(configuration.Assets.DlcAsset), + FallbackAsset = AssetConvertNull(configuration.Assets.FallbackAsset), + }, + }; + + private static string AssetConvertNull(string asset) => string.IsNullOrWhiteSpace(asset) ? null : asset; +} \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/ConfigurationCategories/RichPresenceConfiguration.cs b/ProjectLighthouse/Configuration/ConfigurationCategories/RichPresenceConfiguration.cs new file mode 100644 index 00000000..7a40969d --- /dev/null +++ b/ProjectLighthouse/Configuration/ConfigurationCategories/RichPresenceConfiguration.cs @@ -0,0 +1,31 @@ +using System; + +namespace LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories; + +// ReSharper disable UnusedMember.Global + +[Serializable] +public class RichPresenceConfiguration +{ + public string ApplicationId { get; set; } = "1060973475151495288"; + public string PartyIdPrefix { get; set; } = "project-lighthouse"; + public UsernameType UsernameType { get; set; } = UsernameType.Integer; + public RpcAssets Assets { get; set; } = new(); +} + +public class RpcAssets +{ + public string PodAsset { get; init; } + public string MoonAsset { get; init; } + public string RemoteMoonAsset { get; init; } + public string DeveloperAsset { get; init; } + public string DeveloperAdventureAsset { get; init; } + public string DlcAsset { get; init; } + public string FallbackAsset { get; init; } +} + +public enum UsernameType +{ + Integer = 0, + Username = 1, +} \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index e2c74296..67e8f3ef 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase // This is so Lighthouse can properly identify outdated configurations and update them with newer settings accordingly. // If you are modifying anything here, this value MUST be incremented. // Thanks for listening~ - public override int ConfigVersion { get; set; } = 21; + public override int ConfigVersion { get; set; } = 22; public override string ConfigName { get; set; } = "lighthouse.yml"; public string WebsiteListenUrl { get; set; } = "http://localhost:10060"; @@ -42,6 +42,7 @@ public class ServerConfiguration : ConfigurationBase public CustomizationConfiguration Customization { get; set; } = new(); public RateLimitConfiguration RateLimitConfiguration { get; set; } = new(); public TwoFactorConfiguration TwoFactorConfiguration { get; set; } = new(); + public RichPresenceConfiguration RichPresenceConfiguration { get; set; } = new(); public override ConfigurationBase Deserialize(IDeserializer deserializer, string text) => deserializer.Deserialize(text); } \ No newline at end of file