├── Langs ├── Langs.ja.Designer.cs ├── Langs.en-US.Designer.cs ├── Langs.zh-CN1.Designer.cs ├── Langs.Designer.cs ├── Langs.resx └── Langs.zh-CN.resx ├── bass.dll ├── salt.pdn ├── bass_fx.dll ├── favicon.ico ├── Image ├── bg_dummy.jpg ├── outline_search_white_24dp.png └── outline_find_replace_white_24dp.png ├── .vscode └── settings.json ├── README.md ├── Properties ├── Settings.settings ├── AssemblyInfo.cs ├── Settings.Designer.cs ├── Resources.Designer.cs └── Resources.resx ├── AutoSaveModule ├── GlobalAutoSaveContext.cs ├── IAutoSave.cs ├── IAutoSaveContext.cs ├── LocalAutoSaveContext.cs ├── AutoSaveIndex.cs ├── GlobalAutoSave.cs ├── LocalAutoSave.cs ├── IAutoSaveRecoverer.cs ├── AutoSaveExceptions.cs ├── IAutoSaveIndexManager.cs ├── SafeTerminationDetector.cs ├── AutoSaveManager.cs ├── FumenInfos.cs ├── AutoSaveRecoverer.cs └── AutoSaveIndexManager.cs ├── .github └── workflows │ └── main.yml ├── SubWindow ├── MuriCheckResult.xaml.cs ├── BPMtap.xaml.cs ├── BPMtap.xaml ├── MuriCheckResult.xaml ├── MuriCheck.xaml ├── Infomation.xaml ├── Infomation.xaml.cs ├── AutoSaveRecover.xaml ├── EditorSettingPanel.xaml.cs ├── SoundSetting.xaml.cs ├── AutoSaveRecover.xaml.cs ├── EditorSettingPanel.xaml ├── SoundSetting.xaml └── MuriCheck.xaml.cs ├── MajdataEdit.sln ├── App.xaml.cs ├── WebControl.cs ├── .gitattributes ├── MajdataEdit.csproj ├── Majson.cs ├── .gitignore ├── Mirror.cs └── slide_time.json /Langs/Langs.ja.Designer.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Langs/Langs.en-US.Designer.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Langs/Langs.zh-CN1.Designer.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bass.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/bass.dll -------------------------------------------------------------------------------- /salt.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/salt.pdn -------------------------------------------------------------------------------- /bass_fx.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/bass_fx.dll -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/favicon.ico -------------------------------------------------------------------------------- /Image/bg_dummy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/Image/bg_dummy.jpg -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotnet.preferCSharpExtension": true, 3 | "cmake.configureOnOpen": true 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *** 2 | 请参阅[MajdataView](https://github.com/LingFeng-bbben/MajdataView) 3 | *** 4 | 今后的更新和说明也将在那个页面发布。请留意。 5 | -------------------------------------------------------------------------------- /Image/outline_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/Image/outline_search_white_24dp.png -------------------------------------------------------------------------------- /Image/outline_find_replace_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LingFeng-bbben/MajdataEdit/HEAD/Image/outline_find_replace_white_24dp.png -------------------------------------------------------------------------------- /Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /AutoSaveModule/GlobalAutoSaveContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 全局自动保存上下文 10 | /// 11 | public class GlobalAutoSaveContext : IAutoSaveContext 12 | { 13 | public string GetSavePath() 14 | { 15 | return Environment.CurrentDirectory + "/.autosave"; 16 | } 17 | } -------------------------------------------------------------------------------- /AutoSaveModule/IAutoSave.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 自动保存行为接口 10 | /// 职责仅为进行自动保存行为 11 | /// 12 | internal interface IAutoSave 13 | { 14 | /// 15 | /// 执行自动保存行为 16 | /// 17 | /// 是否成功保存 18 | bool DoAutoSave(); 19 | } -------------------------------------------------------------------------------- /AutoSaveModule/IAutoSaveContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 自动保存上下文接口 10 | /// 接口可以获取自动保存需要的上下文内容,如路径 11 | /// 12 | internal interface IAutoSaveContext 13 | { 14 | /// 15 | /// 获取保存路径,不包含文件名,结尾没有斜杠 16 | /// 17 | /// 18 | string GetSavePath(); 19 | } -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | run-name: Build editor exe 3 | on: [push, pull_request] 4 | jobs: 5 | build: 6 | runs-on: windows-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: actions/setup-dotnet@v3 10 | with: 11 | dotnet-version: 6.0.x 12 | - run: dotnet restore 13 | - run: dotnet publish -c Release -r win-x64 --no-self-contained 14 | - run: ls -R 15 | - uses: actions/upload-artifact@v3 16 | with: 17 | name: Build 18 | path: bin\Release\net6.0-windows\win-x64\publish 19 | -------------------------------------------------------------------------------- /AutoSaveModule/LocalAutoSaveContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 本地自动保存上下文 10 | /// 11 | public class LocalAutoSaveContext : IAutoSaveContext 12 | { 13 | public string GetSavePath() 14 | { 15 | var maidataDir = MainWindow.maidataDir; 16 | if (maidataDir.Length == 0) throw new LocalDirNotOpenYetException(); 17 | 18 | return MainWindow.maidataDir + "/.autosave"; 19 | } 20 | } -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Windows; 3 | 4 | // 将 ComVisible 设置为 false 会使此程序集中的类型 5 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 6 | //请将此类型的 ComVisible 特性设置为 true。 7 | [assembly: ComVisible(false)] 8 | 9 | //若要开始生成可本地化的应用程序,请设置 10 | //.csproj 文件中的 CultureYouAreCodingWith 11 | //例如,如果您在源文件中使用的是美国英语, 12 | //使用的是美国英语,请将 设置为 en-US。 然后取消 13 | //对以下 NeutralResourceLanguage 特性的注释。 更新 14 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 15 | 16 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 17 | 18 | 19 | [assembly: ThemeInfo( 20 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置 21 | //(未在页面中找到资源时使用, 22 | //或应用程序资源字典中找到时使用) 23 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 24 | //(未在页面中找到资源时使用, 25 | //、应用程序或任何主题专用资源字典中找到时使用) 26 | )] -------------------------------------------------------------------------------- /AutoSaveModule/AutoSaveIndex.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 自动保存索引 用于索引当前环境中自动保存的文件 10 | /// 11 | public class AutoSaveIndex 12 | { 13 | /// 14 | /// 已存在的自动保存文件数量 15 | /// 16 | public int Count = 0; 17 | 18 | /// 19 | /// 自动保存文件列表 20 | /// 21 | public List FilesInfo = new(); 22 | 23 | public class FileInfo 24 | { 25 | /// 26 | /// 自动保存文件名 27 | /// 28 | public string? FileName; 29 | 30 | /// 31 | /// 原先的文件路径 32 | /// 33 | public string? RawPath; 34 | 35 | /// 36 | /// 自动保存时间 37 | /// 38 | public long SavedTime; 39 | } 40 | } -------------------------------------------------------------------------------- /AutoSaveModule/GlobalAutoSave.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 全局自动保存 10 | /// 它将自动保存的文件存储在majdata的根目录中 11 | /// 12 | public class GlobalAutoSave : IAutoSave 13 | { 14 | private readonly IAutoSaveIndexManager indexManager = new AutoSaveIndexManager(); 15 | private readonly IAutoSaveContext saveContext = new GlobalAutoSaveContext(); 16 | 17 | public GlobalAutoSave() 18 | { 19 | indexManager.ChangePath(saveContext.GetSavePath()); 20 | indexManager.SetMaxAutoSaveCount(AutoSaveManager.GLOBAL_AUTOSAVE_MAX_COUNT); 21 | } 22 | 23 | 24 | public bool DoAutoSave() 25 | { 26 | var newSaveFilePath = indexManager.GetNewAutoSaveFileName(); 27 | 28 | SimaiProcess.SaveData(newSaveFilePath); 29 | 30 | indexManager.RefreshIndex(); 31 | 32 | return true; 33 | } 34 | } -------------------------------------------------------------------------------- /SubWindow/MuriCheckResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace MajdataEdit; 6 | 7 | /// 8 | /// Window1.xaml 的交互逻辑 9 | /// 10 | public class ErrorInfo 11 | { 12 | public int positionX; 13 | public int positionY; 14 | 15 | public ErrorInfo(int _posX, int _posY) 16 | { 17 | positionX = _posX; 18 | positionY = _posY; 19 | } 20 | } 21 | 22 | public partial class MuriCheckResult : Window 23 | { 24 | public List errorPosition = new(); 25 | 26 | public MuriCheckResult() 27 | { 28 | InitializeComponent(); 29 | } 30 | 31 | public void ListBoxItem_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) 32 | { 33 | var item = (ListBoxItem)sender; 34 | var index = int.Parse(item.Name[2..]); 35 | var errorInfo = errorPosition[index]; 36 | 37 | ((MainWindow)Owner).ScrollToFumenContentSelection(errorInfo.positionX, errorInfo.positionY); 38 | } 39 | } -------------------------------------------------------------------------------- /AutoSaveModule/LocalAutoSave.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | /// 9 | /// 本地自动保存 10 | /// 它将自动保存的文件存储在当前谱面的目录中 11 | /// 12 | public class LocalAutoSave : IAutoSave 13 | { 14 | private readonly IAutoSaveIndexManager indexManager = new AutoSaveIndexManager(); 15 | private readonly IAutoSaveContext saveContext = new LocalAutoSaveContext(); 16 | 17 | public LocalAutoSave() 18 | { 19 | indexManager.SetMaxAutoSaveCount(AutoSaveManager.LOCAL_AUTOSAVE_MAX_COUNT); 20 | } 21 | 22 | 23 | public bool DoAutoSave() 24 | { 25 | // 本地自动保存前 总是尝试将当前目录更新到目前打开的文件夹上 26 | indexManager.ChangePath(saveContext.GetSavePath()); 27 | 28 | var newSaveFilePath = indexManager.GetNewAutoSaveFileName(); 29 | 30 | SimaiProcess.SaveData(newSaveFilePath); 31 | 32 | indexManager.RefreshIndex(); 33 | 34 | return true; 35 | } 36 | } -------------------------------------------------------------------------------- /Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace MajdataEdit.Properties { 11 | 12 | 13 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 14 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] 15 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 16 | 17 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 18 | 19 | public static Settings Default { 20 | get { 21 | return defaultInstance; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MajdataEdit.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1525 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MajdataEdit", "MajdataEdit.csproj", "{83EE1671-5045-4416-9D8B-054F389A511F}" 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 | {83EE1671-5045-4416-9D8B-054F389A511F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {83EE1671-5045-4416-9D8B-054F389A511F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {83EE1671-5045-4416-9D8B-054F389A511F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {83EE1671-5045-4416-9D8B-054F389A511F}.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 = {8DFDC425-4B58-40AD-B262-BD69B3321253} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Windows; 3 | using System.Windows.Threading; 4 | using WPFLocalizeExtension.Engine; 5 | 6 | namespace MajdataEdit; 7 | 8 | /// 9 | /// App.xaml 的交互逻辑 10 | /// 11 | public partial class App : Application 12 | { 13 | public App() 14 | { 15 | LocalizeDictionary.Instance.SetCurrentThreadCulture = true; 16 | } 17 | 18 | private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 19 | { 20 | if (e.Exception.GetType() == typeof(COMException) && 21 | e.Exception.Message.IndexOf("UCEERR_RENDERTHREADFAILURE") != -1) 22 | { 23 | // 需要开启软件渲染 24 | MessageBox.Show(MajdataEdit.MainWindow.GetLocalizedString("SoftRenderError"), 25 | MajdataEdit.MainWindow.GetLocalizedString("Error")); 26 | Shutdown(114); 27 | return; 28 | } 29 | 30 | MessageBox.Show(e.Exception.Source + " At:\n" + e.Exception.Message + "\n" + e.Exception.StackTrace, "发生错误", 31 | MessageBoxButton.OK, MessageBoxImage.Error); 32 | e.Handled = true; 33 | } 34 | } -------------------------------------------------------------------------------- /SubWindow/BPMtap.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace MajdataEdit; 4 | 5 | /// 6 | /// BPMtap.xaml 的交互逻辑 7 | /// 8 | public partial class BPMtap : Window 9 | { 10 | private List bpms = new(); 11 | private DateTime lastTime = DateTime.MinValue; 12 | 13 | public BPMtap() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | private void Tap_Button_Click(object sender, RoutedEventArgs e) 19 | { 20 | if (lastTime != DateTime.MinValue) 21 | { 22 | var delta = (DateTime.Now - lastTime).TotalSeconds; 23 | bpms.Add(60d / delta); 24 | } 25 | 26 | lastTime = DateTime.Now; 27 | double sum = 0; 28 | if (bpms.Count <= 0) return; 29 | if (bpms.Count > 20) bpms.RemoveAt(0); 30 | foreach (var bpm in bpms) sum += bpm; 31 | var avg = sum / bpms.Count; 32 | 33 | Tap_Button.Content = string.Format("{0:N1}", avg); 34 | } 35 | 36 | private void Reset_Button_Click(object sender, RoutedEventArgs e) 37 | { 38 | bpms = new List(); 39 | lastTime = DateTime.MinValue; 40 | Tap_Button.Content = "Tap"; 41 | } 42 | } -------------------------------------------------------------------------------- /AutoSaveModule/IAutoSaveRecoverer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) Moying-moe All rights reserved. Licensed under the MIT license. 3 | See LICENSE in the project root for license information. 4 | */ 5 | 6 | namespace MajdataEdit.AutoSaveModule; 7 | 8 | internal interface IAutoSaveRecoverer 9 | { 10 | /// 11 | /// 获取本地的自动保存文件列表 12 | /// 13 | /// 14 | List GetLocalAutoSaves(); 15 | 16 | /// 17 | /// 获取全局的自动保存文件列表 18 | /// 19 | /// 20 | List GetGlobalAutoSaves(); 21 | 22 | /// 23 | /// 获取所有的自动保存文件列表 包括本地的和全局的 24 | /// 25 | /// 26 | List GetAllAutoSaves(); 27 | 28 | /// 29 | /// 获取指定路径的谱面的信息 30 | /// 31 | /// 32 | /// 33 | FumenInfos GetFumenInfos(string path); 34 | 35 | /// 36 | /// 根据recoveredFileInfo恢复文件 37 | /// 38 | /// 39 | /// 40 | bool RecoverFile(AutoSaveIndex.FileInfo recoveredFileInfo); 41 | } -------------------------------------------------------------------------------- /WebControl.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net.Http; 3 | using System.Reflection; 4 | using System.Text; 5 | 6 | namespace MajdataEdit; 7 | 8 | internal static class WebControl 9 | { 10 | public static string RequestPOST(string url, string data = "") 11 | { 12 | try 13 | { 14 | using var client = new HttpClient(); 15 | 16 | var webRequest = new HttpRequestMessage(HttpMethod.Post, url) 17 | { 18 | Content = new StringContent(data, Encoding.UTF8) 19 | }; 20 | 21 | var response = client.Send(webRequest); 22 | using var reader = new StreamReader(response.Content.ReadAsStream()); 23 | 24 | return reader.ReadToEnd(); 25 | } 26 | catch 27 | { 28 | return "ERROR"; 29 | } 30 | } 31 | 32 | public static string RequestGETAsync(string url) 33 | { 34 | var executingAssembly = Assembly.GetExecutingAssembly(); 35 | 36 | using var httpClient = new HttpClient(); 37 | var request = new HttpRequestMessage(HttpMethod.Get, url); 38 | request.Headers.Add("User-Agent", $"{executingAssembly.GetName().Name!} / {executingAssembly.GetName().Version!.ToString(3)}"); 39 | var response = httpClient.Send(request); 40 | using var reader = new StreamReader(response.Content.ReadAsStream()); 41 | 42 | return reader.ReadToEnd(); 43 | } 44 | } -------------------------------------------------------------------------------- /SubWindow/BPMtap.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |