mirror of
https://github.com/SirHumza/orbisRPC.git
synced 2026-10-06 10:00:36 +02:00
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:
1 parent
7622c4915b
commit
af1a48dbf3
20 files changed
+49
-49
No files matched your search
@@ -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
@@ -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
|
||||
```
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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 */
|
||||
@@ -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.
@@ -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;}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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){
|
||||
@@ -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);
|
||||
File renamed without changes.
+7
-7
@@ -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."
|
||||
Reference in new issue
Block a user