-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1625e01
Showing
11 changed files
with
474 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
bin/* | ||
obj/* | ||
*.user | ||
*.xcf | ||
HarmonyPatches/RemoveSplashscreen.cs | ||
HarmonyPatchHelper.cs | ||
Screenshots/SocialPreview.jpg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup /> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Runtime.CompilerServices; | ||
using IPA.Config.Stores; | ||
using UnityEngine; | ||
|
||
[assembly: InternalsVisibleTo(GeneratedStore.AssemblyVisibilityTarget)] | ||
namespace SmoothedController { | ||
internal class PluginConfig { | ||
public static PluginConfig Instance { get; set; } | ||
public virtual bool Enabled { get; set; } = true; | ||
public virtual float PositionSmoothing { get; set; } = 3f; | ||
public virtual float RotationSmoothing { get; set; } = 12f; | ||
public virtual float SmallMovementThresholdAngle { get; set; } = 6f; | ||
|
||
/// <summary> | ||
/// This is called whenever BSIPA reads the config from disk (including when file changes are detected). | ||
/// </summary> | ||
public virtual void OnReload() { | ||
// Do stuff after config is read from disk. | ||
} | ||
|
||
/// <summary> | ||
/// Call this to force BSIPA to update the config file. This is also called by BSIPA if it detects the file was modified. | ||
/// </summary> | ||
public virtual void Changed() { | ||
// Do stuff when the config is changed. | ||
} | ||
|
||
/// <summary> | ||
/// Call this to have BSIPA copy the values from <paramref name="other"/> into this config. | ||
/// </summary> | ||
public virtual void CopyFrom(PluginConfig other) { | ||
// This instance's members populated from other | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- This file contains the build tasks and targets for verifying the manifest, zipping Release builds, | ||
and copying the plugin to to your Beat Saber folder. Only edit this if you know what you are doing. --> | ||
<Project> | ||
<PropertyGroup> | ||
<BuildTargetsVersion>2.0</BuildTargetsVersion> | ||
<!--Set this to true if you edit this file to prevent automatic updates--> | ||
<BuildTargetsModified>false</BuildTargetsModified> | ||
<!--Output assembly path without extension--> | ||
<OutputAssemblyName>$(OutputPath)$(AssemblyName)</OutputAssemblyName> | ||
<!--Path to folder to be zipped. Needs to be relative to the project directory to work without changes to the 'BuildForCI' target.--> | ||
<ArtifactDestination>$(OutputPath)Final</ArtifactDestination> | ||
<ErrorOnMismatchedVersions Condition="'$(Configuration)' == 'Release'">True</ErrorOnMismatchedVersions> | ||
</PropertyGroup> | ||
<!--Build Targets--> | ||
<!--Displays a warning if BeatSaberModdingTools.Tasks is not installed.--> | ||
<Target Name="CheckBSMTInstalled" AfterTargets="BeforeBuild" Condition="'$(BSMTTaskAssembly)' == ''"> | ||
<Warning Text="The BeatSaberModdingTools.Tasks nuget package doesn't seem to be installed, advanced build targets will not work." /> | ||
</Target> | ||
<!--Runs a build task to get info about the project used by later targets.--> | ||
<Target Name="GetProjectInfo" AfterTargets="CheckBSMTInstalled" DependsOnTargets="CheckBSMTInstalled" Condition="'$(BSMTTaskAssembly)' != ''"> | ||
<Message Text="Using AssemblyVersion defined in project instead of 'Properties\AssemblyInfo.cs'" Importance="high" Condition="'$(AssemblyVersion)' != ''" /> | ||
<GetManifestInfo FailOnError="$(ErrorOnMismatchedVersions)"> | ||
<Output TaskParameter="PluginVersion" PropertyName="PluginVersion" /> | ||
<Output TaskParameter="BasePluginVersion" PropertyName="BasePluginVersion" /> | ||
<Output TaskParameter="GameVersion" PropertyName="GameVersion" /> | ||
</GetManifestInfo> | ||
<PropertyGroup> | ||
<AssemblyVersion>$(BasePluginVersion)</AssemblyVersion> | ||
<FileVersion>$(BasePluginVersion)</FileVersion> | ||
<InformationalVersion>$(BasePluginVersion)</InformationalVersion> | ||
</PropertyGroup> | ||
<GetCommitInfo ProjectDir="$(ProjectDir)"> | ||
<Output TaskParameter="CommitHash" PropertyName="CommitHash" /> | ||
<Output TaskParameter="Branch" PropertyName="Branch" /> | ||
<Output TaskParameter="Modified" PropertyName="GitModified" /> | ||
</GetCommitInfo> | ||
<PropertyGroup> | ||
<!--Build name for artifact/zip file--> | ||
<ArtifactName>$(AssemblyName)</ArtifactName> | ||
<ArtifactName Condition="'$(PluginVersion)' != ''">$(ArtifactName)-$(PluginVersion)</ArtifactName> | ||
<ArtifactName Condition="'$(GameVersion)' != ''">$(ArtifactName)-bs$(GameVersion)</ArtifactName> | ||
<ArtifactName Condition="'$(CommitHash)' != '' AND '$(CommitHash)' != 'local'">$(ArtifactName)-$(CommitHash)</ArtifactName> | ||
</PropertyGroup> | ||
</Target> | ||
<!--Build target for Continuous Integration builds. Set up for GitHub Actions.--> | ||
<Target Name="BuildForCI" AfterTargets="Build" DependsOnTargets="GetProjectInfo" Condition="'$(ContinuousIntegrationBuild)' == 'True' AND '$(BSMTTaskAssembly)' != ''"> | ||
<PropertyGroup> | ||
<!--Set 'ArtifactName' if it failed before.--> | ||
<ArtifactName Condition="'$(ArtifactName)' == ''">$(AssemblyName)</ArtifactName> | ||
</PropertyGroup> | ||
<Message Text="Building for CI" Importance="high" /> | ||
<Message Text="PluginVersion: $(PluginVersion), AssemblyVersion: $(AssemblyVersion), GameVersion: $(GameVersion)" Importance="high" /> | ||
<Message Text="::set-output name=filename::$(ArtifactName)" Importance="high" /> | ||
<Message Text="::set-output name=assemblyname::$(AssemblyName)" Importance="high" /> | ||
<Message Text="::set-output name=artifactpath::$(ProjectDir)$(ArtifactDestination)" Importance="high" /> | ||
<Message Text="Copying '$(OutputAssemblyName).dll' to '$(ProjectDir)$(ArtifactDestination)\Plugins\$(AssemblyName).dll'" Importance="high" /> | ||
<Copy SourceFiles="$(OutputAssemblyName).dll" DestinationFiles="$(ProjectDir)$(ArtifactDestination)\Plugins\$(AssemblyName).dll" /> | ||
</Target> | ||
<!--Creates a BeatMods compliant zip file with the release.--> | ||
<Target Name="ZipRelease" AfterTargets="Build" Condition="'$(DisableZipRelease)' != 'True' AND '$(Configuration)' == 'Release' AND '$(BSMTTaskAssembly)' != ''"> | ||
<PropertyGroup> | ||
<!--Set 'ArtifactName' if it failed before.--> | ||
<ArtifactName Condition="'$(ArtifactName)' == ''">$(AssemblyName)</ArtifactName> | ||
<DestinationDirectory>$(OutDir)zip\</DestinationDirectory> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<OldZips Include="$(DestinationDirectory)$(AssemblyName)*.zip"/> | ||
</ItemGroup> | ||
<Copy SourceFiles="$(OutputAssemblyName).dll" DestinationFiles="$(ArtifactDestination)\Plugins\$(AssemblyName).dll" /> | ||
<Message Text="PluginVersion: $(PluginVersion), AssemblyVersion: $(AssemblyVersion), GameVersion: $(GameVersion)" Importance="high" /> | ||
<Delete Files="@(OldZips)" TreatErrorsAsWarnings="true" ContinueOnError="true" /> | ||
<ZipDir SourceDirectory="$(ArtifactDestination)" DestinationFile="$(DestinationDirectory)$(ArtifactName).zip" /> | ||
</Target> | ||
<!--Copies the assembly and pdb to the Beat Saber folder.--> | ||
<Target Name="CopyToPlugins" AfterTargets="Build" Condition="'$(DisableCopyToPlugins)' != 'True' AND '$(ContinuousIntegrationBuild)' != 'True'"> | ||
<PropertyGroup> | ||
<PluginDir>$(BeatSaberDir)\Plugins</PluginDir> | ||
<CanCopyToPlugins>True</CanCopyToPlugins> | ||
<CopyToPluginsError Condition="!Exists('$(PluginDir)')">Unable to copy assembly to game folder, did you set 'BeatSaberDir' correctly in your 'csproj.user' file? Plugins folder doesn't exist: '$(PluginDir)'.</CopyToPluginsError> | ||
<!--Error if 'BeatSaberDir' does not have 'Beat Saber.exe'--> | ||
<CopyToPluginsError Condition="!Exists('$(BeatSaberDir)\Beat Saber.exe')">Unable to copy to Plugins folder, '$(BeatSaberDir)' does not appear to be a Beat Saber game install.</CopyToPluginsError> | ||
<!--Error if 'BeatSaberDir' is the same as 'LocalRefsDir'--> | ||
<CopyToPluginsError Condition="'$(BeatSaberDir)' == '$(LocalRefsDir)' OR '$(BeatSaberDir)' == ''">Unable to copy to Plugins folder, 'BeatSaberDir' has not been set in your 'csproj.user' file.</CopyToPluginsError> | ||
<CanCopyToPlugins Condition="'$(CopyToPluginsError)' != ''">False</CanCopyToPlugins> | ||
</PropertyGroup> | ||
<!--Check if Beat Saber is running--> | ||
<IsProcessRunning ProcessName="Beat Saber" Condition="'$(BSMTTaskAssembly)' != ''"> | ||
<Output TaskParameter="IsRunning" PropertyName="IsRunning" /> | ||
</IsProcessRunning> | ||
<PropertyGroup> | ||
<!--If Beat Saber is running, output to the Pending folder--> | ||
<PluginDir Condition="'$(IsRunning)' == 'True'">$(BeatSaberDir)\IPA\Pending\Plugins</PluginDir> | ||
</PropertyGroup> | ||
<Warning Text="$(CopyToPluginsError)" Condition="'$(CopyToPluginsError)' != ''" /> | ||
<Message Text="Copying '$(OutputAssemblyName).dll' to '$(PluginDir)'." Importance="high" Condition="$(CanCopyToPlugins)" /> | ||
<Copy SourceFiles="$(OutputAssemblyName).dll" DestinationFiles="$(PluginDir)\$(AssemblyName).dll" Condition="$(CanCopyToPlugins)" /> | ||
<Copy SourceFiles="$(OutputAssemblyName).pdb" DestinationFiles="$(PluginDir)\$(AssemblyName).pdb" Condition="'$(CanCopyToPlugins)' == 'True' AND Exists('$(OutputAssemblyName).pdb')" /> | ||
<Warning Text="Beat Saber is running, restart the game to use the latest build." Condition="'$(IsRunning)' == 'True'" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using HarmonyLib; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Reflection.Emit; | ||
using UnityEngine; | ||
using UnityEngine.XR; | ||
|
||
namespace SmoothedController.HarmonyPatches { | ||
class wrapper { | ||
public Vector3 smoothedPosition = Vector3.zero; | ||
public Quaternion smoothedRotation = Quaternion.identity; | ||
public float angleVelocitySnap = 1f; | ||
} | ||
|
||
[HarmonyPatch(typeof(VRController), "Update")] | ||
public static class Smoother { | ||
public static bool enabled = true; | ||
|
||
static Dictionary<XRNode, wrapper> idk = new Dictionary<XRNode, wrapper>(); | ||
|
||
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { | ||
if(!ILUtil.CheckIL(instructions, new Dictionary<int, OpCode>() { | ||
{50, OpCodes.Ldarg_0}, | ||
{51, OpCodes.Ldfld}, | ||
{68, OpCodes.Ret} | ||
})) return instructions; | ||
|
||
ILUtil.InsertFn(50, ref instructions, AccessTools.Method(typeof(Smoother), nameof(YES))); | ||
|
||
return instructions; | ||
} | ||
|
||
static float posSmoth = 20f - Mathf.Clamp(PluginConfig.Instance.PositionSmoothing, 0f, 20f); | ||
static float rotSmoth = 20f - Mathf.Clamp(PluginConfig.Instance.RotationSmoothing, 0f, 20f); | ||
|
||
static VRController instance; | ||
static void YES() { | ||
if(instance == null || !enabled || !PluginConfig.Instance.Enabled) | ||
return; | ||
|
||
wrapper wrapperI = null; | ||
|
||
if(!idk.TryGetValue(instance.node, out wrapperI)) | ||
idk.Add(instance.node, wrapperI = new wrapper()); | ||
|
||
var angDiff = Quaternion.Angle(wrapperI.smoothedRotation, instance.transform.localRotation); | ||
wrapperI.angleVelocitySnap = Math.Min(wrapperI.angleVelocitySnap + angDiff, 90f); | ||
|
||
var snapMulti = Mathf.Clamp(wrapperI.angleVelocitySnap / PluginConfig.Instance.SmallMovementThresholdAngle, 0.1f, 2.5f); | ||
|
||
if(wrapperI.angleVelocitySnap > 0.1) { | ||
wrapperI.angleVelocitySnap -= Math.Max(0.4f, wrapperI.angleVelocitySnap / 1.7f); | ||
} | ||
|
||
if(PluginConfig.Instance.PositionSmoothing > 0f) { | ||
wrapperI.smoothedPosition = Vector3.Lerp(wrapperI.smoothedPosition, instance.transform.localPosition, posSmoth * Time.deltaTime * snapMulti); | ||
instance.transform.localPosition = wrapperI.smoothedPosition; | ||
} | ||
|
||
if(PluginConfig.Instance.RotationSmoothing > 0f) { | ||
wrapperI.smoothedRotation = Quaternion.Lerp(wrapperI.smoothedRotation, instance.transform.localRotation, rotSmoth * Time.deltaTime * snapMulti); | ||
instance.transform.localRotation = wrapperI.smoothedRotation; | ||
} | ||
} | ||
|
||
static void Prefix(VRController __instance, VRControllerTransformOffset ____transformOffset) { | ||
// Check if the VRController's gameObject name starts with "C" (Controller) so that sabers (LeftHand / RightHand) are not smoothed lmao | ||
if(__instance.gameObject.name[0] != 'C') { | ||
instance = null; | ||
return; | ||
} | ||
|
||
instance = __instance; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using HarmonyLib; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Reflection.Emit; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SmoothedController { | ||
static class ILUtil { | ||
public static bool CheckIL(IEnumerable<CodeInstruction> instructions, Dictionary<int, OpCode> confirmations) { | ||
foreach(var c in confirmations) { | ||
if(instructions.ElementAt(c.Key).opcode != c.Value) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
public static void InsertFn(int index, ref IEnumerable<CodeInstruction> instructions, MethodInfo fn) { | ||
if(fn.ReturnType != typeof(void) || !fn.IsStatic) | ||
throw new Exception("FN must be static void"); | ||
|
||
var l = instructions.ToList(); | ||
|
||
l.Insert(index, new CodeInstruction(OpCodes.Call, fn)); | ||
|
||
instructions = l; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 Kinsi | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using BeatSaberMarkupLanguage.Settings; | ||
using HarmonyLib; | ||
using IPA; | ||
using IPA.Config; | ||
using IPA.Config.Stores; | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using UnityEngine; | ||
using UnityEngine.SceneManagement; | ||
using IPALogger = IPA.Logging.Logger; | ||
|
||
namespace SmoothedController { | ||
[Plugin(RuntimeOptions.SingleStartInit)] | ||
public class Plugin { | ||
internal static Plugin Instance { get; private set; } | ||
internal static IPALogger Log { get; private set; } | ||
internal static Harmony harmony { get; private set; } | ||
|
||
[Init] | ||
public void Init(IPALogger logger, Config conf) { | ||
Instance = this; | ||
Log = logger; | ||
PluginConfig.Instance = conf.Generated<PluginConfig>(); | ||
} | ||
|
||
[OnStart] | ||
public void OnApplicationStart() { | ||
BSMLSettings.instance.AddSettingsMenu("Smooth Controller", "SmoothedController.UI.settings.bsml", PluginConfig.Instance); | ||
|
||
harmony = new Harmony("Kinsi55.BeatSaber.SmoothedController"); | ||
harmony.PatchAll(Assembly.GetExecutingAssembly()); | ||
} | ||
|
||
[OnExit] | ||
public void OnApplicationQuit() { | ||
harmony.UnpatchAll(harmony.Id); | ||
} | ||
} | ||
} |
Oops, something went wrong.