mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-01 05:49:23 +00:00
Custom Components & Managed Libs
This commit is contained in:
parent
d5a2b8d2df
commit
abad2dfb8a
12 changed files with 413 additions and 8 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -3,6 +3,10 @@
|
||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# Nstrip & ManagedLibs stuff
|
||||||
|
NStrip.exe
|
||||||
|
_ManagedLibs/*.dll
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
|
|
|
@ -87,12 +87,12 @@ internal static class BodySystemPatches
|
||||||
SetPelvisWeight(solver.spine, 0f);
|
SetPelvisWeight(solver.spine, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IKFixesMod.EntryUseFakeRootAngle.Value && !BodySystem.isCalibratedAsFullBody)
|
if (IKFixes.EntryUseFakeRootAngle.Value && !BodySystem.isCalibratedAsFullBody)
|
||||||
{
|
{
|
||||||
// Emulate maxRootAngle because CVR doesn't have the player controller set up ideally for VRIK.
|
// Emulate maxRootAngle because CVR doesn't have the player controller set up ideally for VRIK.
|
||||||
// This is a small small fix, but makes it so the feet dont point in the direction of the head
|
// This is a small small fix, but makes it so the feet dont point in the direction of the head
|
||||||
// when turning. It also means turning with joystick & turning IRL make feet behave the same and follow behind.
|
// when turning. It also means turning with joystick & turning IRL make feet behave the same and follow behind.
|
||||||
float weightedAngleLimit = IKFixesMod.EntryFakeRootAngleLimit.Value * solver.locomotion.weight;
|
float weightedAngleLimit = IKFixes.EntryFakeRootAngleLimit.Value * solver.locomotion.weight;
|
||||||
float pivotAngle = MovementSystem.Instance.rotationPivot.eulerAngles.y;
|
float pivotAngle = MovementSystem.Instance.rotationPivot.eulerAngles.y;
|
||||||
float deltaAngleRoot = Mathf.DeltaAngle(pivotAngle, _ikSimulatedRootAngle);
|
float deltaAngleRoot = Mathf.DeltaAngle(pivotAngle, _ikSimulatedRootAngle);
|
||||||
float absDeltaAngleRoot = Mathf.Abs(deltaAngleRoot);
|
float absDeltaAngleRoot = Mathf.Abs(deltaAngleRoot);
|
||||||
|
@ -111,6 +111,11 @@ internal static class BodySystemPatches
|
||||||
// VR default is 25 degrees, but maybe during emotes needs 180 degrees..?
|
// VR default is 25 degrees, but maybe during emotes needs 180 degrees..?
|
||||||
solver.spine.maxRootAngle = BodySystem.isCalibratedAsFullBody ? 0f : 25f;
|
solver.spine.maxRootAngle = BodySystem.isCalibratedAsFullBody ? 0f : 25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// custom IK settings
|
||||||
|
solver.spine.neckStiffness = IKFixes.EntryNeckStiffness.Value;
|
||||||
|
solver.spine.bodyRotStiffness = IKFixes.EntryBodyRotStiffness.Value;
|
||||||
|
solver.spine.rotateChestByHands = IKFixes.EntryRotateChestByHands.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
|
@ -2,16 +2,25 @@
|
||||||
|
|
||||||
namespace NAK.Melons.IKFixes;
|
namespace NAK.Melons.IKFixes;
|
||||||
|
|
||||||
public class IKFixesMod : MelonMod
|
public class IKFixes : MelonMod
|
||||||
{
|
{
|
||||||
public const string SettingsCategory = "IKFixes";
|
public const string SettingsCategory = nameof(IKFixes);
|
||||||
public static readonly MelonPreferences_Category CategoryIKFixes = MelonPreferences.CreateCategory(SettingsCategory);
|
public static readonly MelonPreferences_Category Category = MelonPreferences.CreateCategory(SettingsCategory);
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<bool> EntryUseFakeRootAngle =
|
public static readonly MelonPreferences_Entry<bool> EntryUseFakeRootAngle =
|
||||||
CategoryIKFixes.CreateEntry("Use Fake Root Angle", true, description: "Emulates maxRootAngle. This fixes feet pointing in direction of head when looking around.");
|
Category.CreateEntry("Use Fake Root Angle", true, description: "Emulates maxRootAngle. This fixes feet pointing in direction of head when looking around.");
|
||||||
|
|
||||||
public static readonly MelonPreferences_Entry<float> EntryFakeRootAngleLimit =
|
public static readonly MelonPreferences_Entry<float> EntryFakeRootAngleLimit =
|
||||||
CategoryIKFixes.CreateEntry("Fake Root Angle Limit", 25f, description: "Specifies the maximum angle the lower body can have relative to the head when rotating.");
|
Category.CreateEntry("Fake Root Angle Limit", 25f, description: "Specifies the maximum angle the lower body can have relative to the head when rotating.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryNeckStiffness =
|
||||||
|
Category.CreateEntry("Neck Stiffness", 0.2f, description: "Neck stiffness.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryBodyRotStiffness =
|
||||||
|
Category.CreateEntry("Body Rot Stiffness", 0.1f, description: "Body rotation stiffness.");
|
||||||
|
|
||||||
|
public static readonly MelonPreferences_Entry<float> EntryRotateChestByHands =
|
||||||
|
Category.CreateEntry("Rot Chest By Hands", 1f, description: "Rotate chest by hands.");
|
||||||
|
|
||||||
public override void OnInitializeMelon()
|
public override void OnInitializeMelon()
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ using System.Reflection;
|
||||||
[assembly: AssemblyProduct(nameof(NAK.Melons.IKFixes))]
|
[assembly: AssemblyProduct(nameof(NAK.Melons.IKFixes))]
|
||||||
|
|
||||||
[assembly: MelonInfo(
|
[assembly: MelonInfo(
|
||||||
typeof(NAK.Melons.IKFixes.IKFixesMod),
|
typeof(NAK.Melons.IKFixes.IKFixes),
|
||||||
nameof(NAK.Melons.IKFixes),
|
nameof(NAK.Melons.IKFixes),
|
||||||
AssemblyInfoParams.Version,
|
AssemblyInfoParams.Version,
|
||||||
AssemblyInfoParams.Author,
|
AssemblyInfoParams.Author,
|
||||||
|
|
109
NAK.CustomComponents/Components/NAKPointerTracker.cs
Normal file
109
NAK.CustomComponents/Components/NAKPointerTracker.cs
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
using ABI.CCK.Components;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NAK.CCK.CustomComponents;
|
||||||
|
|
||||||
|
public class NAKPointerTracker : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Configuration
|
||||||
|
public Transform referenceTransform;
|
||||||
|
public string pointerType = "";
|
||||||
|
public float radius = 0.1f;
|
||||||
|
public Vector3 offset = Vector3.zero;
|
||||||
|
|
||||||
|
// Animator module
|
||||||
|
public Animator animator;
|
||||||
|
public string parameterName;
|
||||||
|
|
||||||
|
// Internal stuff
|
||||||
|
float initialAngle;
|
||||||
|
CVRPointer trackedPointer;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
// Create collider
|
||||||
|
Collider collider = base.gameObject.GetComponent<Collider>();
|
||||||
|
if (collider == null)
|
||||||
|
{
|
||||||
|
SphereCollider sphereCollider = base.gameObject.AddComponent<SphereCollider>();
|
||||||
|
sphereCollider.isTrigger = true;
|
||||||
|
Vector3 lossyScale = base.transform.lossyScale;
|
||||||
|
sphereCollider.radius = radius / Mathf.Max(Mathf.Max(lossyScale.x, lossyScale.y), lossyScale.z);
|
||||||
|
sphereCollider.center = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create rigidbody (required for triggers)
|
||||||
|
Rigidbody rigidbody = base.gameObject.GetComponent<Rigidbody>();
|
||||||
|
if (rigidbody == null)
|
||||||
|
{
|
||||||
|
rigidbody = base.gameObject.AddComponent<Rigidbody>();
|
||||||
|
rigidbody.useGravity = false;
|
||||||
|
rigidbody.isKinematic = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
if (referenceTransform == null) referenceTransform = transform;
|
||||||
|
Vector3 direction = (transform.TransformPoint(offset) - referenceTransform.position);
|
||||||
|
Vector3 projectedDirection = Vector3.ProjectOnPlane(direction, referenceTransform.up);
|
||||||
|
initialAngle = Vector3.SignedAngle(referenceTransform.forward, projectedDirection, referenceTransform.up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
if (base.isActiveAndEnabled)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
Gizmos.matrix = Matrix4x4.TRS(base.transform.position, base.transform.rotation, Vector3.one);
|
||||||
|
Gizmos.DrawWireSphere(offset, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTriggerEnter(Collider other)
|
||||||
|
{
|
||||||
|
if (trackedPointer != null) return;
|
||||||
|
|
||||||
|
// generic pointer or specific pointer
|
||||||
|
CVRPointer pointer = other.gameObject.GetComponent<CVRPointer>();
|
||||||
|
if (pointer != null && (String.IsNullOrEmpty(pointerType) || pointer.type == pointerType))
|
||||||
|
{
|
||||||
|
trackedPointer = pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (trackedPointer == null) return;
|
||||||
|
|
||||||
|
// Check if tracked pointer was disabled
|
||||||
|
if (!trackedPointer.isActiveAndEnabled)
|
||||||
|
{
|
||||||
|
ReleasePointer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackPointer()
|
||||||
|
{
|
||||||
|
if (animator != null)
|
||||||
|
{
|
||||||
|
float angle = GetAngleFromPosition(trackedPointer.transform.position, initialAngle);
|
||||||
|
animator.SetFloat(parameterName + "_Angle", angle / 360);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleasePointer()
|
||||||
|
{
|
||||||
|
trackedPointer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetAngleFromPosition(Vector3 trackedPos, float offset = 0)
|
||||||
|
{
|
||||||
|
Vector3 direction = (trackedPos - referenceTransform.position);
|
||||||
|
Vector3 projectedDirection = Vector3.ProjectOnPlane(direction, referenceTransform.up);
|
||||||
|
float angle = Vector3.SignedAngle(referenceTransform.forward, projectedDirection, referenceTransform.up) - offset;
|
||||||
|
if (angle < 0) angle += 360f;
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
}
|
53
NAK.CustomComponents/CustomComponents.csproj
Normal file
53
NAK.CustomComponents/CustomComponents.csproj
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net472</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="SFX\**" />
|
||||||
|
<EmbeddedResource Remove="SFX\**" />
|
||||||
|
<None Remove="SFX\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="0Harmony">
|
||||||
|
<HintPath>..\_ManagedLibs\0Harmony.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Assembly-CSharp">
|
||||||
|
<HintPath>..\_ManagedLibs\Assembly-CSharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Assembly-CSharp-firstpass">
|
||||||
|
<HintPath>..\_ManagedLibs\Assembly-CSharp-firstpass.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DarkRift">
|
||||||
|
<HintPath>..\_ManagedLibs\DarkRift.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="MelonLoader">
|
||||||
|
<HintPath>..\_ManagedLibs\MelonLoader.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AnimationModule">
|
||||||
|
<HintPath>..\_ManagedLibs\UnityEngine.AnimationModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
|
<HintPath>..\_ManagedLibs\UnityEngine.CoreModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.InputLegacyModule">
|
||||||
|
<HintPath>..\_ManagedLibs\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.PhysicsModule">
|
||||||
|
<HintPath>..\_ManagedLibs\UnityEngine.PhysicsModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="Deploy" AfterTargets="Build">
|
||||||
|
<Copy SourceFiles="$(TargetPath)" DestinationFolder="C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" />
|
||||||
|
<Message Text="Copied $(TargetPath) to C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" Importance="high" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
25
NAK.CustomComponents/CustomComponents.sln
Normal file
25
NAK.CustomComponents/CustomComponents.sln
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.2.32630.192
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomComponents", "CustomComponents.csproj", "{D83D5845-288A-4783-993D-09364AA48593}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D83D5845-288A-4783-993D-09364AA48593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D83D5845-288A-4783-993D-09364AA48593}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D83D5845-288A-4783-993D-09364AA48593}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D83D5845-288A-4783-993D-09364AA48593}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {A05CB0F0-E92F-4634-AA89-357AA256AD29}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
15
NAK.CustomComponents/Main.cs
Normal file
15
NAK.CustomComponents/Main.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using ABI_RC.Core.Util.AssetFiltering;
|
||||||
|
using MelonLoader;
|
||||||
|
using NAK.CCK.CustomComponents;
|
||||||
|
|
||||||
|
namespace NAK.Melons.CustomComponents;
|
||||||
|
|
||||||
|
public class CustomComponents : MelonMod
|
||||||
|
{
|
||||||
|
public override void OnInitializeMelon()
|
||||||
|
{
|
||||||
|
// Add our CCK component to the prop whitelist
|
||||||
|
var propWhitelist = SharedFilter._spawnableWhitelist;
|
||||||
|
propWhitelist.Add(typeof(NAKPointerTracker));
|
||||||
|
}
|
||||||
|
}
|
30
NAK.CustomComponents/Properties/AssemblyInfo.cs
Normal file
30
NAK.CustomComponents/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using MelonLoader;
|
||||||
|
using NAK.Melons.CustomComponents.Properties;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||||
|
[assembly: AssemblyTitle(nameof(NAK.Melons.CustomComponents))]
|
||||||
|
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||||
|
[assembly: AssemblyProduct(nameof(NAK.Melons.CustomComponents))]
|
||||||
|
|
||||||
|
[assembly: MelonInfo(
|
||||||
|
typeof(NAK.Melons.CustomComponents.CustomComponents),
|
||||||
|
nameof(NAK.Melons.CustomComponents),
|
||||||
|
AssemblyInfoParams.Version,
|
||||||
|
AssemblyInfoParams.Author,
|
||||||
|
downloadLink: "https://github.com/NotAKidOnSteam/UndoPropButton"
|
||||||
|
)]
|
||||||
|
|
||||||
|
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||||
|
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||||
|
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||||
|
[assembly: HarmonyDontPatchAll]
|
||||||
|
|
||||||
|
namespace NAK.Melons.CustomComponents.Properties;
|
||||||
|
internal static class AssemblyInfoParams
|
||||||
|
{
|
||||||
|
public const string Version = "1.0.0";
|
||||||
|
public const string Author = "NotAKidoS";
|
||||||
|
}
|
23
NAK.CustomComponents/format.json
Normal file
23
NAK.CustomComponents/format.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"_id": 147,
|
||||||
|
"name": "PropUndoButton",
|
||||||
|
"modversion": "1.0.1",
|
||||||
|
"gameversion": "2022r170",
|
||||||
|
"loaderversion": "0.5.7",
|
||||||
|
"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/PropUndoButton/releases/download/v1.0.1/PropUndoButton.dll",
|
||||||
|
"sourcelink": "https://github.com/NotAKidOnSteam/PropUndoButton/",
|
||||||
|
"changelog": "- Initial Release\n- Added redo button.\n- Mitigated issue of props getting stuck locally if deleting them before they fully spawn.\n- Lowered SFX volume to match existing UI sounds.",
|
||||||
|
"embedcolor": "#00FFFF"
|
||||||
|
}
|
0
_ManagedLibs/.keep
Normal file
0
_ManagedLibs/.keep
Normal file
132
nstrip_copy_stuff.ps1
Normal file
132
nstrip_copy_stuff.ps1
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
# CVR and Melon Loader Dependencies
|
||||||
|
$0HarmonydllPath = "\MelonLoader\0Harmony.dll"
|
||||||
|
$melonLoaderdllPath = "\MelonLoader\MelonLoader.dll"
|
||||||
|
$cvrManagedDataPath = "\ChilloutVR_Data\Managed"
|
||||||
|
|
||||||
|
$cvrPath = $env:CVRPATH
|
||||||
|
$cvrExecutable = "ChilloutVR.exe"
|
||||||
|
$cvrDefaultPath = "C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR"
|
||||||
|
|
||||||
|
if ($cvrPath -and (Test-Path "$cvrPath\$cvrExecutable")) {
|
||||||
|
# Found ChilloutVR.exe in the existing CVRPATH
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Found the ChilloutVR folder on: $cvrPath"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Check if ChilloutVR.exe exists in default Steam location
|
||||||
|
if (Test-Path "$cvrDefaultPath\$cvrExecutable") {
|
||||||
|
# Set CVRPATH environment variable to default Steam location
|
||||||
|
Write-Host "Found the ChilloutVR on the default steam location, setting the CVRPATH Env Var at User Level!"
|
||||||
|
[Environment]::SetEnvironmentVariable("CVRPATH", $cvrDefaultPath, "User")
|
||||||
|
$env:CVRPATH = $cvrDefaultPath
|
||||||
|
$cvrPath = $env:CVRPATH
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "[ERROR] ChilloutVR.exe not found in CVRPATH or the default Steam location."
|
||||||
|
Write-Host " Please define the Environment Variable CVRPATH pointing to the ChilloutVR folder!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scriptDir = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
|
||||||
|
$managedLibsFolder = $scriptDir + "\_ManagedLibs"
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Copying the DLLs from the CVR, MelonLoader, and Mods folder to the ManagedLibs"
|
||||||
|
|
||||||
|
|
||||||
|
Copy-Item $cvrPath$0HarmonydllPath -Destination $managedLibsFolder
|
||||||
|
Copy-Item $cvrPath$melonLoaderdllPath -Destination $managedLibsFolder
|
||||||
|
Copy-Item $cvrPath$cvrManagedDataPath"\*" -Destination $managedLibsFolder
|
||||||
|
|
||||||
|
|
||||||
|
# Third Party Dependencies
|
||||||
|
$melonModsPath="\Mods\"
|
||||||
|
$modNames = @("BTKUILib")
|
||||||
|
$missingMods = New-Object System.Collections.Generic.List[string]
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($modName in $modNames) {
|
||||||
|
$modDll = $modName + ".dll"
|
||||||
|
$modPath = $cvrPath + $melonModsPath + $modDll
|
||||||
|
$managedLibsModPath = "$managedLibsFolder\$modDll"
|
||||||
|
|
||||||
|
# Attempt to grab from the mods folder
|
||||||
|
if (Test-Path $modPath -PathType Leaf) {
|
||||||
|
Write-Host " Copying $modDll from $melonModsPath to \_ManagedLibs!"
|
||||||
|
Copy-Item $modPath -Destination $managedLibsFolder
|
||||||
|
}
|
||||||
|
# Check if they already exist in the ManagedLibs
|
||||||
|
elseif (Test-Path $managedLibsModPath -PathType Leaf) {
|
||||||
|
Write-Host " Ignoring $modDll since already exists in \_ManagedLibs!"
|
||||||
|
}
|
||||||
|
# If we fail, lets add to the missing mods list
|
||||||
|
else {
|
||||||
|
$missingMods.Add($modName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($missingMods.Count -gt 0) {
|
||||||
|
# If we have missing mods, let's fetch them from the latest CVR Modding Group API
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Failed to find $($missingMods.Count) mods. We're going to search in CVR MG verified mods" -ForegroundColor Red
|
||||||
|
Write-Host "You can download them and move to $managedLibsFolder"
|
||||||
|
|
||||||
|
$cvrModdingApiUrl = "https://api.cvrmg.com/v1/mods"
|
||||||
|
$cvrModdingDownloadUrl = "https://api.cvrmg.com/v1/mods/download/"
|
||||||
|
$latestModsResponse = Invoke-RestMethod $cvrModdingApiUrl -UseBasicParsing
|
||||||
|
|
||||||
|
foreach ($modName in $missingMods) {
|
||||||
|
$mod = $latestModsResponse | Where-Object { $_.name -eq $modName }
|
||||||
|
if ($mod) {
|
||||||
|
$modDownloadUrl = $cvrModdingDownloadUrl + $($mod._id)
|
||||||
|
# It seems power shell doesn't like to download .dll from https://api.cvrmg.com (messes with some anti-virus)
|
||||||
|
# Invoke-WebRequest -Uri $modDownloadUrl -OutFile $managedLibsFolder -UseBasicParsing
|
||||||
|
# Write-Host " $modName was downloaded successfully to $managedLibsFolder!"
|
||||||
|
Write-Host " $modName Download Url: $modDownloadUrl"
|
||||||
|
} else {
|
||||||
|
Write-Host " $modName was not found in the CVR Modding Group verified mods!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Copied all libraries!"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Press any key to strip the Dlls using NStrip"
|
||||||
|
$HOST.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
|
||||||
|
$HOST.UI.RawUI.Flushinputbuffer()
|
||||||
|
|
||||||
|
Write-Host "NStrip Convert all private/protected stuff to public. Requires <AllowUnsafeBlocks>true></AllowUnsafeBlocks>"
|
||||||
|
|
||||||
|
# Create an array to hold the file names to strip
|
||||||
|
$dllsToStrip = @('Assembly-CSharp.dll','Assembly-CSharp-firstpass.dll','AVProVideo.Runtime.dll')
|
||||||
|
|
||||||
|
# Check if NStrip.exe exists in the current directory
|
||||||
|
if(Test-Path -Path ".\NStrip.exe") {
|
||||||
|
$nStripPath = ".\NStrip.exe"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Try to locate NStrip.exe in the PATH
|
||||||
|
$nStripPath = Get-Command -Name NStrip.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
|
||||||
|
if($nStripPath -eq $null) {
|
||||||
|
# Display an error message if NStrip.exe could not be found
|
||||||
|
Write-Host "Could not find NStrip.exe in the current directory nor in the PATH." -ForegroundColor Red
|
||||||
|
Write-Host "Visit https://github.com/bbepis/NStrip/releases/latest to grab a copy." -ForegroundColor Red
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Loop through each DLL file to strip and call NStrip.exe
|
||||||
|
foreach($dllFile in $dllsToStrip) {
|
||||||
|
$dllPath = Join-Path -Path $managedLibsFolder -ChildPath $dllFile
|
||||||
|
& $nStripPath -p -n $dllPath $dllPath
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Copied all libraries and stripped the DLLs!"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Press any key to exit"
|
||||||
|
$HOST.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
|
||||||
|
$HOST.UI.RawUI.Flushinputbuffer()
|
Loading…
Add table
Add a link
Reference in a new issue