mirror of
https://github.com/knutwurst/patchdl.git
synced 2026-10-06 09:00:23 +02:00
PatchDL 0.0.1: scan, resolve, download and install PS5 game patches
Standalone PS5 payload with an embedded web UI on :12880, no etaHEN. - Scans installed titles and classifies the source (genuine install, ShadowMountPlus mount, preinstall, unknown) from the on-disk layout. - Reads name, installed version and the Sony version.xml URL from the PS5 app database (vendored SQLite). - Resolves version.xml past nanoDNS via a raw DNS query, TLS pinned to the SCEI DNAS root. - Filters patches to the newest one compatible with the current firmware. - Downloads the patch and installs it through AppInstUtil (sysmodule loaded at runtime), gated to genuine installs with a package title-id match guard. - Action-based UI filters and an on-screen startup notification with the URL.
This commit is contained in:
1 parent
4a14c689e5
commit
01464ae88a
31 files changed
+273765
-365
No files matched your search
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
# Deploy patchdl to the PS5 via the Payload Manager HTTP API (port 8084).
|
||||
# The uploaded filename carries the version so it is identifiable in the
|
||||
# Payload Manager UI. patchdl self-kills any running instance, so this is
|
||||
# an idempotent redeploy.
|
||||
#
|
||||
# Usage: scripts/deploy_ps5.sh [PS5_HOST]
|
||||
# PS5_HOST defaults to $PS5_HOST or ps5-slim.fritz.box
|
||||
set -eu
|
||||
|
||||
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
HOST=${1:-${PS5_HOST:-ps5-slim.fritz.box}}
|
||||
PM_PORT=${PM_PORT:-8084}
|
||||
HTTP_PORT=${PATCHDL_HTTP_PORT:-12880}
|
||||
|
||||
VERSION=$(sed -n 's/.*PATCHDL_VERSION[^"]*"\([^"]*\)".*/\1/p' "$ROOT_DIR/src/patchdl_version.h")
|
||||
[ -n "$VERSION" ] || { echo "could not read PATCHDL_VERSION" >&2; exit 1; }
|
||||
|
||||
SRC_ELF="$ROOT_DIR/patchdl-ps5.elf"
|
||||
[ -f "$SRC_ELF" ] || { echo "build first: $SRC_ELF missing" >&2; exit 1; }
|
||||
|
||||
UP_NAME="patchdl-ps5-v${VERSION}.elf"
|
||||
TMP_ELF="$ROOT_DIR/$UP_NAME"
|
||||
cp "$SRC_ELF" "$TMP_ELF"
|
||||
|
||||
echo "Uploading $UP_NAME to $HOST:$PM_PORT ..."
|
||||
curl -fsS -m120 -X POST "http://$HOST:$PM_PORT/manage:upload?filename=$UP_NAME" \
|
||||
-H 'Content-Type: application/octet-stream' --data-binary @"$TMP_ELF" >/dev/null
|
||||
rm -f "$TMP_ELF"
|
||||
|
||||
PAYLOAD_PATH=$(curl -fsS -m15 "http://$HOST:$PM_PORT/list_payloads" | \
|
||||
UP_NAME="$UP_NAME" python3 -c '
|
||||
import os, sys, json
|
||||
want = os.environ["UP_NAME"]
|
||||
obj = json.load(sys.stdin)
|
||||
paths = obj.get("payloads", obj) if isinstance(obj, dict) else obj
|
||||
for p in paths:
|
||||
if isinstance(p, str) and p.endswith(want):
|
||||
print(p); break
|
||||
')
|
||||
[ -n "$PAYLOAD_PATH" ] || { echo "uploaded payload not found in list_payloads" >&2; exit 1; }
|
||||
|
||||
echo "Launching $PAYLOAD_PATH ..."
|
||||
curl -fsS -m20 "http://$HOST:$PM_PORT/loadpayload:$PAYLOAD_PATH" >/dev/null
|
||||
|
||||
printf "Waiting for web server on :%s " "$HTTP_PORT"
|
||||
i=0
|
||||
while [ "$i" -lt 20 ]; do
|
||||
if curl -fsS -m4 "http://$HOST:$HTTP_PORT/api/status" >/dev/null 2>&1; then
|
||||
echo " up."
|
||||
curl -fsS -m6 "http://$HOST:$HTTP_PORT/api/status"; echo
|
||||
echo "UI: http://$HOST:$HTTP_PORT/"
|
||||
exit 0
|
||||
fi
|
||||
printf "."
|
||||
sleep 2
|
||||
i=$((i + 1))
|
||||
done
|
||||
echo " timeout — server did not answer." >&2
|
||||
exit 1
|
||||
Reference in new issue
Block a user