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