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:
1 parent
5152e6e0a6
commit
2d6b2a3cd1
37 files changed
+1284
-451
No files matched your search
@@ -3,6 +3,7 @@ package dev.zprestige.prestige.ui;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.zprestige.prestige.client.AppPaths;
|
||||
import dev.zprestige.prestige.client.Prestige;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -17,7 +18,7 @@ import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Local (offline) backend of the Configs page. Every config is one JSON file in {@code <gameDir>/prestige/configs/}:
|
||||
* Local (offline) backend of the Configs page. Every config is one JSON file in the shared OpenPrestige data directory:
|
||||
* the card metadata plus the client's own snapshot ({@code ConfigManager.saveToJson()}), which is applied again with
|
||||
* {@code ConfigManager.loadFromJson(String)}. "Public configs" lists the configs saved with Public visibility, "Personal configs"
|
||||
* lists all of them; Create saves the current module/HUD state, Update overwrites it, Delete removes the file.
|
||||
@@ -45,6 +46,10 @@ public final class LocalConfigs {
|
||||
private static String lastQuery = null;
|
||||
|
||||
static Path dir() {
|
||||
return AppPaths.configs().resolve("presets");
|
||||
}
|
||||
|
||||
private static Path legacyDir() {
|
||||
Path base;
|
||||
try { base = net.fabricmc.loader.api.FabricLoader.getInstance().getGameDir(); } catch (Throwable t) { base = Path.of("."); }
|
||||
return base.resolve("prestige").resolve("configs");
|
||||
@@ -86,21 +91,61 @@ public final class LocalConfigs {
|
||||
for (Path p : (Iterable<Path>) s.filter(f -> f.getFileName().toString().endsWith(".json"))::iterator) {
|
||||
try {
|
||||
Entry e = GSON.fromJson(Files.readString(p, StandardCharsets.UTF_8), Entry.class);
|
||||
if (e == null || e.name == null || e.name.isBlank()) continue;
|
||||
if (e.tags == null) e.tags = new ArrayList<>();
|
||||
e.tags.removeIf(java.util.Objects::isNull);
|
||||
if (e.desc == null) e.desc = "";
|
||||
if (e.author == null) e.author = "";
|
||||
if (e.date == null) e.date = "";
|
||||
ALL.add(e);
|
||||
if (normalize(e)) ALL.add(e);
|
||||
} catch (Throwable t) { System.out.println("[prestige-ui] config " + p.getFileName() + ": " + t); }
|
||||
}
|
||||
}
|
||||
importLegacy(d);
|
||||
} catch (IOException e) { System.out.println("[prestige-ui] configs dir: " + e); }
|
||||
ALL.sort(Comparator.comparingInt((Entry e) -> e.id).reversed());
|
||||
rebuild();
|
||||
}
|
||||
|
||||
private static boolean normalize(Entry entry) {
|
||||
if (entry == null || entry.name == null || entry.name.isBlank()) return false;
|
||||
if (entry.tags == null) entry.tags = new ArrayList<>();
|
||||
entry.tags.removeIf(java.util.Objects::isNull);
|
||||
if (entry.desc == null) entry.desc = "";
|
||||
if (entry.author == null) entry.author = "";
|
||||
if (entry.date == null) entry.date = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
private static JsonObject configWithoutId(Entry entry) {
|
||||
JsonObject config = GSON.toJsonTree(entry).getAsJsonObject();
|
||||
config.remove("id");
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void importLegacy(Path directory) throws IOException {
|
||||
Path legacy = legacyDir().toAbsolutePath().normalize();
|
||||
if (!Files.isDirectory(legacy)) return;
|
||||
String key = java.util.UUID.nameUUIDFromBytes(legacy.toString().getBytes(StandardCharsets.UTF_8)).toString();
|
||||
Path marker = directory.resolve(".imported-" + key);
|
||||
if (Files.exists(marker)) return;
|
||||
try (Stream<Path> files = Files.list(legacy)) {
|
||||
for (Path path : files.filter(p -> p.getFileName().toString().endsWith(".json")).toList()) {
|
||||
Entry entry;
|
||||
try {
|
||||
entry = GSON.fromJson(Files.readString(path, StandardCharsets.UTF_8), Entry.class);
|
||||
} catch (RuntimeException error) {
|
||||
System.out.println("[prestige-ui] could not import " + path.getFileName() + ": " + error);
|
||||
continue;
|
||||
}
|
||||
if (!normalize(entry)) continue;
|
||||
JsonObject content = configWithoutId(entry);
|
||||
if (ALL.stream().anyMatch(existing -> configWithoutId(existing).equals(content))) continue;
|
||||
int originalId = entry.id;
|
||||
if (ALL.stream().anyMatch(existing -> existing.id == originalId)) {
|
||||
entry.id = ALL.stream().mapToInt(existing -> existing.id).max().orElse(0) + 1;
|
||||
}
|
||||
Files.writeString(file(entry), GSON.toJson(entry), StandardCharsets.UTF_8, java.nio.file.StandardOpenOption.CREATE_NEW);
|
||||
ALL.add(entry);
|
||||
}
|
||||
}
|
||||
Files.writeString(marker, "");
|
||||
}
|
||||
|
||||
private static Path file(Entry e) { return dir().resolve(e.id + "_" + e.name.replaceAll("[^A-Za-z0-9_.-]", "_") + ".json"); }
|
||||
|
||||
private static void write(Entry e) {
|
||||
|
||||
Reference in new issue
Block a user