diff --git a/example_convert_linear_mcpack.py b/example_convert_linear_mcpack.py deleted file mode 100644 index 41bde1b..0000000 --- a/example_convert_linear_mcpack.py +++ /dev/null @@ -1,24 +0,0 @@ -# THIS PROGRAM IS ONLY A TEST EXAMPLE - - -from msctPkgver.main import * - -convertion = midiConvert() -convertion.convert(input("请输入midi文件路径:"), input("请输入输出路径:")) -print( - convertion.to_mcpack( - 3, - bool(int(input("是否自动重置计分板(1|0):"))), - bool(int(input("是否开启进度条(1|0):"))), - input("请输入计分板名称:"), - str(input("请输入音量(0-1):")), - bool(input("请输入速度倍率:")), - ) -) - -# for the test -# if __name__ == '__main__': -# convertion = midiConvert() -# convertion.convert(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\victory.mid", ".") -# convertion.tomcpack( -# 1, True, True, "scb", 1, 1) diff --git a/magicDemo.py b/magicDemo.py deleted file mode 100644 index 302449c..0000000 --- a/magicDemo.py +++ /dev/null @@ -1,350 +0,0 @@ -# -*- coding: utf-8 -*- - - -# 音·创 开发交流群 861684859 -# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com -# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") -# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md - - -""" -音·创 库版 MIDI转换示例程序 -Musicreater Package Version : Demo for Midi Conversion - -Copyright 2023 all the developers of Musicreater - -开源相关声明请见 ./License.md -Terms & Conditions: ./Lisense.md -""" - -import datetime -import random -import os -import sys - -languages = { - "ZH_CN": { - "MSCT": "音·创", - "ChooseLang": "选择语言", - "LangChd": "当前语言已经切换为", - "ZH_CN": "简体中文", - "ZH_TW": "繁体中文(台湾)", - "EN_GB": "英语(英国)", - "EN_US": "英语(美国)", - ":": ":", - ",": ",", - ".": "。", - "ChoosePath": "请输入MIDI路径或所在文件夹", - "ChooseFileFormat": "请输入输出格式[BDX(1) 或 MCPACK(0)]", - "EnterMethod": "请输入转换算法[{}~{}]", - "MethodRangeErr": "输入的转换算法应为 [{},{}](首尾皆含)之间的一个整数。", - "ChoosePlayer": "请选择播放方式[计分板(1) 或 延迟(0)]", - "WhetherArgEntering": "是否为文件夹内文件的转换统一参数[是(1) 或 否(0)]", - "EnterArgs": "请输入转换参数", - "noteofArgs": "注:文件夹内的全部midi将统一以此参数转换", - "EnterVolume": "请输入音量大小(0~1)", - "EnterSpeed": "请输入速度倍率", - "WhetherPgb": "是否自动生成进度条[是(1) 或 否(0)]", - "WhetherCstmProgressBar": "是否自定义进度条[是(1) 或 否(0)]", - "EnterProgressBarStyle": "请输入进度条样式", - "EnterSbName": "请输入计分板名称", - "EnterSelecter": "请输入播放者选择器", - "WhetherSbReset": "是否自动重置计分板[是(1) 或 否(0)]", - "EnterAuthor": "请输入作者", - "EnterMaxHeight": "请输入指令结构最大生成高度", - "ErrEnter": "输入错误", - "Re-Enter": "请重新输入", - "Dealing": "正在处理", - "FileNotFound": "文件(夹)不存在", - "ChooseOutPath": "请输入结果输出路径", - "Saying": "言·论", - "Failed": "失败", - "CmdLength": "指令数量", - "MaxDelay": "曲目时间(游戏刻)", - "PlaceSize": "结构占用大小", - "LastPos": "最末方块坐标", - "PressEnterExit": "请按下回车键退出。", - } -} - -if sys.argv.__len__() > 0: - currentLang = sys.argv[0] - if currentLang not in languages.keys(): - currentLang = "ZH_CN" -else: - currentLang = "ZH_CN" - - -def _(__): - """ - `languages` - """ - return languages[currentLang][__] - - -try: - import msctPkgver -except ModuleNotFoundError as E: - if input("您需要安装 mido、Brotli 模块才能使用这个样例\n请问是否安装?(y/n):").lower() in ("y", "1"): - os.system("pip install -r requirements.txt") - import msctPkgver - else: - raise E - -try: - from msctPkgver.magicBeing import * - import requests -except ModuleNotFoundError as E: - if input( - "您需要安装以下模块才能使用这个样例\nrequests==2.28.1\nrich==12.6.0\nzhdate==0.1\n请问是否安装?(y/n):" - ).lower() in ("y", "1"): - open("Demo_Requirements.txt", "w").write("requests==2.28.1\nrich==12.6.0") - os.system("pip install -r Demo_Requirements.txt") - os.remove("./Demo_Requirements.txt") - from msctPkgver.magicBeing import * - import requests - else: - raise E - -MainConsole.print( - "[#121110 on #F0F2F4] ", - style="#121110 on #F0F2F4", - justify="center", -) - -# 显示大标题 -MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF") -MainConsole.rule( - title="[bold #AB70FF]Welcome to Independent Musicreater Converter", characters="-" -) - -nowYang = datetime.datetime.now() - -if nowYang.month == 8 and nowYang.day == 6: - # 诸葛八卦生日 - MainConsole.print( - "[#7DB5F0 on #121110]今天可不是催更的日子!\n诸葛亮与八卦阵{}岁生日快乐!".format(nowYang.year - 2009), - style="#7DB5F0 on #121110", - justify="center", - ) -elif nowYang.month == 4 and nowYang.day == 3: - # 金羿生日快乐 - MainConsole.print( - "[#0089F2 on #F0F2F4]今天就不要催更啦!\n金羿{}岁生日快乐!".format(nowYang.year - 2006), - style="#0089F2 on #F0F2F4", - justify="center", - ) -else: - # 显示箴言部分 - MainConsole.print( - "[#121110 on #F0F2F4]{}".format( - random.choice( - requests.get( - "https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt" - ) - .text.strip("\n") - .split("\n") - ) - ), - style="#121110 on #F0F2F4", - justify="center", - ) - -prt(f"{_('LangChd')}{_(':')}{_(currentLang)}") - - -def format_ipt( - notice: str, - fun, - err_note: str = f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", - *extraArg, -): - """循环输入,以某种格式 - notice: 输入时的提示 - fun: 格式函数 - err_note: 输入不符格式时的提示 - *extraArg: 对于函数的其他参数""" - while True: - result = ipt(notice) - try: - fun_result = fun(result, *extraArg) - break - except ValueError: - prt(err_note) - continue - return result, fun_result - - -# 获取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( - ( - 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(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") - continue - else: - prt(f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}") - continue - break - -# 获取输出地址 -out_path = format_ipt( - f"{_('ChooseOutPath')}{_(':')}", - os.path.exists, - f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}", -)[0].lower() - -conversion = msctPkgver.midiConvert() - - -def isMethodOK(sth: str): - if int(sth) in range(1, len(conversion.methods) + 1): - return int(sth) - else: - raise ValueError - - -convert_method = format_ipt( - f"{_('EnterMethod').format(1, len(conversion.methods))}{_(':')}", - isMethodOK, - f"{_('MethodRangeErr').format(1, len(conversion.methods))}", -)[1] - -# 选择输出格式 -while True: - fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower() - if fileFormat in ("0", "mcpack"): - fileFormat = 0 - playerFormat = 1 - break - - elif fileFormat in ("1", "bdx"): - fileFormat = 1 - while True: - playerFormat = ipt(f"{_('ChoosePlayer')}{_(':')}").lower() - if playerFormat in ("0", "延迟", "delay"): - playerFormat = 0 - elif playerFormat in ("1", "计分板", "scoreboard"): - playerFormat = 1 - else: - prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") - continue - break - else: - prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") - continue - break - -debug = False - - -# 真假字符串判断 -def bool_str(sth: str) -> bool: - try: - return bool(int(sth)) - except ValueError: - if str(sth).lower() == "true": - return True - elif str(sth).lower() == "false": - return False - else: - raise ValueError("布尔字符串啊?") - - -if os.path.exists("./demo_config.json"): - import json - - prompts = json.load(open("./demo_config.json", "r", encoding="utf-8")) - if prompts[-1] == "debug": - debug = True - prompts = prompts[:-1] -else: - prompts = [] - # 提示语 检测函数 错误提示语 - for args in [ - ( - f'{_("EnterVolume")}{_(":")}', - float, - ), - ( - f'{_("EnterSpeed")}{_(":")}', - float, - ), - ( - f'{_("WhetherPgb")}{_(":")}', - bool_str, - ), - ( - f'{_("EnterSbName")}{_(":")}', - str, - ) - if playerFormat == 1 - else ( - f'{_("EnterSelecter")}{_(":")}', - str, - ), - ( - f'{_("WhetherSbReset")}{_(":")}', - bool_str, - ) - if playerFormat == 1 - else (), - ( - f'{_("EnterAuthor")}{_(":")}', - str, - ) - if fileFormat == 1 - else (), - ( - f'{_("EnterMaxHeight")}{_(":")}', - int, - ) - if fileFormat == 1 - else (), - ]: - if args: - prompts.append(format_ipt(*args)[1]) - -conversion = msctPkgver.midiConvert(debug) -for singleMidi in midis: - prt("\n" f"{_('Dealing')} {singleMidi} {_(':')}") - conversion.convert(singleMidi, out_path) - if debug: - with open("./records.json", "a", encoding="utf-8") as f: - json.dump(conversion.toDICT(), f) - f.write(5 * "\n") - conversion_result = ( - conversion.to_mcpack(convert_method, *prompts) - if fileFormat == 0 - else ( - conversion.to_BDX_file(convert_method, *prompts) - if playerFormat == 1 - else conversion.to_BDX_file_with_delay(convert_method, *prompts) - ) - ) - - if conversion_result[0]: - prt( - f" {_('CmdLength')}{_(':')}{conversion_result[1]}{_(',')}{_('MaxDelay')}{_(':')}{conversion_result[2]}{f'''{_(',')}{_('PlaceSize')}{_(':')}{conversion_result[3]}{_(',')}{_('LastPos')}{_(':')}{conversion_result[4]}''' if fileFormat == 1 else ''}" - ) - else: - prt(f"{_('Failed')}") - -exitSth = ipt(_("PressEnterExit")).lower() -if exitSth == "record": - import json - - with open("./demo_config.json", "w", encoding="utf-8") as f: - json.dump(prompts, f) -elif exitSth == "delrec": - os.remove("./demo_config.json") diff --git a/msctPkgver/bdxRead.py b/msctPkgver/bdxRead.py deleted file mode 100644 index eeeb146..0000000 --- a/msctPkgver/bdxRead.py +++ /dev/null @@ -1 +0,0 @@ -import brotli;input(brotli.decompress(open(input("BDX文件:"), "rb").read()[3:])) \ No newline at end of file diff --git a/msctPkgver/magicBeing.py b/msctPkgver/magicBeing.py deleted file mode 100644 index acfb3c7..0000000 --- a/msctPkgver/magicBeing.py +++ /dev/null @@ -1,147 +0,0 @@ -from rich.console import Console -from typing import Any, Literal, Optional, TextIO - -MainConsole = Console() - -JustifyMethod = Literal["default", "left", "center", "right", "full"] -OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"] - - -# 高级的打印函数 -def prt( - *objects: Any, - sep: str = " ", - end: str = "\n", - justify: Optional[JustifyMethod] = None, - overflow: Optional[OverflowMethod] = None, - no_wrap: Optional[bool] = None, - emoji: Optional[bool] = None, - markup: Optional[bool] = None, - highlight: Optional[bool] = None, - width: Optional[int] = None, - height: Optional[int] = None, - crop: bool = True, - soft_wrap: Optional[bool] = None, - new_line_start: bool = False, -) -> None: - """打印到控制台。 - - Args: - objects (位置性的args): 要记录到终端的对象。 - sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。 - end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。 - justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。 - overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。 - no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。 - emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。 - markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。 - highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。 - width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。 - height - crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。 - soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。 - new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。 - """ - MainConsole.print( - *objects, - sep=sep, - end=end, - style="#F0F2F4 on #121110", - justify=justify, - overflow=overflow, - no_wrap=no_wrap, - emoji=emoji, - markup=markup, - highlight=highlight, - width=width, - height=height, - crop=crop, - soft_wrap=soft_wrap, - new_line_start=new_line_start, - ) - - -# 高级的输入函数 -def ipt( - *objects: Any, - sep: str = " ", - justify: Optional[JustifyMethod] = None, - overflow: Optional[OverflowMethod] = None, - no_wrap: Optional[bool] = None, - emoji: Optional[bool] = None, - markup: Optional[bool] = None, - highlight: Optional[bool] = None, - width: Optional[int] = None, - height: Optional[int] = None, - crop: bool = True, - soft_wrap: Optional[bool] = None, - new_line_start: bool = False, - password: bool = False, - stream: Optional[TextIO] = None, -) -> str: - """显示一个提示并等待用户的输入。 - - 它的工作方式与Python内建的 :func:`input` 函数相同,如果Python内建的 :mod:`readline` 模块先前已经加载,则提供详细的行编辑和历史功能。 - - Args: - objects (位置性的args): 要记录到终端的对象。 - sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。 - justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。 - overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。 - no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。 - emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。 - markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。 - highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。 - width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。 - crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。 - height - soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。 - new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。 - password (bool, 可选): 隐藏已经输入的文案,默认值为`False`。 - stream (TextIO, 可选): 可选从文件中读取(而非控制台),默认为 `None`。 - - Returns: - str: 从stdin读取的字符串 - """ - MainConsole.print( - *objects, - sep=sep, - end="", - style="#F0F2F4 on #121110", - justify=justify, - overflow=overflow, - no_wrap=no_wrap, - emoji=emoji, - markup=markup, - highlight=highlight, - width=width, - height=height, - crop=crop, - soft_wrap=soft_wrap, - new_line_start=new_line_start, - ) - - return MainConsole.input(password=password, stream=stream) - - -def format_ipt( - notice: str, - fun, - err_note: str = "", - *extraArg, -): - """循环输入,以某种格式 - notice: 输入时的提示 - fun: 格式函数 - err_note: 输入不符格式时的提示 - *extraArg: 对于函数的其他参数""" - while True: - result = ipt(notice) - # noinspection PyBroadException - try: - fun_result = fun(result, *extraArg) - break - except: - prt(err_note) - continue - return result, fun_result diff --git a/msctPkgver/utilsFuture.py b/msctPkgver/utilsFuture.py deleted file mode 100644 index 56f1a78..0000000 --- a/msctPkgver/utilsFuture.py +++ /dev/null @@ -1,365 +0,0 @@ -import math -import os -import brotli -from exceptions import * - -key = { - "x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"], - "y": [b"\x11", b"\x10", b"\x1d", b"\x16", b"\x17"], - "z": [b"\x13", b"\x12", b"\x1e", b"\x18", b"\x19"], -} -"""key存储了方块移动指令的数据,其中可以用key[x|y|z][0|1]来表示xyz的减或增 -而key[][2+]是用来增加指定数目的""" - -x = "x" -y = "y" -z = "z" - - -def move(axis: str, value: int): - if value == 0: - return b"" - if abs(value) == 1: - return key[axis][0 if value == -1 else 1] - - pointer = sum( - [ - 1 if i else 0 - for i in ( - value != -1, - value < -1 or value > 1, - value < -128 or value > 127, - value < -32768 or value > 32767, - ) - ] - ) - - return key[axis][pointer] + value.to_bytes(2 ** (pointer - 2), "big", signed=True) - - -def makeZip(sourceDir, outFilename, compression=8, exceptFile=None): - """使用compression指定的算法打包目录为zip文件\n - 默认算法为DEFLATED(8),可用算法如下:\n - STORED = 0\n - DEFLATED = 8\n - BZIP2 = 12\n - LZMA = 14\n - """ - import zipfile - - zipf = zipfile.ZipFile(outFilename, "w", compression) - pre_len = len(os.path.dirname(sourceDir)) - for parent, dirnames, filenames in os.walk(sourceDir): - for filename in filenames: - if filename == exceptFile: - continue - pathfile = os.path.join(parent, filename) - arc_name = pathfile[pre_len:].strip(os.path.sep) # 相对路径 - zipf.write(pathfile, arc_name) - zipf.close() - - -def formCMD_blk( - command: str, - particularValue: int, - impluse: int = 0, - condition: bool = False, - needRedstone: bool = True, - tickDelay: int = 0, - customName: str = "", - executeOnFirstTick: bool = False, - trackOutput: bool = True, -): - """ - 使用指定项目返回指定的指令方块放置指令项 - :param command: `str` - 指令 - :param particularValue: - 方块特殊值,即朝向 - :0 下 无条件 - :1 上 无条件 - :2 z轴负方向 无条件 - :3 z轴正方向 无条件 - :4 x轴负方向 无条件 - :5 x轴正方向 无条件 - :6 下 无条件 - :7 下 无条件 - - :8 下 有条件 - :9 上 有条件 - :10 z轴负方向 有条件 - :11 z轴正方向 有条件 - :12 x轴负方向 有条件 - :13 x轴正方向 有条件 - :14 下 有条件 - :14 下 有条件 - 注意!此处特殊值中的条件会被下面condition参数覆写 - :param impluse: `int 0|1|2` - 方块类型 - 0脉冲 1循环 2连锁 - :param condition: `bool` - 是否有条件 - :param needRedstone: `bool` - 是否需要红石 - :param tickDelay: `int` - 执行延时 - :param customName: `str` - 悬浮字 - lastOutput: `str` - 上次输出字符串,注意此处需要留空 - :param executeOnFirstTick: `bool` - 执行第一个已选项(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) - :param trackOutput: `bool` - 是否输出 - - :return:str - """ - block = b"\x24" + particularValue.to_bytes(2, byteorder="big", signed=False) - - for i in [ - impluse.to_bytes(4, byteorder="big", signed=False), - bytes(command, encoding="utf-8") + b"\x00", - bytes(customName, encoding="utf-8") + b"\x00", - bytes("", encoding="utf-8") + b"\x00", - tickDelay.to_bytes(4, byteorder="big", signed=True), - executeOnFirstTick.to_bytes(1, byteorder="big"), - trackOutput.to_bytes(1, byteorder="big"), - condition.to_bytes(1, byteorder="big"), - needRedstone.to_bytes(1, byteorder="big"), - ]: - block += i - return block - - -def __fillSquareSideLength(total: int, max_height: int): - """给定总方块数量和最大高度,返回所构成的图形外切正方形的边长 - :param total: 总方块数量 - :param max_height: 最大高度 - :return: 外切正方形的边长 int""" - return math.ceil(math.sqrt(math.ceil(total / max_height))) - - -axisParticularValue = { - x: { - True: 5, - False: 4, - }, - y: { - True: 1, - False: 0, - }, - z: { - True: 3, - False: 2, - }, -} - - -def toLineBDX_bytes( - commands: list, - axis: str, - forward: bool, -): - _bytes = b"" - impluse = 2 - needRedstone = False - customName = "" - executeOnFirstTick = False - trackOutput = True - for cmd, condition in commands: - _bytes += formCMD_blk( - cmd, - axisParticularValue[axis][forward], - impluse=impluse, - condition=condition, - needRedstone=needRedstone, - customName=customName, - executeOnFirstTick=executeOnFirstTick, - trackOutput=trackOutput, - ) + move(axis, 1 if forward else -1) - return _bytes - - -def toBDX_bytes( - commands: list, - max_height: int = 64, -): - """ - :param commands: 指令列表(指令, 条件) - :param max_height: 生成结构最大高度 - :return 成功与否,成功返回(True,未经过压缩的源,结构占用大小),失败返回(False,str失败原因) - """ - - _sideLength = __fillSquareSideLength(len(commands), max_height) - _bytes = b"" - - y_forward = True - z_forward = True - - now_y = 0 - now_z = 0 - now_x = 0 - - for cmd, delay in commands: - impluse = 2 - condition = False - needRedstone = False - tickDelay = delay - customName = "" - executeOnFirstTick = False - trackOutput = True - _bytes += formCMD_blk( - cmd, - (1 if y_forward else 0) - if ( - ((now_y != 0) and (not y_forward)) - or (y_forward and (now_y != (max_height - 1))) - ) - else (3 if z_forward else 2) - if ( - ((now_z != 0) and (not z_forward)) - or (z_forward and (now_z != _sideLength)) - ) - else 5, - impluse=impluse, - condition=condition, - needRedstone=needRedstone, - tickDelay=tickDelay, - customName=customName, - executeOnFirstTick=executeOnFirstTick, - trackOutput=trackOutput, - ) - - now_y += 1 if y_forward else -1 - - if ((now_y >= max_height) and y_forward) or ((now_y < 0) and (not y_forward)): - now_y -= 1 if y_forward else -1 - - y_forward = not y_forward - - now_z += 1 if z_forward else -1 - - if ((now_z > _sideLength) and z_forward) or ( - (now_z < 0) and (not z_forward) - ): - now_z -= 1 if z_forward else -1 - z_forward = not z_forward - _bytes += key[x][1] - now_x += 1 - else: - - _bytes += key[z][int(z_forward)] - - else: - - _bytes += key[y][int(y_forward)] - - return ( - _bytes, - [ - now_x + 1, - max_height if now_x or now_z else now_y, - _sideLength if now_x else now_z, - ], - [now_x, now_y, now_z], - ) - - -def toBDXfile( - funcList: list, - author: str = "Eilles", - max_height: int = 64, - outfile: str = "./test.bdx", -): - """ - :param funcList: 指令集列表: 指令系统[ 指令集[ 单个指令( str指令, bool条件性 ), ], ] - :param author: 作者名称 - :param max_height: 生成结构最大高度 - :param outfile: str 输出文件 - :return 成功与否,指令总长度,指令总延迟,指令结构总大小,画笔最终坐标 - """ - - with open(os.path.abspath(outfile), "w+", encoding="utf-8") as f: - f.write("BD@") - - _bytes = ( - b"BDX\x00" + author.encode("utf-8") + b" & Musicreater\x00\x01command_block\x00" - ) - totalSize = {x: 0, y: 0, z: 0} - totalLen = 0 - for func in funcList: - totalLen += len(func) - cmdBytes, size, finalPos = toBDX_bytes(func, max_height) - _bytes += cmdBytes - _bytes += move(x, 2) - _bytes += move(y, -finalPos[1]) - _bytes += move(z, -finalPos[2]) - totalSize[x] += size[0] + 2 - totalSize[y] = max(totalSize[y], size[1]) - totalSize[z] = max(totalSize[z], size[2]) - - with open( - os.path.abspath(outfile), - "ab+", - ) as f: - f.write(brotli.compress(_bytes + b"XE")) - - return True, totalLen, 0, list(totalSize.values()), finalPos - - -def toLineBDXfile( - funcList: list, - axis_: str, - forward_: bool, - author: str = "Eilles", - outfile: str = "./test.bdx", -): - """ - :param funcList: 指令集列表: 指令系统[ 指令集[ 单个指令( str指令, bool条件性 ), ], ] - :param axis_: - :param forward_: - :param author: 作者名称 - :param outfile: str 输出文件 - :return 成功与否,指令总长度,指令总延迟,指令结构总大小,画笔最终坐标 - """ - - with open(os.path.abspath(outfile), "w+", encoding="utf-8") as f: - f.write("BD@") - - _bytes = ( - b"BDX\x00" + author.encode("utf-8") + b" & Musicreater\x00\x01command_block\x00" - ) - totalSize = {x: 0, y: 0, z: 0} - totalLen = 0 - for func in funcList: - totalLen += len(func) - _bytes += toLineBDX_bytes(func, axis_, forward_) - _bytes += move(z if axis_ == x else x, 2) - - totalSize[z if axis_ == x else x] += 2 - totalSize[axis_] = max(totalSize[axis_], len(func)) - - with open( - os.path.abspath(outfile), - "ab+", - ) as f: - f.write(brotli.compress(_bytes + b"XE")) - - return True, totalLen, 0, list(totalSize.values()) - - -def format_ipt(notice: str, fun, err_note: str = "", *extraArg): - """循环输入,以某种格式 - notice: 输入时的提示 - fun: 格式函数 - err_note: 输入不符格式时的提示 - *extraArg: 对于函数的其他参数""" - while True: - result = input(notice) - try: - fun_result = fun(result, *extraArg) - break - except ValueError: - print(err_note) - continue - return result, fun_result