mirror of
https://github.com/djdevin/recnet-plugin.git
synced 2026-09-08 06:31:29 -07:00
Compare commits
4 Commits
0.0.2
...
20230414.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ddda007c1 | |||
| 6a62f0cc1d | |||
| a6e4555a00 | |||
| 326188c7a0 |
+3
-5
@@ -1,5 +1,3 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
GamePath.props
|
||||
obj
|
||||
bin
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
# CLAUDE.md
|
||||
|
||||
Guidance for working in this repo. This is a **BepInEx 6 (IL2CPP)** Harmony plugin that points the
|
||||
Rec Room client at a self-hosted server. Read the README for the user-facing overview; this file is
|
||||
the stuff you only learn by getting burned.
|
||||
|
||||
## Build & deploy
|
||||
|
||||
```sh
|
||||
dotnet build -c Debug -p:GamePath="C:\Games\depots\471711\23191908"
|
||||
```
|
||||
|
||||
- `GamePath` points at the Rec Room install root. It's normally set in the gitignored
|
||||
`GamePath.props` (see `GamePath.props.example`); the `-p:GamePath=...` override is handy for one-offs.
|
||||
- The project references ~150 interop DLLs from `$(GamePath)\BepInEx\interop`. Those are generated by
|
||||
Il2CppInterop the first time the game runs under BepInEx — if they're missing, launch the game once.
|
||||
- A post-build `DeployPlugin` target copies `RecNetPlugin.dll` into `$(GamePath)\BepInEx\plugins\`.
|
||||
**The copy fails while Rec Room is running** (the DLL is locked) — that's an MSB3027 error, not a
|
||||
compile error. Close the game and rebuild. The DLL is also always left in `bin/Debug/net6.0/`.
|
||||
|
||||
## Hard-won gotchas (read before patching anything)
|
||||
|
||||
1. **Interop assemblies are stubs. The real code is native.** The DLLs under `BepInEx/interop` are
|
||||
Il2CppInterop proxies — method bodies just marshal into `GameAssembly.dll`. dnSpy / managed
|
||||
decompilation of the interop shows *no real logic*. You cannot read the actual algorithms
|
||||
statically; you learn behavior by patching + logging at runtime.
|
||||
|
||||
2. **Obfuscated names differ per game build.** Rec Room's type/method names are obfuscated
|
||||
(`PGECJHKNIEN`, `MDBMGOBECDJ`, `cm_did_ppk`, etc.). A dnSpy dump from *some* build will not
|
||||
necessarily match the interop you compile against. Real example from the DUID work: a dnSpy dump
|
||||
called the method `CheckForMismatch` and the pref field `DBAIOPIEJNC`, but in our interop the
|
||||
method is `CheckForDUIDMismatch` and neither `DBAIOPIEJNC` nor `MDBMGOBECDJ` exist at all. **Always
|
||||
resolve members against the interop DLLs you actually build against** (see the Cecil snippet below),
|
||||
never against a dump from an unknown build.
|
||||
|
||||
3. **Patch the concrete class, not the IL2CPP "interface".** Il2CppInterop renders IL2CPP interfaces
|
||||
as abstract classes deriving from `Il2CppObjectBase`. Harmony will happily patch an abstract method
|
||||
and throw no error, but the prefix **never runs** because the game dispatches to the concrete
|
||||
implementation. This cost us a whole "shipped fix" that did nothing. Concrete impls live in
|
||||
`Assembly-CSharp.dll`. Example: patch `CheatManager.CheckForDUIDMismatch`, *not* the interface
|
||||
`PGECJHKNIEN.CheckForDUIDMismatch`. Verify with Cecil that `IsAbstract == false` before trusting a
|
||||
patch.
|
||||
|
||||
4. **Obfuscated members live in the global namespace** and are referenced unqualified in this codebase
|
||||
(e.g. `typeof(LEALBOODIEE)`, `PGECJHKNIEN`). No `using` needed.
|
||||
|
||||
5. **Harmony prefix conventions here:** force a value + `return false` to skip the original (see
|
||||
`Patches/EACPatches.cs`). **Bind parameters positionally (`__0`, `__1`, …), never by their
|
||||
obfuscated name** — obfuscated *parameter* names change per build just like type names, and binding
|
||||
by name fails at load with `Parameter "XXX" not found in method ...`. For out-params take
|
||||
`ref string __0` plus `ref bool __result`.
|
||||
|
||||
6. **Method names in `[HarmonyPatch]` are strings — the compiler does not check them.** A renamed
|
||||
*type* is a build error; a renamed *method* builds fine and only shows up as a HarmonyX error in
|
||||
`LogOutput.log` at load, or (worse) as a patch that silently never runs. After a game upgrade,
|
||||
re-verify every string method name with Cecil, don't just trust a green build.
|
||||
|
||||
### Surviving a game-version upgrade
|
||||
|
||||
Obfuscated names are re-rolled every build. Unobfuscated names (`CheckForDUIDMismatch`, `WriteDUIDs`,
|
||||
`ClearDUIDs`, `SendRequest`, `NotifyServerCertificate`, `GenerateChallengeResponse`) have been stable
|
||||
across upgrades so far; everything else must be re-resolved. Don't guess from the old name — **search
|
||||
the new interop by signature**, which is what actually identifies the target:
|
||||
|
||||
| Patch | Target | Signature that identifies it |
|
||||
| --- | --- | --- |
|
||||
| `PhotonPatches` | `HPEENKELKDJ.MGKINLFMJLB` | only instance, 0-param method returning `Photon.Realtime.AppSettings` in `Assembly-CSharp` (the static/2-param `PUNNetworkManager` sibling also returns it — exclude it) |
|
||||
| `EACPatches` (is-ready) | `EACManager.MCFIOBHCFBB` | only static, 0-param `bool` on `EACManager` that isn't a property getter; type lives in `RecRoom.Rranticheat.Runtime.dll` |
|
||||
|
||||
> **Il2CppInterop regenerates on launch and obfuscation can differ between generations.** Only scan the
|
||||
> interop the game *actually loaded* — check that its mtime is *after* the last game launch, and treat a
|
||||
> clean HarmonyX load (no "Could not find method") as the real proof. A stale/mismatched interop
|
||||
> generation once produced a whole different name set (`IHODDIDPEOD.JEGOHKJDPFH`, `EACManager.KOIFGPGJGKB`)
|
||||
> that got overwritten on the next launch back to the names below — patching against it failed at load.
|
||||
|
||||
Renames observed in the **20230414 build** (`C:\Games\recflare-client`, Steam manifest
|
||||
`3668280474894052876`):
|
||||
|
||||
- `LEALBOODIEE.GBNKOFMAJPA` → `HPEENKELKDJ.MGKINLFMJLB`
|
||||
- `EACManager.IMMGELPFGCK` → `EACManager.MCFIOBHCFBB`
|
||||
- `CheckForDUIDMismatch` out-param → `BPOGCIINKBB` (still bound as `__0`, no source change)
|
||||
|
||||
Renames observed in the **07-21 build** (`C:\Games\recflare-client`), for reference:
|
||||
|
||||
- `CheckForDUIDMismatch` out-param `ALOMDLLNIMD` → `LICOPEEMHHG` (now bound as `__0`)
|
||||
- `GenerateChallengeResponse` param `PGCINMIEBJP` → `__0`
|
||||
- `GPFPFDBGCEK.AMOHMPKKGHL` → `LEALBOODIEE.GBNKOFMAJPA`
|
||||
- `EACManager.FJLMLEPOKGE` → `EACManager.IMMGELPFGCK`
|
||||
- `JAPJPGNBMNM`, `HPHDJAFFHCN<>`, `HAAHJPGNIMD` — **gone** from `Assembly-CSharp`. These were the
|
||||
image-signing `PromisePatch`, now deleted and replaced by `ImageSigningPatch` (see below), which
|
||||
hooks framework types instead and so has no obfuscated names left to break.
|
||||
|
||||
## Image signature verification
|
||||
|
||||
The client verifies images against an RSA public key whose modulus is a string literal in
|
||||
`global-metadata.dat`. Patching that literal is fragile; **don't**. Hook the framework instead.
|
||||
|
||||
The decisive observation: the literal base64-decodes to **exactly 256 bytes and does not start with
|
||||
`0x30`**, so it is a *raw* 2048-bit modulus, not a DER/SPKI blob. The client therefore cannot hand it
|
||||
to a key-import API — it has to base64-decode it and hand-build `RSAParameters { Modulus, Exponent }`.
|
||||
Those are plain `mscorlib` calls with unobfuscated names. Confirmed working at runtime: images load
|
||||
with no signing check.
|
||||
|
||||
`Patches/ImageSigningPatch.cs` hooks, all in `Il2Cppmscorlib.dll`:
|
||||
|
||||
| Hook | Purpose |
|
||||
| --- | --- |
|
||||
| `Convert.FromBase64String` | catches the literal regardless of which crypto stack consumes it (guarded by a length check first — it runs for every base64 decode in the game) |
|
||||
| `RSACryptoServiceProvider.ImportParameters` | swaps the modulus in place (both keys are 2048-bit, so no realloc) |
|
||||
| `RSACryptoServiceProvider.VerifyData` / `VerifyHash` ×2 | forces the verify to succeed |
|
||||
|
||||
Config lives in `[Signing]`. `Disable Signature Verification` defaults **true** — that's the shipped
|
||||
behaviour, since this setup doesn't use image signing. `Signing Modulus Override` is the secondary
|
||||
path for a deployment that *does* want signed images (keeps real verification, against your keypair).
|
||||
|
||||
Two things to remember:
|
||||
|
||||
- **Blast radius:** forcing verify-true affects *all* mscorlib RSA verification, not just images.
|
||||
BestHTTP's TLS uses its own bundled BouncyCastle, so cert validation appears unaffected — inferred
|
||||
from assembly layout, not proven. Keep it behind the config knob.
|
||||
- **If it ever stops working:** the patch logs `[SIG] stock modulus seen at <hook>` on first sighting.
|
||||
No such line = verification moved to `BestHTTP.SecureProtocol.Org.BouncyCastle`; the equivalent
|
||||
hooks there are `RsaKeyParameters..ctor(bool, BigInteger, BigInteger)` and the **concrete**
|
||||
`RsaDigestSigner`/`PssSigner.VerifySignature` (not the abstract `ISigner` — gotcha 3).
|
||||
- The stock modulus is hardcoded in the patch. If a future build re-rolls the key, the match silently
|
||||
stops firing; that log line is how you'd notice.
|
||||
|
||||
## Inspecting the game
|
||||
|
||||
Use **Mono.Cecil** for static metadata/signature checks (accessibility, abstract-ness, exact param
|
||||
names, which assembly a concrete impl lives in). Mark-of-the-web will block loading `Mono.Cecil.dll`
|
||||
directly — copy it somewhere local, `Unblock-File`, then load via bytes:
|
||||
|
||||
```powershell
|
||||
$interop = "$env:GamePath\BepInEx\interop"
|
||||
$dst = "$scratch\Mono.Cecil.dll"
|
||||
# NOTE: Mono.Cecil.dll ships in BepInEx/core, NOT in BepInEx/interop.
|
||||
Copy-Item "$env:GamePath\BepInEx\core\Mono.Cecil.dll" $dst; Unblock-File $dst
|
||||
[System.Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes($dst)) | Out-Null
|
||||
$asm = [Mono.Cecil.AssemblyDefinition]::ReadAssembly("$interop\Assembly-CSharp.dll")
|
||||
# then walk $asm.MainModule.GetTypes(), inspect .Methods / .Fields / .IsAbstract / .IsStatic ...
|
||||
```
|
||||
|
||||
Not every target is in `Assembly-CSharp` — `EACManager` is in `RecRoom.Rranticheat.Runtime.dll`,
|
||||
`HTTPManager`/`LegacyTlsAuthentication` in `RecNet.Runtime.dll`. When a lookup comes up empty, sweep
|
||||
all ~305 DLLs in `interop/` (`ReadAssembly` each, `.Dispose()` after) before concluding it's gone.
|
||||
|
||||
Notes:
|
||||
- Windows PowerShell 5.1 has **no** `?.` null-conditional operator — use explicit `$x -eq $null` checks.
|
||||
- String literals (pref keys, endpoints, GUIDs) are in `RecRoom_Data/il2cpp_data/Metadata/global-metadata.dat`.
|
||||
`grep -a -o -E '[ -~]{4,}' global-metadata.dat | grep -i <thing>` extracts them.
|
||||
- The BepInEx runtime log is `$(GamePath)/BepInEx/LogOutput.log`. Our plugin logs under the
|
||||
`RecNet Plugin` source. `[HTTP]`, `[DUID]`, `[DUID-PROBE]`, `[DEVICEID]`, `[CORRUPT]` are our tags.
|
||||
- PlayerPrefs on Windows live in the registry at `HKCU\Software\Against Gravity\Rec Room`, value names
|
||||
are `<key>_h<unityHash>`, values are `REG_BINARY`. CodeStage AntiCheat stores strings *obscured*
|
||||
(XOR-encrypted), so a stored id will not appear as plaintext in registry or files.
|
||||
|
||||
## Case study: the Create Account / DUID hang
|
||||
|
||||
The gnarliest bug so far; the diagnostic tooling for it still lives in the repo. Summary:
|
||||
|
||||
- **Symptom:** on some machines Create Account hangs. Log shows a `PlayerReporting/v1/deviceId` POST
|
||||
returning `200 {"success":true}`, after which the client never calls the `create_account` OAuth and
|
||||
never persists the id (`WriteDUIDs` never runs).
|
||||
- **Trigger:** a device-id **mismatch**. `CheatManager.CheckForDUIDMismatch(out string)` returns true
|
||||
when the stored id differs from `SystemInfo.deviceUniqueIdentifier`. True → migration path → POST →
|
||||
hang. Machines whose stored id matches never take the path.
|
||||
- **Stored id:** PlayerPrefs key `cm_did_ppk` (registry `cm_did_ppk_h3478365449`), CodeStage
|
||||
ObscuredString-encoded. `CheatManager.WriteDUIDs()` writes it, `ClearDUIDs()` deletes it. In our
|
||||
interop these are **instance** methods (a dnSpy dump showed them static — build difference again).
|
||||
- **Two surprises:**
|
||||
1. Deleting the registry value did **not** change the `oldDeviceId` in the POST, and the probe
|
||||
showed no `cm_did_ppk` read that session — i.e. the "old" id is **not sourced from local
|
||||
PlayerPrefs** on the failing path. Consequence: **a registry-reset script does not fix it.**
|
||||
2. `game callback attached = True` on that request → the client is genuinely waiting on the
|
||||
response. But the real server already returns `{"success":true}` at 200 and it still hangs, so the
|
||||
accepting response shape (if one exists) is something more specific.
|
||||
|
||||
> ### ⚠️ OPEN QUESTION — where does the old DUID actually live?
|
||||
> We have **not** found the source of the `oldDeviceId` value. It survives a full delete of the
|
||||
> `HKCU\Software\Against Gravity\Rec Room` registry key, it does not appear as plaintext anywhere in
|
||||
> `AppData/LocalLow/Against Gravity/Rec Room`, and on the failing run the `cm_did_ppk` PlayerPref is
|
||||
> never read. So `cm_did_ppk` is *a* copy but not the one that seeds the migration POST. Leading (but
|
||||
> unconfirmed) theory: it's held server-side by the archival server, which recorded it from prior
|
||||
> POSTs, and/or cached in memory from a server response. **Until this is found, the only reliable fix
|
||||
> is `Suppress` (client) or correcting the value server-side — not clearing local storage.** Next
|
||||
> steps to try: inspect what the recflare backend stores/returns for the account's device id; dump the
|
||||
> `HTTPCache` entries decoded (not plaintext); trace who sets the field the POST body reads from.
|
||||
- **Working client-side workaround:** force `CheckForDUIDMismatch` → false (skips the migration path
|
||||
entirely). Config: `Suppress DUID Mismatch = true`.
|
||||
- **Proper root-cause fix:** server-side — make the endpoint stop reporting a stale `old` id (so
|
||||
`old == new`, no mismatch) or return whatever the client needs to proceed.
|
||||
|
||||
### Diagnostic knobs (all in `[Advanced]`)
|
||||
|
||||
`Suppress DUID Mismatch` defaults **true** (it's the shipped fix). Everything else defaults **false** —
|
||||
those are investigation tools, not normal config. See the patch files for details.
|
||||
|
||||
| Config key | Patch file | What it does |
|
||||
| --- | --- | --- |
|
||||
| `Suppress DUID Mismatch` | `DUIDMismatchPatch.cs` | **The fix (default true).** Force `CheckForDUIDMismatch` → false. |
|
||||
| `Simulate DUID Mismatch` | `DUIDMismatchPatch.cs` | Force it → true. Reproduce the hang without a corrupt value. |
|
||||
| `Corrupt Stored DUID` | `CorruptDUIDPatch.cs` | One-shot: write a truncated id via `WriteDUIDs` (spoofing `SystemInfo.deviceUniqueIdentifier`) to create a *genuinely* corrupt stored value. |
|
||||
| `Restore Stored DUID` | `CorruptDUIDPatch.cs` | One-shot undo: `WriteDUIDs` with the real id. |
|
||||
| `DeviceId Response Override` / `Status` | `DeviceIdResponsePatch.cs` | Rewrite the `deviceId` response body/status in-flight to probe what shape the client will accept. |
|
||||
| (probe) | `DUIDProbePatch.cs` | Logs every PlayerPrefs get/set and the `WriteDUIDs`/`ClearDUIDs` calls — `WriteDUIDs() called` is the "client accepted the response" signal. |
|
||||
|
||||
`DUIDMismatchPatch` has three modes: `Simulate` → force true, `Suppress` → force false, neither →
|
||||
pass through to the real check (needed to observe a genuinely corrupt stored value).
|
||||
|
||||
**The diagnostic patches should not ship in a release build** — strip them (or at least confirm their
|
||||
knobs default false: `Simulate`, `Corrupt`, `Restore`, `DeviceId Response Override`) before cutting a
|
||||
release. `Suppress DUID Mismatch` is the real fix and defaults **true**, so it stays on.
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CannedNet.Client", "CannedNet.Client\CannedNet.Client.csproj", "{B6704474-3934-43AE-9E89-E5851F6A266B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B6704474-3934-43AE-9E89-E5851F6A266B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B6704474-3934-43AE-9E89-E5851F6A266B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B6704474-3934-43AE-9E89-E5851F6A266B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B6704474-3934-43AE-9E89-E5851F6A266B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,454 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyName>CannedNet.Client</AssemblyName>
|
||||
<Product>My first plugin</Product>
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>
|
||||
https://api.nuget.org/v3/index.json;
|
||||
https://nuget.bepinex.dev/v3/index.json;
|
||||
https://nuget.samboy.dev/v3/index.json
|
||||
</RestoreAdditionalProjectSources>
|
||||
<RootNamespace>CannedNet.Client</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile"/>
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="2.*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="AstarPathfindingProject">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\AstarPathfindingProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Bitpacker">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Bitpacker.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Circuits.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CSCore">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\CSCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EasyAntiCheat.Client">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\EasyAntiCheat.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppMono.Security">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppMono.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2Cppmscorlib">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2Cppmscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Configuration">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Configuration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Core">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Drawing">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Runtime.Serialization">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Xml">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Il2CppSystem.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Oculus.Platform">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Oculus.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Oculus.VR">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Oculus.VR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OSA">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\OSA.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.ClipperLib">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Pathfinding.ClipperLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Ionic.Zip.Reduced">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Poly2Tri">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Pathfinding.Poly2Tri.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Photon3Unity3D">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Photon3Unity3D.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonChat">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonChat.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonRealtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonRealtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonUnityNetworking">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonUnityNetworking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonUnityNetworking.Utilities">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonUnityNetworking.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonVoice.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice.API">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonVoice.API.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice.PUN">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonVoice.PUN.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonWebSocket">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\PhotonWebSocket.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pngcs">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Pngcs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Agdxgidisplays.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Agdxgidisplays.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Agmobilear.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Agmobilear.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Assetbundles.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Assetbundles.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Async">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Async.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Circuitsv2.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Circuitsv2.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.CultureUtil.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.CultureUtil.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Datastructures.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.EditorHelpers.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.EditorHelpers.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.iOSNative.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.iOSNative.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.DataTypes.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Networking.DataTypes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.Mocks">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Networking.Mocks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.NetworkedObjects.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Networking.NetworkedObjects.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.RPC.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Networking.RPC.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.SynchronizedFields.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Networking.SynchronizedFields.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ProBuilderExtensions">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.ProBuilderExtensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Promises.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Promises.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ResourceManagement.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.ResourceManagement.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Scheduler.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Scheduler.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Streamingaudio.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Streamingaudio.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Tmp_overrides.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Tmp_overrides.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Tweening.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Tweening.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Unityextensions.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\RecRoom.Unityextensions.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.Foundation">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SA.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.Foundation.Network">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SA.Foundation.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.Foundation.Tests">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SA.Foundation.Tests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.iOS">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SA.iOS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.iOS.XCode">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SA.iOS.XCode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SteamVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR_Actions">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\SteamVR_Actions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Addressables">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Addressables.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Burst">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Burst.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Burst.Unsafe">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Burst.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Collections">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Jobs">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Jobs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Mathematics">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Mathematics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Postprocessing.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.Postprocessing.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipelines.Core.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipelines.Universal.Runtime">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ResourceManager">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.ARFoundation">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.XR.ARFoundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.ARSubsystems">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.XR.ARSubsystems.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.Management">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Unity.XR.Management.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpatialTracking">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SpatialTracking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UNETModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UNETModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XR.LegacyInputHelpers">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.XR.LegacyInputHelpers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Valve.Newtonsoft.Json">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\Valve.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XboxUWP">
|
||||
<HintPath>..\..\..\Downloads\Radium_PC_20260220_KbdgFG\BepInEx\interop\XboxUWP.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
using BestHTTP;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace CannedNet.Client.Patches;
|
||||
|
||||
public class SendRequestPatch
|
||||
{
|
||||
[HarmonyPatch(typeof(HTTPManager), "SendRequest", [typeof(HTTPRequest)])]
|
||||
public class ConnectToRecNetPatch
|
||||
{
|
||||
private static void Prefix(ref HTTPRequest request)
|
||||
{
|
||||
Plugin.Log.LogInfo($"hi {request.Uri.Host}");
|
||||
|
||||
if (request.Uri.Host.ToString().Contains("ns.rec.net"))
|
||||
request.Uri = new Il2CppSystem.Uri("https://ns.lapis.codes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using BepInEx;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace CannedNet.Client;
|
||||
|
||||
[BepInPlugin("lapis.cannednet.client", "CannedNet Client", "1.0.0")]
|
||||
public class Plugin : BasePlugin
|
||||
{
|
||||
internal static new ManualLogSource Log;
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
Log = base.Log;
|
||||
Log.LogInfo($"I JUST HIT THE JACKPOTTTT!!!!! YUH YUH YUH!");
|
||||
|
||||
Harmony.CreateAndPatchAll(typeof(Plugin).Assembly);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<Project>
|
||||
<!-- Copy this file to "GamePath.props" (same folder) and set GamePath to your local
|
||||
Rec Room install. GamePath.props is gitignored, so your local path stays out of the repo.
|
||||
|
||||
The install must have been launched once under BepInEx 6 (IL2CPP) so that
|
||||
BepInEx/interop/ is populated with the proxy assemblies this project references. -->
|
||||
<PropertyGroup>
|
||||
<GamePath>C:\Path\To\RecRoom</GamePath>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 djdevin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,77 @@
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
// Test tool: persist a genuinely corrupt STORED device id on this machine, matching the friend's
|
||||
// condition (stored id truncated, current id healthy).
|
||||
//
|
||||
// We can't hand-craft the stored value: it lives in PlayerPrefs under an obfuscated key, encoded as a
|
||||
// CodeStage ObscuredString, and both the key and the encode method are renamed per game build. So we
|
||||
// let the game write it: WriteDUIDs() stores ObscuredString(SystemInfo.deviceUniqueIdentifier) under
|
||||
// the right key. We temporarily spoof deviceUniqueIdentifier to a truncated value around that one
|
||||
// call, so the game encrypts+stores a bad id with its own (unknown-to-us) key. Afterwards the spoof
|
||||
// is off, so the current id reads healthy again -> stored != current -> real mismatch on next launch.
|
||||
[HarmonyPatch]
|
||||
public static class CorruptDUIDPatch
|
||||
{
|
||||
// Only true for the duration of the WriteDUIDs() call below, so the SystemInfo getter is spoofed
|
||||
// exactly there and nowhere else.
|
||||
private static bool _spoofActive;
|
||||
private static string _spoofValue = "";
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SystemInfo), "get_deviceUniqueIdentifier")]
|
||||
private static bool DeviceIdGetterPrefix(ref string __result)
|
||||
{
|
||||
if (!_spoofActive)
|
||||
return true;
|
||||
__result = _spoofValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the corruption was written (so the caller marks it done and won't repeat).
|
||||
public static bool CorruptStored(GameObject cheatMgrGo)
|
||||
{
|
||||
var cm = cheatMgrGo.GetComponent<CheatManager>() ?? cheatMgrGo.GetComponentInChildren<CheatManager>();
|
||||
if (cm == null)
|
||||
{
|
||||
Plugin.Log.LogError("[CORRUPT] could not find CheatManager component; nothing written");
|
||||
return false;
|
||||
}
|
||||
|
||||
var real = SystemInfo.deviceUniqueIdentifier; // spoof off -> real id
|
||||
var bad = real is { Length: >= 7 } ? real.Substring(0, 7) : "badduid";
|
||||
|
||||
_spoofValue = bad;
|
||||
_spoofActive = true;
|
||||
try
|
||||
{
|
||||
cm.WriteDUIDs(); // encodes+stores ObscuredString(bad) under the real key
|
||||
}
|
||||
finally
|
||||
{
|
||||
_spoofActive = false;
|
||||
}
|
||||
|
||||
Plugin.Log.LogWarning($"[CORRUPT] wrote truncated stored DUID = \"{bad}\" (real id = \"{real}\"). " +
|
||||
"Set 'Corrupt Stored DUID' back to false and relaunch to drive the real mismatch path.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Undo: overwrite the stored value with the real id by calling WriteDUIDs with the spoof off.
|
||||
public static bool RestoreStored(GameObject cheatMgrGo)
|
||||
{
|
||||
var cm = cheatMgrGo.GetComponent<CheatManager>() ?? cheatMgrGo.GetComponentInChildren<CheatManager>();
|
||||
if (cm == null)
|
||||
{
|
||||
Plugin.Log.LogError("[CORRUPT] could not find CheatManager component; nothing restored");
|
||||
return false;
|
||||
}
|
||||
|
||||
cm.WriteDUIDs(); // spoof off -> stores ObscuredString(real deviceUniqueIdentifier)
|
||||
Plugin.Log.LogWarning($"[CORRUPT] restored stored DUID to real id = \"{SystemInfo.deviceUniqueIdentifier}\". " +
|
||||
"Set 'Restore Stored DUID' back to false.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using HarmonyLib;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
// Controls CheatManager.CheckForDUIDMismatch, which returns true when the machine's stored device id
|
||||
// differs from the freshly-derived one. A true result sends the client down the migration path that
|
||||
// POSTs PlayerReporting/v1/deviceId and then stalls on Create Account.
|
||||
//
|
||||
// Three modes, chosen by config:
|
||||
// Simulate = true -> force TRUE (fake a mismatch to reproduce the hang without a corrupt value)
|
||||
// Suppress = true -> force FALSE (the workaround fix: never migrate, never hang)
|
||||
// both false -> pass through, let the REAL check run against the actual stored value
|
||||
// (needed to observe a genuinely corrupt stored id, e.g. after Corrupt Stored DUID)
|
||||
//
|
||||
// Patch the concrete CheatManager method, NOT the abstract PGECJHKNIEN interface, or the prefix
|
||||
// never runs.
|
||||
[HarmonyPatch]
|
||||
public static class DUIDMismatchPatch
|
||||
{
|
||||
private const string SimulatedStoredDeviceId = "491e8b9";
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CheatManager), "CheckForDUIDMismatch")]
|
||||
// __0 = the out-param (positional). Its obfuscated name changes every game build, so binding it
|
||||
// by name throws "Parameter ... not found" on upgrade.
|
||||
private static bool Prefix(ref string __0, ref bool __result)
|
||||
{
|
||||
if (Plugin.SimulateDUIDMismatch.Value)
|
||||
{
|
||||
__0 = SimulatedStoredDeviceId;
|
||||
__result = true;
|
||||
Plugin.Log.LogWarning($"[DUID] simulating mismatch, stored id = {SimulatedStoredDeviceId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Plugin.SuppressDUIDMismatch.Value)
|
||||
{
|
||||
__0 = string.Empty;
|
||||
__result = false;
|
||||
Plugin.Log.LogInfo("[DUID] mismatch check forced to false (suppressed)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pass through to the real check.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
// Diagnostic only. Two jobs:
|
||||
// 1. Show where the stored device id lives, by logging PlayerPrefs reads/writes.
|
||||
// 2. Show how far the DUID migration branch gets, by logging CheatManager's other DUID methods.
|
||||
// If WriteDUIDs() never fires after the deviceId POST, the flow stalls before it.
|
||||
[HarmonyPatch]
|
||||
public static class DUIDProbePatch
|
||||
{
|
||||
// PlayerPrefs.GetString is called constantly, so log each key only once — except device/DUID
|
||||
// keys, which we always log so we can watch them change across the migration.
|
||||
private static readonly HashSet<string> SeenKeys = new();
|
||||
|
||||
private static bool IsInteresting(string key) =>
|
||||
key != null && (key.Contains("DUID") || key.Contains("Duid") || key.Contains("duid")
|
||||
|| key.Contains("Device") || key.Contains("device")
|
||||
|| key.Contains("Anon") || key.Contains("anon"));
|
||||
|
||||
private static void Note(string op, string key, string value)
|
||||
{
|
||||
if (IsInteresting(key))
|
||||
Plugin.Log.LogWarning($"[DUID-PROBE] {op} {key} = \"{value}\"");
|
||||
else if (SeenKeys.Add($"{op}:{key}"))
|
||||
Plugin.Log.LogInfo($"[DUID-PROBE] {op} {key} = \"{value}\"");
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlayerPrefs), nameof(PlayerPrefs.GetString), [typeof(string)])]
|
||||
private static void GetStringPostfix(string key, string __result) => Note("get", key, __result);
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlayerPrefs), nameof(PlayerPrefs.GetString), [typeof(string), typeof(string)])]
|
||||
private static void GetStringDefaultPostfix(string key, string __result) => Note("get", key, __result);
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerPrefs), nameof(PlayerPrefs.SetString))]
|
||||
private static void SetStringPrefix(string key, string value) => Note("SET", key, value);
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerPrefs), nameof(PlayerPrefs.DeleteKey))]
|
||||
private static void DeleteKeyPrefix(string key) => Note("DEL", key, "<deleted>");
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CheatManager), "WriteDUIDs")]
|
||||
private static void WriteDUIDsPrefix() => Plugin.Log.LogWarning("[DUID-PROBE] WriteDUIDs() called");
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CheatManager), "WriteDUIDs")]
|
||||
private static void WriteDUIDsPostfix() => Plugin.Log.LogWarning("[DUID-PROBE] WriteDUIDs() returned");
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CheatManager), "ClearDUIDs")]
|
||||
private static void ClearDUIDsPrefix() => Plugin.Log.LogWarning("[DUID-PROBE] ClearDUIDs() called");
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using BestHTTP;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime;
|
||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
// Experiment harness for the Create Account hang.
|
||||
//
|
||||
// On a device-id mismatch the client POSTs PlayerReporting/v1/deviceId, the server answers
|
||||
// 200 {"success":true}, and then the client stops: CheatManager.WriteDUIDs() is never called, so the
|
||||
// new id is never persisted and the flow never reaches create_account. That means the client can't
|
||||
// proceed on what it got back.
|
||||
//
|
||||
// This rewrites that one response body before the game sees it, so response shapes can be tried
|
||||
// without redeploying the server. WriteDUIDs() appearing in the log (see DUIDProbePatch) is the
|
||||
// pass signal: it means the client accepted the response and resumed the migration.
|
||||
[HarmonyPatch]
|
||||
public static class DeviceIdResponsePatch
|
||||
{
|
||||
private const string Endpoint = "/PlayerReporting/v1/deviceId";
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(HTTPManager), "SendRequest", [typeof(HTTPRequest)])]
|
||||
private static void Prefix(HTTPRequest request)
|
||||
{
|
||||
if (!request.Uri.AbsoluteUri.Contains(Endpoint, StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
var original = request.Callback;
|
||||
|
||||
// Whether the game attached a completion callback at all. If this logs False, the client is
|
||||
// not waiting on this request through the callback API and the "stuck on the response" model
|
||||
// is wrong -- that would be worth knowing before chasing response shapes any further.
|
||||
Plugin.Log.LogWarning($"[DEVICEID] request seen; game callback attached = {original != null}");
|
||||
|
||||
var body = Plugin.DeviceIdResponseOverride.Value;
|
||||
if (string.IsNullOrEmpty(body))
|
||||
return;
|
||||
|
||||
var status = Plugin.DeviceIdResponseStatus.Value;
|
||||
|
||||
request.Callback = DelegateSupport.ConvertDelegate<OnRequestFinishedDelegate>(
|
||||
(Action<HTTPRequest, HTTPResponse>)((req, resp) =>
|
||||
{
|
||||
if (resp != null)
|
||||
{
|
||||
// Set both: DataAsText is computed from Data but cached in dataAsText once read,
|
||||
// and our own HTTP logger may already have read it.
|
||||
resp.Data = new Il2CppStructArray<byte>(Encoding.UTF8.GetBytes(body));
|
||||
resp.dataAsText = body;
|
||||
resp.StatusCode = status;
|
||||
Plugin.Log.LogWarning($"[DEVICEID] response overridden -> {status} {body}");
|
||||
}
|
||||
|
||||
original?.Invoke(req, resp);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using HarmonyLib;
|
||||
using Org.BouncyCastle.Crypto.Tls;
|
||||
|
||||
namespace CannedNet.Client.Patches;
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
public class FuckOffTLS
|
||||
/**
|
||||
Disables TLS certificate pinning. Even though we connect over SSL it seems some certificates
|
||||
might be pinned.
|
||||
*/
|
||||
public class DisableTLSPinning
|
||||
{
|
||||
[HarmonyPatch(typeof(LegacyTlsAuthentication), "NotifyServerCertificate")]
|
||||
public class TlsPatch
|
||||
@@ -13,4 +17,4 @@ public class FuckOffTLS
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using HarmonyLib;
|
||||
using RecRoom.AntiCheat;
|
||||
using System.Text;
|
||||
using Il2CppSystem;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
[HarmonyPatch]
|
||||
public static class EACPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
// The "is ready" check: the only static, 0-param bool method on EACManager that isn't a property
|
||||
// getter. 20230414 build: MCFIOBHCFBB (was IMMGELPFGCK, was FJLMLEPOKGE). Method names here are
|
||||
// strings, so a rename is not a compile error — it shows up as a HarmonyX "method not found" at load.
|
||||
[HarmonyPatch(typeof(EACManager), "MCFIOBHCFBB")]
|
||||
private static bool IsReadyPatch(ref bool __result)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(EACManager), "GenerateChallengeResponse")]
|
||||
// __0 = the challenge string (positional); obfuscated param names shift between game builds.
|
||||
private static bool GenerateChallengeResponsePatch(string __0, ref string __result)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(__0))
|
||||
__result = Convert.ToBase64String(Encoding.UTF8.GetBytes(__0));
|
||||
else
|
||||
__result = Convert.ToBase64String(Encoding.UTF8.GetBytes("nothing"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||
using Il2CppSystem.Security.Cryptography;
|
||||
using Convert = Il2CppSystem.Convert;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
// Image signing: the client verifies images against an RSA public key whose modulus is a string
|
||||
// literal in global-metadata.dat. Patching that literal is fragile, so we intervene at the framework
|
||||
// level instead, between the literal and the verify.
|
||||
//
|
||||
// The stored value is 256 bytes once base64-decoded and does NOT start with 0x30, so it is a RAW
|
||||
// 2048-bit modulus, not a DER/SPKI blob. The client therefore has to base64-decode it and hand-build
|
||||
// an RSAParameters { Modulus, Exponent }. Both of those steps are plain framework calls with
|
||||
// unobfuscated names, which is why hooking here survives game rebuilds (unlike the obfuscated
|
||||
// PromisePatch this replaces).
|
||||
//
|
||||
// Two knobs, see [Signing] in the .cfg:
|
||||
// Disable Signature Verification -> THE FIX (default true). Forces the RSA verify to succeed, so
|
||||
// the modulus never has to match and unsigned images load. This
|
||||
// self-hosted setup does not use image signing.
|
||||
// Signing Modulus Override -> secondary: swap in your own modulus and keep real verification,
|
||||
// for a deployment that DOES want signed images. Ignored (well,
|
||||
// redundant) while the verify is disabled.
|
||||
//
|
||||
// Both are belt-and-braces: we swap at Convert.FromBase64String (catches the value regardless of
|
||||
// which crypto stack consumes it) AND at ImportParameters (catches it if the client uses some other
|
||||
// base64 decoder). Whichever fires first wins; the second sees the already-swapped value and no-ops.
|
||||
//
|
||||
// If the log never shows "[SIG] stock modulus seen", the client is not using mscorlib RSA at all —
|
||||
// the fallback is BestHTTP.SecureProtocol.Org.BouncyCastle, where the equivalent hooks are
|
||||
// RsaKeyParameters..ctor(bool, BigInteger, BigInteger) and the concrete RsaDigestSigner/PssSigner
|
||||
// .VerifySignature (NOT the ISigner "interface", which is abstract and never dispatches).
|
||||
[HarmonyPatch]
|
||||
public static class ImageSigningPatch
|
||||
{
|
||||
// The stock 2048-bit public modulus baked into global-metadata.dat (base64, 344 chars).
|
||||
private const string StockModulusBase64 =
|
||||
"X07yXkxaaLcZ1wVXfkWjgFkkqdoLhDFm0GPODsF+Q47pSUlbLvtXGqStnyEJEIrQmgDiicAvCdGRq4lovr2l5sIP" +
|
||||
"MaoyizsbVHBdwLUrCsji0RvSBnmvN+8KqQ8STnB4DP4pAsPilfD35def4WuX/xMCXB5+hQUVhv27HPV8Dj9XzHuJ" +
|
||||
"AijIM9UwDZmvUcECyiO4wv+TaZi2+ELBtaLCQR8Gm1ZPeDEwP62Ch6MJy0jx5pkvvD0KdF9Wye+3/Wx31Zn/Trdo" +
|
||||
"9HL4sGFWPDM9H9kQhZd5wkTHuxpwGIIhlzIwvY2/pBGdZKP6fi1D2jROEmVkBDyhmYY9nO+s3/bndQ==";
|
||||
|
||||
private const int ModulusBytes = 256;
|
||||
|
||||
private static byte[] _stockModulus;
|
||||
private static byte[] _override;
|
||||
private static bool _overrideResolved;
|
||||
private static bool _loggedSeen;
|
||||
private static bool _loggedForced;
|
||||
|
||||
private static byte[] Stock => _stockModulus ??= System.Convert.FromBase64String(StockModulusBase64);
|
||||
|
||||
// Decoded lazily and cached, so a malformed config value is reported once instead of per call.
|
||||
private static byte[] Override
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_overrideResolved)
|
||||
return _override;
|
||||
_overrideResolved = true;
|
||||
|
||||
var raw = Plugin.SigningModulusOverride.Value;
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
return _override = null;
|
||||
|
||||
try
|
||||
{
|
||||
var bytes = System.Convert.FromBase64String(raw.Trim());
|
||||
if (bytes.Length != ModulusBytes)
|
||||
{
|
||||
Plugin.Log.LogError(
|
||||
$"[SIG] 'Signing Modulus Override' decoded to {bytes.Length} bytes, expected {ModulusBytes} " +
|
||||
"(a raw 2048-bit modulus). Ignoring it. Note this must be the bare modulus, NOT a PEM/DER key.");
|
||||
return _override = null;
|
||||
}
|
||||
|
||||
Plugin.Log.LogWarning("[SIG] signing modulus override active");
|
||||
return _override = bytes;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
Plugin.Log.LogError("[SIG] 'Signing Modulus Override' is not valid base64. Ignoring it.");
|
||||
return _override = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsStock(Il2CppStructArray<byte> value)
|
||||
{
|
||||
if (value == null || value.Length != ModulusBytes)
|
||||
return false;
|
||||
|
||||
var stock = Stock;
|
||||
for (var i = 0; i < ModulusBytes; i++)
|
||||
if (value[i] != stock[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void NoteSeen(string where)
|
||||
{
|
||||
if (_loggedSeen)
|
||||
return;
|
||||
_loggedSeen = true;
|
||||
Plugin.Log.LogWarning($"[SIG] stock modulus seen at {where}");
|
||||
}
|
||||
|
||||
// Choke point 1: the base64 decode of the literal. Guarded by a length check first, because this
|
||||
// runs for every base64 decode in the game.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Convert), nameof(Convert.FromBase64String))]
|
||||
private static bool FromBase64StringPrefix(string __0, ref Il2CppStructArray<byte> __result)
|
||||
{
|
||||
if (__0 == null || __0.Length != StockModulusBase64.Length || __0 != StockModulusBase64)
|
||||
return true;
|
||||
|
||||
NoteSeen("Convert.FromBase64String");
|
||||
|
||||
var replacement = Override;
|
||||
if (replacement == null)
|
||||
return true;
|
||||
|
||||
var arr = new Il2CppStructArray<byte>(ModulusBytes);
|
||||
for (var i = 0; i < ModulusBytes; i++)
|
||||
arr[i] = replacement[i];
|
||||
|
||||
__result = arr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Choke point 2: the key import. Mutates the modulus in place — both are 2048-bit, so the array
|
||||
// is already the right size and no reallocation is needed.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RSACryptoServiceProvider), nameof(RSACryptoServiceProvider.ImportParameters))]
|
||||
private static void ImportParametersPrefix(RSAParameters __0)
|
||||
{
|
||||
var modulus = __0?.Modulus;
|
||||
if (!IsStock(modulus))
|
||||
return;
|
||||
|
||||
NoteSeen("RSACryptoServiceProvider.ImportParameters");
|
||||
|
||||
var replacement = Override;
|
||||
if (replacement == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < ModulusBytes; i++)
|
||||
modulus[i] = replacement[i];
|
||||
}
|
||||
|
||||
// Forces EVERY mscorlib RSA verification to succeed, not just image signatures. BestHTTP's TLS
|
||||
// uses its own bundled BouncyCastle rather than mscorlib RSA, so this should not touch
|
||||
// certificate validation — but it is a blunt instrument, so it stays behind a config knob rather
|
||||
// than being unconditional.
|
||||
private static bool ForceVerifyTrue(ref bool __result)
|
||||
{
|
||||
if (!Plugin.DisableSignatureVerification.Value)
|
||||
return true;
|
||||
|
||||
if (!_loggedForced)
|
||||
{
|
||||
_loggedForced = true;
|
||||
Plugin.Log.LogWarning("[SIG] signature verification disabled — RSA verify forced to true");
|
||||
}
|
||||
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RSACryptoServiceProvider), nameof(RSACryptoServiceProvider.VerifyData))]
|
||||
private static bool VerifyDataPrefix(ref bool __result) => ForceVerifyTrue(ref __result);
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RSACryptoServiceProvider), nameof(RSACryptoServiceProvider.VerifyHash),
|
||||
[typeof(Il2CppStructArray<byte>), typeof(int), typeof(Il2CppStructArray<byte>)])]
|
||||
private static bool VerifyHashPrefix(ref bool __result) => ForceVerifyTrue(ref __result);
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RSACryptoServiceProvider), nameof(RSACryptoServiceProvider.VerifyHash),
|
||||
[typeof(Il2CppStructArray<byte>), typeof(Il2CppStructArray<byte>), typeof(HashAlgorithmName),
|
||||
typeof(RSASignaturePadding)])]
|
||||
private static bool VerifyHashPaddingPrefix(ref bool __result) => ForceVerifyTrue(ref __result);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using ExitGames.Client.Photon;
|
||||
using HarmonyLib;
|
||||
using Photon.Realtime;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
/**
|
||||
Patches Photon to use the App IDs and server hostname/port specified in the plugin config.
|
||||
*/
|
||||
// Obfuscated names shift every game build. Re-resolve by signature: the target is the only
|
||||
// instance, 0-param method returning Photon.Realtime.AppSettings in Assembly-CSharp.
|
||||
// 20230414 build: HPEENKELKDJ.MGKINLFMJLB (was LEALBOODIEE.GBNKOFMAJPA, was GPFPFDBGCEK.AMOHMPKKGHL).
|
||||
[HarmonyPatch(typeof(HPEENKELKDJ), "MGKINLFMJLB")]
|
||||
public class PhotonPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
private static void Postfix(ref AppSettings __result)
|
||||
{
|
||||
if (__result != null)
|
||||
{
|
||||
__result.AppIdRealtime = Plugin.AppIdRT.Value;
|
||||
__result.AppIdVoice = Plugin.AppIdVoice.Value;
|
||||
__result.AppIdChat = Plugin.AppIdChat.Value;
|
||||
__result.FixedRegion = "us";
|
||||
__result.UseNameServer = true;
|
||||
__result.Protocol = ConnectionProtocol.Udp;
|
||||
|
||||
if (Plugin.EnableAdvancedSettings.Value)
|
||||
{
|
||||
__result.Server = Plugin.PhotonHostname.Value;
|
||||
__result.Port = Plugin.PhotonPort.Value == 0
|
||||
? 4533
|
||||
: Plugin.PhotonPort.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using BestHTTP;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime;
|
||||
|
||||
namespace RecNetPlugin.Patches;
|
||||
|
||||
/**
|
||||
Intercept a variety of HTTP requests and rewrite them to point to our own custom server.
|
||||
*/
|
||||
public class SendRequestPatch
|
||||
{
|
||||
// Official name server host to redirect away from, swapped for the custom server.
|
||||
private const string OfficialNameServer = "ns.rec.net";
|
||||
|
||||
// Skip when HTTP-logging so we don't spam the logs.
|
||||
private static readonly string[] LogIgnoreSubstrings =
|
||||
{
|
||||
"/api/gamesight/event",
|
||||
"/data/heartbeat",
|
||||
"/identify",
|
||||
"/httpapi",
|
||||
"/data/event",
|
||||
};
|
||||
|
||||
private static bool IsIgnoredForLogging(string url)
|
||||
{
|
||||
foreach (var s in LogIgnoreSubstrings)
|
||||
if (url.Contains(s, StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cap logged bodies so a large response/request doesn't flood the log.
|
||||
private const int MaxLoggedBodyLength = 10000;
|
||||
|
||||
private static string Truncate(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s) || s.Length <= MaxLoggedBodyLength)
|
||||
return s;
|
||||
return s.Substring(0, MaxLoggedBodyLength) + $"... <truncated {s.Length - MaxLoggedBodyLength} chars>";
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(HTTPManager), "SendRequest", [typeof(HTTPRequest)])]
|
||||
public class ConnectToRecNetPatch
|
||||
{
|
||||
private static void Prefix(ref HTTPRequest request)
|
||||
{
|
||||
var debug = Plugin.Debug.Value && !IsIgnoredForLogging(request.Uri.AbsoluteUri);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
var entityBody = request.GetEntityBody();
|
||||
string body;
|
||||
if (entityBody == null)
|
||||
body = "<none>";
|
||||
else if (IsBinaryContentType(request.GetFirstHeaderValue("content-type")) || LooksBinary(entityBody))
|
||||
body = BinaryPreview(entityBody);
|
||||
else
|
||||
body = System.Text.Encoding.UTF8.GetString(entityBody);
|
||||
Plugin.Log.LogInfo($"[HTTP] {request.MethodType} {request.Uri.AbsoluteUri} body={Truncate(body)}");
|
||||
}
|
||||
|
||||
var host = request.Uri.Host;
|
||||
if (host == OfficialNameServer)
|
||||
{
|
||||
// Redirect the nameserver lookup to the custom server, swapping only the host.
|
||||
var newHost = new System.Uri(Plugin.ServerHostname.Value).Host;
|
||||
var builder = new Il2CppSystem.UriBuilder(request.Uri) { Host = newHost };
|
||||
request.Uri = builder.Uri;
|
||||
|
||||
if (debug)
|
||||
Plugin.Log.LogInfo($"[HTTP] intercepted {host} -> {newHost}");
|
||||
}
|
||||
|
||||
if (debug)
|
||||
LogResponseWhenDone(request);
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps the request's completion callback so we log the response (status + body) when it
|
||||
// finishes, then forwards to the game's original callback. This is how we see *which*
|
||||
// request comes back empty (RecNet throws "Response was empty" on a blank body).
|
||||
private static void LogResponseWhenDone(HTTPRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var original = request.Callback;
|
||||
var url = request.Uri.AbsoluteUri;
|
||||
|
||||
request.Callback = DelegateSupport.ConvertDelegate<OnRequestFinishedDelegate>(
|
||||
(Action<HTTPRequest, HTTPResponse>)((req, resp) =>
|
||||
{
|
||||
if (resp == null)
|
||||
Plugin.Log.LogWarning($"[HTTP] <- {url} NO RESPONSE (state={req.State})");
|
||||
else
|
||||
{
|
||||
string text;
|
||||
if (IsBinaryContentType(resp.GetFirstHeaderValue("content-type")))
|
||||
text = "<binary>";
|
||||
else
|
||||
{
|
||||
text = resp.DataAsText;
|
||||
if (string.IsNullOrEmpty(text)) text = "<empty>";
|
||||
}
|
||||
var msg = $"[HTTP] <- {resp.StatusCode} {url} body={Truncate(text)}";
|
||||
if (resp.StatusCode is >= 200 and < 300)
|
||||
Plugin.Log.LogInfo(msg);
|
||||
else
|
||||
Plugin.Log.LogError(msg);
|
||||
}
|
||||
|
||||
original?.Invoke(req, resp);
|
||||
}));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Plugin.Log.LogError($"[HTTP] failed to attach response logger: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
// Content-Type prefixes/keywords we treat as textual; anything else is logged as <binary> so we
|
||||
// don't dump image/asset bytes into the log.
|
||||
private static readonly string[] TextContentTypes =
|
||||
{
|
||||
"text/", "application/json", "application/xml", "application/javascript",
|
||||
"application/x-www-form-urlencoded", "+json", "+xml",
|
||||
};
|
||||
|
||||
// True if the body is (probably) binary and shouldn't be logged as text. Defaults to text when
|
||||
// there's no Content-Type, so we err toward logging rather than hiding.
|
||||
private static bool IsBinaryContentType(string contentType)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentType)) return false;
|
||||
|
||||
foreach (var t in TextContentTypes)
|
||||
if (contentType.Contains(t, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Render the leading bytes of a binary body as text so structured framing (e.g. multipart form
|
||||
// boundaries and part headers) stays readable, while raw bytes are shown as \xNN escapes. Capped
|
||||
// at MaxLoggedBodyLength since the interesting framing is at the front.
|
||||
private static string BinaryPreview(byte[] data)
|
||||
{
|
||||
if (data.Length == 0) return "<binary empty>";
|
||||
|
||||
var sb = new System.Text.StringBuilder(MaxLoggedBodyLength + 32);
|
||||
sb.Append("<binary ").Append(data.Length).Append(" bytes> ");
|
||||
var i = 0;
|
||||
// Cap on rendered length, not byte count: escapes expand a byte to 4 chars, so this keeps the
|
||||
// preview near MaxLoggedBodyLength and avoids a second pass by Truncate at the log site.
|
||||
for (; i < data.Length && sb.Length < MaxLoggedBodyLength; i++)
|
||||
{
|
||||
var b = data[i];
|
||||
if (b == 0x09 || b == 0x0A || b == 0x0D || (b >= 0x20 && b < 0x7F))
|
||||
sb.Append((char)b);
|
||||
else
|
||||
sb.Append("\\x").Append(b.ToString("x2"));
|
||||
}
|
||||
if (i < data.Length)
|
||||
sb.Append($"... <truncated {data.Length - i} bytes>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
// Content sniff for raw request bytes — the Content-Type header isn't reliably set at
|
||||
// SendRequest time (e.g. multipart form bodies set it lazily, and the body still embeds the
|
||||
// raw image), so look at the bytes: a NUL byte, or a high ratio of non-text control bytes in
|
||||
// the first chunk, means it's binary (or binary-mixed like a multipart upload).
|
||||
private static bool LooksBinary(byte[] data)
|
||||
{
|
||||
if (data.Length == 0) return false;
|
||||
|
||||
var sample = Math.Min(data.Length, 4096);
|
||||
var nonText = 0;
|
||||
for (var i = 0; i < sample; i++)
|
||||
{
|
||||
var b = data[i];
|
||||
if (b == 0) return true;
|
||||
// Control chars other than tab/newline/carriage-return.
|
||||
if (b < 0x20 && b != 0x09 && b != 0x0A && b != 0x0D) nonText++;
|
||||
}
|
||||
return nonText * 100 / sample > 10;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace RecNetPlugin;
|
||||
|
||||
[BepInPlugin("net.rec.plugin", "RecNet Plugin", "1.0.0")]
|
||||
public class Plugin : BasePlugin
|
||||
{
|
||||
internal static new ManualLogSource Log;
|
||||
|
||||
public static ConfigEntry<string> AppIdRT { get; private set; }
|
||||
public static ConfigEntry<string> AppIdVoice { get; private set; }
|
||||
public static ConfigEntry<string> AppIdChat { get; private set; }
|
||||
public static ConfigEntry<string> ServerHostname { get; private set; }
|
||||
public static ConfigEntry<bool> EnableAdvancedSettings { get; private set; }
|
||||
public static ConfigEntry<string> PhotonHostname { get; private set; }
|
||||
public static ConfigEntry<int> PhotonPort { get; private set; }
|
||||
public static ConfigEntry<bool> Debug { get; private set; }
|
||||
public static ConfigEntry<bool> SimulateDUIDMismatch { get; private set; }
|
||||
public static ConfigEntry<bool> SuppressDUIDMismatch { get; private set; }
|
||||
public static ConfigEntry<bool> CorruptStoredDUID { get; private set; }
|
||||
public static ConfigEntry<bool> RestoreStoredDUID { get; private set; }
|
||||
public static ConfigEntry<string> DeviceIdResponseOverride { get; private set; }
|
||||
public static ConfigEntry<int> DeviceIdResponseStatus { get; private set; }
|
||||
public static ConfigEntry<bool> DisableSignatureVerification { get; private set; }
|
||||
public static ConfigEntry<string> SigningModulusOverride { get; private set; }
|
||||
|
||||
private static bool _corruptDone;
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
Log = base.Log;
|
||||
|
||||
AppIdRT = Config.Bind("Photon", "App Id Realtime", "", "Photon Realtime App ID");
|
||||
AppIdVoice = Config.Bind("Photon", "App Id Voice", "", "Photon Voice App ID");
|
||||
AppIdChat = Config.Bind("Photon", "App Id Chat", "", "Photon Chat App ID");
|
||||
EnableAdvancedSettings = Config.Bind("Advanced", "Enabled Advanced Settings", false, "Allows other fields below in the advanced section to be modified.");
|
||||
PhotonHostname = Config.Bind("Advanced", "Photon NameServer", "", "Custom Photon NameServer");
|
||||
PhotonPort = Config.Bind("Advanced", "Photon NameServer Port", 0, "Custom Photon NameServer Port (if 0, it will be default)");
|
||||
ServerHostname = Config.Bind("Server", "RecNet NameServer Host", "https://ns.rec.net", "Host for the RecNet NameServer.");
|
||||
Debug = Config.Bind("Advanced", "Debug", false, "Show debug logs (HTTP tracing, etc. WARNING: will include sensitive information such as passwords and auth tokens in the logs, be careful when sharing them!)");
|
||||
SimulateDUIDMismatch = Config.Bind("Advanced", "Simulate DUID Mismatch", false, "Force CheckForDUIDMismatch to return TRUE (fakes the comparison only). Reproduces the hang path but does not corrupt any stored value. Leave false for normal play.");
|
||||
SuppressDUIDMismatch = Config.Bind("Advanced", "Suppress DUID Mismatch", true, "Force CheckForDUIDMismatch to return FALSE (the workaround fix, ON by default): the client never migrates and never takes the Create Account hang path. No-op on healthy machines (the real check returns false anyway); on mismatched machines it skips the hang. Set false only to observe the real mismatch behavior for debugging.");
|
||||
CorruptStoredDUID = Config.Bind("Advanced", "Corrupt Stored DUID", false, "ONE-SHOT TEST: on next launch, write a truncated device id into the DUID pref via the game's own WriteDUIDs, producing a genuinely corrupt STORED value (real current id) — exactly the friend's condition. After it logs '[CORRUPT] wrote', set this back to false and relaunch to drive the real mismatch path. Use 'Restore Stored DUID' to undo.");
|
||||
RestoreStoredDUID = Config.Bind("Advanced", "Restore Stored DUID", false, "ONE-SHOT UNDO: on next launch, call WriteDUIDs with the real device id, overwriting any corrupt stored value with a good one. Set back to false after it logs '[CORRUPT] restored'.");
|
||||
DeviceIdResponseOverride = Config.Bind("Advanced", "DeviceId Response Override", "", "Replace the body of the PlayerReporting/v1/deviceId response with this text, to test what shape the client will accept. Empty = leave the server's response alone.");
|
||||
DeviceIdResponseStatus = Config.Bind("Advanced", "DeviceId Response Status", 200, "HTTP status to force on the PlayerReporting/v1/deviceId response. Only applies when the override body is set.");
|
||||
|
||||
DisableSignatureVerification = Config.Bind("Signing", "Disable Signature Verification", true, "Force RSA signature verification to succeed (ON by default), so the client stops checking that images are signed with Rec Room's private key. This is what lets a self-hosted server serve its own images without the baked-in modulus matching. Set false only if you actually want signed images, in which case use 'Signing Modulus Override' instead. NOTE: this forces ALL mscorlib RSA verification to pass, not just image signatures.");
|
||||
SigningModulusOverride = Config.Bind("Signing", "Signing Modulus Override", "", "Optional alternative to disabling verification: your own RSA public modulus, base64, RAW 2048-bit (256 bytes decoded) — NOT a PEM/DER key. When set, it is substituted for the modulus baked into global-metadata.dat and real verification still runs, so images stay signed with your keypair. Redundant while 'Disable Signature Verification' is true. Empty = leave the stock modulus alone.");
|
||||
|
||||
Harmony.CreateAndPatchAll(typeof(Plugin).Assembly);
|
||||
|
||||
SceneManager.sceneLoaded += (Action<Scene, LoadSceneMode>)OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
// CheatManager boots us out of rooms when it runs, but it's ALSO the DUID service the DI
|
||||
// container resolves for account creation / login (destroying it removes that service).
|
||||
// So instead of destroying it, *deactivate* the GameObject: it stops running (no Update /
|
||||
// coroutines, so no boot) while the component still exists, so the DI container can still
|
||||
// resolve PGECJHKNIEN and call its DUID methods. It's recreated per scene, so deactivate
|
||||
// each freshly-spawned (active) instance on every load. (GameObject.Find only returns active
|
||||
// objects, so once deactivated it isn't found again.)
|
||||
var cheatMgr = GameObject.Find("GameRoot/(Startup)(Clone)/Core Systems/[CheatManager]");
|
||||
if (cheatMgr == null)
|
||||
return;
|
||||
|
||||
// One-shot corruption for testing: must run while the component is still active (before we
|
||||
// deactivate it below), because it calls the live CheatManager.WriteDUIDs().
|
||||
if (CorruptStoredDUID.Value && !_corruptDone)
|
||||
_corruptDone = Patches.CorruptDUIDPatch.CorruptStored(cheatMgr);
|
||||
else if (RestoreStoredDUID.Value && !_corruptDone)
|
||||
_corruptDone = Patches.CorruptDUIDPatch.RestoreStored(cheatMgr);
|
||||
|
||||
cheatMgr.SetActive(false);
|
||||
Log.LogInfo("cheatmanager deactivated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
# RecNet Plugin
|
||||
|
||||
A [BepInEx 6](https://github.com/BepInEx/BepInEx) (IL2CPP) plugin that points the Rec Room client at a self-hosted / private server.
|
||||
|
||||
It does this entirely client-side with [Harmony](https://harmony.pardeike.net/) patches — no game files are modified on disk (except global-metadata.dat - needed for image signatures). The plugin rewrites the RecNet name-server lookups, swaps in your own Photon credentials, and disables the client-side guards (EasyAntiCheat, TLS certificate pinning) that would otherwise reject a non-official server.
|
||||
|
||||
> ⚠️ This disables anti-cheat and certificate validation on the client. Use at your own risk.
|
||||
|
||||
## Safety
|
||||
|
||||
Using BepInEx plugins may cause anti-virus scanners or Windows Defender to pick it up as a threat.
|
||||
|
||||
If you don't trust the complied .DLL, you can build it yourself.
|
||||
|
||||
See https://github.com/djdevin/recnet-plugin#from-source
|
||||
|
||||
## What it does
|
||||
|
||||
| Patch | File | Effect |
|
||||
| --- | --- | --- |
|
||||
| Name-server redirect | `Patches/SendRequestPatch.cs` | Intercepts `BestHTTP` requests and rewrites the host `ns.rec.net` → your configured server. Also provides optional HTTP request/response logging for development. |
|
||||
| Photon override | `Patches/PhotonPatches.cs` | Replaces the Realtime / Voice / Chat App IDs (and optionally the Photon name server + port) with your own. |
|
||||
| EAC bypass | `Patches/EACPatches.cs` | Forces EasyAntiCheat "ready" and stubs the challenge-response so the client connects without the official anti-cheat. |
|
||||
| TLS bypass | `Patches/DisableTLSPinning.cs` | Skips server-certificate validation so a custom server's cert is accepted. |
|
||||
| Promise stub | `Patches/PromisePatch.cs` | Allows custom global-metadata.dat files without the game crashing. |
|
||||
| CheatManager handling | `Plugin.cs` | Deactivates the in-game `CheatManager` (which would otherwise boot you from rooms) while keeping it resolvable for account creation / login. |
|
||||
| DUID mismatch workaround | `Patches/DUIDMismatchPatch.cs` | Forces the device-id mismatch check to "no mismatch" so the Create Account hang (below) is skipped. **On by default**; no-op on healthy machines. |
|
||||
|
||||
## The Create Account / DUID hang
|
||||
|
||||
Some machines hang forever on **Create Account**. This turned out to be a genuinely nasty one, so it's
|
||||
worth documenting.
|
||||
|
||||
**What happens:** when the client's *stored* device id (DUID) differs from the one derived at runtime,
|
||||
the client takes a "migration" path — it POSTs to `PlayerReporting/v1/deviceId`, the server answers
|
||||
`200 {"success":true}`, and then the client **stalls**: it never makes the `create_account` OAuth call
|
||||
and never persists the new id. Machines whose stored id already matches never take this path, which is
|
||||
why the bug hits some players and not others (and is hard to reproduce if your own machine is fine).
|
||||
|
||||
**The decision point** is `CheatManager.CheckForDUIDMismatch`. Forcing it to return *true* reproduces
|
||||
the hang on any machine; forcing it *false* skips the whole path. That false-forcing is the shipping
|
||||
workaround, exposed as the `Suppress DUID Mismatch` config option, which is **on by default**. It's a
|
||||
no-op on healthy machines (their real check already returns false) and skips the hang on affected ones.
|
||||
|
||||
**Still unsolved:** we have not found where the "old" device id in that POST actually comes from. It
|
||||
survives deleting the entire `HKCU\Software\Against Gravity\Rec Room` registry key, and on the failing
|
||||
run the local `cm_did_ppk` PlayerPref is never even read — so clearing local storage does **not** fix
|
||||
it. The leading theory is that it's held server-side (recorded by the server from earlier reports)
|
||||
and/or cached in memory from a server response, which would make the proper fix server-side. See
|
||||
`CLAUDE.md` for the full investigation and the diagnostic tooling.
|
||||
|
||||
> ⚠️ `Suppress DUID Mismatch` is a workaround: it lets account creation through but does **not** repair
|
||||
> a genuinely corrupt stored/served id — it just stops the client from acting on the mismatch.
|
||||
|
||||
## Requirements
|
||||
|
||||
- A Rec Room install set up with **BepInEx 6 (IL2CPP, bleeding-edge)**, launched at least once so the IL2CPP interop assemblies have been generated under `BepInEx/interop/`.
|
||||
- **.NET 6 SDK** to build the plugin.
|
||||
- Your own server endpoints: a RecNet name server, and [Photon](https://www.photonengine.com) app keys.
|
||||
|
||||
_Looking for a custom RecNet server?_ Try https://github.com/djdevin/recflare
|
||||
|
||||
## Installing
|
||||
|
||||
1. Download the game using https://github.com/SteamRE/DepotDownloader. The manifest ID is `7859140924515540835`.
|
||||
Example: `depotdownloader -app 471710 -depot 471711 -manifest 7859140924515540835`
|
||||
**You must use this specific version.**
|
||||
3. Install BepInEx to the game. See https://docs.bepinex.dev/articles/user_guide/installation/index.html. **Note that you must use version 6!**
|
||||
|
||||
Alternatively, use the [RecFlare client](https://github.com/djdevin/recflare-client)
|
||||
|
||||
### From release
|
||||
|
||||
1. Download a release from [/releases](/releases)
|
||||
2. Drop the `.dll` file into `BepInEx/plugins/`
|
||||
|
||||
### From source
|
||||
|
||||
The project references the game's interop DLLs, so the build needs to know where your Rec Room install lives. Set `GamePath` using any one of:
|
||||
|
||||
1. **A local props file** (recommended):
|
||||
```sh
|
||||
cp GamePath.props.example GamePath.props
|
||||
```
|
||||
then edit `GamePath` in `GamePath.props` to point at your Rec Room install root. This file is local-only and stays out of the repo.
|
||||
|
||||
2. **An environment variable:**
|
||||
```sh
|
||||
set RECROOM_PATH=C:\Path\To\RecRoom # cmd
|
||||
$env:RECROOM_PATH = "C:\Path\To\RecRoom" # PowerShell
|
||||
```
|
||||
|
||||
3. **On the command line:**
|
||||
```sh
|
||||
dotnet build -p:GamePath="C:\Path\To\RecRoom"
|
||||
```
|
||||
|
||||
Then build:
|
||||
|
||||
```sh
|
||||
dotnet build
|
||||
```
|
||||
|
||||
The build validates that `GamePath` is set and that `$(GamePath)\BepInEx\interop` exists, and fails with a clear message otherwise.
|
||||
|
||||
A post-build step (the `DeployPlugin` target in the `.csproj`) automatically copies the built `RecNetPlugin.dll` into your Rec Room install's `BepInEx/plugins/` folder after every build. (The copy will fail if Rec Room is running, since the DLL is locked — close the game and rebuild.) Since `GamePath` already points at your install, you don't need to copy anything by hand — just `dotnet build` and launch the game.
|
||||
|
||||
If you need the DLL elsewhere, it's also left in `bin/Debug/net6.0/`.
|
||||
|
||||
## Configuration
|
||||
|
||||
Start the game for the first time. In `BepInEx` you should now see a `config` folder. If not, verify BepInEx installation and version.
|
||||
|
||||
Inside `config`, edit the `net.rec.plugin.cfg` file and update as needed:
|
||||
|
||||
**[Server]**
|
||||
- `RecNet NameServer Host` — base URL of your RecNet name server (like `https://ns.rec.net`).
|
||||
|
||||
**[Photon]**
|
||||
- `App Id Realtime` — Photon Realtime App ID.
|
||||
- `App Id Voice` — Photon Voice App ID.
|
||||
- `App Id Chat` — Photon Chat App ID.
|
||||
|
||||
**[Signing]**
|
||||
- `Disable Signature Verification` — stops the client checking that images are signed with Rec Room's
|
||||
private key, so your own server can serve images. **On by default**; leave it alone unless you
|
||||
specifically want signed images.
|
||||
- `Signing Modulus Override` — only for setups that *do* want image signing: your own RSA public
|
||||
modulus (base64, raw 2048-bit — not a PEM/DER key). Keeps real verification, against your keypair.
|
||||
Leave empty otherwise.
|
||||
|
||||
**[Advanced]**
|
||||
- `Enabled Advanced Settings` — must be `true` to apply the custom Photon name server / port below.
|
||||
- `Photon NameServer` — custom Photon name server host.
|
||||
- `Photon NameServer Port` — custom port (`0` uses the default, `4533`).
|
||||
- `Debug` — verbose HTTP request/response logging (only needed for development)
|
||||
> ⚠️ Debug logs include **sensitive data** (passwords, auth tokens). Be careful when sharing them.
|
||||
- `Suppress DUID Mismatch` — skips the Create Account / DUID hang (see above). **On by default**; the
|
||||
only DUID option meant for normal use. Set `false` only to observe the real mismatch for debugging.
|
||||
|
||||
The remaining `[Advanced]` DUID options — `Simulate DUID Mismatch`, `Corrupt Stored DUID`,
|
||||
`Restore Stored DUID`, `DeviceId Response Override`, `DeviceId Response Status` — are **diagnostic
|
||||
tools** used to investigate the hang. Leave them at their defaults unless you're debugging it; see
|
||||
`CLAUDE.md` for what each one does.
|
||||
|
||||
## Project layout
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `Plugin.cs` | Plugin entry point, config bindings, Harmony bootstrap |
|
||||
| `Patches/` | Harmony patches (HTTP, EAC, TLS, Photon, DUID) |
|
||||
| `CLAUDE.md` | Developer notes: build gotchas, IL2CPP/interop caveats, and the full DUID-hang investigation |
|
||||
| `RecNetPlugin.csproj` | Build config + interop references (driven by `GamePath`), and the `DeployPlugin` post-build copy |
|
||||
| `GamePath.props.example` | Template for your local `GamePath.props` |
|
||||
|
||||
## FAQ
|
||||
|
||||
**Can I use this for my own Rec Room server?**
|
||||
|
||||
Yes. That's the point.
|
||||
|
||||
## Credits
|
||||
|
||||
Based on https://github.com/CannedNet/CannedNet.Client
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
@@ -0,0 +1,948 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyName>RecNetPlugin</AssemblyName>
|
||||
<Product>RecNetPlugin</Product>
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>
|
||||
https://api.nuget.org/v3/index.json;
|
||||
https://nuget.bepinex.dev/v3/index.json;
|
||||
https://nuget.samboy.dev/v3/index.json
|
||||
</RestoreAdditionalProjectSources>
|
||||
<RootNamespace>RecNetPlugin</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- GamePath = root of a Rec Room install whose BepInEx/interop/ has been populated.
|
||||
It is intentionally NOT hardcoded here so the repo is distributable. Set it via ONE of:
|
||||
1. a local GamePath.props file (copy GamePath.props.example -> GamePath.props; gitignored)
|
||||
2. a RECROOM_PATH environment variable
|
||||
3. the command line: dotnet build -p:GamePath="D:\Path\To\RecRoom" -->
|
||||
<Import Project="$(MSBuildThisFileDirectory)GamePath.props" Condition="Exists('$(MSBuildThisFileDirectory)GamePath.props')" />
|
||||
|
||||
<PropertyGroup>
|
||||
<GamePath Condition="'$(GamePath)' == '' and '$(RECROOM_PATH)' != ''">$(RECROOM_PATH)</GamePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="ValidateGamePath" BeforeTargets="ResolveAssemblyReferences;Build">
|
||||
<Error Condition="'$(GamePath)' == ''"
|
||||
Text="GamePath is not set. Copy GamePath.props.example to GamePath.props and set your Rec Room install path (or set the RECROOM_PATH env var, or pass -p:GamePath=...). See CLAUDE.md." />
|
||||
<Error Condition="'$(GamePath)' != '' and !Exists('$(GamePath)\BepInEx\interop')"
|
||||
Text="GamePath '$(GamePath)' has no BepInEx\interop folder. Point it at a Rec Room install that has been launched once under BepInEx so the IL2CPP interop assemblies are generated." />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile"/>
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="2.*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="AstarPathfindingProject">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\AstarPathfindingProject.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Backtrace.Unity">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Backtrace.Unity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.All.Injection.Debugging">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.All.Injection.Debugging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.All.Injection.PhotonNetSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.All.Injection.PhotonNetSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.All.Injection.UnityEngine">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.All.Injection.UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.All.Mock">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.All.Mock.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.All.RecRoom">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.All.RecRoom.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Dynamic.Core.NetSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Dynamic.Core.NetSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Dynamic.Mock">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Dynamic.Mock.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Shared.Core.ByteCode">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Shared.Core.ByteCode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Shared.CV2.Dependencies">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Shared.CV2.Dependencies.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Shared.RecRoom.Engine">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Shared.RecRoom.Engine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Shared.RecRoom.Objects">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Shared.RecRoom.Objects.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Shared.Utilities">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Shared.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.CompileSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.CompileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.GraphSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.GraphSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.NetSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.NetSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.RequestReduce">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.RequestReduce.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.TreeSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.TreeSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.TypeCheckSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.TypeCheckSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.TypeSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.TypeSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Core.UnificationSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Core.UnificationSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.EV">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.EV.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.RecRoom">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.RecRoom.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.Static.Utilities">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.Static.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Circuits.V2">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Circuits.V2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Codestage.Anticheattoolkit.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Codestage.Anticheattoolkit.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CSCore">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\CSCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EasyAntiCheat.Client">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\EasyAntiCheat.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppMicrosoft.Bcl.HashCode">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppMicrosoft.Bcl.HashCode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppMicrosoft.CognitiveServices.Speech.csharp">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppMicrosoft.CognitiveServices.Speech.csharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppMicrosoft.Toolkit.HighPerformance">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppMicrosoft.Toolkit.HighPerformance.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppMono.Security">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppMono.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2Cppmscorlib">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2Cppmscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Buffers">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Configuration">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Configuration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Core">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Data">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Drawing">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Memory">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Numerics">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Numerics.Vectors">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Runtime.Serialization">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Xml">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Xml.Linq">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Il2CppSystem.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Kyub.EmojiSearch">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Kyub.EmojiSearch.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Logger.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Logger.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NewPlayerChallenges.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\NewPlayerChallenges.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Nito.Collections.Deque">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Nito.Collections.Deque.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Oculus.Platform">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Oculus.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Oculus.VR">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Oculus.VR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OSA">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\OSA.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.ClipperLib">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Pathfinding.ClipperLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Ionic.Zip.Reduced">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pathfinding.Poly2Tri">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Pathfinding.Poly2Tri.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Photon3Unity3D">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Photon3Unity3D.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonChat">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonChat.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonRealtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonRealtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonUnityNetworking">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonUnityNetworking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonUnityNetworking.Utilities">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonUnityNetworking.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonVoice.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice.API">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonVoice.API.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PhotonVoice.PUN">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\PhotonVoice.PUN.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Pngcs">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Pngcs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecNet.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecNet.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecNet.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecNet.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Agdxgidisplays.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Agdxgidisplays.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.AgInitialization.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.AgInitialization.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.AgInitialization.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.AgInitialization.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Agmobilear.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Agmobilear.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Analytics.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Analytics.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ApplicationLifecycle.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ApplicationLifecycle.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Assetbundles.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Assetbundles.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Async">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Async.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Attributes.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Attributes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Audio.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Audio.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.AutomationTests.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.AutomationTests.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.BitPacker.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.BitPacker.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Build.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Build.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Challenges.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Challenges.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Chat.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Chat.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.CircuitsV1.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.CircuitsV1.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ClusterLods.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ClusterLods.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.CodeGen.Attributes">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.CodeGen.Attributes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Commandline.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Commandline.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.CommonDataTypes.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.CommonDataTypes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Configloader.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Configloader.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Connectables.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Connectables.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Content.Authoring.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Content.Authoring.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Creation.Interfaces.UX.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Creation.Interfaces.UX.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Creation.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Creation.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.CultureUtil.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.CultureUtil.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.CollisionMesh.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Datastructures.CollisionMesh.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.CullingGroupManager.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Datastructures.CullingGroupManager.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.OverridableFields.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Datastructures.OverridableFields.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Datastructures.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Datastructures.Singletons.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Datastructures.Singletons.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Debugging.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Debugging.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.EditorHelpers.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.EditorHelpers.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Encoding.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Encoding.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Experiments.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Experiments.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.FastLines.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.FastLines.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.FuzzySearch.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.FuzzySearch.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.GameSystems.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.GameSystems.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Imageutils.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Imageutils.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Imposters.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Imposters.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Instantiation.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Instantiation.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.iOSNative.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.iOSNative.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.JuniorAccountVisibility.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.JuniorAccountVisibility.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Keepsakes.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Keepsakes.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Keepsakes.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Keepsakes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Keepsakes.UnityExtensions">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Keepsakes.UnityExtensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Localization.Service">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Localization.Service.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Maker.Core.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Maker.Core.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Maker.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Maker.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.MemoryStats.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.MemoryStats.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Minijson.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Minijson.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.MobileHome.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.MobileHome.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Nativemesh.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Nativemesh.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.DataTypes.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.DataTypes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.NetworkedObjects.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.NetworkedObjects.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.PhotonImpl.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.PhotonImpl.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.RoomLoading.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.RoomLoading.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.RPC.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.RPC.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Networking.SynchronizedFields.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Networking.SynchronizedFields.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.Algorithms.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.Algorithms.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.Common.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.Common.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.DataStructures.Performance.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.DataStructures.Performance.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.DataStructures.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.DataStructures.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.Debugging.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.Debugging.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.NoEngine.JetBrains.Annotations">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.NoEngine.JetBrains.Annotations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Attributes.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Attributes.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.BitPacker.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.BitPacker.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.ComponentData.Generated.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.ComponentData.Generated.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.ComponentData.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.ComponentData.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.ConfigUI.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.ConfigUI.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Entities.Core.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Entities.Core.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Entities.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Entities.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Interfaces.ConfigUI.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Interfaces.ConfigUI.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Interfaces.Prefabs.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Interfaces.Prefabs.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Interfaces.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Interfaces.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Prefabs.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Prefabs.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Properties.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Properties.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Protobufs.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Protobufs.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.RendererV1.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.RendererV1.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Services.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Services.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Systems.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Systems.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Telemetry.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Telemetry.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Transmission.PUN.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Transmission.PUN.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectModel.Transmission.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectModel.Transmission.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ObjectPool.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ObjectPool.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Persistence.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Persistence.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.PlatformNotifications.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.PlatformNotifications.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Preferences.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Preferences.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.PrefParsers.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.PrefParsers.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ProgressionEvents.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ProgressionEvents.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ProgressionEvents.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ProgressionEvents.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Promises.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Promises.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Protobuf.Debugging.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Protobuf.Debugging.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Protobuf.Extensions.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Protobuf.Extensions.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Protobuf.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Protobuf.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Protobuf.UnityExtensions.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Protobuf.UnityExtensions.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Rbex.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Rbex.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ResourceManagement.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ResourceManagement.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RoomLoading.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RoomLoading.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RoomPermissions.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RoomPermissions.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Rranticheat.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Rranticheat.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RRUI.Core.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RRUI.Core.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RRUI.Data.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RRUI.Data.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RRUI.Navigation.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RRUI.Navigation.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.RRUI.Theme.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.RRUI.Theme.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Scheduling.Interface.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Scheduling.Interface.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Scheduling.Scheduler.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Scheduling.Scheduler.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Scheduling.Schedules.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Scheduling.Schedules.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.ShapeRendering.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.ShapeRendering.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Streamingaudio.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Streamingaudio.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Studio.Common.LocalTesting">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Studio.Common.LocalTesting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Studio.Common.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Studio.Common.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.TagsAndLayers.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.TagsAndLayers.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Time.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Time.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Time.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Time.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Tweening.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Tweening.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.UIInteraction.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.UIInteraction.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Unityextensions.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Unityextensions.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.UrlHandler.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.UrlHandler.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Utf8json.Interfaces">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Utf8json.Interfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Utf8json.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Utf8json.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RecRoom.Versioning.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\RecRoom.Versioning.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.Foundation">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SA.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.Foundation.Network">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SA.Foundation.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.iOS">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SA.iOS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SA.iOS.XCode">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SA.iOS.XCode.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Singular">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Singular.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StansAssets.Foundation">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\StansAssets.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StansAssets.Plugins">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\StansAssets.Plugins.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StatsigUnity.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\StatsigUnity.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SteamVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR_Actions">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\SteamVR_Actions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="TextureTool.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\TextureTool.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ToxMod">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\ToxMod.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UJect.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UJect.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UJect.UnityExtensions">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UJect.UnityExtensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Addressables">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Addressables.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Burst">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Burst.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Burst.Unsafe">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Burst.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Collections">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Entities">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Entities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.InputSystem">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.InputSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Jobs">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Jobs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Localization">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Localization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Mathematics">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Mathematics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ProBuilder">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.ProBuilder.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Properties">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Properties.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipelines.Core.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipelines.Universal.Runtime">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ResourceManager">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Serialization">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.ARFoundation">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.ARFoundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.ARSubsystems">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.ARSubsystems.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.Management">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.Management.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.Oculus">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.Oculus.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.OpenVR">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.OpenVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.XR.PSVR">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Unity.XR.PSVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ClothModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Physics2DModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.Physics2DModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpatialTracking">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SpatialTracking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubsystemsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.SubsystemsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainPhysicsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TerrainPhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TilemapModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TilemapModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsNativeModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UIElementsNativeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UNETModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UNETModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VehiclesModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.VehiclesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Valve.Newtonsoft.Json">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\Valve.Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XboxUWP">
|
||||
<HintPath>$(GamePath)\BepInEx\interop\XboxUWP.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="DeployPlugin" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(OutputPath)$(AssemblyName).dll" DestinationFolder="$(GamePath)\BepInEx\plugins\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user