nitai/projects
asset-proxy / src / deploy.sh
79 lines · 4.5 KB Raw
1#!/usr/bin/env bash
2set -euo pipefail
3
4APP=/root/asset-proxy
5SITE=/root/projects-site
6SLUG=asset-proxy
7OUT=$SITE/data/$SLUG
8
9echo "==> building linux release binary"
10cd "$APP"
11cargo build --release
12
13echo "==> building windows release binary"
14cargo build --release --target x86_64-pc-windows-gnu
15
16echo "==> staging binaries"
17mkdir -p "$OUT/files" "$OUT/src" "$OUT/shots"
18rm -f "$OUT/files/"*
19cp target/release/asset-proxy "$OUT/files/asset-proxy-linux-x86_64"
20cp target/x86_64-pc-windows-gnu/release/asset-proxy.exe "$OUT/files/asset-proxy.exe"
21
22echo "==> snapshotting source"
23rm -rf "$OUT/src"; mkdir -p "$OUT/src"
24find . \
25 -path ./target -prune -o \
26 -path ./cache -prune -o \
27 -path ./swaps -prune -o \
28 -name 'Cargo.lock' -prune -o \
29 -name 'ca-*.pem' -prune -o \
30 -type f -print | while read -r f; do
31 dest="$OUT/src/${f#./}"; mkdir -p "$(dirname "$dest")"; cp "$f" "$dest"
32done
33
34echo "==> source archive"
35( cd "$OUT/src" && zip -q -r -9 "$OUT/files/asset-proxy-source.zip" . )
36chmod 644 "$OUT/files/"*
37
38echo "==> registering in projects.json"
39python3 - "$SITE/data/projects.json" <<'PY'
40import json, sys
41path = sys.argv[1]
42d = json.load(open(path))
43entry = {
44 "slug": "asset-proxy",
45 "name": "asset-proxy",
46 "tagline": "A local proxy that swaps Roblox assets on the wire — textures, audio, meshes — with a live web dashboard. From-scratch Fleasion, and it never touches the game process.",
47 "language": "Rust",
48 "year": "2026",
49 "tags": ["Rust","MITM proxy","Roblox","Asset swap","Live dashboard","No injection"],
50 "summary": "Sits between Roblox and its CDN as a MITM proxy — its own CA, a leaf cert minted per host — and rewrites asset downloads before they reach the client. Replace any texture, sound or mesh with a local file, all client-side; only you see it. It also rips every original asset a game loads straight to disk, and ships a live web dashboard (browser, not egui): a real-time feed of everything the client fetches, image previews, and click-to-swap. It is not an executor and does no code injection — it's a plain HTTPS proxy, the same class of tool as Burp, so there's no anti-cheat anywhere in the picture.",
51 "highlights": [
52 {"value": "0", "label": "code injected into Roblox"},
53 {"value": "80+", "label": "asset types you can swap"},
54 {"value": "live", "label": "web dashboard, no egui"},
55 {"value": "rip", "label": "every asset a game loads, to disk"}
56 ],
57 "sections": [
58 {"title": "How it works", "body": "On startup it points Roblox's asset hostnames (assetdelivery.roblox.com, fts.rbxcdn.com) at 127.0.0.1 via the hosts file and serves them from a local HTTPS server on :443 — so the client thinks it's talking to Roblox but reaches the proxy, which presents a leaf certificate signed by a CA you install once. Per request it reads the asset id (or CDN hash); if a matching file is in ./swaps it serves that, otherwise it fetches the real asset — resolving Roblox's true IP first so it never loops back through the hijacked name — streams it, and caches the original. Needs root (Linux) or admin (Windows) to edit the hosts file and bind :443. A CONNECT proxy on :8080 is kept as a fallback for proxy-aware clients."},
59 {"title": "The dashboard", "body": "A second server on :8081 serves a hand-built web UI: a live table of every asset the client pulls, with type badges, sizes, image thumbnails straight from the cache, and a one-click swap (pick a local file, it's replaced on the next fetch). No desktop toolkit, no egui — just open it in a browser."},
60 {"title": "Not an executor", "body": "It runs entirely outside Roblox. No injection into RobloxPlayerBeta, no VM hooking, no Hyperion — the client just talks HTTPS through a proxy it trusts. That's the whole reason it's a clean, buildable tool where a real executor isn't."}
61 ],
62 "downloads": [
63 {"label": "Windows x86-64", "file": "asset-proxy.exe", "platform": "windows", "note": "the proxy + web dashboard in one .exe; set it as your system/Roblox proxy"},
64 {"label": "Linux x86-64", "file": "asset-proxy-linux-x86_64", "platform": "linux", "note": "same, for Sober — pair with Sober's proxy setting"}
65 ],
66 "source_zip": "asset-proxy-source.zip",
67 "screenshots": []
68}
69d.setdefault("projects", [])
70d["projects"] = [p for p in d["projects"] if p.get("slug") != "asset-proxy"]
71d["projects"].insert(0, entry)
72json.dump(d, open(path, "w"), indent=1)
73print(" ok, projects:", [p["slug"] for p in d["projects"]])
74PY
75
76echo "==> rebuilding site"
77cd "$SITE"; cargo build --release
78if systemctl is-active --quiet projects-site; then systemctl restart projects-site; fi
79echo "done."