diff --git a/README.md b/README.md index 2ea24aa..fca1a16 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

一个免费开源的《我的世界》数字音频转换器

- +

@@ -15,65 +15,42 @@ [![][release]](../../releases) -简体中文 | [English](README_EN.md) + ## 软件介绍🚀 -伶伦 是一款免费开源的 **《我的世界》** 数字音频工作站 +**伶伦** 是一款免费开源的 **《我的世界》** 数字音频工作站 -伶伦转换器 是仅用于 **《我的世界》** 数字音频转换的工具 +**伶伦转换器** 是仅用于 **《我的世界》** 数字音频转换的工具 欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) -## 软件架构🏢 +## 教程📕 -暂无 +[转换器的使用与安装](./docs/功能使用说明.md) -## 使用教程📕 +[对于小白的答疑指南](./docs/新手答疑指南.md) -暂无 +[对于本软件部分疑问的一些解答](./docs/问与答.md) -### 安装教程 -暂无 +[生成文件的使用](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md) + +[转换库的代码文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md) + +[转换乐器对照参考表](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E8%BD%AC%E6%8D%A2%E4%B9%90%E5%99%A8%E5%AF%B9%E7%85%A7%E8%A1%A8.md) ## 致谢列表🙏 -> 感谢广大群友为此程序提供的测试等支持 +> 感谢广大群友为此库提供的测试和建议等 > -> 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我! +> 若您对我们有所贡献但您的名字没有出现在此列表中,请联系我们! ## 联系我们📞 QQ群 [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) -## 待办事项⏲ - -* - [ ] 支持自动安装 -* - [ ] 支持多语言 -* - [ ] 支持音乐编辑 -* - [ ] 窗口优化 -* - [ ] 1.支持插件功能 -* - [ ] 2.进度条 -* - [ ] 3.可以将音乐写入音符盒(红乐) -* - [ ] 4.修改UI界面使之适应当前功能 -* - [ ] 5.支持自动给音符盒绑定更多的音色 -* - [ ] 6.可以由.schematic文件导入地图,亦可反向处理 -* - [ ] 7.制作软件下载器使用户更直观地操作 -* - [ ] 8.支持自定义创建websocket服务器播放音乐 -* - [ ] 9.支持使用红石播放音乐 -* - [ ] 10.支持采用延时的播放器 -* - [ ] 11.支持使用bdx导出结构 -* - [ ] 12.支持采用tp的方法播放 -* - [ ] 13.支持识别曲谱(简谱)图片解析音乐 -* - [ ] 14.支持使用瀑布流的方式播放音乐 -* - [ ] 15.支持读入Everyone Piano的曲谱文件(.eop) -* - [ ] 16.支持读入Musescore的通用曲谱文件,即musicXML(.mscz、.mscx) -* - [ ] 17.支持自动搜寻地图目录位置(网易&微软) -* - [ ] 18.支持读入JPword曲谱文件(.jpd) -* - [ ] 19.新的UI设计,以及UI主题文件 -* - [ ] 20.以小节为单位做音符播放时间对标 - +电邮 [TriM-Organization@hotmail.com](mailto:TriM-Organization@hotmail.com) [Bilibili: 凌云金羿]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge diff --git a/docs/download&start/Android.md b/docs/download&start/Android.md index 78976cb..7c56e91 100644 --- a/docs/download&start/Android.md +++ b/docs/download&start/Android.md @@ -46,7 +46,7 @@ 那么请把看到的如左下图的界面变为右下图吧: - +
diff --git a/docs/功能使用说明.md b/docs/功能使用说明.md index 208ef41..807318d 100644 --- a/docs/功能使用说明.md +++ b/docs/功能使用说明.md @@ -5,40 +5,44 @@ ## 下载与启动教程 ### [视窗(Windows)操作系统](./download%26start/Windows.md) -### [里纽克斯(Linux)与其衍生操作系统](./download%26start/Linux.md) +### [林纳克斯(Linux)与其衍生操作系统](./download%26start/Linux.md) ### [安卓(Android)与其衍生操作系统](./download%26start/Android.md) ## 使用教程 1. 参数说明 - + -- midi路径:含有mid文件路径、文件名、后缀的完整文件路径,或者一个目录(magicDemo可接受批量转换)。可以使用相对或绝对路径皆可 +- MIDI地址:含有mid文件路径、文件名、后缀的完整文件路径,或者一个目录(可接受批量转换)。相对或绝对路径皆可 -- 输出路径:输出文件夹的路径,不需要指示文件名 +- 输出地址:输出文件夹的路径,不需要指示文件名 -- 转换算法:通过不同通道隔离音轨,识别最佳乐器的算法编号为3(金羿的算法);将所有的音轨合并,通过通道来分组的算法编号为2(神羽和金羿的算法);旧算法,即通过音轨分组的算法编号为1(Dislink的算法)。新算法在某些方面转换效果更好,但是如果新算法转换有误的话,请使用旧算法。 +- 转换算法(**已废弃**):通过不同通道隔离音轨,识别最佳乐器的算法编号为3(金羿的算法);将所有的音轨合并,通过通道来分组的算法编号为2(神羽和金羿的算法);旧算法,即通过音轨分组的算法编号为1(Dislink的算法)。新算法在某些方面转换效果更好,但是如果新算法转换有误的话,请使用旧算法。 -- 输出格式:目前的演示程序仅支持`BDX`结构和`MCPACK`包 +- 输出文件类型:支持 `BDX` 结构和 `MCPACK` 包,其中,以 `BDX` 结构输出支持延迟和积分两种播放器, `MCPACK` 附加包则比前者多了一种 中继器播放器。 -- 播放方式:目前的转换库仅支持**计分板**和**延迟**的两种播放方式,具体地关于这些播放方式如何使用的问题,详见[生成文件的使用说明](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md) +- 播放器类型:`BDX` 结构仅支持**计分板**和**延迟**的两种播放方式;`MCPACK`则支持**计分板**、**延迟**和**中继器**三种播放方式。具体地关于这些播放方式如何使用的问题,详见[生成文件的使用说明](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md) -- 音量:小数数据,在0~1(包含首尾)的范围之内,用以表示播放音量大小。 +- 音量大小:正小数,在0(不含)~1(包含)的范围之内,用以表示播放音量大小。 -- 速度倍率:小数数据,其值不可为0,用以表示游戏中播放此音乐的速度倍数。 +- 速度倍率:正小数,其值不可为0,用以表示游戏中播放此音乐的速度倍数。 -- 进度条:是否启用进度条。目前的转换库已经支持自定义进度条,但是当前的演示程序并不能做到这一点。具体的有关进度条自定义的内容,可以看[功能文档](./%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E8%BF%9B%E5%BA%A6%E6%9D%A1%E8%87%AA%E5%AE%9A%E4%B9%89)中的相关部分自行修改参数。 +- 进度条:是否启用自动生成进度条。 -- 计分板名称(仅计分板播放器):游戏内的计分板名称 + - 若是,则可选是否自定义进度条 + + 自定义的进度条样式,可以参考[功能文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E8%BF%9B%E5%BA%A6%E6%9D%A1%E8%87%AA%E5%AE%9A%E4%B9%89) + +- 计分板名称(仅计分板播放器):游戏内的用以延迟的计分板名称 - 是否重置计分板(仅计分板播放器):歌曲放完是否重置,推荐选择自动重置 - 玩家选择器(仅延迟播放器):包括 `@x` 在内的全部选择器。例:若要选择全部标签为`Holo`的玩家,则需要如此输入:`@a[tag=Holo]` -- 作者(仅BDX结构):音乐结构的生成作者 +- 作者(仅BDX结构):结构的生成作者署名 -- 指令结构最大高度(仅结构输出):生成音乐结构的最大堆叠高度,可以查看相关[结构部分的开发文档](./%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84##%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F)了解详细知识。 +- 指令结构最大高度(`MCPACK`的计分板播放器不含此项):生成音乐结构的最大堆叠高度。对于如何堆叠的问题,可以查看[结构部分的开发文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F)了解详细内容。 - 没有报错且在输出路径下找到对应的文件即为生成成功: diff --git a/docs/新手答疑指南.md b/docs/新手答疑指南.md index ed05de2..66271bd 100644 --- a/docs/新手答疑指南.md +++ b/docs/新手答疑指南.md @@ -1,24 +1,24 @@ -

伶伦转换器

+

**伶伦转换器**

# 新手答疑指南 **考虑到某些用户电脑技术不是特别先进,且对这个项目充满了好奇心,但是又了解的不是很充分,为此,我特别在这里写一份新手指南,以满足各位的好奇心。放心,本文件全程中文。** -## 第一部分 关于音·创的作用 +## 第一部分 关于 **音·创** 的作用 -### 1.1 音·创简介 +### 1.1 **音·创** 简介 -音·创 Musicreater 是一款免费开源的针对 **《我的世界》** 的midi音乐转换库 +**音·创 _Musicreater_** 是一款免费开源的针对 **《我的世界》** 的midi音乐转换库 -而能够与人交互,以达到转换功能的,是 音·创 的程序实现:伶伦转换器。 +而能够与人交互,以达到转换功能的,是 **音·创** 库的程序实现:**伶伦转换器**。 -伶伦转换器 目前已经具备较为完善的[**教程**](./%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),其中包括了下载安装一类,使你能够方便地进行转换。 +**伶伦转换器** 目前已经具备较为完善的[**教程**](./%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),其中包括了下载安装一类,使你能够方便地进行转换。 -伶伦转换器也是免费开源的,采用**带有特殊条款的Apache2.0**开源协议授权,详情请见[协议](../LICENSE.md)。 +**伶伦转换器**也是免费开源的,采用**带有特殊条款的Apache2.0**开源协议授权,详情请见[协议](../LICENSE.md)。 -另外的,伶伦转换器并不是伶伦的主要开发方向,其功能也并非是伶伦本体(伶伦DAW)所提供的主要功能。**从音·创到伶伦的开发,其目的是为了方便《我的世界》的音乐作者,进行《我的世界》相关音乐的开发与创作**,而并不是转换MIDI文件!音·创的实现是在伶伦DAW之前试行一定的技术探索,以更好地开发数字音乐工作站。 +另外的,**伶伦转换器**并不是伶伦的主要开发方向,其功能也并非是 **伶伦** 本体(伶伦DAW)所提供的主要功能。**从 _音·创_ 到 _伶伦_ 的开发,其目的是为了方便 _《我的世界》_ 的音乐作者,进行 _《我的世界》_ 相关音乐的开发与创作**,而并不是转换MIDI文件!转换器的实现是在数字音频工作站的开发之前进行一定的技术探索,以更好地开发数字音乐工作站。 -### 1.2 音·创库版本到底目前有什么功能? +### 1.2 **音·创** 库到底有什么功能? * - [x] 支持导入`.mid`文件 * - [x] 支持写入`.mcpack`文件 * - [x] 支持写入`.bdx`文件 @@ -59,7 +59,7 @@ 0. 最简单的方法是向你心仪的作编曲人投递一份申请,请求TA将其作编曲过程中的相关工程文件给你,这样,你就可以获得一首乐曲的电子曲谱,从而获得其MIDI文件。 1. 如果无法向作曲人申请相关文件的话,成为一个作编曲人也许是一个不错的选择,当然,很多人做不到这一点,但是有必要提到这一点,当你在下面的渠道中都无法获得想要的文件时,你应该考虑是不是需要自己创作内容,或者,请别人帮你创作内容。 -2. 当你没有这样的文件时,问问别人或者从群里下载公开的文件也是个思路,不过这个办法通常使用次数有限且能找到的文件不多,不过,值得注意的是,**[音·创开发交流群](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)的群文件中所含的MIDI文件均为网友分享学习交流使用,请在下载后一个小时内删除。** +2. 当你没有这样的文件时,问问别人或者从群里下载公开的文件也是个思路,不过这个办法通常使用次数有限且能找到的文件不多,不过,值得注意的是,[**音·创**开发交流群](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)的**群文件中所含的MIDI文件均为网友分享学习交流使用,请在下载后一个小时内删除。** 3. 自己找MIDI:现在,我将给你提供一个完整的找mid的方法,请认真学习: **1.** 首先你需要在[MidiShow](www.midishow.com)网站中注册一个账号,并不复杂,你可能只需要一个QQ号便可以授权登录。 @@ -125,7 +125,7 @@ 如果你是使用桌面平台游玩基岩版,像我一样,是可以直接打开这个文件、并将这个包导入我的世界的。当然,移动平台也很简单,在游戏资源包界面有导入本地资源包的选项,便可将其导入。 -资源包导入世界之后的使用方法,我们也制作了[**简单的教程**](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),如果你对使用导入后的文件有所疑问,可以看看。 +资源包导入世界之后的使用方法,我们也制作了[**简单的教程**](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),如果你对使用导入后的文件有所疑问,可以看看。 #### 2.4.2 .bdx是什么 diff --git a/docs/生成文件的使用说明.md b/docs/生成文件的使用说明.md deleted file mode 100644 index 629042e..0000000 --- a/docs/生成文件的使用说明.md +++ /dev/null @@ -1,40 +0,0 @@ -

伶伦转换器

- -# 生成文件的使用 - -*这是本库所生成文件的使用声明,不是使用教程,点击[此处查看使用教程](%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md);若要查看有关文件结构的内容,可以点击[此处](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E8%AF%B4%E6%98%8E.md)* - -## 附加包格式 - -支持的文件后缀:`.MCPACK` - -1. 导入附加包 -2. 在一个循环方块中输入指令 `function index` -3. 将需要聆听音乐的实体的播放所用计分板设置为 `1` -4. 激活循环方块 -5. 若想要暂停播放,可以停止循环指令方块的激活状态 -6. 若想要重置某实体的播放,可以将其播放用的计分板重置 - -> 其中 步骤三 和 步骤四 的顺序可以调换。 - -## 结构格式 - -支持的文件后缀:`.MCSTRUCTURE`、`.BDX` - -1. 将结构导入世界 - -- 延迟播放器 - - 2. 将结构生成的第一个指令方块之模式更改为**脉冲** - 3. 激活脉冲方块 - 4. 若欲重置播放,可以停止对此链的激活,例如停止区块加载 - 5. 此播放器不支持暂停 - -- 计分板播放器 - - 2. 在所生成的第一个指令方块前,放置一个循环指令方块,其朝向应当对着所生成的第一个方块 - 3. 在循环指令方块中输入使播放对象的播放用计分板加分的指令,延迟为`0`,每次循环增加`1`分 - 4. 激活循环方块 - 5. 若想要暂停播放,可以停止循环指令方块的激活状态 - 6. 若想要重置某实体的播放,可以将其播放用的计分板重置 - diff --git a/docs/问与答.md b/docs/问与答.md index a131ca3..3e021d1 100644 --- a/docs/问与答.md +++ b/docs/问与答.md @@ -4,19 +4,19 @@ ## 关于音·创与伶伦转换器 -1. “伶伦”是什么? +1. “**伶伦**”是什么? - 伶伦是一个针对《我的世界》的数字音频工作站,用以创作、编辑《我的世界》风格的曲目。 + **伶伦** 是一个针对《我的世界》的数字音频工作站,用以创作、编辑《我的世界》风格的曲目。 -2. “伶伦转换器”是什么? +2. “**伶伦转换器**”是什么? - 伶伦转换器是一个用于将Midi文件转换至我的世界可读格式的工具。其使用音·创库作为转换工具库,其目的旨在方便midi创作者进行简单的音乐转换,同时也是音·创库的一个项目实现。 + **伶伦转换器** 是一个用于将Midi文件转换至我的世界可读格式的工具。其使用 **音·创** 作为转换工具库,其目的旨在方便midi创作者进行简单的音乐转换,同时也是 **音·创** 的一个实现。 -3. 为什么要将音·创库的功能迁移至伶伦转换器? +3. 为什么要将 **音·创** 的功能迁移至 **伶伦转换器**? - 音·创库作为单独存在的转换工具库,如果每次更新都需要从源码下载更新可能对用户十分的不友好。而且,音·创库的实现本是为了其他程序的调用,而不是一个转换程序。经过一段时间的观察与开发后,我们发现如果是以一种“可以用来转换音乐”的工具出现在大众面前,那么音·创库不仅不能被人理解,反而可能会让人困惑于其的具体功用,因此将伶伦转换器作为音·创库的实现,将独立的转换功能用更加亲用户的形式展现在大众面前,是一个更好的选择。 + **音·创** 作为单独存在的转换工具库,如果每次更新都需要从源码下载更新可能对用户十分的不友好。而且,**音·创** 的实现本是为了其他程序的调用,而不是一个转换程序。经过一段时间的观察与开发后,我们发现如果是以一种“可以用来转换音乐”的工具出现在大众面前,那么 **音·创** 不仅不能被人理解,反而可能会让人困惑于其的具体功用,因此将 **伶伦转换器** 作为 **音·创** 库的实现,将独立的转换功能用更加亲用户的形式展现在大众面前,是一个更好的选择。 -4. 之前使用的“音·创库版本”的示例程序,现在还能用吗? +4. 之前使用的“**音·创库版本**”的示例程序,现在还能用吗? 仍然可以使用,不过由于不再维护,已有的错误不会自动修复。 @@ -30,6 +30,6 @@ 详见问1,切换你所需要的播放器即可。 -4. 转换算法是什么?怎么填?是越新越好吗? +4. **(_已废弃_)** 转换算法是什么?怎么填?是越新越好吗? 转换算法是音·创库中所需要指定的内容,转换的算法都已经开源,可以在音·创仓库内找到。目前转换算法1对应的算法是将midi文件中的所有音轨单独提取并逐轨解析。而算法2是将所有音符单独提取出来,而后解析各个音符。算法的转换过程的差异可能会导致结果不同,但由于算法1已经不在进行主动维护,算法2的效果将会比1更好,所以建议使用算法2。算法3所对应的是尚在研究的插值算法,使用可能导致转换出错。 \ No newline at end of file diff --git a/llc_cli.py b/llc_cli.py index af961eb..289063c 100644 --- a/llc_cli.py +++ b/llc_cli.py @@ -14,7 +14,7 @@ Copyright © 2023 EillesWan & TriM Org. Terms & Conditions: ./Lisense.md """ -__version__ = "0.0.5" +__version__ = "0.0.6" import datetime import os @@ -24,15 +24,16 @@ import sys import Musicreater from Musicreater.plugin import ConvertConfig from Musicreater.plugin.bdxfile import to_BDX_file_in_delay, to_BDX_file_in_score -from Musicreater.plugin.funcpack import to_function_addon_in_score -from Musicreater.plugin.mcstructpack import to_mcstructure_addon_in_delay, to_mcstructure_addon_in_redstone_cd +from Musicreater.plugin.addonpack import ( + to_addon_pack_in_delay, + to_addon_pack_in_repeater, + to_addon_pack_in_score, +) +from Musicreater.constants import DEFAULT_PROGRESSBAR_STYLE + # from Musicreater.plugin.mcstructure import commands_to_structure, commands_to_redstone_delay_structure from utils.io import * -from languages.lang import languages - -print("小贴:不妨试试Mid-BDX转换网页:在线的多功能Midi转换器") -print("https://dislink.github.io/midi2bdx/") MainConsole.print( "[#121110 on #F0F2F4] ", @@ -44,36 +45,25 @@ osc.project_name = "伶伦转换器" osc.version = __version__ -def go_for_args( - languageChange: str = "ZH-CN", debugMode: str = "False", logfile: str = "True" -): - global currentLang - global logger - currentLang = ( - languageChange.upper() - if languageChange.upper() in languages.keys() - else "ZH-CN" - ) - osc.isRelease = False if debugMode.lower() in ("true", "1") else True - logger.printing = not osc.isRelease - logger.writing = True if logfile.lower() in ("true", "1") else False - - if len(sys.argv) > 0: + + def go_for_args(debugMode: str = "False", logfile: str = "True"): + global logger + osc.isRelease = False if debugMode.lower() in ("true", "1") else True + logger.printing = not osc.isRelease + logger.writing = True if logfile.lower() in ("true", "1") else False + go_for_args(*sys.argv) -def _(__): - """ - `languages` - """ - return languages[currentLang][__] - - # 显示大标题 MainConsole.rule(title="[bold #AB70FF]欢迎使用伶伦独立转换器", characters="=", style="#26E2FF") -MainConsole.rule(title="[bold #AB70FF]Welcome to Linglun Converter", characters="-") -MainConsole.rule(title="[#AB70FF]版本{} | 音·创内核版本{}".format(__version__,Musicreater.__version__), characters="=", style="#26E2FF") +# MainConsole.rule(title="[bold #AB70FF]Welcome to Linglun Converter", characters="-") +MainConsole.rule( + title="[#AB70FF]版本{} | 音·创内核版本{}".format(__version__, Musicreater.__version__), + characters="-", + style="#26E2FF", +) nowYang = datetime.datetime.now() @@ -99,13 +89,13 @@ else: justify="center", ) -prt(f"{_('LangChd')}{_(':')}{_(currentLang)}") +# prt(f"{_('LangChd')}{_(':')}{_(currentLang)}") def format_ipt( notice: str, fun, - err_note: str = f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", + err_note: str = "输入内容有误,请重新输入。", *extraArg, ): """循环输入,以某种格式 @@ -126,167 +116,183 @@ def format_ipt( # 获取midi列表 while True: - midi_path = ipt(f"{_('ChoosePath')}{_(':')}").lower() - if os.path.exists(midi_path): - if os.path.isfile(midi_path): - midis = (midi_path,) - elif os.path.isdir(midi_path): - midis = tuple( - ( + midi_path = ipt(f"请键入MIDI地址或所在目录地址:") + try: + if os.path.exists(midi_path): + if os.path.isfile(midi_path): + midis = (midi_path,) + elif os.path.isdir(midi_path): + midis = ( os.path.join(midi_path, i) for i in os.listdir(midi_path) if i.lower().endswith(".mid") or i.lower().endswith(".midi") ) - ) + else: + prt("输入内容有误,请重新输入。") + continue else: - prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") + prt("该地址不存在,或无法访问该地址,请重新输入。") continue - else: - prt(f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}") + except PermissionError: + prt("无法访问该地址,请检查是否给予程序相关文件的访问权限。") continue break # 获取输出地址 -out_path = format_ipt( - f"{_('ChooseOutPath')}{_(':')}", - os.path.exists, - f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}", -)[0].lower() +while True: + out_path = ipt(f"请键入文件生成输出地址:") + try: + if not os.path.exists(out_path): + prt("该地址不存在,或无法访问该地址,请重新输入。") + continue + except PermissionError: + prt("无法访问该地址,请检查是否给予程序相关文件的访问权限。") + continue + break # 选择输出格式 def is_in_bdx_mcpack(sth: str): - if sth.lower() in ("0", "mcpack"): - return 0 - - elif sth.lower() in ("1", "bdx"): - return 1 - - else: - raise ValueError("文件格式字符串啊?") - - -fileFormat = format_ipt( - f"{_('ChooseFileFormat')}{_(':')}", - is_in_bdx_mcpack, - f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", -)[1] + return isin(sth, {1: ("bdx", "1", "币帝查", "币帝·艾克斯"), 0: ("mcpack", "0", "唉姆西·派克")}) def is_in_player(sth: str): - if sth.lower() in ("0", "延迟", "delay"): - return 0 - elif sth.lower() in ("1", "计分板", "scoreboard"): - return 1 - elif sth.lower() in ('2', "红石", 'redstone'): - return 2 - else: - raise ValueError("播放器字符串啊?") + return isin( + sth, + { + 0: ("delay", "0", "延迟", "帝蕾"), + 1: ("score", "1", "计分板", "积分", "积分板", "计分", "斯阔尔"), + 2: ("repeater", "2", "中继器", "瑞皮特"), + }, + ) -playerFormat = format_ipt( - f"{_('ChoosePlayer')}{_(':')}", - is_in_player, - f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", +output_file_format = format_ipt( + "请键入输出文件类型 (mcpack/0|bdx/1)", + is_in_bdx_mcpack, + "输入内容有误,请重新输入。", )[1] +if output_file_format == 0: + player_format = format_ipt( + "请选择播放器类型 (延迟/0|计分板/1|中继器/2)", + is_in_player, + "输入内容有误,请重新输入。", + )[1] +else: + player_format = format_ipt( + "请选择播放器类型 (延迟/0|计分板/1)", + is_in_player, + "输入内容有误,请重新输入。", + )[1] -# 真假字符串判断 -def bool_str(sth: str) -> bool: - try: - return bool(int(sth)) - except ValueError: - if str(sth).lower() in ("true", "真", "是"): - return True - elif str(sth).lower() == ("false", "假", "否", "非"): - return False - else: - raise ValueError("布尔字符串啊?") +old_exe_enabled = format_ipt( + "启用1.19以前的旧版execute指令格式 (否/0|是/1):", bool_str, "输入内容格式错误,应为 是/1/真/t/y 或 否/0/假/f/n" +)[1] if os.path.exists("./demo_config.json"): import json prompts = json.load(open("./demo_config.json", "r", encoding="utf-8")) - + prompts = prompts[:-1] else: prompts = [] # 提示语 检测函数 错误提示语 for args in [ ( - f'{_("EnterVolume")}{_(":")}', - float, + "音量大小 (0,1]:", + float_str, ), ( - f'{_("EnterSpeed")}{_(":")}', - float, + "速度倍率 (0,+∞):", + float_str, ), ( - f'{_("WhetherPgb")}{_(":")}', + "自动生成进度条 (否/0|是/1):", bool_str, ), ( - f'{_("EnterSbName")}{_(":")}', + "计分板名称:", str, ) - if playerFormat == 1 + if player_format == 1 else ( - f'{_("EnterSelecter")}{_(":")}', + "受播放玩家的选择器:", str, ), ( - f'{_("WhetherSbReset")}{_(":")}', + "自动重置计分板 (否/0|是/1):", bool_str, ) - if playerFormat == 1 + if player_format == 1 else (), ( - f'{_("EnterAuthor")}{_(":")}', + "BDX作者署名:", str, ) - if fileFormat == 1 + if output_file_format == 1 else (), ( - f'{_("EnterMaxHeight")}{_(":")}', + "结构生成最大高度 (0,+∞):", int, ) - if playerFormat == 0 + if player_format == 0 else (), ]: if args: - prompts.append(format_ipt(*args)[1]) + prompts.append( + format_ipt(*args, err_note="输入内容格式错误,应符合 {}".format(args[1]))[1] + ) +if prompts[2]: + costom_pgb_enabled = format_ipt( + "自定义进度条样式 (否/0|是/1):", bool_str, "输入内容格式错误,应为 是/1/真/t/y 或 否/0/假/f/n" + )[1] + if costom_pgb_enabled: + style = ipt("基本样式组 (回车默认):") + if not style: + style = DEFAULT_PROGRESSBAR_STYLE[0] + yet_part = ipt("未播放样式 (回车默认):") + if not yet_part: + yet_part = DEFAULT_PROGRESSBAR_STYLE[1][1] + done_part = ipt("已播放样式 (回车默认):") + if not done_part: + done_part = DEFAULT_PROGRESSBAR_STYLE[1][0] -if playerFormat == 1: - cvt_method = to_function_addon_in_score -elif playerFormat == 0: - cvt_method = to_mcstructure_addon_in_delay -elif playerFormat == 2: - cvt_method = to_mcstructure_addon_in_redstone_cd +if player_format == 1: + cvt_method = to_addon_pack_in_score +elif player_format == 0: + cvt_method = to_addon_pack_in_delay +elif player_format == 2: + cvt_method = to_addon_pack_in_repeater for singleMidi in midis: - prt("\n" f"{_('Dealing')} {singleMidi} {_(':')}") - cvt_mid = Musicreater.MidiConvert.from_midi_file(singleMidi, old_exe_format=False) - cvt_cfg = ConvertConfig(out_path, *prompts[:3]) - - conversion_result = (( - cvt_method(cvt_mid, cvt_cfg, *prompts[3:]) - )if fileFormat == 0 + prt("\n" f"正在处理 {singleMidi}") + cvt_mid = Musicreater.MidiConvert.from_midi_file( + singleMidi, old_exe_format=old_exe_enabled + ) + cvt_cfg = ConvertConfig(out_path, *prompts[:2], progressbar=((style, (done_part, yet_part)) if costom_pgb_enabled else True) if prompts[2] else False) # type: ignore + + conversion_result = ( + (cvt_method(cvt_mid, cvt_cfg, *prompts[3:])) # type: ignore + if output_file_format == 0 else ( - to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:]) - if playerFormat == 1 - else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:]) - )) + to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:]) + if player_format == 1 + else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:]) + ) + ) prt( - f" {_('CmdLength')}{_(':')}{conversion_result[0]}{_(',')}{_('MaxDelay')}{_(':')}{conversion_result[1]}{f'''{_(',')}{_('PlaceSize')}{_(':')}{conversion_result[2]}{_(',')}{_('LastPos')}{_(':')}{conversion_result[3]}''' if fileFormat == 1 else ''}" - ) + f" 指令总长:{conversion_result[0]},播放刻数:{conversion_result[1]}{f''',结构大小:{conversion_result[2]},末点坐标:{conversion_result[3]}''' if output_file_format == 1 else ''}" # type: ignore + ) -exitSth = ipt(_("PressEnterExit")).lower() +exitSth = ipt("结束。换行以退出程序。") if exitSth == "record": import json diff --git a/utils/io.py b/utils/io.py index e95cf8d..4cf084c 100644 --- a/utils/io.py +++ b/utils/io.py @@ -178,3 +178,39 @@ def format_ipt( prt(err_note) continue return result, fun_result + +def isin(sth: str, range_list: dict): + sth = sth.lower() + for bool_value, res_list in range_list.items(): + if sth in res_list: + return bool_value + raise ValueError + + +# 真假字符串判断 +def bool_str(sth: str): + try: + return bool(float(sth)) + except: + if str(sth).lower() in ("true", "真", "是", 'y', 't'): + return True + elif str(sth).lower() in ("false", "假", "否", 'f', 'n'): + return False + else: + raise ValueError + + +def float_str(sth: str): + try: + return float(sth) + except ValueError: + try: + return float(sth.replace("壹", "1").replace("贰", "2").replace("叁", "3").replace("肆", "4").replace("伍", "5").replace("陆", "6").replace("柒", "7").replace("捌", "8").replace("玖", "9").replace("零", "0").replace("一", "1").replace("二",'2').replace("三", "3").replace("四", "4").replace("五", "5").replace("六", "6").replace("七", "7").replace("八", "8").replace("九", "9").replace("〇", "0").replace("洞", "0").replace("幺", "1").replace("俩", "2").replace("两", "2").replace("拐","7").replace("点",'.')) + except: + raise ValueError + +def int_str(sth: str): + try: + return int(float_str(sth)) + except ValueError: + raise ValueError \ No newline at end of file