Modules - madmagic007/Oculus-Quest-Presence GitHub Wiki
Modules
Modules are expansions for the OQRPC tool. Modules allow for more detailed information about the current topmost program on the quest to be showed in the Discord Rich Presence.
Initializing a module
First your application must create a JSON file in the external directory sdcard/android/data/com.madmagic.oqrpc/files/OQRPC Modules/
. The file name must be unique, it is recommended to use the package name of the app the module is designed for, followed by the .json extension. It is recommended that your application checks if this file exists at launch.
Contents of the JSON file
Key | Type | Required | Description |
---|---|---|---|
packageName | String | true | The package name that has to be topmost for the program to open a socket at the provided port for detailed presence data |
port | integer | true | The port that will be used for the socket |
appId | String | false | Your own Discord application id |
Example module:
{
"packageName": "com.madmagic.oqrpc",
"port": 12345,
"appId": "594525674946616292"
}
Sending the response:
Your app will need to open a TCP server socket bound to localhost on the port in module.json. This socket must listen for any connections, and when one is received, will reply. The format for replies is as follows:
4 byte length prefix (Big Endian)
JSON response (Encoded as UTF-8)
An example implementation of the socket code in java can be seen below. The JSON is generated by the function generateJSON
(this is for you to implement, as your app will return its own data from the game, format is below). For a C++ implementation using POSIX sockets, you could look at the beat saber rich presence mod.
Please note: This will be the status as is, the OQPRC main program will not change any of the presence values itself anymore.
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class example {
public void startListening(String bindAddress, int bindPort) {
try {
ServerSocket socket = new ServerSocket(bindPort);
while (true) {
Socket client = socket.accept();
DataOutputStream stream = new DataOutputStream(client.getOutputStream());
byte[] data = generateJSON().getBytes(StandardCharsets.UTF_8);
stream.writeInt(data.length);
stream.write(data);
client.close();
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
Contents of the socket response (all are optional)
Key | Type | Description |
---|---|---|
details | String | Top text of the presence |
state | String | Bottom text of the presence |
largeImageKey | String | Image key to use for the large image |
largeImageText | String | Tooltip for the large image |
smallImageKey | String | Image key to use for the small image |
smallImageText | String | Tooltip for the small image |
remaining | integer | Time displayed as remaining, provided value should be given in seconds. Can't be used together with elapsed being true |
elapsed | boolean | Time displayed as elapsed. Starts counting from the first time this key is given until it is not present in the JSON. Can't be used when remaining time is given |
Example JSON:
{
"details": "Setting up presence",
"state": "Looking at modules",
"largeImageKey": "questLarge",
"largeImageText": "OQRPC v2.5.0 by MadMagic",
"smallImageKey": "questSmall",
"smallImageText": "Playing on Oculus Quest",
"remaining": 120
}