chore: rename project PS4RP -> orbisRPC

- Repo renamed to SirHumza/orbisRPC on GitHub
- Source dir PS4RP/ -> orbisrpc/
- Binaries ps4rp.{elf,fself,bin} -> orbisrpc.{elf,fself,bin}
- On-console config dir /data/PS4RP -> /data/orbisRPC
- Build outputs, HTTP UA, net pool/socket names, README, SETUP
  guide all updated to orbisRPC
This commit is contained in:
SirHumza committed 2026-08-14 10:31:14 +02:00
1 parent 7622c4915b
commit af1a48dbf3
20 files changed
+49 -49

No files matched your search

+15 -15
View File
@@ -1,4 +1,4 @@
# PS4RP — Discord Rich Presence for the PS4
# orbisRPC — Discord Rich Presence for the PS4
A background daemon that runs **entirely on your jailbroken PS4** and posts what you're
playing to your Discord profile as Rich Presence — "Playing *Call of Duty: Black
@@ -14,17 +14,17 @@ It's Discord's "now-playing" integration, the way the PS5 does it — but for a
The PS4 only runs one foreground app at a time, so a normal homebrew app gets
suspended the moment you launch a game and can't report your activity while you
play. PS4RP avoids that by running as a **GoldHEN payload daemon**: it loads at
play. orbisRPC avoids that by running as a **GoldHEN payload daemon**: it loads at
boot (from `GoldHEN/payloads/`) and keeps running in the background while games
launch in the foreground.
```
+--------------------------+ HTTPS/WebSocket +-------------------+
| PS4RP (payload daemon) | wss://gateway.discord.gg | Discord |
| orbisRPC (payload daemon) | wss://gateway.discord.gg | Discord |
| on your PS4 @ 192.168.1.136 | <-- presence --> | (your profile) |
+-------------+--------------+ +-----------------+
|
detects running game (process list + app.db) | config + token (/data/PS4RP)
detects running game (process list + app.db) | config + token (/data/orbisRPC)
v
+--------------------------+
| /user/app/CUSAxxxx |
@@ -54,7 +54,7 @@ Everything stays on the PS4. Your Mac only touches this repo to *build* it.
| M5 — GoldHEN autoload + package + install | pending (needs on-console test) |
| On-console validation (M1's TLS + detection against live FW) | pending |
`build/ps4rp.elf` (169 KB) and `build/ps4rp.fself` (175 KB) link successfully
`build/orbisrpc.elf` (169 KB) and `build/orbisrpc.fself` (175 KB) link successfully
against OpenOrbis v0.5.4; the TLS layer uses `libSceLibreSSL`'s OpenSSL-ABI
exports (`SSL_CTX_new` / `SSL_connect` / `SSL_write` / `SSL_read`).
@@ -79,27 +79,27 @@ brew install llvm # clang 21
OO_PS4_TOOLCHAIN=~/PS4Toolchain/OpenOrbis/PS4Toolchain \
LLD=/Users/mac/lldbuild/build/bin/ld.lld \
./scripts/build.sh
# -> build/ps4rp.elf, build/ps4rp.fself, build/eboot.bin
# -> build/orbisrpc.elf, build/orbisrpc.fself, build/eboot.bin
```
The runtime artifact is `build/ps4rp.fself` (GoldHEN payload) or
The runtime artifact is `build/orbisrpc.fself` (GoldHEN payload) or
`build/eboot.bin` (PKG route). No toolchain = no build.
---
## Installing on the PS4 (no PC after first build)
1. Build `ps4rp.pkg` (or grab the `.elf` payload) on any Mac/computer.
1. Build `orbisrpc.pkg` (or grab the `.elf` payload) on any Mac/computer.
2. Transfer to the PS4 over FTP, or on a USB stick.
3. **Daemon route (recommended):** put `ps4rp.fself` in
3. **Daemon route (recommended):** put `orbisrpc.fself` in
`/data/GoldHEN/payloads/` — it auto-loads on every boot and runs in the
background while you game. (GoldHEN 2.2.)
4. Or install `ps4rp.pkg` like any homebrew app if you prefer a foreground
4. Or install `orbisrpc.pkg` like any homebrew app if you prefer a foreground
launcher (note: it suspends once a game opens, so the daemon route is what
powers presence-during-play).
Config lives at `/data/PS4RP/config.json` — edit it over FTP or on a USB stick.
Logs go to `/data/PS4RP/log.txt`.
Config lives at `/data/orbisRPC/config.json` — edit it over FTP or on a USB stick.
Logs go to `/data/orbisRPC/log.txt`.
---
@@ -111,9 +111,9 @@ account automating itself (which Discord bans on the user account — see notes
repo). Steps:
1. Open https://discord.com/developers/applications → **New Application** → name it
`PS4RP` (or whatever) → **Create**.
`orbisRPC` (or whatever) → **Create**.
2. Copy the **Application ID** (Client ID) and **Client Secret** into
`/data/PS4RP/config.json` (`client_id`, `client_secret`).
`/data/orbisRPC/config.json` (`client_id`, `client_secret`).
3. In the app → **OAuth2 → Redirects**, add:
`https://example.com/callback`
4. In the app → **OAuth2 → Scopes**, add `rpc.activities.write` (and `identify`).
@@ -133,7 +133,7 @@ After that it just runs. No PC needed at runtime.
A registered application acting on your permission is the supported integration path.
- Discord may require your application to be verified to use `rpc.activities.write`.
For a personal, low-traffic app it usually works unverified; worst case it labels
the activity "via PS4RP".
the activity "via orbisRPC".
---
+11 -11
View File
@@ -1,4 +1,4 @@
# PS4RP — Deploy + setup guide
# orbisRPC — Deploy + setup guide
Target: GoldHEN 2.2 jailbroken PS4 (FW 9.00), daemon route.
@@ -7,7 +7,7 @@ Target: GoldHEN 2.2 jailbroken PS4 (FW 9.00), daemon route.
Via FTP (the console must be awake and online):
```
put build/ps4rp.fself -> /data/GoldHEN/payloads/ps4rp.fself
put build/orbisrpc.fself -> /data/GoldHEN/payloads/orbisrpc.fself
```
GoldHEN auto-loads payloads from `/data/GoldHEN/payloads/` at boot and keeps
@@ -16,8 +16,8 @@ them running in the background while games run in the foreground.
Also make the config dir + seed the config:
```
mkdir /data/PS4RP
put config/config.json -> /data/PS4RP/config.json
mkdir /data/orbisRPC
put config/config.json -> /data/orbisRPC/config.json
```
## 2. First boot check
@@ -25,14 +25,14 @@ put config/config.json -> /data/PS4RP/config.json
Reboot (or run the payload from the GoldHEN loader) and check:
```
get /data/PS4RP/log.txt
get /data/orbisRPC/log.txt
```
Expected lines:
```
[..] config not found at /data/PS4RP/config.json; defaults applied (only first run)
[..] FATAL: set client_id + auth_code (or refresh) in /data/PS4RP/config.json
[..] config not found at /data/orbisRPC/config.json; defaults applied (only first run)
[..] FATAL: set client_id + auth_code (or refresh) in /data/orbisRPC/config.json
```
The FATAL exit is expected until you supply Discord credentials (step 3).
@@ -40,13 +40,13 @@ The FATAL exit is expected until you supply Discord credentials (step 3).
## 3. One-time Discord app setup
1. Open https://discord.com/developers/applications -> New Application -> name it
(e.g. `PS4RP`) -> Create.
(e.g. `orbisRPC`) -> Create.
2. Copy **Application ID** and **Client Secret**.
3. In the app -> **OAuth2 -> General**, add a Redirect URL:
`http://localhost:6770/callback`
4. In the app -> **OAuth2 -> Scopes**, enable `rpc.activities.write` and
`identify` (and `rpc` if prompted).
5. Edit `/data/PS4RP/config.json` over FTP/USB:
5. Edit `/data/orbisRPC/config.json` over FTP/USB:
- `client_id`: your Application ID
- `client_secret`: your Client Secret
6. Generate an authorization code on any device (phone/PC — one time only):
@@ -89,7 +89,7 @@ The daemon exchanges the `auth_code` once for an access + refresh token
(`token_expires_at`, `refresh_token` in config). It refreshes automatically
before expiry. The one-time `auth_code` is blanked after use.
Config lives on the PS4 at `/data/PS4RP/config.json` — no PC needed at runtime.
Config lives on the PS4 at `/data/orbisRPC/config.json` — no PC needed at runtime.
## Troubleshooting
@@ -108,5 +108,5 @@ Config lives on the PS4 at `/data/PS4RP/config.json` — no PC needed at runtime
OO_PS4_TOOLCHAIN=~/PS4Toolchain/OpenOrbis/PS4Toolchain \
LLD=/Users/mac/lldbuild/build/bin/ld.lld \
./scripts/build.sh
# -> build/ps4rp.fself
# -> build/orbisrpc.fself
```
View File
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
+4 -4
View File
@@ -1,10 +1,10 @@
/* cfg.h - /data/PS4RP/config.json load/save */
/* cfg.h - /data/orbisRPC/config.json load/save */
#ifndef CFG_H
#define CFG_H
#include <stdint.h>
#define CFG_PATH "/data/PS4RP/config.json"
#define LOG_PATH "/data/PS4RP/log.txt"
#define DATA_DIR "/data/PS4RP"
#define CFG_PATH "/data/orbisRPC/config.json"
#define LOG_PATH "/data/orbisRPC/log.txt"
#define DATA_DIR "/data/orbisRPC"
typedef struct {
char client_id[64]; /* Discord application client id */
char client_secret[128]; /* only needed to exchange code / refresh */
+1 -1
View File
@@ -151,7 +151,7 @@ int detect_current_game(char *out_name, size_t cap, char *out_path, size_t p_cap
}else{
strncpy(out_name, "(unknown game)", cap-1); out_name[cap-1]=0;
}
if(out_path){ snprintf(out_path, p_cap, "/data/PS4RP/.lastgame/%s", titleId[0]?titleId:"unknown"); }
if(out_path){ snprintf(out_path, p_cap, "/data/orbisRPC/.lastgame/%s", titleId[0]?titleId:"unknown"); }
log_msg("detect: active name=%s tid=%s", out_name, titleId);
return 0;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
+5 -5
View File
@@ -28,7 +28,7 @@ static int http_init(void){
if((r=sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_HTTP))<0){log_msg("load HTTP fail %d",r);return -2;}
if((r=sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_SSL))<0){log_msg("load SSL fail %d",r);return -3;}
if((r=sceNetInit())<0){log_msg("sceNetInit %d",r);return -4;}
s_http_mem=(int)sceNetPoolCreate("ps4rpN",NET_POOL,0); if(s_http_mem<0){log_msg("netpool %d",s_http_mem);return -5;}
s_http_mem=(int)sceNetPoolCreate("orbisrpcN",NET_POOL,0); if(s_http_mem<0){log_msg("netpool %d",s_http_mem);return -5;}
s_ssl_mem=(int)sceSslInit(SSL_PL); if(s_ssl_mem<0){log_msg("sslinit %d",s_ssl_mem);return -6;}
if((r=sceHttpInit(s_http_mem,s_ssl_mem,HTTP_PL))<0){log_msg("httpinit %d",r);return -7;}
s_http_ctx=r;
@@ -70,11 +70,11 @@ int http_oauth_token(const char *client_id,const char *client_secret,
"&grant_type=refresh_token&refresh_token=%s", refresh_token);
else blen+=snprintf(body+blen,sizeof body-blen,"&grant_type=client_credentials&scope=applications.commands");
const char *URL="https://discord.com/api/oauth2/token";
tpl=sceHttpCreateTemplate(s_http_ctx, "PS4RP/1.0", ORBIS_HTTP_VERSION_1_1, 0); if(tpl<0){log_msg("tmpl %d",tpl);rc=-1;goto done;}
tpl=sceHttpCreateTemplate(s_http_ctx, "orbisRPC/1.0", ORBIS_HTTP_VERSION_1_1, 0); if(tpl<0){log_msg("tmpl %d",tpl);rc=-1;goto done;}
conn=sceHttpCreateConnectionWithURL(tpl, URL, 0); if(conn<0){log_msg("conn %d",conn);rc=-2;goto done;}
req=sceHttpCreateRequestWithURL(conn, ORBIS_METHOD_POST, URL, (uint64_t)blen); if(req<0){log_msg("req %d",req);rc=-3;goto done;}
sceHttpAddRequestHeader(req,"Content-Type","application/x-www-form-urlencoded",0);
sceHttpAddRequestHeader(req,"User-Agent","PS4RP/1.0",0);
sceHttpAddRequestHeader(req,"User-Agent","orbisRPC/1.0",0);
if((rc=sceHttpSendRequest(req,body,blen))<0){log_msg("send %d",rc);rc=-4;goto done;}
if((rc=sceHttpGetStatusCode(req,&status))<0){log_msg("stat %d",rc);rc=-5;goto done;}
char resp[2048]; int total=0,len;
@@ -96,10 +96,10 @@ done:
int http_get(const char *url,char *out,size_t cap){
if(http_init()) return -10;
int32_t tpl=0,conn=0,req=0,rc=0;
tpl=sceHttpCreateTemplate(s_http_ctx,"PS4RP/1.0",ORBIS_HTTP_VERSION_1_1,0); if(tpl<0)return -1;
tpl=sceHttpCreateTemplate(s_http_ctx,"orbisRPC/1.0",ORBIS_HTTP_VERSION_1_1,0); if(tpl<0)return -1;
conn=sceHttpCreateConnectionWithURL(tpl,url,0); if(conn<0){rc=-2;goto done;}
req=sceHttpCreateRequestWithURL(conn,ORBIS_METHOD_GET,url,0); if(req<0){rc=-3;goto done;}
sceHttpAddRequestHeader(req,"User-Agent","PS4RP/1.0",0);
sceHttpAddRequestHeader(req,"User-Agent","orbisRPC/1.0",0);
if((rc=sceHttpSendRequest(req,0,0))<0){rc=-4;goto done;}
int total=0,len;
while((len=sceHttpReadData(req,out+total,cap-1-total))>0){total+=len; if(total>(int)cap-1)break;}
View File
File renamed without changes.
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
+3 -3
View File
@@ -1,4 +1,4 @@
/* main.c - PS4RP daemon: detect game -> Discord presence. Runs as GoldHEN payload. */
/* main.c - orbisRPC daemon: detect game -> Discord presence. Runs as GoldHEN payload. */
#include "cfg.h"
#include "log.h"
#include "http.h"
@@ -44,14 +44,14 @@ static void set_game_presence(discord_t *d, const char *name){
"On PS4", /* state */
name, /* details = game name */
1, 1, /* party */
"ps4rp:playing", /* large_image key (asset) */
"orbisrpc:playing", /* large_image key (asset) */
name); /* large_text */
log_msg("presence: %s", name);
}
int main(int argc, char **argv){
(void)argc;(void)argv;
/* GoldHEN payloads: write to /data/PS4RP */
/* GoldHEN payloads: write to /data/orbisRPC */
cfg_load(CFG_PATH, &g_cfg);
if(!g_cfg.enabled){ log_msg("disabled in config; exiting"); return 0; }
if(!g_cfg.client_id[0] || strcmp(g_cfg.client_id,"SET_ME")==0){
+3 -3
View File
@@ -58,7 +58,7 @@ static int net_ensure(void){
uint32_t ur = sceSysmoduleLoadModuleInternal(ORBIS_SYSMODULE_INTERNAL_NET);
if((int)ur < 0){ log_msg("load NET fail %d", (int)ur); return -1; }
if(sceNetInit() < 0){ log_msg("sceNetInit fail"); return -2; }
s_net_mem = (int)sceNetPoolCreate("ps4rpNet", 128*1024, 0);
s_net_mem = (int)sceNetPoolCreate("orbisrpcNet", 128*1024, 0);
if(s_net_mem < 0){ log_msg("net pool fail %d", s_net_mem); return -3; }
s_net_ready = 1;
return 0;
@@ -68,7 +68,7 @@ int ws_connect(ws_t *w, const char *host, int port, const char *resource, const
memset(w,0,sizeof(*w));
if(net_ensure()<0) return -1;
/* resolve host */
int32_t rid = sceNetResolverCreate("ps4rpR", 0, 0);
int32_t rid = sceNetResolverCreate("orbisrpcR", 0, 0);
OrbisNetInAddr in; memset(&in,0,sizeof in);
int resolved = 0;
if(rid >= 0){
@@ -82,7 +82,7 @@ int ws_connect(ws_t *w, const char *host, int port, const char *resource, const
in.s_addr = ia.s_addr;
}
/* TCP socket */
int32_t fd = sceNetSocket("ps4rpWs", ORBIS_NET_AF_INET, ORBIS_NET_SOCK_STREAM, 0);
int32_t fd = sceNetSocket("orbisrpcWs", ORBIS_NET_AF_INET, ORBIS_NET_SOCK_STREAM, 0);
if(fd < 0){ log_msg("socket fail %d",fd); return -5; }
OrbisNetSockaddr sa; memset(&sa,0,sizeof sa);
sa.len = (uint8_t)sizeof(sa);
View File
File renamed without changes.
+7 -7
View File
@@ -1,5 +1,5 @@
#!/bin/bash
# build.sh - PS4RP: compile payload ELF + fself for PS4.
# build.sh - orbisRPC: compile payload ELF + fself for PS4.
# Usage: ./scripts/build.sh [elf|fself|all] default: all
set -euo pipefail
SDK="${OO_PS4_TOOLCHAIN:-/Users/mac/PS4Toolchain/OpenOrbis/PS4Toolchain}"
@@ -20,15 +20,15 @@ export OO_PS4_TOOLCHAIN="$SDK"
OUT="$ROOT/build"; mkdir -p "$OUT"
echo "=== compiling ==="
for f in log cfg jsonlite b64 http ws detect discord main; do
"$CC" $CFLAGS -c -o "$OUT/$f.o" "PS4RP/$f.c" || { echo "compile $f FAILED"; exit 1; }
"$CC" $CFLAGS -c -o "$OUT/$f.o" "orbisrpc/$f.c" || { echo "compile $f FAILED"; exit 1; }
done
echo "=== linking ($LD) ==="
"$LD" $OUT/*.o -o "$OUT/ps4rp.elf" $LDFLAGS || { echo "link FAILED"; exit 1; }
echo "ELF -> $OUT/ps4rp.elf"
"$LD" $OUT/*.o -o "$OUT/orbisrpc.elf" $LDFLAGS || { echo "link FAILED"; exit 1; }
echo "ELF -> $OUT/orbisrpc.elf"
MODE="${1:-all}"
if [ "$MODE" = "fself" ] || [ "$MODE" = "all" ]; then
"$SDK/bin/macos/create-fself-macos" -in="$OUT/ps4rp.elf" \
-out="$OUT/ps4rp.fself" --eboot "$OUT/ps4rp.bin" --paid 0x3800000000000011
echo "FSELF -> $OUT/ps4rp.fself"
"$SDK/bin/macos/create-fself-macos" -in="$OUT/orbisrpc.elf" \
-out="$OUT/orbisrpc.fself" --eboot "$OUT/orbisrpc.bin" --paid 0x3800000000000011
echo "FSELF -> $OUT/orbisrpc.fself"
fi
echo "done."