mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 15:09:26 -07:00
148 lines
2.6 KiB
C#
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>";
|
|
}
|
|
}
|
|
|
|
}
|