mirror of
https://github.com/notmaj0r/CheatRunner.git
synced 2026-10-18 23:07:10 -05:00
v0.17.1: Rebuilt with latest SDK
Should work on all firmwares, up to 13.60.
This commit is contained in:
1 parent
89095e4b8a
commit
548f21a41f
9 files changed
+210
-199
No files matched your search
+8
-1
@@ -1,6 +1,11 @@
|
||||
# CheatRunner — Changelog
|
||||
|
||||
## v0.17
|
||||
## v0.17.1
|
||||
|
||||
- **Added: support for 13.60 firmware** — rebuilt against the latest ps5-payload-sdk.
|
||||
|
||||
<details>
|
||||
<summary><b>v0.17</b></summary>
|
||||
|
||||
- **Fixed: the trainer/cheat menu, Settings page, and Support/donate popup could silently fail to appear on some PS5 firmwares** (reported on 4.03) — the "Cheat menu loaded" toast would show, but the menu itself never appeared, same for Settings and Support. Root cause, confirmed against that firmware's actual WebKit source: every full-screen overlay in the dashboard positioned itself with the CSS `inset` shorthand, which is gated behind WebKit's `CSSLogicalEnabled` runtime flag — off by default in this build. With `inset` silently dropped, the overlay never got a `top`/`right`/`bottom`/`left`, so it had no size or position to render at, regardless of `display`/`visibility`/`opacity`. (Two earlier attempts in this same release — switching `display:none` to `visibility`/`opacity`, then adding a `transition` — treated it as a compositing/paint timing issue and didn't address this.) Replaced `inset` with explicit `top`/`right`/`bottom`/`left` everywhere it was used for positioning (the three overlays, plus several decorative background/glow/shimmer effects that had the same silent failure but went unnoticed since they're cosmetic). Confirmed fixed on the reporting user's PS5.
|
||||
- **Fixed: the Settings page's ON/OFF toggle switches were too cramped for the text**, and the green "ON" fill sat slightly off-center — a CSS math bug on every toggle switch in the app, not just Settings.
|
||||
@@ -16,6 +21,8 @@
|
||||
- **Added an "Enable hotkey" switch in Settings → Hotkey, off by default.** On some firmwares (seen on 4.xx) the hook can still crash SceShellUI despite the fix above — the rest of CheatRunner works fully with it off; turn it on once you've confirmed it's stable on your firmware.
|
||||
- **Fixed a garbled "…" character** ("Search settings…", the health panel's "Loading…") showing as mojibake on the PS5 browser — replaced with plain periods.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>v0.16</b></summary>
|
||||
|
||||
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
project(CheatRunnerPayload C CXX)
|
||||
set(CHEATRUNNER_VERSION "0.17")
|
||||
|
||||
# Embed CheatRunner.png as a C byte array (cheatrunner_png.h in build dir).
|
||||
# If the asset is missing, generate a tiny fallback icon so builds still work.
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CheatRunner.png")
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/CheatRunner.png" _CR_PNG_HEX HEX)
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," _CR_PNG_BYTES "${_CR_PNG_HEX}")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cheatrunner_png.h"
|
||||
"static const unsigned char g_cheatrunner_png[] = {${_CR_PNG_BYTES}};\n"
|
||||
)
|
||||
else()
|
||||
message(WARNING "CheatRunner.png missing; generating fallback cheatrunner_png.h")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cheatrunner_png.h"
|
||||
"static const unsigned char g_cheatrunner_png[] = {"
|
||||
"0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,"
|
||||
"0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x01,"
|
||||
"0x00,0x00,0x00,0x01,0x08,0x06,0x00,0x00,0x00,0x1F,0x15,0xC4,"
|
||||
"0x89,0x00,0x00,0x00,0x0D,0x49,0x44,0x41,0x54,0x78,0x9C,0x63,"
|
||||
"0x00,0x01,0x00,0x00,0x05,0x00,0x01,0x0D,0x0A,0x2D,0xB4,0x00,"
|
||||
"0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82};\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Embed dist/CheatRunner.pkg as a C byte array (cheatrunner_tile_pkg.h).
|
||||
# Build the PKG first with: cd pkg-source && ./build-pkg.sh
|
||||
# If absent the auto-install feature is compiled out but everything else works.
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/dist/CheatRunner.pkg")
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/dist/CheatRunner.pkg" _PKG_HEX HEX)
|
||||
string(LENGTH "${_PKG_HEX}" _PKG_HEX_LEN)
|
||||
math(EXPR _PKG_LEN "${_PKG_HEX_LEN} / 2")
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," _PKG_BYTES "${_PKG_HEX}")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cheatrunner_tile_pkg.h"
|
||||
"static const unsigned char g_cheatrunner_tile_pkg[] = {${_PKG_BYTES}};\n"
|
||||
"static const size_t g_cheatrunner_tile_pkg_len = ${_PKG_LEN}u;\n"
|
||||
)
|
||||
set(_HAVE_TILE_PKG ON)
|
||||
message(STATUS "CheatRunner tile PKG: embedding ${_PKG_LEN} bytes from dist/CheatRunner.pkg")
|
||||
else()
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cheatrunner_tile_pkg.h"
|
||||
"/* dist/CheatRunner.pkg not present at configure time — auto-install disabled */\n"
|
||||
)
|
||||
set(_HAVE_TILE_PKG OFF)
|
||||
message(STATUS "CheatRunner tile PKG: dist/CheatRunner.pkg not found — auto-install disabled (run pkg-source/build-pkg.sh first)")
|
||||
endif()
|
||||
|
||||
# Gzip-compress the dashboard assets at build time on the host (real zlib,
|
||||
# not available in the target SDK) and embed the finished bytes — the PS5
|
||||
# binary just serves them, it never compresses anything itself.
|
||||
# find_package(Python3) instead of a hardcoded "python3" command: on Windows
|
||||
# python3.exe is often a Microsoft Store app-execution-alias stub, not a real
|
||||
# interpreter, while the actual install is reachable as "python"/"py".
|
||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||
|
||||
foreach(_ASSET html css js)
|
||||
execute_process(
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_gzip_header.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/dashboard_${_ASSET}.inc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dashboard_${_ASSET}_gz.h"
|
||||
"g_dashboard_${_ASSET}_gz"
|
||||
RESULT_VARIABLE _GZ_RC
|
||||
)
|
||||
if(NOT _GZ_RC EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to gzip-compress dashboard_${_ASSET}.inc for embedding")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(GLOB CHEATRUNNER_SRC CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
|
||||
)
|
||||
|
||||
# --- Hotkey injected payload ------------------------------------------------
|
||||
# A separate PIE executable, built as its own target then embedded into
|
||||
# CheatRunner.elf as a byte array and written into SceShellUI via elfldr_exec.
|
||||
add_executable(cr_getdata_payload
|
||||
src/payload/cr_getdata_payload.c
|
||||
src/payload/cr_detour.c
|
||||
src/payload/hde64.c
|
||||
)
|
||||
set_target_properties(cr_getdata_payload PROPERTIES
|
||||
OUTPUT_NAME cr_getdata_payload.elf
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/payload"
|
||||
)
|
||||
target_include_directories(cr_getdata_payload PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/payload"
|
||||
)
|
||||
target_compile_options(cr_getdata_payload PRIVATE -fPIE -Wall -Wextra -O2)
|
||||
target_link_options(cr_getdata_payload PRIVATE "-Wl,--allow-multiple-definition")
|
||||
target_link_libraries(cr_getdata_payload PRIVATE kernel_sys)
|
||||
if(CMAKE_STRIP)
|
||||
add_custom_command(TARGET cr_getdata_payload POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:cr_getdata_payload>
|
||||
)
|
||||
endif()
|
||||
|
||||
set(_GETDATA_BLOB_HEADER "${CMAKE_CURRENT_BINARY_DIR}/cr_getdata_payload_blob.h")
|
||||
add_custom_command(
|
||||
OUTPUT "${_GETDATA_BLOB_HEADER}"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_blob_header.py"
|
||||
"$<TARGET_FILE:cr_getdata_payload>"
|
||||
"${_GETDATA_BLOB_HEADER}"
|
||||
"g_cr_getdata_payload_elf"
|
||||
DEPENDS cr_getdata_payload
|
||||
COMMENT "Embedding cr_getdata_payload.elf as a byte array"
|
||||
)
|
||||
add_custom_target(cr_getdata_payload_blob DEPENDS "${_GETDATA_BLOB_HEADER}")
|
||||
|
||||
add_executable(CheatRunner
|
||||
${CHEATRUNNER_SRC}
|
||||
src/third_party/cJSON.c
|
||||
src/third_party/stb_impl.c
|
||||
src/third_party/mc4/aes.c
|
||||
src/third_party/mc4/base64.c
|
||||
src/third_party/mc4/mc4decrypter.c
|
||||
)
|
||||
|
||||
set_target_properties(CheatRunner PROPERTIES
|
||||
OUTPUT_NAME CheatRunner.elf
|
||||
)
|
||||
|
||||
add_dependencies(CheatRunner cr_getdata_payload_blob)
|
||||
|
||||
target_include_directories(CheatRunner PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
target_include_directories(CheatRunner PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
target_compile_options(CheatRunner PRIVATE -Wall -Wextra -O2)
|
||||
target_compile_definitions(CheatRunner PRIVATE CHEATRUNNER_VERSION="${CHEATRUNNER_VERSION}")
|
||||
target_link_options(CheatRunner PRIVATE "-Wl,--allow-multiple-definition")
|
||||
target_compile_definitions(CheatRunner PRIVATE CHEATRUNNER_HAVE_BROWSER_OPEN=1)
|
||||
|
||||
set(CHEATRUNNER_LIBS
|
||||
kernel_sys
|
||||
SceSystemService
|
||||
SceUserService
|
||||
SceAppInstUtil
|
||||
SceHttp
|
||||
SceSsl
|
||||
SceNet
|
||||
ScePad
|
||||
pthread
|
||||
)
|
||||
|
||||
# ps5-payload-sdk exposes sceLncUtil* through libSceSystemService.
|
||||
# Do not link -lSceLncUtil: many SDK bundles do not ship a separate library,
|
||||
# but libSceSystemService contains the needed stubs.
|
||||
target_compile_definitions(CheatRunner PRIVATE
|
||||
CHEATRUNNER_HAVE_SCE_LNCUTIL=1
|
||||
CHEATRUNNER_HAVE_SCE_USER_LIST=1
|
||||
)
|
||||
if(_HAVE_TILE_PKG)
|
||||
target_compile_definitions(CheatRunner PRIVATE CHEATRUNNER_HAVE_TILE_PKG=1)
|
||||
endif()
|
||||
message(STATUS "Using sceLncUtil* symbols from SceSystemService")
|
||||
message(STATUS "sceUserServiceGetLoginUserIdList: enabled")
|
||||
|
||||
# SQLite-backed app.db scanner (primary game list, falls back to folder scan).
|
||||
#
|
||||
# The ps5-payload-sdk does not ship libsqlite3. To enable:
|
||||
# 1. Download the amalgamation from https://sqlite.org/download.html
|
||||
# (sqlite-amalgamation-*.zip → sqlite3.c + sqlite3.h)
|
||||
# 2. Place both files in src/third_party/
|
||||
# 3. Re-run cmake with -DCHEATRUNNER_SQLITE_BUNDLED=ON
|
||||
# (or flip the option(... OFF) below to ON before configuring)
|
||||
#
|
||||
option(CHEATRUNNER_SQLITE_BUNDLED "Bundle sqlite3 amalgamation (src/third_party/sqlite3.c)" OFF)
|
||||
if(CHEATRUNNER_SQLITE_BUNDLED)
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/sqlite3.c")
|
||||
message(FATAL_ERROR "CHEATRUNNER_SQLITE_BUNDLED=ON but src/third_party/sqlite3.c not found. "
|
||||
"Download the amalgamation from https://sqlite.org/download.html")
|
||||
endif()
|
||||
target_sources(CheatRunner PRIVATE src/third_party/sqlite3.c)
|
||||
target_compile_definitions(CheatRunner PRIVATE
|
||||
CHEATRUNNER_HAVE_SQLITE_APPDB=1
|
||||
SQLITE_THREADSAFE=0
|
||||
SQLITE_DEFAULT_MEMSTATUS=0
|
||||
SQLITE_OMIT_LOAD_EXTENSION
|
||||
)
|
||||
message(STATUS "app.db scanner: SQLite bundled from src/third_party/sqlite3.c")
|
||||
else()
|
||||
message(STATUS "app.db scanner: disabled (folder fallback only) — see CMakeLists.txt to enable")
|
||||
endif()
|
||||
|
||||
target_link_libraries(CheatRunner PRIVATE ${CHEATRUNNER_LIBS})
|
||||
|
||||
if(CMAKE_STRIP)
|
||||
add_custom_command(TARGET CheatRunner POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:CheatRunner>
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,129 @@
|
||||
# Standalone Makefile for CheatRunner.elf — compiles directly with the PS5
|
||||
# payload SDK toolchain.
|
||||
#
|
||||
# Usage:
|
||||
# make # build build-make/CheatRunner.elf
|
||||
# make clean
|
||||
# make SQLITE=1 # force-enable bundled sqlite3 (auto-detected otherwise)
|
||||
# make SQLITE=0 # force-disable it
|
||||
# PS5_PAYLOAD_SDK=/path/to/sdk make
|
||||
|
||||
VERSION := 0.17.1
|
||||
|
||||
BUILD_DIR := build-make
|
||||
GENDIR := $(BUILD_DIR)/gen
|
||||
OBJDIR := $(BUILD_DIR)/obj
|
||||
ELF := $(BUILD_DIR)/CheatRunner.elf
|
||||
|
||||
# ---------------------------------------------------------------- SDK resolve
|
||||
PS5_PAYLOAD_SDK ?=
|
||||
SDK_ROOT := $(patsubst %/toolchain/prospero.cmake,%,$(firstword \
|
||||
$(wildcard $(PS5_PAYLOAD_SDK)/toolchain/prospero.cmake) \
|
||||
$(wildcard ../../ps5-payload-sdk/toolchain/prospero.cmake) \
|
||||
$(wildcard ps5-payload-sdk/toolchain/prospero.cmake) \
|
||||
$(wildcard /opt/ps5-payload-sdk/toolchain/prospero.cmake)))
|
||||
|
||||
ifeq ($(SDK_ROOT),)
|
||||
$(error PS5 payload SDK not found. Set PS5_PAYLOAD_SDK, or place it at ../../ps5-payload-sdk, ./ps5-payload-sdk, or /opt/ps5-payload-sdk)
|
||||
endif
|
||||
|
||||
CC := $(SDK_ROOT)/bin/prospero-clang
|
||||
CXX := $(SDK_ROOT)/bin/prospero-clang++
|
||||
STRIP := $(SDK_ROOT)/bin/prospero-strip
|
||||
|
||||
# ---------------------------------------------------------------- sources
|
||||
SRC_C := $(wildcard src/*.c) \
|
||||
src/third_party/cJSON.c \
|
||||
src/third_party/stb_impl.c \
|
||||
src/third_party/mc4/aes.c \
|
||||
src/third_party/mc4/base64.c \
|
||||
src/third_party/mc4/mc4decrypter.c
|
||||
SRC_CPP := $(wildcard src/*.cpp)
|
||||
|
||||
SQLITE ?= $(if $(and $(wildcard src/third_party/sqlite3.c),$(wildcard src/third_party/sqlite3.h)),1,0)
|
||||
ifeq ($(SQLITE),1)
|
||||
SRC_C += src/third_party/sqlite3.c
|
||||
endif
|
||||
|
||||
OBJ_C := $(patsubst src/%.c,$(OBJDIR)/%.o,$(SRC_C))
|
||||
OBJ_CPP := $(patsubst src/%.cpp,$(OBJDIR)/%.o,$(SRC_CPP))
|
||||
OBJS := $(OBJ_C) $(OBJ_CPP)
|
||||
|
||||
# ---------------------------------------------------------------- generated headers
|
||||
PNG_SRC := $(wildcard CheatRunner.png)
|
||||
PKG_SRC := $(wildcard dist/CheatRunner.pkg)
|
||||
HAVE_TILE_PKG := $(if $(PKG_SRC),1,0)
|
||||
|
||||
PAYLOAD_ELF := $(BUILD_DIR)/payload/cr_getdata_payload.elf
|
||||
PAYLOAD_SRC := src/payload/cr_getdata_payload.c src/payload/cr_detour.c src/payload/hde64.c
|
||||
|
||||
GEN_HEADERS := $(GENDIR)/cr_getdata_payload_blob.h $(GENDIR)/cheatrunner_png.h $(GENDIR)/cheatrunner_tile_pkg.h \
|
||||
$(GENDIR)/dashboard_html_gz.h $(GENDIR)/dashboard_css_gz.h $(GENDIR)/dashboard_js_gz.h
|
||||
|
||||
# ---------------------------------------------------------------- flags
|
||||
DEFINES := -DCHEATRUNNER_VERSION=\"$(VERSION)\" \
|
||||
-DCHEATRUNNER_HAVE_BROWSER_OPEN=1 \
|
||||
-DCHEATRUNNER_HAVE_SCE_LNCUTIL=1 \
|
||||
-DCHEATRUNNER_HAVE_SCE_USER_LIST=1
|
||||
ifeq ($(HAVE_TILE_PKG),1)
|
||||
DEFINES += -DCHEATRUNNER_HAVE_TILE_PKG=1
|
||||
endif
|
||||
ifeq ($(SQLITE),1)
|
||||
DEFINES += -DCHEATRUNNER_HAVE_SQLITE_APPDB=1 -DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
endif
|
||||
|
||||
INCLUDES := -I$(GENDIR) -Isrc
|
||||
CFLAGS := -fPIE -Wall -Wextra -O2 $(INCLUDES) $(DEFINES)
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -Wl,--allow-multiple-definition
|
||||
LIBS := -lkernel_sys -lSceSystemService -lSceUserService -lSceAppInstUtil \
|
||||
-lSceHttp -lSceSsl -lSceNet -lScePad -lpthread
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(ELF)
|
||||
|
||||
$(ELF): $(OBJS) | $(BUILD_DIR)
|
||||
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
@if [ -x "$(STRIP)" ]; then $(STRIP) --strip-all $@; fi
|
||||
|
||||
$(OBJDIR)/%.o: src/%.c $(GEN_HEADERS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o: src/%.cpp $(GEN_HEADERS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
# Hotkey payload: built as its own PIE ELF, then embedded into CheatRunner.elf
|
||||
$(PAYLOAD_ELF): $(PAYLOAD_SRC) | $(BUILD_DIR)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) -fPIE -Wall -Wextra -O2 -Isrc -Isrc/payload $(LDFLAGS) -o $@ $(PAYLOAD_SRC) -lkernel_sys
|
||||
@if [ -x "$(STRIP)" ]; then $(STRIP) --strip-all $@; fi
|
||||
|
||||
$(GENDIR)/cr_getdata_payload_blob.h: $(PAYLOAD_ELF) tools/gen_blob_header.py | $(GENDIR)
|
||||
python3 tools/gen_blob_header.py $< $@ g_cr_getdata_payload_elf
|
||||
|
||||
$(GENDIR)/cheatrunner_png.h: $(PNG_SRC) | $(GENDIR)
|
||||
@if [ -f CheatRunner.png ]; then \
|
||||
python3 -c "d=open('CheatRunner.png','rb').read(); open('$@','w').write('static const unsigned char g_cheatrunner_png[] = {'+','.join(str(b) for b in d)+'};\n')"; \
|
||||
else \
|
||||
printf '%s\n' 'static const unsigned char g_cheatrunner_png[] = {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x06,0x00,0x00,0x00,0x1F,0x15,0xC4,0x89,0x00,0x00,0x00,0x0D,0x49,0x44,0x41,0x54,0x78,0x9C,0x63,0x00,0x01,0x00,0x00,0x05,0x00,0x01,0x0D,0x0A,0x2D,0xB4,0x00,0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82};' > $@; \
|
||||
fi
|
||||
|
||||
$(GENDIR)/cheatrunner_tile_pkg.h: $(PKG_SRC) | $(GENDIR)
|
||||
@if [ -f dist/CheatRunner.pkg ]; then \
|
||||
python3 -c "d=open('dist/CheatRunner.pkg','rb').read(); open('$@','w').write('static const unsigned char g_cheatrunner_tile_pkg[] = {'+','.join(str(b) for b in d)+'};\nstatic const unsigned long g_cheatrunner_tile_pkg_len = %du;\n'%len(d))"; \
|
||||
else \
|
||||
printf '/* dist/CheatRunner.pkg not present -- auto-install disabled */\n' > $@; \
|
||||
fi
|
||||
|
||||
$(GENDIR)/dashboard_%_gz.h: src/dashboard_%.inc tools/gen_gzip_header.py | $(GENDIR)
|
||||
python3 tools/gen_gzip_header.py $< $@ g_dashboard_$*_gz
|
||||
|
||||
$(GENDIR) $(BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
@@ -281,7 +281,7 @@ Recommended project layout:
|
||||
CheatRunner/
|
||||
├── CheatRunnerPayload/
|
||||
│ ├── src/
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── Makefile
|
||||
│ └── build-cheatrunner.ps1
|
||||
└── PS5-Payload-dev/
|
||||
└── sdk-master/
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef CHEATRUNNER_VERSION
|
||||
#define CHEATRUNNER_VERSION "0.17"
|
||||
#define CHEATRUNNER_VERSION "0.17.1"
|
||||
#endif
|
||||
|
||||
#define MAX_GAMES CR_APPDB_MAX_GAMES
|
||||
|
||||
@@ -53,7 +53,7 @@ cr_api_dashboard_handle(int fd, const char *method, const char *path,
|
||||
if (!strcmp(path, "/cache.appcache")) {
|
||||
static const char appcache[] =
|
||||
"CACHE MANIFEST\n"
|
||||
"# CheatRunner v0.17\n"
|
||||
"# CheatRunner v0.17.1\n"
|
||||
"# Build: " __DATE__ " " __TIME__ "\n"
|
||||
"\n"
|
||||
"CACHE:\n"
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
#include "cr_tile_pkg.h"
|
||||
|
||||
#ifndef CHEATRUNNER_VERSION
|
||||
#define CHEATRUNNER_VERSION "0.17"
|
||||
#define CHEATRUNNER_VERSION "0.17.1"
|
||||
#endif
|
||||
|
||||
/* Async-signal-safe crash handler: writes a one-line entry to the crash log
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
# Build-time helper: embeds a binary file as a static C byte array.
|
||||
#
|
||||
# Usage: gen_blob_header.py <blob_path> <header_out_path> <array_name>
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
blob_path, header_path, array_name = sys.argv[1:4]
|
||||
with open(blob_path, "rb") as f:
|
||||
data = f.read()
|
||||
|
||||
with open(header_path, "w") as f:
|
||||
f.write("static const unsigned char %s[] = {\n" % array_name)
|
||||
for i in range(0, len(data), 20):
|
||||
f.write(",".join(str(b) for b in data[i:i + 20]))
|
||||
f.write(",\n")
|
||||
f.write("};\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
# Build-time helper: extracts a dashboard .inc asset's exact byte content by
|
||||
# compiling and running it through the host C compiler (so C string-escape
|
||||
# parsing is never reimplemented by hand), gzip-compresses it, and writes a
|
||||
# header with the compressed bytes as a static C array.
|
||||
#
|
||||
# Usage: gen_gzip_header.py <inc_path> <header_out_path> <array_name>
|
||||
|
||||
import gzip
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
def extract_raw_bytes(inc_path):
|
||||
inc_dir = os.path.dirname(os.path.abspath(inc_path))
|
||||
inc_name = os.path.basename(inc_path)
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
src = os.path.join(td, "dump.c")
|
||||
exe = os.path.join(td, "dump")
|
||||
with open(src, "w") as f:
|
||||
f.write('#include <stdio.h>\n')
|
||||
f.write('static const char DATA[] =\n#include "%s"\n;\n' % inc_name)
|
||||
f.write('int main(void) { fwrite(DATA, 1, sizeof(DATA) - 1, stdout); return 0; }\n')
|
||||
subprocess.run(["cc", "-I", inc_dir, src, "-o", exe], check=True)
|
||||
return subprocess.run([exe], check=True, stdout=subprocess.PIPE).stdout
|
||||
|
||||
|
||||
def main():
|
||||
inc_path, header_path, array_name = sys.argv[1:4]
|
||||
raw = extract_raw_bytes(inc_path)
|
||||
gz = gzip.compress(raw, compresslevel=9, mtime=0)
|
||||
|
||||
with open(header_path, "w") as f:
|
||||
f.write("static const unsigned char %s[] = {\n" % array_name)
|
||||
for i in range(0, len(gz), 20):
|
||||
f.write(",".join(str(b) for b in gz[i:i + 20]))
|
||||
f.write(",\n")
|
||||
f.write("};\n")
|
||||
f.write("static const unsigned long %s_len = %dul;\n" % (array_name, len(gz)))
|
||||
f.write("static const unsigned long %s_raw_len = %dul;\n" % (array_name, len(raw)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user