这是学校里做的更新

This commit is contained in:
EillesWan 2022-10-05 22:18:03 +08:00
parent 3b53846ade
commit 5ea47c54cb
7 changed files with 306 additions and 234 deletions

View File

@ -39,69 +39,6 @@
## 使用教程📕 ## 使用教程📕
> 0. 安装python3.6+
>
> 在安装时一定要勾选Add Python 3.X to PATH不然就要手动设置
>
> 同时装完之后记得在cmd中输入python 试试是否安装成功,
> python的安装可以去网上随便找一下。
> 成功安装之后在cmd中输入python会显示
> <img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
> 之类的东西。
> 1. 安装下载本程序git的话可以使用以下命令
>
> `git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
>
> 没有安装git的话可以下载zip包解压后进入目录即可。
> <img src=" https://foruda.gitee.com/images/1659972440341216712/下载.png" >
> 2. 运行(进入目录)
> 在目录下打开cmd进入到目录下执行以下命令
> <img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
> <img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
> 回车一下,然后:
> <img src=https://foruda.gitee.com/images/1659974794561970425/pip.png>
> 输入下面的三个指令即可!
>
> `pip install mido`
>
> `pip install brotli`
>
> `pip install openpyxl`
>
> 3. 开始使用!
> 在目录下打开cmd步骤与上面的图片一致只是执行的代码换了进入到目录下执行以下命令(选择你需要的)
>
> `python example_convert_bdx.py`
>
> `python example_convert_mcpack.py`
>
> 4. 错误补充说明
> 如果你遇到了以下这种情况
> <img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
> 那么,请按照这篇文章指引做:
> https://blog.csdn.net/qq_41179280/article/details/123804948
>
> 感谢Mono帮我们发现这个问题
>
> 5. 使用补充说明
> <img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
> midi路径含有mid文件路径、文件名、后缀的完整绝对路径
>
> 输出路径:输出文件夹的路径,就写一个英文.(句号)可以表示生成到当前目录下
> (意思就是支持相对路径)
>
> 是否重置计分板1或0歌曲放完是否重置推荐1
>
> 是否启用进度条1或0看个人需要
>
> 计分板名称:游戏内的计分板名称
>
> 音量0-1之间的小数含01正常来说推荐1
>
> 变速float数据一般写1
>
> 没有报错且在输出路径下找到mcpack或bdx即为生成成功
> <img src=https://foruda.gitee.com/images/1659973655881460036/输出.png>
### 对于 进度条自定义 功能的说明 ### 对于 进度条自定义 功能的说明

View File

@ -26,7 +26,6 @@ Musicreater Package Version : Demo for Midi Conversion
limitations under the License. limitations under the License.
""" """
from msctPkgver.main import * from msctPkgver.main import *
import os import os
@ -80,15 +79,14 @@ while True:
if isAutoReset != '': if isAutoReset != '':
isAutoReset = bool(int(isAutoReset)) isAutoReset = bool(int(isAutoReset))
break break
except: except BaseException:
print('输入错误,请重新输入') print('输入错误,请重新输入')
if os.path.isdir(midipath): if os.path.isdir(midipath):
for i in os.listdir(midipath): for i in os.listdir(midipath):
if i.endswith('.mid'): if i.endswith('.mid'):
print(f'正在操作{i}') print(f'正在操作{i}')
convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4] ) convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4])
if outFormat == 0: if outFormat == 0:
convertion.tomcpack( convertion.tomcpack(
1, 1,

View File

@ -20,9 +20,19 @@ if not os.path.exists(outpath):
while True: while True:
try: try:
authorname = input('请输入作者:') authorname = input('请输入作者:')
isProgress = input('是否开启进度条(1|0)') while True:
if isProgress != '': isProgress = input('*进度条[注]')
isProgress = bool(int(isProgress)) if isProgress != '' :
if isProgress in ('1','True'):
isProgress = True
elif isProgress in ('0', 'False'):
isProgress = False
else:
isProgress = isProgress
else:
continue
break
volume = input('请输入音量0-1') volume = input('请输入音量0-1')
if volume != '': if volume != '':
volume = float(volume) volume = float(volume)
@ -35,10 +45,9 @@ while True:
heightmax = int(heightmax) heightmax = int(heightmax)
break break
except: except BaseException:
print('输入错误,请重新输入') print('输入错误,请重新输入')
if os.path.isdir(midipath): if os.path.isdir(midipath):
for i in os.listdir(midipath): for i in os.listdir(midipath):
if i.endswith('.mid'): if i.endswith('.mid'):
@ -47,7 +56,7 @@ if os.path.isdir(midipath):
convertion.toBDXfile_withDelay( convertion.toBDXfile_withDelay(
1, 1,
authorname if authorname != '' else input('请输入作者:'), authorname if authorname != '' else input('请输入作者:'),
isProgress if isProgress != '' else bool(int(input('是否开启进度条(1|0)'))), isProgress,
heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')), heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
volume if volume != '' else float(input('请输入音量(0-1]')), volume if volume != '' else float(input('请输入音量(0-1]')),
speed if speed != '' else float(input('请输入速度倍率:')), speed if speed != '' else float(input('请输入速度倍率:')),
@ -59,7 +68,7 @@ else:
convertion.toBDXfile_withDelay( convertion.toBDXfile_withDelay(
1, 1,
authorname if authorname != '' else input('请输入作者:'), authorname if authorname != '' else input('请输入作者:'),
isProgress if isProgress != '' else bool(int(input('是否开启进度条(1|0)'))), isProgress,
heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')), heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
volume if volume != '' else float(input('请输入音量(0-1]')), volume if volume != '' else float(input('请输入音量(0-1]')),
speed if speed != '' else float(input('请输入速度倍率:')), speed if speed != '' else float(input('请输入速度倍率:')),

111
docs/使用教程.md Normal file
View File

@ -0,0 +1,111 @@
# 演示程序使用教程
*由于先前的 **读我文件**(README.md) 过于冗杂,现另辟蹊径来给大家全方位的教程。*
*这是演示程序的使用教程,将在这里提供演示程序的相应的使用教程*
## 视窗(Windows)操作系统
### 运行环境安装
0. 安装python3.6+
首先需要下载Python的安装包
> [下载64位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
> [下载32位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
在安装时,最好需要勾选 `Add Python 3.X to PATH` ,如下图所示,当然,如果您对自己非常自信,您也可以手动设置此项目:
<img src=https://foruda.gitee.com/images/1662736520757331846/e38efb81_9911226.png>
若您对Python一知半解或者不怎么了解、并对自己的系统盘有大约150*MB*的信心的话,您可以在安装时直接选择*快速安装*(Install Now)
若您选择了*自定义安装*(Customize Installation),请务必勾选 `pip``py launcher` 便于后续安装依赖,如下图:
<img src=https://foruda.gitee.com/images/1662736621235871190/2ac3d98f_9911226.png>
安装结束之后可以在*终端*(命令行/PowerShell/Bash/etc)中输入python 试试是否安装成功成功安装之后在终端中输入python会显示诸如如下图片的提示
<img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
1. 下载本代码库以及演示程序
- 若您使用git请直接拷贝本仓库
`git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
- 若您不使用git可以在*码云*(Gitee)或GitHub下载zip包或者[加入QQ群聊861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr),在群文件中获取。
<img src=" https://foruda.gitee.com/images/1659972440341216712/下载.png" >
2. 安装依赖
请以管理员模式打开您的*终端*(命令行/PowerShell/Bash/etc)
例如,命令行,可以如此打开:在*视窗开始菜单*(Windows开始)中搜索 `cmd`, 并以管理员身份运行
<img src="https://foruda.gitee.com/images/1662736878650993886/62487dd8_9911226.png">
打开了终端之后,请在终端中输入以下指令
`pip install mido -i https://mirrors.aliyun.com/pypi/simple/`
`pip install brotli -i https://mirrors.aliyun.com/pypi/simple/`
安装成功后您可能会见到类似下图的提示:
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
3. 开始使用
在目录下打开终端例如打开命令行请进入到目录下在地址框内输入cmd
<img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
<img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
执行以下命令:(选择你需要的)
`python example_convert_bdx.py`
`python example_convert_mcpack.py`
### 补充错误说明
1. Microsoft Visual C++ Redistributable 环境出错
如果你遇到了以下这种情况
<img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
请下载最新的VCREDIST安装包可以参照[这个网页](https://docs.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist)的说明,也可以在这直接选择你需要的安装包下载:
> [下载64位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x64.exe)
> [下载32位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x64.exe)
感谢群友Mono帮我们发现这个问题
2. 参数补充说明
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
- midi路径含有mid文件路径、文件名、后缀的完整文件路径。可以使用相对或绝对路径皆可
- 输出路径:输出文件夹的路径,不需要指示文件名
- 是否重置计分板1或0歌曲放完是否重置推荐1
- 是否启用进度条1或0看个人需要
*进度条是否启用进度条以及自定义进度条样式。输入0或False表示不启用进度条输入1或True表示使用默认进度条其余的输入均表示使用输入的格式作为自定义的进度条样式
- 计分板名称:游戏内的计分板名称
- 音量0-1之间的小数含01正常来说推荐1
- 变速float数据一般写1
- 玩家选择器:包括 `@x` 在内的全部选择器即若要选择全部标签为Holo的玩家则需要如此输入`@a[tag=Holo]`
- 没有报错且在输出路径下找到mcpack或bdx即为生成成功
<img src=https://foruda.gitee.com/images/1659973655881460036/输出.png>

View File

@ -6,13 +6,13 @@ from msctPkgver.main import *
convertion = midiConvert() convertion = midiConvert()
convertion.convert(input('请输入midi文件路径'), input('请输入输出路径:')) convertion.convert(input('请输入midi文件路径'), input('请输入输出路径:'))
for i in convertion.toBDXfile( for i in convertion.toBDXfile(
1, 1,
input('请输入作者:'), input('请输入作者:'),
bool(int(input('是否开启进度条(1|0)'))), bool(int(input('是否开启进度条(1|0)'))),
int(input('请输入指令结构最大生成高度:')), int(input('请输入指令结构最大生成高度:')),
input('请输入计分板名称:'), input('请输入计分板名称:'),
float(input('请输入音量(0-1]')), float(input('请输入音量(0-1]')),
float(input('请输入速度倍率:')), float(input('请输入速度倍率:')),
bool(int(input('是否自动重置计分板(1|0)'))), bool(int(input('是否自动重置计分板(1|0)'))),
): ):
print(i) print(i)

View File

@ -31,8 +31,10 @@ Note! Except for this source file, all the files in this repository and this pro
def _toCmdList_m1( def _toCmdList_m1(
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0 self,
) -> list: scoreboardname: str = "mscplay",
volume: float = 1.0,
speed: float = 1.0) -> list:
""" """
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表 使用Dislink Sforza的转换思路将midi转换为我的世界命令列表
:param scoreboardname: 我的世界的计分板名称 :param scoreboardname: 我的世界的计分板名称
@ -73,16 +75,14 @@ def _toCmdList_m1(
maxscore = max(maxscore, nowscore) maxscore = max(maxscore, nowscore)
soundID, _X = self.__Inst2soundIDwithX(instrumentID) soundID, _X = self.__Inst2soundIDwithX(instrumentID)
singleTrack.append( singleTrack.append(
"execute @a[scores={" "execute @a[scores={" +
+ str(scoreboardname) str(scoreboardname) +
+ "=" "=" +
+ str(nowscore) str(nowscore) +
+ "}" "}" +
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}" f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
)
commands += 1 commands += 1
if len(singleTrack) != 0: if len(singleTrack) != 0:
tracks.append(singleTrack) tracks.append(singleTrack)
return tracks, commands, maxscore return [tracks, commands, maxscore]

View File

@ -90,7 +90,7 @@ class midiConvert:
钟琴bell管钟chime木琴xylophone的时候为4 钟琴bell管钟chime木琴xylophone的时候为4
而存在一些打击乐器basedrumhatsnare没有音域则没有X那么我们返回7即可 而存在一些打击乐器basedrumhatsnare没有音域则没有X那么我们返回7即可
:param instrumentID: midi的乐器ID :param instrumentID: midi的乐器ID
:param default: 如果instrumentID不在范围内返回的默认我的世界乐器名称 default: 如果instrumentID不在范围内返回的默认我的世界乐器名称
:return: (str我的世界乐器名, int转换算法中的X)""" :return: (str我的世界乐器名, int转换算法中的X)"""
try: try:
a = { a = {
@ -223,21 +223,22 @@ class midiConvert:
126: ("note.basedrum", 7), # 打击乐器无音域 126: ("note.basedrum", 7), # 打击乐器无音域
127: ("note.snare", 7), # 打击乐器无音域 127: ("note.snare", 7), # 打击乐器无音域
}[instrumentID] }[instrumentID]
except: except BaseException:
a = ("note.harp", 6) a = ("note.harp", 6)
return a return a
def __score2time(self, score: int): def __score2time(self, score: int):
return str(int(int(score / 20) / 60)) + ":" + str(int(int(score / 20) % 60)) return str(int(int(score / 20) / 60)) + ":" + \
str(int(int(score / 20) % 60))
def __formProgressBar( def __formProgressBar(
self, self,
maxscore: int, maxscore: int,
scoreboardname: str, scoreboardname: str,
progressbar: tuple = ( progressbar: tuple = (
r"%%N [ %%s/%^s %%% __________ %%t|%^t ]", r"%%N [ %%s/%^s %%% __________ %%t|%^t ]",
("§e=§r", "§7=§r"), ("§e=§r", "§7=§r"),
), ),
) -> list: ) -> list:
pgsstyle = progressbar[0] pgsstyle = progressbar[0]
@ -256,8 +257,11 @@ class midiConvert:
""" """
def __replace( def __replace(
s: str, tobeReplaced: str, replaceWith: str, times: int, other: str s: str,
): tobeReplaced: str,
replaceWith: str,
times: int,
other: str):
if times == 0: if times == 0:
return s.replace(tobeReplaced, other) return s.replace(tobeReplaced, other)
if times == s.count(tobeReplaced): if times == s.count(tobeReplaced):
@ -306,11 +310,11 @@ class midiConvert:
for i in range(maxscore): for i in range(maxscore):
nowstr = pgsstyle nowstr = pgsstyle
if ids[r"%%s"] == True: if ids[r"%%s"]:
nowstr = nowstr.replace(r"%%s", str(i + 1)) nowstr = nowstr.replace(r"%%s", str(i + 1))
if ids[r"%%t"] == True: if ids[r"%%t"]:
nowstr = nowstr.replace(r"%%t", self.__score2time(i + 1)) nowstr = nowstr.replace(r"%%t", self.__score2time(i + 1))
if ids[r"%%%"] == True: if ids[r"%%%"]:
nowstr = nowstr.replace( nowstr = nowstr.replace(
r"%%%", str(int((i + 1) / maxscore * 10000) / 100) + "%" r"%%%", str(int((i + 1) / maxscore * 10000) / 100) + "%"
) )
@ -318,29 +322,33 @@ class midiConvert:
countof_s = int((i + 1) / maxscore * pgblength) countof_s = int((i + 1) / maxscore * pgblength)
finalprgsbar.append( finalprgsbar.append(
"title @a[scores={" "title @a[scores={" +
+ scoreboardname scoreboardname +
+ "=" "=" +
+ str(i + 1) str(
+ "}] actionbar " i +
+ __replace( 1) +
nowstr, "_", progressbar[1][0], countof_s, progressbar[1][1] "}] actionbar " +
) __replace(
) nowstr,
"_",
progressbar[1][0],
countof_s,
progressbar[1][1]))
return finalprgsbar return finalprgsbar
def __formCMDblk( def __formCMDblk(
self, self,
command: str, command: str,
particularValue: int, particularValue: int,
impluse: int = 0, impluse: int = 0,
condition: bool = False, condition: bool = False,
needRedstone: bool = True, needRedstone: bool = True,
tickDelay: int = 0, tickDelay: int = 0,
customName: str = "", customName: str = "",
executeOnFirstTick: bool = False, executeOnFirstTick: bool = False,
trackOutput: bool = True, trackOutput: bool = True,
): ):
""" """
使用指定项目返回指定的指令方块放置指令项 使用指定项目返回指定的指令方块放置指令项
@ -377,7 +385,7 @@ class midiConvert:
执行延时 执行延时
:param customName: `str` :param customName: `str`
悬浮字 悬浮字
:param lastOutput: `str` lastOutput: `str`
上次输出字符串注意此处需要留空 上次输出字符串注意此处需要留空
:param executeOnFirstTick: `bool` :param executeOnFirstTick: `bool`
执行第一个已选项(循环指令方块是否激活后立即执行若为False则从激活时起延迟后第一次执行) 执行第一个已选项(循环指令方块是否激活后立即执行若为False则从激活时起延迟后第一次执行)
@ -386,7 +394,8 @@ class midiConvert:
:return:str :return:str
""" """
block = b"\x24" + particularValue.to_bytes(2, byteorder="big", signed=False) block = b"\x24" + \
particularValue.to_bytes(2, byteorder="big", signed=False)
for i in [ for i in [
impluse.to_bytes(4, byteorder="big", signed=False), impluse.to_bytes(4, byteorder="big", signed=False),
@ -403,8 +412,10 @@ class midiConvert:
return block return block
def _toCmdList_m1( def _toCmdList_m1(
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0 self,
) -> list: scoreboardname: str = "mscplay",
volume: float = 1.0,
speed: float = 1.0) -> list:
""" """
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表 使用Dislink Sforza的转换思路将midi转换为我的世界命令列表
:param scoreboardname: 我的世界的计分板名称 :param scoreboardname: 我的世界的计分板名称
@ -445,23 +456,24 @@ class midiConvert:
maxscore = max(maxscore, nowscore) maxscore = max(maxscore, nowscore)
soundID, _X = self.__Inst2soundIDwithX(instrumentID) soundID, _X = self.__Inst2soundIDwithX(instrumentID)
singleTrack.append( singleTrack.append(
"execute @a[scores={" "execute @a[scores={" +
+ str(scoreboardname) str(scoreboardname) +
+ "=" "=" +
+ str(nowscore) str(nowscore) +
+ "}" "}" +
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}" f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
)
commands += 1 commands += 1
if len(singleTrack) != 0: if len(singleTrack) != 0:
tracks.append(singleTrack) tracks.append(singleTrack)
return tracks, commands, maxscore return [tracks, commands, maxscore]
# 值得注意的是,我这里没有修改 # 值得注意的是,我这里没有修改
def _toCmdList_m2( def _toCmdList_m2(
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0 self,
) -> list: scoreboardname: str = "mscplay",
volume: float = 1.0,
speed: float = 1.0) -> list:
""" """
使用金羿的转换思路将midi转换为我的世界命令列表 使用金羿的转换思路将midi转换为我的世界命令列表
:param scoreboardname: 我的世界的计分板名称 :param scoreboardname: 我的世界的计分板名称
@ -502,26 +514,24 @@ class midiConvert:
maxscore = max(maxscore, nowscore) maxscore = max(maxscore, nowscore)
soundID, _X = self.__Inst2soundIDwithX(instrumentID) soundID, _X = self.__Inst2soundIDwithX(instrumentID)
singleTrack.append( singleTrack.append(
"execute @a[scores={" "execute @a[scores={" +
+ str(scoreboardname) str(scoreboardname) +
+ "=" "=" +
+ str(nowscore) str(nowscore) +
+ "}" "}" +
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}" f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
)
commands += 1 commands += 1
if len(singleTrack) != 0: if len(singleTrack) != 0:
tracks.append(singleTrack) tracks.append(singleTrack)
return tracks, commands, maxscore return [tracks, commands, maxscore]
def _toCmdList_withDelay_m1( def _toCmdList_withDelay_m1(
self, self,
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
player: str = "@a", player: str = "@a",
isMixedWithPrograssBar=False, isMixedWithPrograssBar=False,
) -> list: ) -> list:
""" """
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表并输出每个音符之后的延迟 使用Dislink Sforza的转换思路将midi转换为我的世界命令列表并输出每个音符之后的延迟
@ -538,7 +548,7 @@ class midiConvert:
if volume <= 0: if volume <= 0:
volume = 0.001 volume = 0.001
if isMixedWithPrograssBar == True: if isMixedWithPrograssBar:
isMixedWithPrograssBar = ( isMixedWithPrograssBar = (
r"%%N [ %%s/%^s %%% __________ %%t|%^t ]", r"%%N [ %%s/%^s %%% __________ %%t|%^t ]",
("§e=§r", "§7=§r"), ("§e=§r", "§7=§r"),
@ -567,10 +577,9 @@ class midiConvert:
tracks[nowtick].append( tracks[nowtick].append(
f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}" f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}"
) )
except: except BaseException:
tracks[nowtick] = [ tracks[nowtick] = [
f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}", f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}", ]
]
allticks = list(tracks.keys()) allticks = list(tracks.keys())
@ -592,8 +601,11 @@ class midiConvert:
""" """
def __replace( def __replace(
s: str, tobeReplaced: str, replaceWith: str, times: int, other: str s: str,
): tobeReplaced: str,
replaceWith: str,
times: int,
other: str):
if times == 0: if times == 0:
return s.replace(tobeReplaced, other) return s.replace(tobeReplaced, other)
if times == s.count(tobeReplaced): if times == s.count(tobeReplaced):
@ -656,15 +668,15 @@ class midiConvert:
if isMixedWithPrograssBar: if isMixedWithPrograssBar:
nowstr = pgsstyle nowstr = pgsstyle
if ids[r"%%s"] == True: if ids[r"%%s"]:
nowstr = nowstr.replace(r"%%s", str(allticks[i] + 1)) nowstr = nowstr.replace(r"%%s", str(allticks[i] + 1))
if ids[r"%%t"] == True: if ids[r"%%t"]:
nowstr = nowstr.replace(r"%%t", self.__score2time(allticks[i] + 1))
if ids[r"%%%"] == True:
nowstr = nowstr.replace( nowstr = nowstr.replace(
r"%%%", r"%%t", self.__score2time(
str(int((allticks[i] + 1) / allticks[-1] * 10000) / 100) + "%", allticks[i] + 1))
) if ids[r"%%%"]:
nowstr = nowstr.replace(r"%%%", str(
int((allticks[i] + 1) / allticks[-1] * 10000) / 100) + "%", )
countof_s = int((allticks[i] + 1) / allticks[-1] * pgblength) countof_s = int((allticks[i] + 1) / allticks[-1] * pgblength)
@ -693,14 +705,14 @@ class midiConvert:
return math.ceil(math.sqrt(math.ceil(total / maxHeight))) return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
def tomcpack( def tomcpack(
self, self,
method: int = 1, method: int = 1,
isAutoReset: bool = False, isAutoReset: bool = False,
progressbar=None, progressbar=None,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
) -> bool: ) -> bool or tuple:
""" """
使用method指定的转换算法将midi转换为我的世界mcpack格式的包 使用method指定的转换算法将midi转换为我的世界mcpack格式的包
:param method: 转换算法 :param method: 转换算法
@ -712,7 +724,8 @@ class midiConvert:
:return 成功与否成功返回(True,True)失败返回(False,str失败原因) :return 成功与否成功返回(True,True)失败返回(False,str失败原因)
""" """
if method == 1: if method == 1:
cmdlist, _a, maxscore = self._toCmdList_m1(scoreboardname, volume, speed) cmdlist, _a, maxscore = self._toCmdList_m1(
scoreboardname, volume, speed)
else: else:
return (False, f"无法找到算法ID{method}对应的转换算法") return (False, f"无法找到算法ID{method}对应的转换算法")
del _a del _a
@ -725,24 +738,22 @@ class midiConvert:
# 写入manifest.json # 写入manifest.json
if not os.path.exists(f"{self.outputPath}/temp/manifest.json"): if not os.path.exists(f"{self.outputPath}/temp/manifest.json"):
with open( with open(
f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8" f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8"
) as f: ) as f:
f.write( f.write('{\n "format_version": 1,\n "header": {\n "description": "' +
'{\n "format_version": 1,\n "header": {\n "description": "' self.midFileName +
+ self.midFileName ' Pack : behavior pack",\n "version": [ 0, 0, 1 ],\n "name": "' +
+ ' Pack : behavior pack",\n "version": [ 0, 0, 1 ],\n "name": "' self.midFileName +
+ self.midFileName 'Pack",\n "uuid": "' +
+ 'Pack",\n "uuid": "' str(uuid.uuid4()) +
+ str(uuid.uuid4()) '"\n },\n "modules": [\n {\n "description": "' +
+ '"\n },\n "modules": [\n {\n "description": "' f"the Player of the Music {self.midFileName}" +
+ f"the Player of the Music {self.midFileName}" '",\n "type": "data",\n "version": [ 0, 0, 1 ],\n "uuid": "' +
+ '",\n "type": "data",\n "version": [ 0, 0, 1 ],\n "uuid": "' str(uuid.uuid4()) +
+ str(uuid.uuid4()) '"\n }\n ]\n}')
+ '"\n }\n ]\n}'
)
else: else:
with open( with open(
f"{self.outputPath}/temp/manifest.json", "r", encoding="utf-8" f"{self.outputPath}/temp/manifest.json", "r", encoding="utf-8"
) as manifest: ) as manifest:
data = json.loads(manifest.read()) data = json.loads(manifest.read())
data["header"][ data["header"][
@ -753,22 +764,22 @@ class midiConvert:
data["modules"][0]["description"] = "None" data["modules"][0]["description"] = "None"
data["modules"][0]["uuid"] = str(uuid.uuid4()) data["modules"][0]["uuid"] = str(uuid.uuid4())
manifest.close() manifest.close()
open(f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8").write( open(f"{self.outputPath}/temp/manifest.json", "w",
json.dumps(data) encoding="utf-8").write(json.dumps(data))
)
# 将命令列表写入文件 # 将命令列表写入文件
indexfile = open( indexfile = open(
f"{self.outputPath}/temp/functions/index.mcfunction", "w", encoding="utf-8" f"{self.outputPath}/temp/functions/index.mcfunction",
) "w",
encoding="utf-8")
for track in cmdlist: for track in cmdlist:
indexfile.write( indexfile.write(
"function mscplay/track" + str(cmdlist.index(track) + 1) + "\n" "function mscplay/track" + str(cmdlist.index(track) + 1) + "\n"
) )
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/track{cmdlist.index(track) + 1}.mcfunction", f"{self.outputPath}/temp/functions/mscplay/track{cmdlist.index(track) + 1}.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.write("\n".join(track)) f.write("\n".join(track))
indexfile.writelines( indexfile.writelines(
@ -793,20 +804,22 @@ class midiConvert:
) )
if progressbar: if progressbar:
if progressbar == True: if progressbar:
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction", f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.writelines( f.writelines(
"\n".join(self.__formProgressBar(maxscore, scoreboardname)) "\n".join(
) self.__formProgressBar(
maxscore,
scoreboardname)))
else: else:
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction", f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.writelines( f.writelines(
"\n".join( "\n".join(
@ -819,21 +832,22 @@ class midiConvert:
indexfile.close() indexfile.close()
makeZip( makeZip(
f"{self.outputPath}/temp/", self.outputPath + f"/{self.midFileName}.mcpack" f"{self.outputPath}/temp/",
) self.outputPath +
f"/{self.midFileName}.mcpack")
shutil.rmtree(f"{self.outputPath}/temp/") shutil.rmtree(f"{self.outputPath}/temp/")
def toBDXfile( def toBDXfile(
self, self,
method: int = 1, method: int = 1,
author: str = "Eilles", author: str = "Eilles",
progressbar=False, progressbar=False,
maxheight: int = 64, maxheight: int = 64,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
isAutoReset: bool = False, isAutoReset: bool = False,
): ):
""" """
使用method指定的转换算法将midi转换为BDX结构文件 使用method指定的转换算法将midi转换为BDX结构文件
@ -902,7 +916,7 @@ class midiConvert:
) )
if progressbar: if progressbar:
if progressbar == True: if progressbar:
commands += self.__formProgressBar(maxScore, scoreboardname) commands += self.__formProgressBar(maxScore, scoreboardname)
else: else:
commands += self.__formProgressBar( commands += self.__formProgressBar(
@ -934,7 +948,8 @@ class midiConvert:
nowy += 1 if yforward else -1 nowy += 1 if yforward else -1
if ((nowy > maxheight) and (yforward)) or ((nowy < 0) and (not yforward)): if ((nowy > maxheight) and (yforward)) or (
(nowy < 0) and (not yforward)):
nowy -= 1 if yforward else -1 nowy -= 1 if yforward else -1
yforward = not yforward yforward = not yforward
@ -942,7 +957,7 @@ class midiConvert:
nowz += 1 if zforward else -1 nowz += 1 if zforward else -1
if ((nowz > _sideLength) and (zforward)) or ( if ((nowz > _sideLength) and (zforward)) or (
(nowz < 0) and (not zforward) (nowz < 0) and (not zforward)
): ):
nowz -= 1 if zforward else -1 nowz -= 1 if zforward else -1
zforward = not zforward zforward = not zforward
@ -962,14 +977,14 @@ class midiConvert:
return (True, _bytes, (nowx, maxheight, _sideLength)) return (True, _bytes, (nowx, maxheight, _sideLength))
def toBDXfile_withDelay( def toBDXfile_withDelay(
self, self,
method: int = 1, method: int = 1,
author: str = "Eilles", author: str = "Eilles",
progressbar=False, progressbar=False,
maxheight: int = 64, maxheight: int = 64,
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
player: str = "@a", player: str = "@a",
): ):
""" """
使用method指定的转换算法将midi转换为BDX结构文件 使用method指定的转换算法将midi转换为BDX结构文件
@ -984,7 +999,8 @@ class midiConvert:
""" """
if method == 1: if method == 1:
cmdlist = self._toCmdList_withDelay_m1(volume, speed, player, progressbar) cmdlist = self._toCmdList_withDelay_m1(
volume, speed, player, progressbar)
else: else:
return (False, f"无法找到算法ID {method} 对应的转换算法") return (False, f"无法找到算法ID {method} 对应的转换算法")
@ -1044,7 +1060,8 @@ class midiConvert:
nowy += 1 if yforward else -1 nowy += 1 if yforward else -1
if ((nowy > maxheight) and (yforward)) or ((nowy < 0) and (not yforward)): if ((nowy > maxheight) and (yforward)) or (
(nowy < 0) and (not yforward)):
nowy -= 1 if yforward else -1 nowy -= 1 if yforward else -1
yforward = not yforward yforward = not yforward
@ -1052,7 +1069,7 @@ class midiConvert:
nowz += 1 if zforward else -1 nowz += 1 if zforward else -1
if ((nowz > _sideLength) and (zforward)) or ( if ((nowz > _sideLength) and (zforward)) or (
(nowz < 0) and (not zforward) (nowz < 0) and (not zforward)
): ):
nowz -= 1 if zforward else -1 nowz -= 1 if zforward else -1
zforward = not zforward zforward = not zforward