Build offline OpenPrestige release bundles

Rename the injector and package it with an embedded payload for Windows, Linux, and macOS x64/ARM64. Add a core-only ImGui native build, multi-platform CI and release packaging, and shared per-user storage with legacy config migration.
This commit is contained in:
bbldrizzy committed 2026-11-03 18:45:13 +00:00
1 parent 5152e6e0a6
commit 2d6b2a3cd1
37 files changed
+1284 -451

No files matched your search

+15 -4
View File
@@ -10,7 +10,10 @@ fn main() {
Err(_) => newest_remapped_jar(),
};
if !jar.is_file() {
panic!("payload jar not found: {} (run `gradlew remapJar` or set PRESTIGE_PAYLOAD)", jar.display());
panic!(
"payload jar not found: {} (run `gradlew remapJar` or set PRESTIGE_PAYLOAD)",
jar.display()
);
}
println!("cargo:rerun-if-changed={}", jar.display());
println!("cargo:rustc-env=PRESTIGE_PAYLOAD_JAR={}", jar.display());
@@ -22,14 +25,22 @@ fn newest_remapped_jar() -> PathBuf {
if let Ok(entries) = fs::read_dir(&libs) {
for entry in entries.flatten() {
let name = entry.file_name().to_string_lossy().to_string();
if !name.starts_with("prestige-") || !name.ends_with(".jar") || name.ends_with("-dev.jar") || name.ends_with("-sources.jar") {
if !name.starts_with("prestige-")
|| !name.ends_with(".jar")
|| name.ends_with("-dev.jar")
|| name.ends_with("-sources.jar")
{
continue;
}
let time = entry.metadata().and_then(|m| m.modified()).unwrap_or(std::time::UNIX_EPOCH);
let time = entry
.metadata()
.and_then(|m| m.modified())
.unwrap_or(std::time::UNIX_EPOCH);
if best.as_ref().map_or(true, |(t, _)| time > *t) {
best = Some((time, entry.path()));
}
}
}
best.map(|(_, p)| p).unwrap_or_else(|| libs.join("prestige-0.1.0.jar"))
best.map(|(_, p)| p)
.unwrap_or_else(|| libs.join("prestige-0.1.0.jar"))
}
+2
View File
@@ -6,6 +6,8 @@
mod bridge;
mod jni;
mod log;
#[path = "../../paths.rs"]
mod paths;
mod worker;
use std::ffi::c_void;
+4 -46
View File
@@ -1,61 +1,19 @@
use std::ffi::c_void;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::PathBuf;
use std::sync::OnceLock;
use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(windows)]
extern "system" {
fn GetModuleFileNameW(module: *mut c_void, buf: *mut u16, size: u32) -> u32;
}
#[cfg(unix)]
#[repr(C)]
struct DlInfo {
dli_fname: *const std::ffi::c_char,
dli_fbase: *mut c_void,
dli_sname: *const std::ffi::c_char,
dli_saddr: *mut c_void,
}
#[cfg(unix)]
extern "C" {
fn dladdr(addr: *const c_void, info: *mut DlInfo) -> i32;
}
#[cfg(unix)]
fn module_path() -> PathBuf {
fn anchor() {}
let mut info = DlInfo { dli_fname: std::ptr::null(), dli_fbase: std::ptr::null_mut(), dli_sname: std::ptr::null(), dli_saddr: std::ptr::null_mut() };
let ok = unsafe { dladdr(anchor as fn() as usize as *const c_void, &mut info) };
if ok != 0 && !info.dli_fname.is_null() {
let name = unsafe { std::ffi::CStr::from_ptr(info.dli_fname) };
PathBuf::from(std::ffi::OsStr::from_bytes(name.to_bytes()))
} else {
std::env::temp_dir().join("libprestige_native")
}
}
#[cfg(windows)]
fn module_path() -> PathBuf {
let mut buf = [0u16; 1024];
let len = unsafe { GetModuleFileNameW(crate::MODULE, buf.as_mut_ptr(), buf.len() as u32) } as usize;
PathBuf::from(String::from_utf16_lossy(&buf[..len]))
}
fn log_path() -> &'static PathBuf {
static PATH: OnceLock<PathBuf> = OnceLock::new();
PATH.get_or_init(|| {
module_path().with_file_name("prestige-native.log")
})
PATH.get_or_init(|| crate::paths::native_log(std::process::id()))
}
/// Appends a line to prestige-native.log beside the DLL.
pub fn log(message: &str) {
let secs = SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0);
if let Some(parent) = log_path().parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Ok(mut file) = OpenOptions::new().create(true).append(true).open(log_path()) {
let _ = writeln!(file, "[{secs}] {message}");
}
+4 -2
View File
@@ -29,6 +29,7 @@ pub fn run() {
}
unsafe fn install() -> Result<(), String> {
crate::paths::initialize().map_err(|error| format!("create OpenPrestige data directory: {error}"))?;
let vm = find_vm()?;
let env = attach_current_thread(vm)?;
struct Detach(VmPtr);
@@ -45,7 +46,7 @@ unsafe fn install() -> Result<(), String> {
log!("JVMTI ready");
let jar = write_payload()?;
log!("payload written to {}", jar.display());
log!("using payload at {}", jar.display());
let loader = add_to_knot(&jni, &jar)?;
log!("payload appended to the game class loader: {}", describe(&jni, loader));
@@ -103,7 +104,8 @@ unsafe fn find_vm() -> Result<VmPtr, String> {
}
fn write_payload() -> Result<PathBuf, String> {
let dir = std::env::temp_dir().join("PrestigeLoader");
let dir = crate::paths::initialize().map_err(|e| format!("create OpenPrestige data directory: {e}"))?
.join("runtime").join("payloads");
std::fs::create_dir_all(&dir).map_err(|e| format!("create {}: {e}", dir.display()))?;
let path = dir.join(format!("prestige-payload-{}.jar", std::process::id()));
std::fs::write(&path, PAYLOAD).map_err(|e| format!("write {}: {e}", path.display()))?;