From be814f6be54766bd273889760afa2ad775a1022c Mon Sep 17 00:00:00 2001
From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com>
Date: Tue, 28 May 2024 09:38:00 -0500
Subject: [PATCH] [ScriptingSpoofer] Initial build
---
NAK_CVR_Mods.sln | 12 +++
References.Items.props | 16 +++
ScriptingSpoofer/Main.cs | 109 ++++++++++++++++++++
ScriptingSpoofer/Properties/AssemblyInfo.cs | 30 ++++++
ScriptingSpoofer/ScriptingSpoofer.csproj | 2 +
ScriptingSpoofer/format.json | 23 +++++
6 files changed, 192 insertions(+)
create mode 100644 ScriptingSpoofer/Main.cs
create mode 100644 ScriptingSpoofer/Properties/AssemblyInfo.cs
create mode 100644 ScriptingSpoofer/ScriptingSpoofer.csproj
create mode 100644 ScriptingSpoofer/format.json
diff --git a/NAK_CVR_Mods.sln b/NAK_CVR_Mods.sln
index cd698b8..5615c82 100644
--- a/NAK_CVR_Mods.sln
+++ b/NAK_CVR_Mods.sln
@@ -47,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SwitchToDesktopOnSteamVRExi
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoreMenuOptions", "MoreMenuOptions\MoreMenuOptions.csproj", "{AB07B31E-A930-4CCC-8E02-F2A4D6C52C8F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelativeSync", "RelativeSync\RelativeSync.csproj", "{B48C8F19-9451-4EE2-999F-82C0033CDE2C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptingSpoofer", "ScriptingSpoofer\ScriptingSpoofer.csproj", "{6B4396C7-B451-4FFD-87B6-3ED8377AC308}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -141,6 +145,14 @@ Global
{AB07B31E-A930-4CCC-8E02-F2A4D6C52C8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB07B31E-A930-4CCC-8E02-F2A4D6C52C8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB07B31E-A930-4CCC-8E02-F2A4D6C52C8F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B48C8F19-9451-4EE2-999F-82C0033CDE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B48C8F19-9451-4EE2-999F-82C0033CDE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B48C8F19-9451-4EE2-999F-82C0033CDE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B48C8F19-9451-4EE2-999F-82C0033CDE2C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B4396C7-B451-4FFD-87B6-3ED8377AC308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B4396C7-B451-4FFD-87B6-3ED8377AC308}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B4396C7-B451-4FFD-87B6-3ED8377AC308}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6B4396C7-B451-4FFD-87B6-3ED8377AC308}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/References.Items.props b/References.Items.props
index eb1fc43..0f5b866 100644
--- a/References.Items.props
+++ b/References.Items.props
@@ -124,6 +124,10 @@
$(MsBuildThisFileDirectory)\.ManagedLibs\LibVLCSharp.dll
False
+
+ $(MsBuildThisFileDirectory)\.ManagedLibs\LucHeart.CoreOSC.dll
+ False
+
$(MsBuildThisFileDirectory)\.ManagedLibs\MagicaCloth.dll
False
@@ -136,6 +140,10 @@
$(MsBuildThisFileDirectory)\.ManagedLibs\MeshBakerCore.dll
False
+
+ $(MsBuildThisFileDirectory)\.ManagedLibs\Meta.XR.BuildingBlocks.dll
+ False
+
$(MsBuildThisFileDirectory)\.ManagedLibs\Mono.Security.dll
False
@@ -168,6 +176,14 @@
$(MsBuildThisFileDirectory)\.ManagedLibs\Oculus.LipSync.dll
False
+
+ $(MsBuildThisFileDirectory)\.ManagedLibs\Oculus.Platform.dll
+ False
+
+
+ $(MsBuildThisFileDirectory)\.ManagedLibs\Oculus.VR.dll
+ False
+
$(MsBuildThisFileDirectory)\.ManagedLibs\Photon3Unity3D.dll
False
diff --git a/ScriptingSpoofer/Main.cs b/ScriptingSpoofer/Main.cs
new file mode 100644
index 0000000..9f4183d
--- /dev/null
+++ b/ScriptingSpoofer/Main.cs
@@ -0,0 +1,109 @@
+using System.Reflection;
+using ABI_RC.API;
+using ABI_RC.Core.Networking;
+using ABI_RC.Core.Networking.API.Responses;
+using ABI_RC.Systems.GameEventSystem;
+using HarmonyLib;
+using MelonLoader;
+using Random = UnityEngine.Random;
+
+namespace NAK.ScriptingSpoofer;
+
+public class ScriptingSpoofer : MelonMod
+{
+ public static readonly MelonPreferences_Category Category =
+ MelonPreferences.CreateCategory(nameof(ScriptingSpoofer));
+
+ public static readonly MelonPreferences_Entry EntryEnabled =
+ Category.CreateEntry("Enabled", true, description: "Toggle scripting spoofer.");
+
+ public static readonly MelonPreferences_Entry EntryCensorUsername =
+ Category.CreateEntry("Censor Username", true, description: "Censor username. Toggle to randomize username instead.");
+
+ private static string spoofedUsername;
+ private static string spoofedUserId;
+
+ private static readonly char[] CensorChars = {'!', '@', '#', '$', '%', '^', '&', '*'};
+
+ public override void OnInitializeMelon()
+ {
+ ApplyPatches(typeof(PlayerApiPatches));
+
+ // Regenerate spoofed data on login
+ CVRGameEventSystem.Authentication.OnLogin.AddListener(GenerateRandomSpoofedData);
+ }
+
+ private void ApplyPatches(Type type)
+ {
+ try
+ {
+ HarmonyInstance.PatchAll(type);
+ }
+ catch (Exception e)
+ {
+ LoggerInstance.Msg($"Failed while patching {type.Name}!");
+ LoggerInstance.Error(e);
+ }
+ }
+
+ private static void GenerateRandomSpoofedData(UserAuthResponse _) // we get manually
+ {
+ spoofedUsername = EntryCensorUsername.Value ? GenerateCensoredUsername() : GenerateRandomUsername();
+ spoofedUserId = Guid.NewGuid().ToString();
+ }
+
+ private static string GenerateCensoredUsername()
+ {
+ var originalUsername = AuthManager.Username;
+ var usernameArray = originalUsername.ToCharArray();
+
+ for (var i = 0; i < usernameArray.Length; i++)
+ if (Random.value > 0.7f) usernameArray[i] = CensorChars[Random.Range(0, CensorChars.Length)];
+
+ var modifiedUsername = new string(usernameArray);
+ string[] prefixes = { "xX", "_", Random.Range(10, 99).ToString() };
+ string[] suffixes = { "Xx", "_", Random.Range(10, 99).ToString() };
+
+ var prefix = prefixes[Random.Range(0, prefixes.Length)];
+ var suffix = suffixes[Random.Range(0, suffixes.Length)];
+
+ return prefix + modifiedUsername + suffix;
+ }
+
+ private static string GenerateRandomUsername()
+ {
+ const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ char[] username = new char[Random.Range(5, 15)];
+ for (int i = 0; i < username.Length; i++)
+ username[i] = chars[Random.Range(0, chars.Length)];
+
+ return new string(username);
+ }
+
+ private static class PlayerApiPatches
+ {
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(LocalPlayerApi), nameof(LocalPlayerApi.Username), MethodType.Getter)]
+ [HarmonyPatch(typeof(PlayerApiBase), nameof(PlayerApiBase.Username), MethodType.Getter)]
+ private static bool GetSpoofedUsername(ref PlayerApiBase __instance, ref string __result)
+ {
+ if (__instance.IsRemote) return true;
+ if (!EntryEnabled.Value) return true;
+
+ __result = spoofedUsername;
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(LocalPlayerApi), nameof(LocalPlayerApi.UserID), MethodType.Getter)]
+ [HarmonyPatch(typeof(PlayerApiBase), nameof(PlayerApiBase.UserID), MethodType.Getter)]
+ private static bool GetSpoofedUserId(ref PlayerApiBase __instance, ref string __result)
+ {
+ if (__instance.IsRemote) return true;
+ if (!EntryEnabled.Value) return true;
+
+ __result = spoofedUserId;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ScriptingSpoofer/Properties/AssemblyInfo.cs b/ScriptingSpoofer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ee33846
--- /dev/null
+++ b/ScriptingSpoofer/Properties/AssemblyInfo.cs
@@ -0,0 +1,30 @@
+using MelonLoader;
+using NAK.ScriptingSpoofer.Properties;
+using System.Reflection;
+
+[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
+[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
+[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
+[assembly: AssemblyTitle(nameof(NAK.ScriptingSpoofer))]
+[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
+[assembly: AssemblyProduct(nameof(NAK.ScriptingSpoofer))]
+
+[assembly: MelonInfo(
+ typeof(NAK.ScriptingSpoofer.ScriptingSpoofer),
+ nameof(NAK.ScriptingSpoofer),
+ AssemblyInfoParams.Version,
+ AssemblyInfoParams.Author,
+ downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/ScriptingSpoofer"
+)]
+
+[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
+[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
+[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
+[assembly: HarmonyDontPatchAll]
+
+namespace NAK.ScriptingSpoofer.Properties;
+internal static class AssemblyInfoParams
+{
+ public const string Version = "1.0.0";
+ public const string Author = "NotAKidoS";
+}
\ No newline at end of file
diff --git a/ScriptingSpoofer/ScriptingSpoofer.csproj b/ScriptingSpoofer/ScriptingSpoofer.csproj
new file mode 100644
index 0000000..e94f9dc
--- /dev/null
+++ b/ScriptingSpoofer/ScriptingSpoofer.csproj
@@ -0,0 +1,2 @@
+
+
diff --git a/ScriptingSpoofer/format.json b/ScriptingSpoofer/format.json
new file mode 100644
index 0000000..9cafa87
--- /dev/null
+++ b/ScriptingSpoofer/format.json
@@ -0,0 +1,23 @@
+{
+ "_id": 147,
+ "name": "PropUndoButton",
+ "modversion": "1.0.2",
+ "gameversion": "2024r175",
+ "loaderversion": "0.6.1",
+ "modtype": "Mod",
+ "author": "NotAKidoS",
+ "description": "**CTRL+Z** to undo latest spawned prop. **CTRL+SHIFT+Z** to redo deleted prop.\nIncludes optional SFX for prop spawn, undo, redo, warn, and deny, which can be disabled in settings.\n\nYou can replace the sfx in 'ChilloutVR\\ChilloutVR_Data\\StreamingAssets\\Cohtml\\UIResources\\GameUI\\mods\\PropUndo\\audio'.",
+ "searchtags": [
+ "prop",
+ "undo",
+ "bind",
+ "button"
+ ],
+ "requirements": [
+ "None"
+ ],
+ "downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r25/PropUndoButton.dll",
+ "sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/PropUndoButton/",
+ "changelog": "- Recompiled for 2024r175",
+ "embedcolor": "#00FFFF"
+}
\ No newline at end of file