The T5DE Hub section gets a Server choice (T5DE, Staging, Custom), used from the next start. Without one, the install's channel decides: nightlies and dev builds use hub.staging.t5de.dev, releases hub.t5de.dev. The client passes the channel to the proxy, which keeps each hub's sign-in and product IDs apart; that needs proxy 0.2.0, now pinned. Co-Authored-By: Claude Opus 5.5 <[email protected]>
t5de
Patches for the IMVU Classic client. This repository holds only the patches and the tooling; the client itself is downloaded from IMVU and decompiled locally, and never committed.
Setup
Needs Python 3.12+, git, and 7-Zip (7z on PATH, or installed in its default location on Windows). t5de build
also needs Python 2.7, the client's own Python: found through the py launcher on Windows, python2.7 or python2
on PATH, or the T5DE_PYTHON27 environment variable.
python -m venv .venv
.venv/Scripts/pip install -e . # Linux/macOS: .venv/bin/pip
t5de setup
t5de setup downloads the client version pinned in t5de.toml (checksum-verified), extracts it, and creates
work/: a git repository whose base commit is the decompiled Python (library/) and UI (imvuContent/), with
every patch in patches/ applied on top as one commit each.
Writing patches
work/ is a normal git repository. Edit files, then commit; each commit is one patch.
cd work
# ...edit library/imvu/... or imvuContent/...
git commit -a -m "Show seconds in chat timestamps" -m "Why, and what it changes." \
--trailer "T5de-Id: chat-seconds" --trailer "T5de-Group: chat"
cd ..
t5de save # export every commit after `base` to patches/
Users choose which patches to apply, so every patch needs these trailers in its commit message (the subject is the title users see, the rest of the body the description):
T5de-Id:a short lowercase-words id, unique among the patches.T5de-Name:(optional) the patch's name in the installer, a few words in Title Case like "More Room Filters"; without it the installer shows the subject. The subject and body appear when users hover over it.T5de-Group:the installer's section for an optional patch:general,shop,rooms,avatars,chatorrenderer; orcoreorprivacy(always applied; also addT5de-Required: true).T5de-Depends: id, id(optional): patches this one needs. Required when it changes a function or UI file another patch changes, or uses a function another patch adds;t5de buildtells you.
To change an existing patch, amend or fixup its commit (git rebase -i base), then t5de save. Commit
the files in patches/ to this repository.
t5de setup --force rebuilds work/ from scratch; run t5de save first, or local commits are lost.
Patches can also add files of t5de's own (never IMVU's) to the client folder: commit them under client/ in
work/, and the patcher writes them into the install (client/imvu.ico replaces the client's window icon).
Python patches can change or add functions and methods, but not module-level or class-level code: only the
functions a patch touches are recompiled, because recompiling whole decompiled modules isn't reliable. The original
of every replaced definition stays callable as _t5de_original_<name> (self._t5de_original_<name> for methods),
so a patch can wrap IMVU's code instead of rewriting it; it's always IMVU's original, even when other patches change
the same function. t5de build warns when a patched function's decompiled original doesn't recompile to IMVU's
bytecode; wrap those rather than editing the decompiled text.
Building
t5de build
Writes the patch bundle (build/bundle/manifest.json, also available on its own with t5de bundle), then has the
patcher apply every patch to the client into build/IMVUClient/. The patcher is Go: t5de build runs it with
go run, or set T5DE_PATCHER to a built t5de-patcher. Run build/IMVUClient/IMVUClient.exe to test it, with
a throwaway IMVU account. The patched client keeps its settings and logs apart from an installed
original client (HKCU\Software\T5DE and %APPDATA%\T5DE), so both can be used side by side.
Every request to IMVU's reporting endpoints that the patched client refuses is logged as
t5de: blocked request to in %APPDATA%\T5DE\IMVULog.log.
Patcher
patcher/ is the Go patcher users run on their own copy of IMVU Classic (an installer wizard is to come). It
verifies the client, then writes a patched copy with the chosen patches; the original is untouched:
cd patcher
go run ./cmd/t5de-patcher list -bundle ../build/bundle/manifest.json
go run ./cmd/t5de-patcher apply -bundle ../build/bundle/manifest.json \
-client <IMVU Classic folder> -out <new folder> -patches room-filters,no-ads
Required patches are always applied; -patches picks optional ones (default all, empty for none).
On Windows, install does what the installer will: it finds IMVU Classic (or takes -client), patches a copy into
%LOCALAPPDATA%\T5DEClient (or -dir), keeps a copy of itself and the bundle there, and adds a Start menu
shortcut (-desktop for one on the desktop too) and an "Apps & features" entry, all for the current user without
admin rights. uninstall (also what "Apps & features" runs) removes them, and with -remove-data the patched
client's settings and logs:
go run ./cmd/t5de-patcher install -bundle ../build/bundle/manifest.json -desktop
go run ./cmd/t5de-patcher uninstall
cmd/t5de-setup is the same as a wizard (Wails, with a plain HTML/CSS/JS page in frontend/): install, and
change, repair or uninstall an existing install. Release builds carry the bundle inside (copied to
cmd/t5de-setup/bundle/manifest.json before building); in development pass it:
go build -tags desktop,production -ldflags "-H=windowsgui" -o t5de-setup.exe ./cmd/t5de-setup
./t5de-setup.exe -bundle ../build/bundle/manifest.json
Tests
.venv/Scripts/pip install -e ".[test]"
.venv/Scripts/python -m pytest
Tests that need Python 2.7 or a built client (t5de setup and t5de build) are skipped when those are missing; set
T5DE_REQUIRE_ALL=1 to make them fail instead, as CI does.
CI
.gitea/workflows/ci.yml runs the tests, a fresh t5de setup (which checks the base commit against t5de.toml)
and t5de build, then the client tests, on every push to main and every pull request. The built client is never
uploaded: it contains IMVU's client.
Every run then builds T5DE-Setup.exe (the patcher and the bundle, no IMVU files) and attaches it to the run.
Pushes to main publish it as the nightly pre-release, replacing the previous one; pushing a vX.Y.Z tag
publishes release X.Y.Z:
git tag v0.1.0 && git push origin v0.1.0
Release builds send anonymous usage statistics (Aptabase) and crash reports (Bugsink) when users allow it, to the
servers in the repository secrets APTABASE_HOST, APTABASE_APP_KEY and BUGSINK_DSN. Builds without them,
including local ones, send nothing.
Installs update themselves: when T5DE starts, it looks for a newer build on its channel (releases for releases, the nightly for nightlies) and offers it in the client's update dialog. Updating downloads the new setup, which reapplies the install's patches and settings. Local builds don't update.
.gitea/workflows/imvu-update.yml runs t5de check-update daily and opens an issue when imvu.com has a newer IMVU
Classic release than the one pinned in t5de.toml.