diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..833e6d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +Assets/AssetStoreTools* + +# Visual Studio cache directory +.vs/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta + +# Unity3D Generated File On Crash Reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage diff --git a/BSIndexHapticFix/Components/HapticEmulator.cs b/BSIndexHapticFix/Components/HapticEmulator.cs new file mode 100644 index 0000000..a1d7ce3 --- /dev/null +++ b/BSIndexHapticFix/Components/HapticEmulator.cs @@ -0,0 +1,158 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace BSIndexHapticFix.Components +{ + /// + /// Haptic emulator for a single controller + /// + public class HapticEmulator : MonoBehaviour + { + /// + /// Target XR Node + /// + public UnityEngine.XR.XRNode Node { get; private set; } + /// + /// Is it an Index knuckle? + /// + public bool IsIndexKnuckle { get; private set; } = false; + /// + /// Is left hand + /// + public bool IsLeftHand => Node == UnityEngine.XR.XRNode.LeftHand; + /// + /// Is right hand + /// + public bool IsRightHand => Node == UnityEngine.XR.XRNode.RightHand; + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// Matching XR input device + /// + private UnityEngine.XR.InputDevice? m_Device = null; + /// + /// Remaining haptic time + /// + private float m_OpenVREmulatedHapticRemainingTime = 0f; + /// + /// Remaining haptic strength + /// + private float m_OpenVREmulatedHapticAmplitude = 0f; + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// Start is called before the first frame update + /// + public void Init(UnityEngine.XR.XRNode p_Node) + { + Node = p_Node; + + /// Bind callbacks + UnityEngine.XR.InputDevices.deviceConnected += InputDevices_deviceConnected; + UnityEngine.XR.InputDevices.deviceDisconnected += InputDevices_deviceDisconnected; + + /// In case of late init, search device manually + var l_AvailableDevicesAtNode = new List(); + UnityEngine.XR.InputDevices.GetDevicesAtXRNode(Node, l_AvailableDevicesAtNode); + l_AvailableDevicesAtNode.ForEach(x => InputDevices_deviceConnected(x)); + + GameObject.DontDestroyOnLoad(gameObject); + } + /// + /// On component destroy + /// + private void OnDestroy() + { + /// Remove callbacks + UnityEngine.XR.InputDevices.deviceDisconnected -= InputDevices_deviceDisconnected; + UnityEngine.XR.InputDevices.deviceConnected -= InputDevices_deviceConnected; + } + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + public void SetHaptics(float p_Amplitude, float p_Duration) + { + float l_VibrationStrength = 2f; + + p_Duration *= l_VibrationStrength; + p_Amplitude *= l_VibrationStrength; + + if (p_Amplitude <= 0.01f) + return; + + m_OpenVREmulatedHapticRemainingTime = p_Duration; + m_OpenVREmulatedHapticAmplitude = Mathf.Clamp01(p_Amplitude); + } + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// On XR device connected + /// + /// New device + private void InputDevices_deviceConnected(UnityEngine.XR.InputDevice p_Device) + { + var l_RequiredCharacteristics = UnityEngine.XR.InputDeviceCharacteristics.Controller + | UnityEngine.XR.InputDeviceCharacteristics.TrackedDevice + | UnityEngine.XR.InputDeviceCharacteristics.HeldInHand + | (IsLeftHand ? UnityEngine.XR.InputDeviceCharacteristics.Left : UnityEngine.XR.InputDeviceCharacteristics.Right); + + /// Check for matching role + if (!p_Device.isValid || (p_Device.characteristics & l_RequiredCharacteristics) != l_RequiredCharacteristics) + return; + + m_Device = p_Device; + IsIndexKnuckle = m_Device.Value.name.ToLower().Contains("knuckles"); + + if (IsIndexKnuckle) + StartCoroutine(Coroutine_OpenVRHaptics()); + + Plugin.Logger.Debug($"Device found \"{p_Device.manufacturer}\"-\"{p_Device.name}\" with role \"{p_Device.characteristics}\" serial {p_Device.serialNumber} is index knuckle? {IsIndexKnuckle}"); + } + /// + /// On XR device disconnected + /// + /// Disconnected device + private void InputDevices_deviceDisconnected(UnityEngine.XR.InputDevice p_Device) + { + /// Check for matching role + if (!m_Device.HasValue || m_Device != p_Device) + return; + + m_Device = null; + StopAllCoroutines(); + + Plugin.Logger.Debug($"[OPVR.VRController] Device lost \"{p_Device.manufacturer}\"-\"{p_Device.name}\" with role \"{p_Device.characteristics}\""); + } + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// Handles the haptic process every 1/80 second. + /// + /// + private IEnumerator Coroutine_OpenVRHaptics() + { + const float s_Rate = 1 / 80f; + + var l_Waiter = new WaitForSecondsRealtime(s_Rate); + while (true) + { + m_OpenVREmulatedHapticRemainingTime -= s_Rate; + + if (m_OpenVREmulatedHapticRemainingTime > 0f) + m_Device?.SendHapticImpulse(0, m_OpenVREmulatedHapticAmplitude); + + yield return l_Waiter; + } + } + } +} diff --git a/BSIndexHapticFix/Directory.Build.props b/BSIndexHapticFix/Directory.Build.props new file mode 100644 index 0000000..02c5dc1 --- /dev/null +++ b/BSIndexHapticFix/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + true + true + true + + + false + true + true + + \ No newline at end of file diff --git a/BSIndexHapticFix/Directory.Build.targets b/BSIndexHapticFix/Directory.Build.targets new file mode 100644 index 0000000..1c2dd75 --- /dev/null +++ b/BSIndexHapticFix/Directory.Build.targets @@ -0,0 +1,96 @@ + + + + + 2.0 + + false + + $(OutputPath)$(AssemblyName) + + $(OutputPath)Final + True + + + + + + + + + + + + + + + + + + + + + + $(AssemblyName) + $(ArtifactName)-$(PluginVersion) + $(ArtifactName)-bs$(GameVersion) + $(ArtifactName)-$(CommitHash) + + + + + + + $(AssemblyName) + + + + + + + + + + + + + + $(AssemblyName) + $(OutDir)zip\ + + + + + + + + + + + + + $(BeatSaberDir)\Plugins + True + Unable to copy assembly to game folder, did you set 'BeatSaberDir' correctly in your 'csproj.user' file? Plugins folder doesn't exist: '$(PluginDir)'. + + Unable to copy to Plugins folder, '$(BeatSaberDir)' does not appear to be a Beat Saber game install. + + Unable to copy to Plugins folder, 'BeatSaberDir' has not been set in your 'csproj.user' file. + False + + + + + + + + $(BeatSaberDir)\IPA\Pending\Plugins + + + + + + + + \ No newline at end of file diff --git a/BSIndexHapticFix/HarmonyPatches/POpenVRHelper_TriggerHapticPulse.cs b/BSIndexHapticFix/HarmonyPatches/POpenVRHelper_TriggerHapticPulse.cs new file mode 100644 index 0000000..c89887f --- /dev/null +++ b/BSIndexHapticFix/HarmonyPatches/POpenVRHelper_TriggerHapticPulse.cs @@ -0,0 +1,32 @@ +using HarmonyLib; +using UnityEngine.XR; + +namespace BSIndexHapticFix.HarmonyPatches +{ + [HarmonyPatch(typeof(OpenVRHelper))] + [HarmonyPatch(nameof(OpenVRHelper.TriggerHapticPulse))] + internal class POpenVRHelper_TriggerHapticPulse + { + static bool Prefix(XRNode node, float duration, float strength, float frequency) + { + if (node == XRNode.LeftHand && Plugin.LeftHapticEmulator && Plugin.LeftHapticEmulator.IsIndexKnuckle) + { + Plugin.LeftHapticEmulator.SetHaptics(strength, duration); + + /// Skip original method + return false; + } + + if (node == XRNode.RightHand && Plugin.RightHapticEmulator && Plugin.RightHapticEmulator.IsIndexKnuckle) + { + Plugin.RightHapticEmulator.SetHaptics(strength, duration); + + /// Skip original method + return false; + } + + /// Forward to base method + return true; + } + } +} diff --git a/BSIndexHapticFix/Plugin.cs b/BSIndexHapticFix/Plugin.cs new file mode 100644 index 0000000..888e08f --- /dev/null +++ b/BSIndexHapticFix/Plugin.cs @@ -0,0 +1,103 @@ +using HarmonyLib; +using IPA; +using System.Reflection; +using UnityEngine; + +namespace BSIndexHapticFix +{ + /// + /// Plugin main class + /// + [Plugin(RuntimeOptions.SingleStartInit)] + public class Plugin + { + /// + /// Logger instance + /// + internal static IPA.Logging.Logger Logger { get; private set; } + /// + /// Harmony ID for patches + /// + internal const string HarmonyID = "com.github.hardcpp.bsindexhapticfix"; + /// + /// Left controller haptic emulator + /// + internal static Components.HapticEmulator LeftHapticEmulator; + /// + /// Right controller haptic emulator + /// + internal static Components.HapticEmulator RightHapticEmulator; + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// Harmony patch holder + /// + private static Harmony m_Harmony; + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// Called when the plugin is first loaded by IPA (either when the game starts or when the plugin is enabled if it starts disabled). + /// [Init] methods that use a Constructor or called before regular methods like InitWithConfig. + /// Only use [Init] with one Constructor. + /// + [Init] + public void Init(IPA.Logging.Logger p_Logger) + { + Logger = p_Logger; + + Logger.Info("BSIndexHapticFix initialized."); + } + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + /// + /// On application start + /// + [OnStart] + public void OnApplicationStart() + { + try + { + Logger.Debug("OnApplicationStart"); + + m_Harmony = new Harmony(HarmonyID); + m_Harmony.PatchAll(Assembly.GetExecutingAssembly()); + + LeftHapticEmulator = new GameObject("BSIndexHapticFix_Left").AddComponent(); + LeftHapticEmulator.Init(UnityEngine.XR.XRNode.LeftHand); + + RightHapticEmulator = new GameObject("BSIndexHapticFix_Right").AddComponent(); + RightHapticEmulator.Init(UnityEngine.XR.XRNode.RightHand); + } + catch (System.Exception p_Exception) + { + Logger.Critical(p_Exception); + } + } + /// + /// On application quit + /// + [OnExit] + public void OnApplicationQuit() + { + try + { + Logger.Debug("OnApplicationQuit"); + + m_Harmony.UnpatchAll(); + + GameObject.Destroy(LeftHapticEmulator); + GameObject.Destroy(RightHapticEmulator); + } + catch (System.Exception p_Exception) + { + Logger.Critical(p_Exception); + } + } + } +} diff --git a/BSIndexHapticFix/Properties/AssemblyInfo.cs b/BSIndexHapticFix/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f5a49e4 --- /dev/null +++ b/BSIndexHapticFix/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BSIndexHapticFix")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BSIndexHapticFix")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6bf8f645-643e-4239-8eda-38337bb12868")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.1")] +[assembly: AssemblyFileVersion("0.0.1")] diff --git a/BSIndexHapticFix/bin/Debug/BSIndexHapticFix.dll b/BSIndexHapticFix/bin/Debug/BSIndexHapticFix.dll new file mode 100644 index 0000000..a7636be Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/BSIndexHapticFix.dll differ diff --git a/BSIndexHapticFix/bin/Debug/Microsoft.Build.Framework.dll b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Framework.dll new file mode 100644 index 0000000..0e4979c Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Framework.dll differ diff --git a/BSIndexHapticFix/bin/Debug/Microsoft.Build.Tasks.Core.dll b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Tasks.Core.dll new file mode 100644 index 0000000..551c2d6 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Tasks.Core.dll differ diff --git a/BSIndexHapticFix/bin/Debug/Microsoft.Build.Utilities.Core.dll b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Utilities.Core.dll new file mode 100644 index 0000000..cef2b58 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/Microsoft.Build.Utilities.Core.dll differ diff --git a/BSIndexHapticFix/bin/Debug/Microsoft.VisualStudio.Setup.Configuration.Interop.dll b/BSIndexHapticFix/bin/Debug/Microsoft.VisualStudio.Setup.Configuration.Interop.dll new file mode 100644 index 0000000..bcc8fbd Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/Microsoft.VisualStudio.Setup.Configuration.Interop.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Buffers.dll b/BSIndexHapticFix/bin/Debug/System.Buffers.dll new file mode 100644 index 0000000..b6d9c77 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Buffers.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Collections.Immutable.dll b/BSIndexHapticFix/bin/Debug/System.Collections.Immutable.dll new file mode 100644 index 0000000..049149f Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Collections.Immutable.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Memory.dll b/BSIndexHapticFix/bin/Debug/System.Memory.dll new file mode 100644 index 0000000..bdfc501 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Memory.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Numerics.Vectors.dll b/BSIndexHapticFix/bin/Debug/System.Numerics.Vectors.dll new file mode 100644 index 0000000..ce46d5b Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Numerics.Vectors.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Resources.Extensions.dll b/BSIndexHapticFix/bin/Debug/System.Resources.Extensions.dll new file mode 100644 index 0000000..73e49c8 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Resources.Extensions.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Runtime.CompilerServices.Unsafe.dll b/BSIndexHapticFix/bin/Debug/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..3156239 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/BSIndexHapticFix/bin/Debug/System.Threading.Tasks.Dataflow.dll b/BSIndexHapticFix/bin/Debug/System.Threading.Tasks.Dataflow.dll new file mode 100644 index 0000000..a6816d4 Binary files /dev/null and b/BSIndexHapticFix/bin/Debug/System.Threading.Tasks.Dataflow.dll differ diff --git a/BSIndexHapticFix/bin/Release/BSIndexHapticFix.dll b/BSIndexHapticFix/bin/Release/BSIndexHapticFix.dll new file mode 100644 index 0000000..e697067 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/BSIndexHapticFix.dll differ diff --git a/BSIndexHapticFix/bin/Release/Final/Plugins/BSIndexHapticFix.dll b/BSIndexHapticFix/bin/Release/Final/Plugins/BSIndexHapticFix.dll new file mode 100644 index 0000000..e697067 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/Final/Plugins/BSIndexHapticFix.dll differ diff --git a/BSIndexHapticFix/bin/Release/Microsoft.Build.Framework.dll b/BSIndexHapticFix/bin/Release/Microsoft.Build.Framework.dll new file mode 100644 index 0000000..0e4979c Binary files /dev/null and b/BSIndexHapticFix/bin/Release/Microsoft.Build.Framework.dll differ diff --git a/BSIndexHapticFix/bin/Release/Microsoft.Build.Tasks.Core.dll b/BSIndexHapticFix/bin/Release/Microsoft.Build.Tasks.Core.dll new file mode 100644 index 0000000..551c2d6 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/Microsoft.Build.Tasks.Core.dll differ diff --git a/BSIndexHapticFix/bin/Release/Microsoft.Build.Utilities.Core.dll b/BSIndexHapticFix/bin/Release/Microsoft.Build.Utilities.Core.dll new file mode 100644 index 0000000..cef2b58 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/Microsoft.Build.Utilities.Core.dll differ diff --git a/BSIndexHapticFix/bin/Release/Microsoft.VisualStudio.Setup.Configuration.Interop.dll b/BSIndexHapticFix/bin/Release/Microsoft.VisualStudio.Setup.Configuration.Interop.dll new file mode 100644 index 0000000..bcc8fbd Binary files /dev/null and b/BSIndexHapticFix/bin/Release/Microsoft.VisualStudio.Setup.Configuration.Interop.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Buffers.dll b/BSIndexHapticFix/bin/Release/System.Buffers.dll new file mode 100644 index 0000000..b6d9c77 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Buffers.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Collections.Immutable.dll b/BSIndexHapticFix/bin/Release/System.Collections.Immutable.dll new file mode 100644 index 0000000..049149f Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Collections.Immutable.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Memory.dll b/BSIndexHapticFix/bin/Release/System.Memory.dll new file mode 100644 index 0000000..bdfc501 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Memory.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Numerics.Vectors.dll b/BSIndexHapticFix/bin/Release/System.Numerics.Vectors.dll new file mode 100644 index 0000000..ce46d5b Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Numerics.Vectors.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Resources.Extensions.dll b/BSIndexHapticFix/bin/Release/System.Resources.Extensions.dll new file mode 100644 index 0000000..73e49c8 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Resources.Extensions.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Runtime.CompilerServices.Unsafe.dll b/BSIndexHapticFix/bin/Release/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..3156239 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/BSIndexHapticFix/bin/Release/System.Threading.Tasks.Dataflow.dll b/BSIndexHapticFix/bin/Release/System.Threading.Tasks.Dataflow.dll new file mode 100644 index 0000000..a6816d4 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/System.Threading.Tasks.Dataflow.dll differ diff --git a/BSIndexHapticFix/bin/Release/zip/BSIndexHapticFix-0.0.1-bs1.18.0.zip b/BSIndexHapticFix/bin/Release/zip/BSIndexHapticFix-0.0.1-bs1.18.0.zip new file mode 100644 index 0000000..dc60786 Binary files /dev/null and b/BSIndexHapticFix/bin/Release/zip/BSIndexHapticFix-0.0.1-bs1.18.0.zip differ diff --git a/BSIndexHapticFix/manifest.json b/BSIndexHapticFix/manifest.json new file mode 100644 index 0000000..d2d5e4d --- /dev/null +++ b/BSIndexHapticFix/manifest.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://raw.githubusercontent.com/bsmg/BSIPA-MetadataFileSchema/master/Schema.json", + "id": "BSIndexHapticFix", + "name": "BSIndexHapticFix", + "author": "HardCPP#1985", + "version": "0.0.1", + "description": "A simple mod that fix index users haptics on knuckles", + "gameVersion": "1.18.0", + "dependsOn": { + "BSIPA": "^4.0.5" + }, + "features": [] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..63bacdc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 HardCPP + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..578ba2e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# BSIndexHapticFix + Fix haptics on index knucles