├── .gitignore ├── MuseDashModManager.sln ├── MuseDashModManager ├── CustomMaps │ ├── Global.cs │ ├── Model.cs │ ├── Patch.cs │ └── Util.cs ├── EntryPoint.cs ├── Global.cs ├── MuseDashModManager.csproj ├── Patch.cs ├── Properties │ └── AssemblyInfo.cs ├── Util.cs └── packages.config ├── Patched_DLL └── Assembly-CSharp.dll ├── README.md └── Resource ├── iyaiya_map1.bms ├── nocover.png └── nocover.psd /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUnit 46 | *.VisualState.xml 47 | TestResult.xml 48 | nunit-*.xml 49 | 50 | # Build Results of an ATL Project 51 | [Dd]ebugPS/ 52 | [Rr]eleasePS/ 53 | dlldata.c 54 | 55 | # Benchmark Results 56 | BenchmarkDotNet.Artifacts/ 57 | 58 | # .NET Core 59 | project.lock.json 60 | project.fragment.lock.json 61 | artifacts/ 62 | 63 | # StyleCop 64 | StyleCopReport.xml 65 | 66 | # Files built by Visual Studio 67 | *_i.c 68 | *_p.c 69 | *_h.h 70 | *.ilk 71 | *.meta 72 | *.obj 73 | *.iobj 74 | *.pch 75 | *.pdb 76 | *.ipdb 77 | *.pgc 78 | *.pgd 79 | *.rsp 80 | *.sbr 81 | *.tlb 82 | *.tli 83 | *.tlh 84 | *.tmp 85 | *.tmp_proj 86 | *_wpftmp.csproj 87 | *.log 88 | *.vspscc 89 | *.vssscc 90 | .builds 91 | *.pidb 92 | *.svclog 93 | *.scc 94 | 95 | # Chutzpah Test files 96 | _Chutzpah* 97 | 98 | # Visual C++ cache files 99 | ipch/ 100 | *.aps 101 | *.ncb 102 | *.opendb 103 | *.opensdf 104 | *.sdf 105 | *.cachefile 106 | *.VC.db 107 | *.VC.VC.opendb 108 | 109 | # Visual Studio profiler 110 | *.psess 111 | *.vsp 112 | *.vspx 113 | *.sap 114 | 115 | # Visual Studio Trace Files 116 | *.e2e 117 | 118 | # TFS 2012 Local Workspace 119 | $tf/ 120 | 121 | # Guidance Automation Toolkit 122 | *.gpState 123 | 124 | # ReSharper is a .NET coding add-in 125 | _ReSharper*/ 126 | *.[Rr]e[Ss]harper 127 | *.DotSettings.user 128 | 129 | # JustCode is a .NET coding add-in 130 | .JustCode 131 | 132 | # TeamCity is a build add-in 133 | _TeamCity* 134 | 135 | # DotCover is a Code Coverage Tool 136 | *.dotCover 137 | 138 | # AxoCover is a Code Coverage Tool 139 | .axoCover/* 140 | !.axoCover/settings.json 141 | 142 | # Visual Studio code coverage results 143 | *.coverage 144 | *.coveragexml 145 | 146 | # NCrunch 147 | _NCrunch_* 148 | .*crunch*.local.xml 149 | nCrunchTemp_* 150 | 151 | # MightyMoose 152 | *.mm.* 153 | AutoTest.Net/ 154 | 155 | # Web workbench (sass) 156 | .sass-cache/ 157 | 158 | # Installshield output folder 159 | [Ee]xpress/ 160 | 161 | # DocProject is a documentation generator add-in 162 | DocProject/buildhelp/ 163 | DocProject/Help/*.HxT 164 | DocProject/Help/*.HxC 165 | DocProject/Help/*.hhc 166 | DocProject/Help/*.hhk 167 | DocProject/Help/*.hhp 168 | DocProject/Help/Html2 169 | DocProject/Help/html 170 | 171 | # Click-Once directory 172 | publish/ 173 | 174 | # Publish Web Output 175 | *.[Pp]ublish.xml 176 | *.azurePubxml 177 | # Note: Comment the next line if you want to checkin your web deploy settings, 178 | # but database connection strings (with potential passwords) will be unencrypted 179 | *.pubxml 180 | *.publishproj 181 | 182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 183 | # checkin your Azure Web App publish settings, but sensitive information contained 184 | # in these scripts will be unencrypted 185 | PublishScripts/ 186 | 187 | # NuGet Packages 188 | *.nupkg 189 | # NuGet Symbol Packages 190 | *.snupkg 191 | # The packages folder can be ignored because of Package Restore 192 | **/[Pp]ackages/* 193 | # except build/, which is used as an MSBuild target. 194 | !**/[Pp]ackages/build/ 195 | # Uncomment if necessary however generally it will be regenerated when needed 196 | #!**/[Pp]ackages/repositories.config 197 | # NuGet v3's project.json files produces more ignorable files 198 | *.nuget.props 199 | *.nuget.targets 200 | 201 | # Microsoft Azure Build Output 202 | csx/ 203 | *.build.csdef 204 | 205 | # Microsoft Azure Emulator 206 | ecf/ 207 | rcf/ 208 | 209 | # Windows Store app package directories and files 210 | AppPackages/ 211 | BundleArtifacts/ 212 | Package.StoreAssociation.xml 213 | _pkginfo.txt 214 | *.appx 215 | *.appxbundle 216 | *.appxupload 217 | 218 | # Visual Studio cache files 219 | # files ending in .cache can be ignored 220 | *.[Cc]ache 221 | # but keep track of directories ending in .cache 222 | !?*.[Cc]ache/ 223 | 224 | # Others 225 | ClientBin/ 226 | ~$* 227 | *~ 228 | *.dbmdl 229 | *.dbproj.schemaview 230 | *.jfm 231 | *.pfx 232 | *.publishsettings 233 | orleans.codegen.cs 234 | 235 | # Including strong name files can present a security risk 236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 237 | #*.snk 238 | 239 | # Since there are multiple workflows, uncomment next line to ignore bower_components 240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 241 | #bower_components/ 242 | 243 | # RIA/Silverlight projects 244 | Generated_Code/ 245 | 246 | # Backup & report files from converting an old project file 247 | # to a newer Visual Studio version. Backup files are not needed, 248 | # because we have git ;-) 249 | _UpgradeReport_Files/ 250 | Backup*/ 251 | UpgradeLog*.XML 252 | UpgradeLog*.htm 253 | ServiceFabricBackup/ 254 | *.rptproj.bak 255 | 256 | # SQL Server files 257 | *.mdf 258 | *.ldf 259 | *.ndf 260 | 261 | # Business Intelligence projects 262 | *.rdl.data 263 | *.bim.layout 264 | *.bim_*.settings 265 | *.rptproj.rsuser 266 | *- [Bb]ackup.rdl 267 | *- [Bb]ackup ([0-9]).rdl 268 | *- [Bb]ackup ([0-9][0-9]).rdl 269 | 270 | # Microsoft Fakes 271 | FakesAssemblies/ 272 | 273 | # GhostDoc plugin setting file 274 | *.GhostDoc.xml 275 | 276 | # Node.js Tools for Visual Studio 277 | .ntvs_analysis.dat 278 | node_modules/ 279 | 280 | # Visual Studio 6 build log 281 | *.plg 282 | 283 | # Visual Studio 6 workspace options file 284 | *.opt 285 | 286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 287 | *.vbw 288 | 289 | # Visual Studio LightSwitch build output 290 | **/*.HTMLClient/GeneratedArtifacts 291 | **/*.DesktopClient/GeneratedArtifacts 292 | **/*.DesktopClient/ModelManifest.xml 293 | **/*.Server/GeneratedArtifacts 294 | **/*.Server/ModelManifest.xml 295 | _Pvt_Extensions 296 | 297 | # Paket dependency manager 298 | .paket/paket.exe 299 | paket-files/ 300 | 301 | # FAKE - F# Make 302 | .fake/ 303 | 304 | # CodeRush personal settings 305 | .cr/personal 306 | 307 | # Python Tools for Visual Studio (PTVS) 308 | __pycache__/ 309 | *.pyc 310 | 311 | # Cake - Uncomment if you are using it 312 | # tools/** 313 | # !tools/packages.config 314 | 315 | # Tabs Studio 316 | *.tss 317 | 318 | # Telerik's JustMock configuration file 319 | *.jmconfig 320 | 321 | # BizTalk build output 322 | *.btp.cs 323 | *.btm.cs 324 | *.odx.cs 325 | *.xsd.cs 326 | 327 | # OpenCover UI analysis results 328 | OpenCover/ 329 | 330 | # Azure Stream Analytics local run output 331 | ASALocalRun/ 332 | 333 | # MSBuild Binary and Structured Log 334 | *.binlog 335 | 336 | # NVidia Nsight GPU debugger configuration file 337 | *.nvuser 338 | 339 | # MFractors (Xamarin productivity tool) working folder 340 | .mfractor/ 341 | 342 | # Local History for Visual Studio 343 | .localhistory/ 344 | 345 | # BeatPulse healthcheck temp database 346 | healthchecksdb 347 | 348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 349 | MigrationBackup/ -------------------------------------------------------------------------------- /MuseDashModManager.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28922.388 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MuseDashModManager", "MuseDashModManager\MuseDashModManager.csproj", "{BC37F97A-B56F-4879-8867-D54C29AD93B6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BC37F97A-B56F-4879-8867-D54C29AD93B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BC37F97A-B56F-4879-8867-D54C29AD93B6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BC37F97A-B56F-4879-8867-D54C29AD93B6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BC37F97A-B56F-4879-8867-D54C29AD93B6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {10198707-8BAA-4C23-911D-47689FA4BD4C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /MuseDashModManager/CustomMaps/Global.cs: -------------------------------------------------------------------------------- 1 | using GameLogic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using UnityEngine; 7 | 8 | namespace MuseDashModManager.CustomMaps 9 | { 10 | class Global 11 | { 12 | public static MusicConfigReader MusicConfigReader = (MusicConfigReader)Activator.CreateInstance(typeof(MusicConfigReader), true); 13 | 14 | public static Sprite SpriteNoCover = null; 15 | 16 | public static CustomMapNameListVariable CustomMapNameListVariable = new CustomMapNameListVariable(); 17 | 18 | public static CustomImageVariable ImageVariable = new CustomImageVariable(); 19 | 20 | public static string MapDirectory = "maps"; 21 | 22 | public static List CustomMapList = new List(); 23 | 24 | public static GameObject CustomAlbumCells; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MuseDashModManager/CustomMaps/Model.cs: -------------------------------------------------------------------------------- 1 | using Assets.Scripts.GameCore; 2 | using Assets.Scripts.GameCore.Managers; 3 | using Assets.Scripts.PeroTools.Commons; 4 | using Assets.Scripts.PeroTools.Nice.Datas; 5 | using Assets.Scripts.PeroTools.Nice.Interface; 6 | using Newtonsoft.Json.Linq; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using UnityEngine; 12 | 13 | namespace MuseDashModManager.CustomMaps 14 | { 15 | public class CustomMap 16 | { 17 | public string Name; 18 | public string Artist; 19 | public string Music; 20 | public string MusicDemo; 21 | public string BPM; 22 | public string Scene; 23 | public string UID; 24 | public AudioClip MusicClip = null; 25 | public AudioClip MusicDemoClip = null; 26 | public Sprite CoverSprite = null; 27 | public string[] Difficulty = new string[3]; 28 | public StageInfo[] stages = new StageInfo[] { null, null, null }; 29 | public string Cover 30 | { 31 | get => UID + "_cover"; 32 | } 33 | 34 | public string Map 35 | { 36 | get => UID + "_map"; 37 | } 38 | 39 | } 40 | 41 | 42 | public class CustomMapNameListVariable : IVariable 43 | { 44 | public object result { get => Global.CustomMapList; set => throw new NotImplementedException(); } 45 | } 46 | 47 | public class CustomMapMasterUnlocker : IVariable 48 | { 49 | public IVariable original; 50 | public CustomMapMasterUnlocker(IVariable original) : base() { this.original = original; } 51 | public object result 52 | { 53 | get 54 | { 55 | try 56 | { 57 | var uid = Singleton.instance["Account"]["SelectedAlbumUid"].result; 58 | if (uid != null && (string)uid == "custom") 59 | { 60 | return true; 61 | } 62 | 63 | } catch {} 64 | 65 | try 66 | { 67 | return original.result; 68 | } 69 | catch 70 | { 71 | return null; 72 | } 73 | 74 | } 75 | set 76 | { 77 | original.result = value; 78 | } 79 | } 80 | } 81 | 82 | public class CustomImageVariable : IVariable 83 | { 84 | public IVariable variable; 85 | public object result 86 | { 87 | get 88 | { 89 | int i = this.variable.GetResult(); 90 | return Global.CustomMapList[i].CoverSprite; 91 | } 92 | 93 | set { } 94 | } 95 | 96 | 97 | } 98 | 99 | public class CustomInfo 100 | { 101 | public static JToken UID() 102 | { 103 | return "custom"; 104 | } 105 | 106 | public static JToken Title() 107 | { 108 | return "自定义谱面"; 109 | } 110 | 111 | public static JToken PrefabsName() 112 | { 113 | return "AlbumCustom"; 114 | } 115 | 116 | public static JToken Price() 117 | { 118 | return "Free"; 119 | } 120 | 121 | public static JToken JsonName() 122 | { 123 | return "custom"; 124 | } 125 | 126 | public static JToken NeedPurchase() 127 | { 128 | return "false"; 129 | } 130 | } 131 | 132 | public class BMSAndStage 133 | { 134 | public iBMSCManager.BMS BMS = null; 135 | public StageInfo StageInfo = null; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /MuseDashModManager/CustomMaps/Patch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Reflection; 5 | using Assets.Scripts.UI.Panels; 6 | using Newtonsoft.Json.Linq; 7 | using Harmony; 8 | using Assets.Scripts.PeroTools.Commons; 9 | using Assets.Scripts.PeroTools.Managers; 10 | using Assets.Scripts.GameCore; 11 | using Assets.Scripts.GameCore.Managers; 12 | using UnityEngine; 13 | using Assets.Scripts.PeroTools.Nice.Components; 14 | using Assets.Scripts.PeroTools.Nice.Variables; 15 | using Assets.Scripts.PeroTools.Nice.Interface; 16 | using Assets.Scripts.PeroTools.AssetBundles; 17 | using Assets.Scripts.PeroTools.Nice.Events; 18 | using Assets.Scripts.PeroTools.Nice.Actions; 19 | using System.IO; 20 | using GameLogic; 21 | using Assets.Scripts.PeroTools.Nice.Datas; 22 | 23 | 24 | namespace MuseDashModManager.CustomMaps 25 | { 26 | class Patch 27 | { 28 | public static bool HasInitAlbumDatas; 29 | 30 | // 安装Patch 31 | public static void InstallPatch(HarmonyInstance harmonyInstance) 32 | { 33 | MethodInfo methodInitAlbumDatas = AccessTools.Method(typeof(Assets.Scripts.UI.Panels.PnlStage), "InitAlbumDatas"); 34 | MethodInfo methodPathIADPostfix = AccessTools.Method(typeof(Patch), "InitAlbumDatasPostfix"); 35 | harmonyInstance.Patch(methodInitAlbumDatas, null, new HarmonyMethod(methodPathIADPostfix), null); 36 | 37 | MethodInfo methodRebuildChildren = AccessTools.Method(typeof(Assets.Scripts.PeroTools.Nice.Components.FancyScrollView), "RebuildChildren"); 38 | MethodInfo methodRCPrefix = AccessTools.Method(typeof(Patch), "FancyScrollAlbumRebuildChildrenPrefix"); 39 | harmonyInstance.Patch(methodRebuildChildren, new HarmonyMethod(methodRCPrefix), null, null); 40 | 41 | MethodInfo methodIsCanPreparationOut = AccessTools.Method(typeof(Assets.Scripts.UI.Panels.PnlStage), "IsCanPreparationOut"); 42 | MethodInfo methodICPOPrefix = AccessTools.Method(typeof(Patch), "IsCanPreparationOutPrefix"); 43 | harmonyInstance.Patch(methodIsCanPreparationOut, new HarmonyMethod(methodICPOPrefix), null, null); 44 | 45 | MethodInfo methodSetBgLockAction = AccessTools.Method(typeof(Assets.Scripts.UI.Panels.PnlStage), "SetBgLockAction"); 46 | MethodInfo methodSBLAPrefix = AccessTools.Method(typeof(Patch), "SetBgLockActionPrefix"); 47 | harmonyInstance.Patch(methodSetBgLockAction, new HarmonyMethod(methodSBLAPrefix), null, null); 48 | 49 | MethodInfo methodOnBattleEnd = AccessTools.Method(typeof(Assets.Scripts.GameCore.Managers.StatisticsManager), "OnBattleEnd"); 50 | MethodInfo methodOBEPrefix = AccessTools.Method(typeof(Patch), "OnBattleEndPrefix"); 51 | harmonyInstance.Patch(methodOnBattleEnd, new HarmonyMethod(methodOBEPrefix), null, null); 52 | 53 | MethodInfo methodChangeMusic = AccessTools.Method(typeof(Assets.Scripts.UI.Panels.PnlStage), "ChangeMusic"); 54 | MethodInfo methodCMPostfix = AccessTools.Method(typeof(Patch), "ChangeMusicPostfix"); 55 | harmonyInstance.Patch(methodChangeMusic, null, new HarmonyMethod(methodCMPostfix), null); 56 | } 57 | 58 | public static void InitAlbumDatasPostfix(PnlStage __instance) 59 | { 60 | var dtype = typeof(PnlStage).GetNestedType("GetData", BindingFlags.NonPublic); 61 | 62 | // 反射获得m_AlbumDatas 63 | Type configManagerType = typeof(PnlStage); 64 | var field = configManagerType.GetField("m_AlbumDatas", BindingFlags.NonPublic | BindingFlags.Instance); 65 | var m_AlbumDatas = 66 | (object[])field.GetValue(__instance); 67 | 68 | if (HasInitAlbumDatas) 69 | { 70 | // 把第2个挪到最后去,别问我为什么 71 | for (int i = 2; i < m_AlbumDatas.Length - 1; ++i) 72 | { 73 | object swap = m_AlbumDatas[i + 1]; 74 | m_AlbumDatas[i + 1] = m_AlbumDatas[i]; 75 | m_AlbumDatas[i] = swap; 76 | } 77 | return; 78 | } 79 | 80 | // 添加Album信息到m_AlbumDatas中 81 | HasInitAlbumDatas = true; 82 | 83 | var dictype = m_AlbumDatas[0].GetType(); 84 | 85 | var newAlbumdata = Array.CreateInstance(dictype, m_AlbumDatas.Length + 1); 86 | m_AlbumDatas.CopyTo(newAlbumdata, 0); 87 | 88 | object newDict = Activator.CreateInstance(dictype); 89 | var addMethod = AccessTools.Method(dictype, "Add", new Type[] { typeof(string), dtype }); 90 | addMethod.Invoke(newDict, new object[] { "uid", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "UID") }); 91 | addMethod.Invoke(newDict, new object[] { "title", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "Title") }); 92 | addMethod.Invoke(newDict, new object[] { "prefabsName", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "PrefabsName") }); 93 | addMethod.Invoke(newDict, new object[] { "price", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "Price") }); 94 | addMethod.Invoke(newDict, new object[] { "jsonName", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "JsonName") }); 95 | addMethod.Invoke(newDict, new object[] { "needPurchase", Delegate.CreateDelegate(dtype, typeof(CustomInfo), "NeedPurchase") }); 96 | 97 | newAlbumdata.SetValue(newDict, m_AlbumDatas.Length); 98 | 99 | field.SetValue(__instance, newAlbumdata); 100 | 101 | GameInit.maxAlbumIndex += 1; 102 | 103 | var sView = __instance.albumFancyScrollView; 104 | 105 | 106 | // 添加Album信息到ConfigManager中 107 | var configManager = Singleton.instance; 108 | var mData = (Dictionary)AccessTools.Field(typeof(ConfigManager), "m_Dictionary").GetValue(configManager); 109 | 110 | var @object = new JObject(); 111 | @object.Add("uid", "custom"); 112 | @object.Add("title", "Custom Maps"); 113 | @object.Add("prefabsName", "AlbumCustom"); 114 | @object.Add("price", "Free"); 115 | @object.Add("jsonName", "custom"); 116 | @object.Add("needPurchase", "false"); 117 | @object.Add("free", true); 118 | 119 | mData["albums"].Add(@object); 120 | 121 | var title = new JObject(); 122 | title.Add("title", "自定义谱面"); 123 | configManager["albums"].Add(title); 124 | 125 | Console.WriteLine("[MuseDashModManager]自定义谱面菜单添加成功"); 126 | } 127 | 128 | public static void FancyScrollAlbumRebuildChildrenPrefix(FancyScrollView __instance) 129 | { 130 | if (__instance.name == "FancyScrollAlbum") 131 | { 132 | // 创建自定义谱面的Album按键 133 | GameObject custom = GameObject.Instantiate(__instance.content.GetChild(0).gameObject); 134 | custom.name = "ImgAlbumCustom"; 135 | 136 | RectTransform transform = (RectTransform)custom.transform; 137 | transform.name = "ImgAlbumCustom"; 138 | var text = transform.GetChild(1).GetComponent(); 139 | text.text = "自定义谱面"; 140 | 141 | transform.GetComponents(typeof(UnityEngine.Object)); 142 | //custom.transform.SetSiblingIndex(__instance.content.childCount); 143 | custom.transform.SetParent(__instance.content); 144 | 145 | } 146 | } 147 | 148 | public static bool IsCanPreparationOutPrefix(PnlStage __instance, ref bool __result) 149 | { 150 | // 解除自定义谱面的上锁状态 151 | if (__instance.GetSelectedMusicAlbumJsonName() == "custom") 152 | { 153 | __result = true; 154 | return false; 155 | } 156 | 157 | return true; 158 | } 159 | 160 | public static bool SetBgLockActionPrefix(PnlStage __instance) 161 | { 162 | // 解除自定义谱面的上锁背景 163 | if (__instance.GetSelectedMusicAlbumJsonName() == "custom") 164 | { 165 | __instance.bgAlbumLock.SetActive(false); 166 | __instance.txtBudgetIsBurning.SetActive(false); 167 | __instance.txtNotPurchase.SetActive(false); 168 | 169 | return false; 170 | } 171 | 172 | return true; 173 | } 174 | 175 | public static bool OnBattleEndPrefix() 176 | { 177 | // 禁用自定义谱面的成绩上传 178 | if (Singleton.instance["Account"]["SelectedMusicUid"].GetResult().StartsWith("custom_")) return false; 179 | return true; 180 | } 181 | 182 | public static void ChangeMusicPostfix(PnlStage __instance) 183 | { 184 | // 禁用掉收藏按钮 185 | if (__instance.GetSelectedMusicAlbumJsonName() == "custom") 186 | { 187 | //__instance.difficulty3Lock.SetActive(false); 188 | //__instance.difficulty3Master.SetActive(__instance.difficulty3.text != "0"); 189 | 190 | __instance.tglLike.gameObject.SetActive(false); 191 | return; 192 | } 193 | 194 | __instance.tglLike.gameObject.SetActive(true); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /MuseDashModManager/CustomMaps/Util.cs: -------------------------------------------------------------------------------- 1 | using Assets.Scripts.GameCore; 2 | using Assets.Scripts.GameCore.Managers; 3 | using Assets.Scripts.PeroTools.AssetBundles; 4 | using Assets.Scripts.PeroTools.Commons; 5 | using Assets.Scripts.PeroTools.Managers; 6 | using Assets.Scripts.PeroTools.Nice.Actions; 7 | using Assets.Scripts.PeroTools.Nice.Datas; 8 | using Assets.Scripts.PeroTools.Nice.Events; 9 | using Assets.Scripts.PeroTools.Nice.Interface; 10 | using Assets.Scripts.PeroTools.Nice.Variables; 11 | using GameLogic; 12 | using Harmony; 13 | using Newtonsoft.Json.Linq; 14 | using System; 15 | using System.Collections.Generic; 16 | using System.IO; 17 | using System.Linq; 18 | using System.Text; 19 | using UnityEngine; 20 | 21 | namespace MuseDashModManager.CustomMaps 22 | { 23 | class Util 24 | { 25 | 26 | public static void Init() 27 | { 28 | Global.SpriteNoCover = LoadNoCoverSpirte(); 29 | // 注册资源 30 | MuseDashModManager.Util.AddAssetEx("AlbumCustom", CreateCustomMusicCells); 31 | 32 | // 设置谱面存储位置 33 | AccessTools.Method(typeof(iBMSCManager), "set_bmsFile").Invoke(iBMSCManager.instance, new object[] { Path.Combine(Directory.GetCurrentDirectory(), Global.MapDirectory).Replace("\\", "/") }); 34 | // 修改大触难度解锁条件,使自定义谱面全解锁 35 | var original = Singleton.instance["Account"]["IsSelectedUnlockMaster"]; 36 | var newpatch = new CustomMapMasterUnlocker(original); 37 | Singleton.instance["Account"].Set("IsSelectedUnlockMaster", newpatch); 38 | 39 | // 加载谱面 40 | DirectoryInfo di = new DirectoryInfo(Global.MapDirectory); 41 | if (!di.Exists) di.Create(); 42 | 43 | foreach(var i in di.GetDirectories()) 44 | { 45 | CustomMap cm = LoadCustomMapFromDirectory(i); 46 | Global.CustomMapList.Add(cm); 47 | } 48 | 49 | // 添加谱面到游戏 50 | AddAllCustomMapToGame(); 51 | } 52 | 53 | public static CustomMap LoadCustomMapFromDirectory(DirectoryInfo di) 54 | { 55 | CustomMap cm = new CustomMap(); 56 | bool setInfo = false; 57 | 58 | for(int i = 0; i < 3; ++i) 59 | { 60 | string mapFileName = String.Format("{0}\\{1}_map{2}.bms", di.FullName, di.Name, i + 1); 61 | if(File.Exists(mapFileName)) 62 | { 63 | string rmapFileName = String.Format("{0}\\{0}_map{1}", di.Name, i + 1); 64 | var inf = LoadAndCreateStageInfo(rmapFileName); 65 | cm.stages[i] = inf.StageInfo; 66 | cm.Difficulty[i] = inf.StageInfo.difficulty.ToString(); 67 | if(!setInfo) 68 | { 69 | setInfo = true; 70 | cm.Name = inf.StageInfo.mapName; 71 | cm.Artist = (string)inf.BMS.info["ARTIST"]; 72 | cm.Scene = inf.StageInfo.scene; 73 | cm.BPM = inf.StageInfo.bpm.ToString(); 74 | cm.Music = (string)inf.BMS.info["WAV10"]; 75 | } 76 | } 77 | } 78 | 79 | string coverFileName = String.Format("{0}\\cover.png", di.FullName); 80 | cm.CoverSprite = File.Exists(coverFileName) ? MuseDashModManager.Util.LoadSpirteFromFile(coverFileName, 440, 440) : Global.SpriteNoCover; 81 | cm.MusicClip = MuseDashModManager.Util.LoadAudioClipFromFile(String.Format("{0}\\{1}", di.FullName, cm.Music)); 82 | 83 | var n = cm.Music.Split('.'); 84 | string demoMusicFileName = String.Format("{0}\\{1}_demo.{2}", di.FullName, n[0], n[1]); 85 | if (File.Exists(demoMusicFileName)) 86 | { 87 | cm.MusicDemo = n[0]; 88 | cm.MusicDemoClip = MuseDashModManager.Util.LoadAudioClipFromFile(demoMusicFileName); 89 | } else 90 | { 91 | cm.MusicDemo = cm.Music; 92 | cm.MusicDemoClip = cm.MusicClip; 93 | } 94 | 95 | cm.Music = n[0]; 96 | 97 | // 分配一个UID,取文件夹名去掉空格 98 | string uid = String.Join("", di.Name.Split(' ', '_')); 99 | // UID重复怎么办? 100 | cm.UID = String.Format("custom_{0}", uid); 101 | return cm; 102 | } 103 | 104 | public static void AddAllCustomMapToGame() 105 | { 106 | // 添加到ConfigManager,以及添加资源 107 | foreach(var i in Global.CustomMapList) 108 | { 109 | AddCustomMapToGame(i); 110 | } 111 | } 112 | 113 | public static void AddCustomMapToGame(CustomMap cm) 114 | { 115 | AddCustomMapToConfigManager(cm); 116 | 117 | // 添加资源 118 | MuseDashModManager.Util.AddAsset(cm.Cover, cm.CoverSprite); 119 | MuseDashModManager.Util.AddAsset(cm.Music, cm.MusicClip); 120 | if(cm.Music != cm.MusicDemo) 121 | MuseDashModManager.Util.AddAsset(cm.MusicDemo, cm.MusicDemoClip); 122 | 123 | for(int i = 0; i < 3; ++i) 124 | { 125 | if(cm.stages[i] != null) 126 | { 127 | string map = String.Format("{0}{1}", cm.Map, i + 1); 128 | MuseDashModManager.Util.AddAsset(map, cm.stages[i]); 129 | } 130 | 131 | } 132 | } 133 | 134 | public static bool HasInitCustomJArray = false; 135 | 136 | public static Sprite LoadNoCoverSpirte() 137 | { 138 | var path = Application.streamingAssetsPath + "/nocover.png"; 139 | return MuseDashModManager.Util.LoadSpirteFromFile(path, 440, 440); 140 | } 141 | 142 | public static void AddCustomMapToConfigManager(CustomMap cm) 143 | { 144 | var configManager = Singleton.instance; 145 | var mData = (Dictionary)AccessTools.Field(typeof(ConfigManager), "m_Dictionary").GetValue(configManager); 146 | 147 | // 添加Custom 148 | if (!HasInitCustomJArray) 149 | { 150 | mData["custom"] = new JArray(); 151 | HasInitCustomJArray = true; 152 | } 153 | 154 | var @object = new JObject(); 155 | @object.Add("uid", cm.UID); 156 | @object.Add("name", cm.Name); 157 | @object.Add("author", cm.Artist); 158 | @object.Add("bpm", cm.BPM); 159 | @object.Add("music", cm.Music); 160 | @object.Add("demo", cm.MusicDemo); 161 | @object.Add("cover", cm.Cover); 162 | @object.Add("noteJson", cm.Map); 163 | @object.Add("scene", cm.Scene); 164 | @object.Add("difficulty1", cm.stages[0] != null ? cm.stages[0].difficulty.ToString() : "0"); 165 | @object.Add("difficulty2", cm.stages[1] != null ? cm.stages[1].difficulty.ToString() : "0"); 166 | @object.Add("difficulty3", cm.stages[2] != null ? cm.stages[2].difficulty.ToString() : "0"); 167 | @object.Add("unlockLevel", "0"); 168 | 169 | 170 | 171 | mData["custom"].Add(@object); 172 | } 173 | 174 | 175 | public static UnityEngine.GameObject CreateCustomMusicCells() 176 | { 177 | if (Global.CustomAlbumCells == null || Global.CustomAlbumCells.Equals(null)) 178 | { 179 | GameObject prefabs = Singleton.instance.LoadFromName("AlbumCollection"); 180 | prefabs = GameObject.Instantiate(prefabs); 181 | prefabs.name = "albumCustom"; 182 | var component = prefabs.GetComponent(); 183 | var ifp = component.playables[0]; 184 | 185 | var fexecute = AccessTools.Field(typeof(If), "m_IsExecute"); 186 | Formula f = (Formula)fexecute.GetValue(ifp); 187 | var mparams = (List)AccessTools.Field(typeof(Formula), "m_Params").GetValue(f); 188 | mparams[1] = Global.CustomMapNameListVariable; // 替换收藏源为自己的列表 189 | 190 | var simage = (SetImage)(((If)ifp).playables[0]); 191 | Global.ImageVariable.variable = prefabs.GetComponent(); 192 | AccessTools.Field(typeof(SetImage), "m_ImageSource").SetValue(simage, Global.ImageVariable); 193 | AccessTools.Field(typeof(SetImage), "m_Path").SetValue(simage, "custom"); 194 | 195 | Global.CustomAlbumCells = prefabs; 196 | } 197 | 198 | var ret = GameObject.Instantiate(Global.CustomAlbumCells); 199 | ret.name.Replace("(Clone)", string.Empty); 200 | return ret; 201 | } 202 | 203 | public static BMSAndStage LoadAndCreateStageInfo(string filename) // 不需要.bms 204 | { 205 | /* 1.加载bms 206 | * 2.转换为MusicData 207 | * 3.创建StageInfo 208 | * */ 209 | var bms = iBMSCManager.instance.Load(filename); 210 | 211 | if (bms == null) 212 | { 213 | return null; 214 | } 215 | 216 | Global.MusicConfigReader.ClearData(); 217 | Global.MusicConfigReader.bms = bms; 218 | Global.MusicConfigReader.Init(""); 219 | 220 | 221 | var info = from m in Global.MusicConfigReader.GetData().ToArray() select (MusicData)m; 222 | 223 | StageInfo stgInfo = new StageInfo 224 | { 225 | musicDatas = info, 226 | delay = Global.MusicConfigReader.delay, 227 | mapName = (string)Global.MusicConfigReader.bms.info["TITLE"], 228 | music = ((string)Global.MusicConfigReader.bms.info["WAV10"]).BeginBefore('.'), 229 | scene = (string)Global.MusicConfigReader.bms.info["GENRE"], 230 | difficulty = int.Parse((string)Global.MusicConfigReader.bms.info["RANK"]), 231 | bpm = Global.MusicConfigReader.bms.GetBpm(), 232 | md5 = Global.MusicConfigReader.bms.md5, 233 | sceneEvents = Global.MusicConfigReader.sceneEvents 234 | }; 235 | 236 | 237 | return new BMSAndStage 238 | { 239 | StageInfo = stgInfo, 240 | BMS = bms 241 | }; 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /MuseDashModManager/EntryPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace MuseDashModManager 6 | { 7 | public class EntryPoint 8 | { 9 | 10 | private static bool hasInited = false; 11 | 12 | public static void InitManager() 13 | { 14 | if (hasInited) return; 15 | 16 | CustomMaps.Util.Init(); 17 | // 安装 Patch 18 | Patch.InstallPatches(); 19 | hasInited = true; 20 | } 21 | 22 | public static object LoadCustomAssetProxy(string name) 23 | { 24 | if(name == null) { 25 | return null; 26 | } 27 | 28 | if(Global.CustomAssetsList.ContainsKey(name)) 29 | { 30 | return Global.CustomAssetsList[name]; 31 | } 32 | 33 | if(Global.CustomAssetsListEx.ContainsKey(name)) 34 | { 35 | return Global.CustomAssetsListEx[name](); 36 | } 37 | 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MuseDashModManager/Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace MuseDashModManager 7 | { 8 | class Global 9 | { 10 | public delegate object GetObject(); 11 | 12 | public static Dictionary CustomAssetsList = new Dictionary(); 13 | public static Dictionary CustomAssetsListEx = new Dictionary(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MuseDashModManager/MuseDashModManager.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BC37F97A-B56F-4879-8867-D54C29AD93B6} 8 | Library 9 | Properties 10 | MuseDashModManager 11 | MuseDashModManager 12 | v3.5 13 | 512 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\Lib.Harmony.1.2.0.1\lib\net35\0Harmony.dll 37 | True 38 | 39 | 40 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\Assembly-CSharp.dll 41 | 42 | 43 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\Assembly-CSharp-firstpass.dll 44 | False 45 | 46 | 47 | False 48 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\Newtonsoft.Json.dll 49 | False 50 | 51 | 52 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\Sirenix.Serialization.dll 53 | False 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.dll 63 | False 64 | 65 | 66 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.AnimationModule.dll 67 | False 68 | 69 | 70 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.AudioModule.dll 71 | False 72 | 73 | 74 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.CoreModule.dll 75 | False 76 | 77 | 78 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.ImageConversionModule.dll 79 | False 80 | 81 | 82 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.UI.dll 83 | False 84 | 85 | 86 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll 87 | False 88 | 89 | 90 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.UnityWebRequestModule.dll 91 | False 92 | 93 | 94 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll 95 | False 96 | 97 | 98 | D:\SteamLibrary\steamapps\common\Muse Dash\MuseDash_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll 99 | False 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /MuseDashModManager/Patch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text; 5 | using Harmony; 6 | 7 | namespace MuseDashModManager 8 | { 9 | class Patch 10 | { 11 | private static HarmonyInstance harmonyInstance = HarmonyInstance.Create("pw.baka.musedash.modmanager"); 12 | 13 | public static void InstallPatches() 14 | { 15 | // CustomMap 16 | CustomMaps.Patch.InstallPatch(harmonyInstance); 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MuseDashModManager/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("MuseDashModManager")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MuseDashModManager")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("bc37f97a-b56f-4879-8867-d54c29ad93b6")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 33 | //通过使用 "*",如下所示: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MuseDashModManager/Util.cs: -------------------------------------------------------------------------------- 1 | using Assets.Scripts.PeroTools.Nice.Values; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using UnityEngine; 8 | 9 | namespace MuseDashModManager 10 | { 11 | class Util 12 | { 13 | // TODO: 向ConfigManager和AudioManager以及AssetBundleManager中添加东西 14 | public static Sprite LoadSpirteFromFile(string path, int width, int height) 15 | { 16 | var fileStream = new FileStream(path, FileMode.Open); 17 | var tex = new UnityEngine.Texture2D(width, height); 18 | 19 | fileStream.Seek(0, SeekOrigin.Begin); 20 | 21 | byte[] binary = new byte[fileStream.Length]; //创建文件长度的buffer 22 | fileStream.Read(binary, 0, (int)fileStream.Length); 23 | 24 | fileStream.Close(); 25 | 26 | ImageConversion.LoadImage(tex, binary); 27 | return Sprite.Create(tex, new UnityEngine.Rect(0, 0, tex.width, tex.height), new UnityEngine.Vector2(0.0f, 0.0f)); 28 | } 29 | 30 | public static UnityEngine.AudioClip LoadAudioClipFromFile(string filename) 31 | { 32 | WWW www = new WWW("file://" + filename); 33 | while (!www.isDone) ; 34 | return www.GetAudioClip(); 35 | } 36 | 37 | public static void AddAsset(string key, object value) 38 | { 39 | if (!Global.CustomAssetsList.ContainsKey(key)) 40 | Global.CustomAssetsList.Add(key, value); 41 | } 42 | 43 | public static void AddAssetEx(string key, Global.GetObject value) 44 | { 45 | if (!Global.CustomAssetsListEx.ContainsKey(key)) 46 | Global.CustomAssetsListEx.Add(key, value); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MuseDashModManager/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Patched_DLL/Assembly-CSharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lyt99/MuseDashModManager/6362964facf1fb657ad79f33daceaa91dffd633e/Patched_DLL/Assembly-CSharp.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MuseDash 自制谱面管理器 2 | 3 | MushDash自制谱面管理器,支持在游戏内加载自制谱面 4 | 5 | 6 | 7 | ## 使用方法 8 | 9 | 使用**Visual Studio 2019**打开项目,补充缺失的引用(位于Managed文件夹内)并生成 10 | 11 | 将生成的**MuseDashModManager.dll**与**0Harmony.dll**,以及 12 | 13 | **Pathced_DLL**/中的Assembly_CSharp.dll复制到**MuseDash_Data/Managed/**文件夹中,覆盖原文件 14 | 15 | **Resource/**中的**nocover.png**复制到**MuseDash_Data/StreamingAssets/**文件夹中 16 | 17 | 即可使用。 18 | 19 | 20 | 21 | ## 谱面制作方法 22 | 23 | 谱面为bms文件,可以使用iBMSC等编辑器编辑。 24 | 25 | 在游戏根目录的**maps**/中新建文件夹,文件夹名称随意(最好为你的曲目名称)。 26 | 27 | 文件夹中有以下文件: 28 | 29 | - **cover.png** : 该谱面的封面文件,大小为440x440,如果没有则会使用默认封面。 30 | - **\{文件夹名称\}\_map1.bms**,**\{文件夹名称\}\_map2.bms**,**\{文件夹名称\}\_map3.bms**对应了曲目的3个难度,由易到难。 31 | - **\{名称\}.wav**或**\{名称\}.ogg**文件为谱面对应的歌曲(目前仅支持这两种格式),\{名称\}由bms中的相关参数规定。 32 | - 同时,可以选择剪辑曲目片段,存放为**\{名称\}\_demo.wav**或者**\{名称\}\_demo.ogg**文件(扩展名与完整歌曲名保持一致),作为选择乐曲界面播放的音乐。如果没有则播放完整歌曲。 33 | 34 | 35 | 36 | Resource文件中提供了一个简易的psd用于制作封面,以及一个示例bms文件。 37 | 38 | 39 | 40 | ## 问题报告 41 | 42 | 请提issue! 43 | 44 | 45 | 46 | ## 已知问题 47 | 48 | - 在游玩自制谱面回到主界面可能会出现无法正常显示主界面歌曲。 49 | - 收藏自定义曲目会导致整个存档损坏(已经屏蔽掉了收藏按钮,不要作死) 50 | - 自定义曲面的封面会比原图略微糊一点 51 | - 多语言时自定义曲面的文字显示不正确 52 | 53 | 54 | 55 | ## 使用库 56 | 57 | [Harmony](https://github.com/pardeike/Harmony/) -------------------------------------------------------------------------------- /Resource/iyaiya_map1.bms: -------------------------------------------------------------------------------- 1 |  2 | *---------------------- HEADER FIELD 3 | 4 | #PLAYER 1 5 | #GENRE scene_05 6 | #TITLE Iyaiya (short ver.) 7 | #ARTIST 小野道 8 | #BPM 128 9 | #PLAYLEVEL 1 10 | #RANK 1 11 | 12 | 13 | #LNTYPE 1 14 | 15 | #WAV01 小型(←) 16 | #WAV02 小型(↖) 17 | #WAV03 小型(↙) 18 | #WAV04 中型1(←) 19 | #WAV05 中型1(↖) 20 | #WAV06 中型1(↙) 21 | #WAV07 中型2(←) 22 | #WAV08 中型2(↖) 23 | #WAV09 中型2(↙) 24 | #WAV0A 大型1 25 | #WAV0B 大型2 26 | #WAV0C 陷阱(↖) 27 | #WAV0D 摆锤(↙) 28 | #WAV0E 双押 29 | #WAV0F 长按 30 | #WAV0G 连打 31 | #WAV0H 齿轮 32 | #WAV10 iyaiya_music.wav 33 | #WAV11 BOSS近战1 34 | #WAV12 BOSS近战2 35 | #WAV13 BOSS远程1 36 | #WAV14 BOSS远程2-1 37 | #WAV15 BOSS远程2-2 38 | #WAV16 BOSS连打1 39 | #WAV17 BOSS连打2 40 | #WAV18 BOSS齿轮 41 | #WAV1A BOSS入场 42 | #WAV1B BOSS退场 43 | #WAV1C BOSS远程1开始 44 | #WAV1D BOSS远程1结束 45 | #WAV1E BOSS远程2开始 46 | #WAV1F BOSS远程2结束 47 | #WAV1G BOSS远程1→远程2 48 | #WAV1H BOSS远程2→远程1 49 | #WAV21 隐藏 50 | #WAV22 红心 51 | #WAV23 音符 52 | 53 | 54 | *---------------------- MAIN DATA FIELD 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | #00514:00010001 63 | 64 | #00614:00010001 65 | 66 | #00714:00010001 67 | 68 | #00814:00010000 69 | 70 | #00913:0E 71 | #00914:0E 72 | 73 | 74 | #01114:04040004 75 | 76 | #01214:04040000 77 | 78 | #01313:00000007 79 | #01314:07070000 80 | 81 | #01413:07070000 82 | 83 | #01514:04040004 84 | 85 | #01614:04040000 86 | 87 | #01714:0B00000B000B0000 88 | #01754:000000000000000F 89 | 90 | 91 | #01914:00040000 92 | #01954:0F 93 | 94 | #02014:04040000 95 | 96 | #02114:04040000 97 | 98 | #02213:04040000 99 | 100 | #02314:07070000 101 | 102 | #02414:07070000 103 | 104 | #02514:07070000 105 | 106 | #02613:07070000 107 | 108 | #02714:0A23 109 | 110 | #02814:0023 111 | #02833:21 112 | 113 | #02914:0H23 114 | 115 | #03014:0A 116 | 117 | #03114:0A23 118 | 119 | #03213:21 120 | #03214:0023 121 | 122 | #03314:0H23 123 | 124 | #03414:0B00000B000B0000 125 | #03454:000000000000000F 126 | 127 | #03515:001A 128 | 129 | #03654:0F 130 | 131 | #03714:1300001300000000 132 | 133 | #03814:1300001300000000 134 | 135 | #03914:13131300 136 | #03915:0000001D 137 | 138 | #04013:04040000 139 | 140 | #04114:14140015 141 | 142 | #04214:15150000 143 | 144 | #04314:1400001400001400 145 | 146 | #04415:1F 147 | #04454:0F 148 | 149 | #04514:000H 150 | #04554:0F 151 | 152 | #04614:2311 153 | 154 | #04714:000H 155 | 156 | #04814:2211 157 | 158 | #04914:00010100 159 | 160 | #05014:13131300 161 | 162 | #05114:0B00000B000B0000 163 | #05154:0000000000000017 164 | 165 | 166 | #05354:17 167 | 168 | #05413:00000023 169 | #05414:000A0000 170 | 171 | #05513:00000023 172 | #05514:00010000 173 | 174 | #05613:00000023 175 | #05614:00010000 176 | 177 | #05713:00000023 178 | #05714:00010000 179 | 180 | #05813:00000001 181 | #05814:00010000 182 | 183 | #05913:00000001 184 | #05914:00010000 185 | 186 | #06014:00010000 187 | 188 | #06113:0E 189 | #06114:0E 190 | 191 | #06214:07070007 192 | 193 | #06314:07070000 194 | 195 | #06413:00000004 196 | #06414:04040000 197 | 198 | #06513:04040000 199 | 200 | #06614:07070007 201 | 202 | #06714:07070000 203 | 204 | #06814:0B00000B000B0000 205 | #06854:000000000000000F 206 | 207 | 208 | #07054:0F 209 | 210 | 211 | -------------------------------------------------------------------------------- /Resource/nocover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lyt99/MuseDashModManager/6362964facf1fb657ad79f33daceaa91dffd633e/Resource/nocover.png -------------------------------------------------------------------------------- /Resource/nocover.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lyt99/MuseDashModManager/6362964facf1fb657ad79f33daceaa91dffd633e/Resource/nocover.psd --------------------------------------------------------------------------------