# 2023Patch — client-side plugins BepInEx 6 (IL2CPP) plugins that make an installed 2023 Rec Room build talk to a Radicade server instead of Rec Room's own services. All projects target `net6.0`, use Harmony, and `AllowUnsafeBlocks` for the metadata/image-key work. ## Projects | Folder | Plugin | Notes | | --- | --- | --- | | `RadicadePatch/` | `com.radicade.patch` "RadicadePatch" 3.0.0 | Current plugin, aimed at the September 2023 build (`20230831`). The server address is compiled in (`Plugin.ServerAddress`, `https://ns.radicade.app/`). | | `RadicadeAugustClient/` | `com.radicade.eacbypass` "Radicade August Client" 2.0.0 | Earlier plugin for the August 2023 build (`20230825`). Requires the metadata/interop repair in `Tools/AugustInterop` first. See its own README. | | `RadicadeEacBypass/` | — | Shared `.cs` sources, not a project. Linked into both plugins (and into `ServerTests`). The root `.gitignore` ignores the folder and then re-allows each shared file individually, so add an entry there when you add a file. `VoiceChatRestrictionPatches.cs` is neither tracked nor present. | ## Building a plugin Both plugin csproj files reference BepInEx assemblies through a `BepInExRoot` property that defaults to a machine-local path. Point it at the game's `BepInEx` folder: ```bash dotnet build 2023Patch/RadicadePatch/RadicadePatch.csproj -c Release \ -p:BepInExRoot='/c/Program Files/RecRoom/BepInEx' ``` Then copy the produced `RadicadePatch.dll` into `BepInEx/plugins`. The two plugins share a configuration identity, so **install only one at a time** — disable or back up the other DLL. > `RadicadePatch` currently fails to compile because it links > `RadicadeEacBypass/VoiceChatRestrictionPatches.cs`, which is not in this > repository. Supply that file (or drop the `` and the calls to it > from `Plugin.cs`/`VoiceChatBanFlagPatches.cs`) before building it. > `RadicadeAugustClient` does not reference that file. ## What the patches do - **Nameserver redirect** (`NameserverRedirect.cs`) — maps the service hosts the client learns from any nameserver onto the equivalent paths on the Radicade server (`auth.…` → `/auth`, `rooms.…` → `/rooms`, and ~40 more), including WebSocket paths. - **Connection gate / nameserver patches** — pin the client to the configured server and reject other hosts. - **Embedded TLS** (`EmbeddedTlsPatches.cs`) — replaces the trust decision for the configured host only, so no certificate is installed system-wide and no other host becomes trusted. - **Hub socket auth** (`HubSocketAuth.cs`) — carries the session token onto the notify WebSocket. - **Response repair / HTTP tolerance** (`ResponseRepair.cs`, `HttpTolerancePatches.cs`) — normalises responses the client is strict about and tolerates the shapes the reimplementation produces. - **Image signature key** (`ImageSignatureRequest.cs`) — detects the key id from the game's metadata so signed image requests can be verified. - **Client text rewrites**, UI prefab repair, collider-cast guard, keepsake tool, invite-online-friends and voice-chat flag patches — the smaller gameplay/UI fixes in `RadicadePatch/`. ## Configuration The August plugin writes `BepInEx/config/com.radicade.eacbypass.cfg`: ```ini [Connection] ServerUrl = https://localhost:3030 [TLS] AllowedHosts = localhost ``` TLS exceptions are limited to `AllowedHosts`. The current `RadicadePatch` compiles its server address in and warns at startup if the install's `RecRoom_Data/radicade-patch.json` marker points at a different server. ## Release build The release pipeline obfuscates the plugin with **Obfuscar** (`RadicadePatch/obfuscar.xml`, tool pinned in the root `dotnet-tools.json`). Because obfuscation renames members that the plugin looks up by name (Harmony patches, reflection, interop), run `Tools/check-obfuscation-safety.py` first — it fails when a renamed member is still reached by string.