diff --git a/AudicaMod/CustomDifficultyNames.csproj b/AudicaMod/CustomDifficultyNames.csproj
new file mode 100644
index 0000000..12bd3e3
--- /dev/null
+++ b/AudicaMod/CustomDifficultyNames.csproj
@@ -0,0 +1,204 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B450DB87-100F-446D-BA5F-93B6E9042F46}
+ Library
+ Properties
+ CustomDifficultyNames
+ CustomDifficultyNames
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ none
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ lib\Assembly-CSharp.dll
+ False
+
+
+ lib\Assembly-CSharp-firstpass.dll
+ False
+
+
+ lib\Il2CppMono.Security.dll
+ False
+
+
+ lib\Il2Cppmscorlib.dll
+ False
+
+
+ lib\Il2CppSystem.dll
+ False
+
+
+ lib\Il2CppSystem.Configuration.dll
+ False
+
+
+ lib\Il2CppSystem.Core.dll
+ False
+
+
+ lib\Il2CppSystem.Runtime.Serialization.dll
+ False
+
+
+ lib\Il2CppSystem.Xml.dll
+ False
+
+
+ lib\MelonLoader.ModHandler.dll
+ False
+
+
+ lib\Oculus.VR.dll
+ False
+
+
+ lib\Sanford.Multimedia.Midi.dll
+ False
+
+
+ lib\SonyNP.dll
+ False
+
+
+ lib\SteamVR.dll
+ False
+
+
+
+
+ packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll
+ True
+ True
+
+
+
+
+
+
+
+
+
+ lib\TwitchChatter.dll
+ False
+
+
+ lib\UnhollowerBaseLib.dll
+ False
+
+
+ lib\UnhollowerRuntimeLib.dll
+ False
+
+
+ lib\Unity.TextMeshPro.dll
+ False
+
+
+ lib\UnityEngine.AIModule.dll
+ False
+
+
+ lib\UnityEngine.AnimationModule.dll
+ False
+
+
+ lib\UnityEngine.AudioModule.dll
+ False
+
+
+ lib\UnityEngine.CoreModule.dll
+ False
+
+
+ lib\UnityEngine.IMGUIModule.dll
+ False
+
+
+ E:\Steam\steamapps\common\Audica\MelonLoader\Managed\UnityEngine.JSONSerializeModule.dll
+
+
+ lib\UnityEngine.ParticleSystemModule.dll
+ False
+
+
+ lib\UnityEngine.Physics2DModule.dll
+ False
+
+
+ lib\UnityEngine.PhysicsModule.dll
+ False
+
+
+ lib\UnityEngine.TerrainModule.dll
+ False
+
+
+ lib\UnityEngine.TextCoreModule.dll
+ False
+
+
+ lib\UnityEngine.TextRenderingModule.dll
+ False
+
+
+ lib\UnityEngine.UI.dll
+ False
+
+
+ lib\UnityEngine.UIModule.dll
+ False
+
+
+ lib\UnityEngine.UnityWebRequestModule.dll
+ False
+
+
+ lib\UnityEngine.UnityWebRequestWWWModule.dll
+ False
+
+
+ lib\UnityEngine.VehiclesModule.dll
+ False
+
+
+ lib\UnityEngine.XRModule.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+ copy "$(TargetPath)" "F:\DATA HDD\Steam\SteamApps\common\Audica\Mods\$(TargetFileName)"
+
+
\ No newline at end of file
diff --git a/AudicaMod/Properties/AssemblyInfo.cs b/AudicaMod/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2b90922
--- /dev/null
+++ b/AudicaMod/Properties/AssemblyInfo.cs
@@ -0,0 +1,26 @@
+using System.Resources;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using MelonLoader;
+using AudicaModding;
+
+[assembly: AssemblyTitle("Custom Difficulty Names")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MeepsKitten")]
+[assembly: AssemblyProduct("Custom Difficulty Names Mod")]
+[assembly: AssemblyCopyright("Created by MeepsKitten")]
+[assembly: AssemblyTrademark("MeepsKitten")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+//[assembly: Guid("")]
+[assembly: AssemblyVersion("1.0.0")]
+[assembly: AssemblyFileVersion("1.0.0")]
+[assembly: NeutralResourcesLanguage("en")]
+[assembly: MelonInfo(typeof(CustomDifficultyNames), "Custom Difficulty Names", "1.0.0", "MeepsKitten")]
+
+
+// Create and Setup a MelonModGame to mark a Mod as Universal or Compatible with specific Games.
+// If no MelonModGameAttribute is found or any of the Values for any MelonModGame on the Mod is null or empty it will be assumed the Mod is Universal.
+// Values for MelonModGame can be found in the Game's app.info file or printed at the top of every log directly beneath the Unity version.
+[assembly: MelonGame("Harmonix Music Systems, Inc.", "Audica")]
\ No newline at end of file
diff --git a/AudicaMod/packages.config b/AudicaMod/packages.config
new file mode 100644
index 0000000..76773c0
--- /dev/null
+++ b/AudicaMod/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/AudicaMod/src/CustomDifficultyName/CustomDifficultyNames.cs b/AudicaMod/src/CustomDifficultyName/CustomDifficultyNames.cs
new file mode 100644
index 0000000..1954fce
--- /dev/null
+++ b/AudicaMod/src/CustomDifficultyName/CustomDifficultyNames.cs
@@ -0,0 +1,85 @@
+using Il2CppSystem;
+using MelonLoader;
+using System.Collections.Generic;
+using UnityEngine;
+using System.IO;
+using System.IO.Compression;
+using MelonLoader.TinyJSON;
+
+namespace AudicaModding
+{
+ public class CustomDifficultyNames : MelonMod
+ {
+ public static Dictionary CustomDifficulties = new Dictionary();
+
+ public class CustomNameData
+ {
+ public bool hasCustomExpertName = false;
+ public bool hasCustomAdvancedName = false;
+ public bool hasCustomModerateName = false;
+ public bool hasCustomBeginnerName = false;
+
+
+ public string customExpert = "";
+ public string customAdvanced = "";
+ public string customModerate = "";
+ public string customBeginner = "";
+ }
+
+ public static void LoadCustomNames()
+ {
+ CustomDifficulties = new Dictionary();
+
+ foreach (SongList.SongData data in SongList.I.songs.ToArray())
+ {
+ ZipArchive SongFiles = ZipFile.OpenRead(data.foundPath);
+
+ foreach (ZipArchiveEntry entry in SongFiles.Entries)
+ {
+ if (entry.Name == "song.desc")
+ {
+ Stream songData = entry.Open();
+ StreamReader reader = new StreamReader(songData);
+ string descDump = reader.ReadToEnd();
+ CustomNameData DifficultyNames = new CustomNameData();
+ DifficultyNames = JSON.Load(descDump).Make();
+
+ bool anyAreTrue = false;
+
+
+ if (DifficultyNames.customExpert.Length > 0)
+ {
+ DifficultyNames.hasCustomExpertName = true;
+ anyAreTrue = true;
+ }
+
+ if (DifficultyNames.customAdvanced.Length > 0)
+ {
+ DifficultyNames.hasCustomAdvancedName = true;
+ anyAreTrue = true;
+ }
+
+ if (DifficultyNames.customModerate.Length > 0)
+ {
+ DifficultyNames.hasCustomModerateName = true;
+ anyAreTrue = true;
+ }
+
+ if (DifficultyNames.customBeginner.Length > 0)
+ {
+ DifficultyNames.hasCustomBeginnerName = true;
+ anyAreTrue = true;
+ }
+
+ if (anyAreTrue)
+ CustomDifficulties[data.songID] = DifficultyNames;
+
+
+ }
+ }
+
+ SongFiles.Dispose();
+ }
+ }
+ }
+}
diff --git a/AudicaMod/src/CustomDifficultyName/DifficultyHooks.cs b/AudicaMod/src/CustomDifficultyName/DifficultyHooks.cs
new file mode 100644
index 0000000..3556ba2
--- /dev/null
+++ b/AudicaMod/src/CustomDifficultyName/DifficultyHooks.cs
@@ -0,0 +1,114 @@
+using Harmony;
+using UnityEngine;
+using System.Reflection;
+using System;
+using MelonLoader;
+using Valve.VR.InteractionSystem;
+using TMPro;
+using System.Collections;
+
+namespace AudicaModding
+{
+ internal static class DifficultyHooks
+ {
+ public static IEnumerator ChangeNamesLP(LaunchPanel __instance)
+ {
+ yield return new WaitForSeconds(0.05f);
+
+ __instance.difficultySelect.gameObject.SetActive(false);
+ var song = SongDataHolder.I.songData;
+ CustomDifficultyNames.CustomNameData data;
+ if (CustomDifficultyNames.CustomDifficulties.ContainsKey(song.songID))
+ {
+ data = CustomDifficultyNames.CustomDifficulties[song.songID];
+
+ if (data.hasCustomExpertName)
+ __instance.expert.GetComponentInChildren().text = data.customExpert;
+
+ if (data.hasCustomAdvancedName)
+ __instance.hard.GetComponentInChildren().text = data.customAdvanced;
+
+ if (data.hasCustomModerateName)
+ __instance.normal.GetComponentInChildren().text = data.customModerate;
+
+ if (data.hasCustomBeginnerName)
+ __instance.easy.GetComponentInChildren().text = data.customBeginner;
+
+ }
+ else
+ {
+ __instance.expert.GetComponentInChildren().text = "Expert";
+ __instance.hard.GetComponentInChildren().text = "Advanced";
+ __instance.normal.GetComponentInChildren().text = "Moderate";
+ __instance.easy.GetComponentInChildren().text = "Beginner";
+ }
+ }
+
+ public static IEnumerator ChangeNamesDS(DifficultySelect __instance)
+ {
+ yield return new WaitForSeconds(0.05f);
+
+ var song = SongDataHolder.I.songData;
+ CustomDifficultyNames.CustomNameData data;
+ if (CustomDifficultyNames.CustomDifficulties.ContainsKey(song.songID))
+ {
+ data = CustomDifficultyNames.CustomDifficulties[song.songID];
+
+ if (data.hasCustomExpertName)
+ __instance.expert.label.text = data.customExpert;
+
+ if (data.hasCustomAdvancedName)
+ __instance.hard.label.text = data.customAdvanced;
+
+ if (data.hasCustomModerateName)
+ __instance.normal.label.text = data.customModerate;
+
+ if (data.hasCustomBeginnerName)
+ __instance.easy.label.text = data.customBeginner;
+
+ }
+ else
+ {
+ __instance.expert.label.text = "Expert";
+ __instance.hard.label.text = "Advanced";
+ __instance.normal.label.text = "Moderate";
+ __instance.easy.label.text = "Beginner";
+ }
+ }
+
+ ///
+ /// Author: MeepsKitten
+ ///
+ [HarmonyPatch(typeof(LaunchPanel), "OnEnable", new Type[0])]
+ private static class DisplayCustomNameLP
+ {
+ private static void Prefix(LaunchPanel __instance)
+ {
+ IEnumerator coroutine = ChangeNamesLP(__instance);
+ MelonCoroutines.Start(coroutine);
+ }
+
+ }
+
+ [HarmonyPatch(typeof(DifficultySelect), "OnEnable", new Type[0])]
+ private static class DisplayCustomNameDS
+ {
+ private static void Postfix(DifficultySelect __instance)
+ {
+ IEnumerator coroutine = ChangeNamesDS(__instance);
+ MelonCoroutines.Start(coroutine);
+ }
+
+ }
+
+ [HarmonyPatch(typeof(SongSelect), "OnEnable", new Type[0])]
+ private static class LoadDiffNamesOnSongSelectLoad
+ {
+ private static void Postfix(DifficultySelect __instance)
+ {
+ CustomDifficultyNames.LoadCustomNames();
+ }
+
+ }
+ }
+}
diff --git a/CustomDifficultyNames.sln b/CustomDifficultyNames.sln
new file mode 100644
index 0000000..72e920a
--- /dev/null
+++ b/CustomDifficultyNames.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.421
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomDifficultyNames", "AudicaMod\CustomDifficultyNames.csproj", "{B450DB87-100F-446D-BA5F-93B6E9042F46}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B450DB87-100F-446D-BA5F-93B6E9042F46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B450DB87-100F-446D-BA5F-93B6E9042F46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B450DB87-100F-446D-BA5F-93B6E9042F46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B450DB87-100F-446D-BA5F-93B6E9042F46}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {94835E94-EEB2-4CC4-9159-C27DDB4EBBF4}
+ EndGlobalSection
+EndGlobal