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
}