Files
Radicade/2023Patch/RadicadePatch/UnboundPropFreezePatch.cs
T
2026-10-16 23:33:13 -07:00

148 lines
2.6 KiB
C#

using System;
using HarmonyLib;
using Il2CppInterop.Runtime;
using RecRoom;
using RecRoom.ObjectModel;
using UnityEngine;
[HarmonyPatch]
internal static class UnboundPropFreezePatch
{
private static readonly bool _disabled = IsDisabled();
private static int _alreadyInert;
private static bool _loggedNoRigidbody;
private static bool _loggedFailure;
private static readonly Type[] Companions = new Type[3]
{
typeof(EmbodiedObject),
typeof(RbexEntity),
typeof(TransformEntity)
};
internal static bool Enabled => !_disabled;
private static bool IsDisabled()
{
try
{
string environmentVariable = Environment.GetEnvironmentVariable("RADICADE_UNBOUND_PROP_FREEZE");
if (string.IsNullOrWhiteSpace(environmentVariable))
{
return false;
}
bool result;
switch (environmentVariable.Trim().ToLowerInvariant())
{
case "0":
case "off":
case "false":
case "no":
result = true;
break;
default:
result = false;
break;
}
return result;
}
catch
{
return false;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(RigidbodyEx), "Awake")]
private static void Postfix(RigidbodyEx __instance)
{
if (!Enabled || __instance == null)
{
return;
}
try
{
if (!IsBound(__instance))
{
Freeze(__instance);
}
}
catch (Exception ex)
{
if (!_loggedFailure)
{
_loggedFailure = true;
RadicadeEacBypassPlugin.LogSource.LogWarning((object)("[PropGuard] could not freeze an unbound prop (" + ex.GetType().Name + ": " + ex.Message + "); the prop is left exactly as the game built it."));
}
}
}
private static bool IsBound(RigidbodyEx rigidbodyEx)
{
Type[] companions = Companions;
foreach (Type type in companions)
{
try
{
if (rigidbodyEx.GetComponent(Il2CppType.From(type)) != null)
{
return true;
}
}
catch
{
return true;
}
}
return false;
}
private static void Freeze(RigidbodyEx rigidbodyEx)
{
Rigidbody unityRigidbody = rigidbodyEx.unityRigidbody;
if (unityRigidbody == null)
{
if (!_loggedNoRigidbody)
{
_loggedNoRigidbody = true;
}
try
{
rigidbodyEx.ClearUnityRigidbodyVelocity();
return;
}
catch
{
return;
}
}
if (unityRigidbody.isKinematic)
{
_alreadyInert++;
return;
}
unityRigidbody.isKinematic = true;
unityRigidbody.velocity = Vector3.zero;
unityRigidbody.angularVelocity = Vector3.zero;
}
private static string Describe(RigidbodyEx rigidbodyEx)
{
try
{
GameObject gameObject = ((Component)rigidbodyEx).gameObject;
return (gameObject == null) ? "<no game object>" : ("'" + gameObject.name + "'");
}
catch
{
return "<unnamed>";
}
}
}