This commit is contained in:
EillesWan 2023-02-01 22:10:35 +08:00
commit 3669b5f804
15 changed files with 2510 additions and 197 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.yaml linguist-language=Python
*.xml linguist-language=Python
*.md linguist-language=Python

24
.gitignore vendored
View File

@ -1,18 +1,21 @@
# sth. can't open
/msctPkgver/secrets/*.py
/msctPkgver/secrets/*.c
# mystuff
.vscode
/.vscode
*.mid
*.midi
*.mcpack
*.bdx
*.json
# Byte-compiled / optimized / DLL files
# Byte-compiled / optimized
__pycache__/
*.py[cod]
*.pyc
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
@ -143,3 +146,12 @@ dmypy.json
# Cython debug symbols
cython_debug/
# Pycharm
/.idea
# log
/.log
# package
.7z

120
README.md
View File

@ -22,118 +22,48 @@
简体中文 | [English](README_EN.md)
## 软件介绍🚀
## 介绍🚀
· Musicreater 是一款免费开源的 **我的世界基岩版** 音乐制作软件
· 是一个免费开源的针对 **我的世界** 的midi音乐转换库
欢迎加群[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
**注意注意注意当前版本正在进行代码重构详细信息请进入QQ群了解**
## 文档📄
## 软件作者✒
[生成文件的使用](./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)
金羿 Eilles我的世界基岩版指令师个人开发者B站不知名UP主南昌在校高中生
[仓库API文档](./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)
## 作者✒
金羿 Eilles我的世界基岩版指令师个人开发者B站不知名UP主江西在校高中生
诸葛亮与八卦阵 bgArray我的世界基岩版玩家喜欢编程和音乐深圳初二学生
## 软件架构🏢
## 致谢🙏
本致谢列表排名无顺序
软件采用 *Python* 作为第一语言目前还没有使用其他语言辅助
支持 Windows7+ 以及各个支持 Python3.6+ Linux
***各位开发人员注意多语言支持请使用函数`_`加载文字如需补充请在简体中文的语言文件(zh-CN.lang)中补充***
## 使用教程📕
***请注意·创是音乐的 编辑 软件不是转换软件若要直接转换midi音乐到我的世界请见 [· 包版本](https://gitee.com/EillesWan/Musicreater/blob/pkgver/)***
### 安装教程
下载[·创自动安装器](https://gitee.com/EillesWan/Musicreater/releases/)将其放在你希望安装音·创的位置运行后将自动安装
提示下载源最好选择\"2 GitHub\"
### 从源代码运行教程
#### Windows7+
0. [Gitee下载需要登陆](https://gitee.com/EillesWan/Musicreater)
[Github下载](https://github.com/EillesWan/Musicreater)本程序源代码
1. 安装Python 3.8.10
[下载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)
2. 以管理员身份运行 作者的自我修养.py :
- 点击 开始 菜单搜索 `命令提示符`
- 右键点击 `命令提示符` 左键点击 以管理员身份运行
- 作者的自我修养.py 拖拽入开启的窗口按下回车
3. 等待安装完成后双击运行 Musicreater.py
#### Linux
0. 若你没有足够优秀的环境推荐先在终端敲
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python3
sudo apt-get install python3-pip
sudo apt-get install git
```
1. 若你足够自信该整的都整了就在你想下载此程序的地方打开终端
```bash
sudo git clone https://gitee.com/EillesWan/Musicreater.git
cd Musicreater
python3 作者的自我修养.py
python3 Musicreater.py
```
### 使用说明
1. 直接运行就好
2. 后期会出详细的使用教程
3. 如果在使用过程中发现了bug拜托请上报给我详见下方联系方式
## 诸葛亮与八卦阵的关于羽音缭绕资源包应用地说明(不必要)📖
0. ***注意注意这一条说明是供给老版本(Delta 0.1.x)使用的***
1. 首先这里的提示是给想使用多音色资源包的人的如果你想用就请下载 [神羽资源包神羽自己的链接](https://pan.baidu.com/s/11uoq5zwN7c3rX-98DqVpJg)提取码:ek3t
2. 下载到你自己电脑上某个位置可以不放置于本项目下音色资源包较大可以选取只下载
`神羽资源包_乐器音源的资源包\羽音缭绕-midiout_25.0` 这个文件夹再嫌麻烦的话也可以只下载其中的
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\mcpack(国际版推荐)格式_25.0` 或者
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\zip格式_25.0`
4. 接下来就是关键了*音创*中绑定资源包
首先先打开 *音创*->帮助与疑问->\[神羽资源包位置选择\]选择文件夹... 这时候会跳出选择框
关键来了选择***您下载的`羽音缭绕-midiout_25.0`文件夹或者`mcpack(国际版推荐)格式_25.0``zip格式_25.0`的上级目录***
举个例子我的文件路径是这样的
`L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0`这里面有`神羽资源包_25.0_使用方法.xls`
`mcpack(国际版推荐)格式_25.0``zip格式_25.0`两个文件夹和一个.xls文件而你在音创中
也应该选择这个文件夹**L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0**
6. 如果你想使用音色资源包来制作函数那么解析时你应该用 *音创*->编辑->从midi导入音轨且用新方法解析
然后再使用 *音创*->函数->下面的四个新函数
## 致谢列表🙏
- 感谢由 **[Fuckcraft](https://github.com/fuckcraft)** **鸣凤鸽子** 带来的我的世界websocket服务器功能
- 感谢 **昀梦**\<QQ1515399885\> 找出指令生成错误bug并指正
- 感谢由 **Charlie_Ping** **查理平** 带来的bdx转换功能
- 感谢由 **CMA_2401PT** 带来的 BDXWorkShop 供本程序对于bdx操作的指导
- 感谢由 **神羽** (**Miracle Plume**)\<QQshenyu40403\>带来的羽音缭绕基岩版音色资源包
- 感谢 **Arthur Morgan**\<QQ312280061\> 对本程序的排错提出了最大的支持
- 感谢由 **Dislink Sforza** \<QQ1600515314\>带来的midi音色解析以及转换指令的算法我们将其改编并应用
- 感谢 **Touch** **偷吃** \<QQ1793537164\>提供的测试支持并对程序的改进提供了丰富的意见
- 感谢 **Mono**\<QQ738893087\>反馈安装时的问题
- 感谢由 **Charlie_Ping 查理平** 带来的BDX文件转换参考以及MIDI-我的世界对应乐器参考表格
- 感谢由 **[CMA_2401PT](https://github.com/CMA2401PT)** 为我们的软件开发的一些方面进行指导同时我们参考了他的BDXworkshop作为BDX结构编辑的参考
- 感谢由 **[Dislink Sforza](https://github.com/Dislink) 断联·斯福尔扎**\<QQ1600515314\> 带来的midi音色解析以及转换指令的算法我们将其改编并应用同时感谢他的[网页版转换器](https://dislink.github.io/midi2bdx/)给我们的开发与更新带来巨大的压力和动力让我们在原本一骑绝尘的摸鱼道路上转向开发希望他能考上一个理想的大学
- 感谢 **Touch 偷吃**\<QQ1793537164\> 提供的BDX导入测试支持并对程序的改进提供了丰富的意见同时也感谢他的不断尝试新的内容使我们的排错更进一步
- 感谢 **Mono**\<QQ738893087\> 反馈安装时的问题辅助我们找到了视窗操作系统下的兼容性问题
- 感谢 **Ammelia 艾米利亚**\<QQ2838334637\> 敦促我们进行新的功能开发并为新功能提出了非常优秀的大量建议以及提供的BDX导入测试支持为我们的新结构生成算法提供了大量的实际理论支持
- 感谢 **[神羽](https://gitee.com/snowykami) [SnowyKami](https://github.com/snowyfirefly)** 对我们项目的支持与宣传
- 感谢 **指令师_苦力怕 playjuice123**\<QQ240667197\>为我们的程序找出错误并提醒我们修复一个一直存在的大bug
- 感谢 **雷霆**\<QQ3555268519\>为我们的程序找出错误并提醒修复bug
> 感谢广大群友为此程序提供的测试等支持
> 感谢广大群友为此程序提供的测试等支持
>
> 若您对我们有所贡献但您的名字没有显示在此列表中请联系我
> 若您对我们有所贡献但您的名字没有显示在此列表中请联系我们
## 联系我们📞
## 联系📞
若遇到库中的问题欢迎在[](https://gitee.com/TriM-Organization/Musicreater/issues/new)提出你的issue
如果需要与开发组进行交流欢迎加入我们的[开发闲聊Q群](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
## 待办事项⏲
- [] 喵喵喵
[Bilibili: 凌云金羿]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge

View File

@ -17,121 +17,52 @@
[![][license]](LICENSE)
[![][release]](../../releases)
[简体中文](README.md) | English
[简体中文🇨🇳](README.md) | English🇬🇧
**Notice that the language support of *README* may be a little SLOW.**
**Notice that the language translation of *Musicreater* may be a little SLOW.**
## Introduction🚀
Musicreater(·) is an free open source software which is used for making and also creating music in **Minecraft: Bedrock Edition**.
Musicreater is a free open-source library used for converting midi file into formats that could be read in *Minecraft*.
Welcome to join our QQ group: [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
**ATTENTION!** This software is under testing and developing, there is still a lot of bugs needed to be fixed. Please use it wisely.
## Documentation📄
(Not in English yet)
[生成文件的使用](./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)
[仓库API文档](./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)
### Authors✒
Eilles (金羿)A high school student, individual developer, unfamous BilibiliUPer, which knows a little about commands in *Minecraft: Bedrock Edition*
Eilles (金羿)A senior high school student, individual developer, unfamous Bilibili UPer, which knows a little about commands in *Minecraft: Bedrock Edition*
bgArray "诸葛亮与八卦阵": Fix bugs, improve code aesthetics, add new functions, change data format, etc.
bgArray "诸葛亮与八卦阵": A junior high school student, player of *Minecraft: Bedrock Edition*, which is a fan of music and programming.
### Framework🏢
Developed under *Python3.8 3.9*. However, theoretically support Python3.6+.
Support Windows7+ && Linux (that supports Python3.6+)
***ATTENTION TO DEVELOPERS!!! TO SUPPORT DIFFERENT LANGUAGES, PLEASE USE FUNCTION(METHOD) `_` TO LOAD TEXTs!!! IF YOU NEED TO SUPPLEMENT, PLEASE ADD THEM IN SIMPLEFIED CHINESE\'S LANGUAGE FILE(zh-CN.lang), WHEATHER WHAT LANGUAGE YOU USE!!!***
## Instructions📕
### Installation
Download the *[MSCT Auto Installer](https://github.com/EillesWan/Musicreater/releases/tag/v0.2.0.0-Delta)*, put it in a directory that you want to install *Musicreater* into. Then run the auto installer and it will help you to install the *Musicreator* as well as Python3.8(if you haven\'t install it)
Tips: You'd better choose the \"2 GitHub\" download source
### Run with Source Code
#### Windows7+
0. First, download the source code pack of Musicreater.
[Download from Gitee (Need to Login)](https://gitee.com/EillesWan/Musicreater/repository/archive/master.zip)
[Download from Github](https://github.com/EillesWan/Musicreater/archive/refs/heads/master.zip)
1. Install Python 3.8.10
[Download the 64-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
[Download the 32-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
2. After completing installation, we need to install the libraries :
- Open "Start Menu" and find `cmd`
- Run `cmd` as Administrator
- Drag "作者的自我修养.py" into the opened window and press Enter
3. After completing installationdouble click Musicreater.py to run
#### Linux
0. If you 're not sure whether your environment is good enough, please run these commands on Terminal
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python3
sudo apt-get install python3-pip
sudo apt-get install git
```
1. Now if you are confident enough about your runtime environment, open Terminal on the place which you want to download Musicreater, and run these
```bash
sudo git clone https://gitee.com/EillesWan/Musicreater.git
cd Musicreater
python3 作者的自我修养.py
python3 Musicreater.py
```
### Instructions of Using
1. Just run Musicreater.pyc(or .py) if you have installed well
2. Detailed instructions is coming soon
3. If you find a bug, could you please report it to me? My contact info is right below.
## Explanation of the use of *PlumeAudioSurrounding Resource Pack* by bgArray (unnecessary)📖
1. First! The tips here are for those who want to use the multi tone resource package, [Shenyu resource package (Shenyu's own link)](https://pan.baidu.com/s/11uoq5zwN7c3rX-98DqVpJg) \(Extraction code: `ek3t`\)
2. Download it to any location on your PC. Note that it does ***not*** need to be placed in the directory where *Musicreater* are. The audio resource package is large, so you can choose to download only:`神羽资源包_乐器音源的资源包\羽音缭绕-midiout_25.0`.
Also, you can download only `神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\mcpack(国际版推荐)格式_25.0` or
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\zip格式_25.0`.
4. The next step is the most IMPORTANT: to bind the resource package to *Musicreater*
First, open *Musicreater*->Q&A->Select \[MiraclePlumeResourcePack\]... .At this time, in the selection box,
the IMPORTANT step comes, select: ***The directory you downloaded: `羽音缭绕-midiout_25.0`, or also the parent directory `mcpack(国际版推荐)格式_25.0`or`zip格式_25.0`***
For example, my file path is as follows:
`L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0` and in the directory, there are two folders and one .xls file:
`神羽资源包_25.0_使用方法.xls`, `mcpack(国际版推荐)格式_25.0` and `zip格式_25.0`, so in *Musicreater* you should also select this folder: **L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0**
6. If you want to use the Miracle Plume Bedrock Edition Audio Resource Pack to make .mcfunction s, you should use Musicreater -> Edit - > Import audio tracks from MIDI and parse them with a new method, and then use it
Musicreater - > function (package) - > the following four new functions
## Thanks🙏
This list is not in any order.
1. Thank [Fuckcraft](https://github.com/fuckcraft) *(鸣凤鸽子 ,etc)* for the function of Creating the Websocket Server for Minecraft: Bedrock Edition.
- *!! They have given me the rights to directly copy the lib into Musicreater*
2. Thank *昀梦*\<QQ1515399885\> for finding and correcting the bugs in the commands that *Musicreater* Created.
3. Thank *Charlie_Ping 查理平* for bdx convert funtion.
4. Thank *CMA_2401PT* for BDXWorkShop as the .bdx structure's operation guide.
5. Thank *Miracle Plume 神羽* \<QQshenyu40403\> for the Miracle Plume Bedrock Edition Audio Resource Pack
6. Thank *Arthur Morgan* for his/her biggest support for the debugging of Musicreater
7. Thanks for a lot of groupmates who support me and help me to test the program.
8. If you have give me some help but u haven't been in the list, please contact me.
- Thank *昀梦*\<QQ1515399885\> for finding and correcting the bugs in the commands that *Musicreater* generated.
- Thank *Charlie_Ping 查理平* for bdx convert function for reference, and the chart that's used to convert the mid's instruments into Minecraft's instruments.
- Thank *[CMA_2401PT](https://github.com/CMA2401PT)* for BDXWorkShop for reference of the .bdx structure's operation, and his guidance in some aspects of our development.
- Thank *[Dislink Sforza](https://github.com/Dislink) 断联·斯福尔扎* \<QQ1600515314\> for his midi analysis algorithm brought to us, we had adapted it and made it applied in one of our working method; Also, thank him for the [WebConvertor](https://dislink.github.io/midi2bdx/) which brought us so much pressure and power to develop as well as update our projects better, instead of loaf on our project. We hope he can get into a good university as he wantted to!
- Thank *Touch 偷吃*\<QQ1793537164\> for support of debugging and testing program and algorithm, as well his/her suggestions to the improvement of our project
- Thank *Mono*\<QQ738893087\> for reporting problems while installing
- Thank *Ammelia 艾米利亚*\<QQ2838334637\> for urging us to develop new functions, and put forward a lot of excellent suggestions for new functions, as well as the BDX file's importing test support provided, which has given a lot of practical theoretical support for our new Structure Generating Algorithm
- 感谢 *[神羽](https://gitee.com/snowykami) [SnowyKami](https://github.com/snowyfirefly)* for supporting and promoting our project
## Contact Information📞
> Thanks for a lot of groupmates's support and help
>
> If you have given contribution but haven't been in the list, please contact us!
### Author *Eilles*(金羿)
## Contact Us📞
1. QQ 2647547478
2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
3. WeChat WYI_DoctorYI
### Author *bgArray*(诸葛亮与八卦阵)
1. QQ 4740437765
Meet problems? Welcome to give out your issue [here](https://gitee.com/EillesWan/Musicreater/issues/new)!
Want to get in contact of developers? Welcome to join our [Chat QQ group](https://jq.qq.com/?_wv=1027&k=hpeRxrYr).

View File

@ -0,0 +1,187 @@
<h1 align="center">· Musicreater</h1>
<h2 align="center">库版 Package Version</h2>
<p align="center">
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
</p>
**此为开发相关文档内容包括所生成文件结构的详细说明特殊参数的详细解释**
# 库的简单调用
参见[magicDemo.py的相关部分](../magicDemo.py#L436)使用此库进行MIDI转换非常简单。
```python
import msctPkgver # 导入转换库
# 首先新建转换对象。
conversion = msctPkgver.midiConvert()
# 值得注意的是,一个转换对象可以转换多个文件。
# 也就是在实例化的时候不进行对文件的绑定。
# 如果有调试需要,可以在实例化时传入参数 debug = True
# 如conversion = msctPkgver.midiConvert(debug=True)
# 设置输入输出地址并指定execute指令语法
# 地址都为字符串类型,不能传入文件流
midi_path = "./where/you/place/.midi/files.mid"
output_folder = "./where/you/want2/convert/into/"
old_execute_format = False # 指定是否使用旧的execute指令语法即1.18及以前的《我的世界:基岩版》语法)
conversion.convert(midi_path,output_folder,old_execute_format)
# 进行转换并接受输出,具体的参数均在文档中有相关说明
method_id = 2 # 指定使用的转换算法
convertion_result = conversion.tomcpack(method_id,*prompts)
# 转换结果是一个元组。
# 若其转换成功,则前三位必为
# True, 指令数量, 最大延迟
# 其中,最大延迟可以理解为计分板的最大值
# 如果转换失败,暂时还没有定返回值的规则
# 但是有一点是肯定的,数据结构必定是元组
print(convertion_result)
```
# 生成文件结构
## 名词解释
|名词|解释|备注|
|--------|-----------|----------|
|指令区|一个用于放置指令系统的区域通常是常加载区|常见于服务器指令系统好友联机房间中|
|指令链|与链式指令方块不同一个指令链通常指代的是一串由某种非链式指令方块作为开头后面连着一串链式指令方块的结构|通常的链都应用于需要单次激活而多指令的简单功能|
|起始块|链最初的那个非链式指令方块|此方块为脉冲方块或重复方块皆可|
|指令系统系统|指令系统通常指的是由一个或多个指令链以及相关红石机构相互配合一同组成的为达到某种特定的功能而构建的整体结构|通常的系统都应用于需要综合调配指令的复杂功能可由多个实现不同功能的模块构成不同系统之间可以相互调用各自的模块|
|游戏刻|游戏的一刻是指我的世界的游戏循环运行一次所占用的时间[详见我的世界中文维基](https://minecraft.fandom.com/zh/wiki/%E5%88%BB#%E6%B8%B8%E6%88%8F%E5%88%BB))。指令方块的延迟功能(即指令方块的“延迟刻数”设置项,此项的名称被误译为“已选中项的延迟”)的单位即为`1`游戏刻。|正常情况下游戏固定以每秒钟20刻的速率运行。但是由于游戏内的绝大多数操作都是基于刻数而非现实中的时间来计时并进行的一次游戏循环内也许会发生大量的操作很多情况下一秒对应的游戏刻会更少。 |
## 文件格式
1. 附加包格式`.mcpack`
使用附加包格式导出音乐则音乐会以指令函数文件`.mcfunction`存储于附加包内在附加包中函数文件的存储结构应为
- `functions\`
- `index.mcfunction`
- `mscply\`
- `progressShow.mcfunction`
- `track1.mcfunction`
- `track2.mcfunction`
- ...
- `trackN.mcfunction`
如图其中`index.mcfunction`文件和`mscply`文件夹存在于函数目录的根下`mscply`目录中包含音乐导出的众多音轨播放文件`trackX.mcfunction`同时若生成此包时选择了带有进度条的选项则会包含`progressShow.mcfunction`文件
`index.mcfunction`用于开始播放其中包含打开各个音轨对应函数的指令以及加分指令这里的加分是将**播放计分板的值大于等于`1`**的所有**玩家**的播放计分板分数增加`1`同时若生成此包时选择了自动重置计分板的选项则会包含一条重置计分板的指令
> 你知道吗·创的最早期版本我的世界函数音乐生成器正是用函数来播放不过这个版本采取的读入数据的形式大有不同
2. 结构格式
无论是音·创生成的是何种结构`MCSTRUCTURE`还是`BDX`都会依照此处的格式来生成此处我们想说明的结构的格式不是结构文件存储的格式而是结构导出之后方块将如何摆放的问题结构文件存储的格式这一点在各个我的世界开发的相关网站上都可能会有说明
考虑到进行我的世界游戏开发时为了节约常加载区域很多游戏会将指令区设立为一种层叠式的结构这种结构会限制每一层的指令系统的高度但是虽然长宽也是有限的却仍然比其纵轴延伸得更加自由
所以结构的生成形状依照给定的高度和内含指令的数量决定$Z$轴延伸长度为指令方块数量对于给定高度之商的向下取整结果的平方根的向下取整用数学公式的方式表达则是
$$MaxZ = \left\lfloor\sqrt{\left\lfloor{\frac{NoC}{MaxH}}\right\rfloor}\right\rfloor$$
其中$MaxZ$即生成结构的$Z$轴最大延伸长度$NoC$表示链结构中所含指令方块的个数$MaxH$表示给定的生成结构的最大高度
我们的结构生成器在生成指令链时将首先以相对坐标系$(0, 0, 0)$即相对原点开始自下向上堆叠高度轴$Y$的长当高度轴达到了限制的高度时便将$Z$轴向正方向堆叠`1`个方块并开始自上向下重新堆叠直至高度轴坐标达到相对为`0`若当所生成结构的$Z$轴长达到了其最大延伸长度则此结构生成器将反转$Z$轴的堆叠方向直至$Z$轴坐标相对为`0`如此往复直至指令链堆叠完成
## 播放器
以结构生成的文件可以采用多种方式播放一类播放方式我们称其为**播放器**例如**延迟播放器****计分板播放器**等等以后推出的新的播放器届时也会在此处更新
为什么要设计这么多播放器是为了适应不同的播放环境需要通常情况下一个音乐中含有多个音符音符与音符之间存在间隔这里就产生了不一样的实现音符间时间间隔的方式而不同的应用环境下又会产生不一样的要求接下来将对不同的播放器进行详细介绍
1. 计分板播放器
计分板播放器是一种传统的我的世界音乐播放方式通过对于计分板加分来实现播放不同的音符一个很简单的原理就是**用不同的计分板分值对应不同的音符**再通过加分来达到那个分值即播放出来
**·**用来达到这种效果的指令是这样的
```mcfunction
execute @a[scores={ScBd=x}] ~ ~ ~ playsound InstID @s ~ ~Ht ~ Vlct Ptc
```
|参数|说明|备注|
|--------|-----------|----------|
|`ScBd`|指定的计分板名称||
|`x`|音发出时对应的分数值||
|`InstID`|声音效果ID|不同的声音ID可以对应不同的乐器详见转换[乐器对照表](./%E8%BD%AC%E6%8D%A2%E4%B9%90%E5%99%A8%E5%AF%B9%E7%85%A7%E8%A1%A8.md)|
|`Ht`|播放点对玩家的距离|通过距离来表达声音的响度$S$表示此参数`Ht`以Vol表示音量百分比则计算公式为$S = \frac{1}{Vol}-1$|
|`Vlct`|原生我的世界中规定的播放力度|这个参数是一个谜一样的存在似乎它的值毫不重要因为无论这个值是多少我们听起来都差不多当此音符所在MIDI通道为第一通道则这个值为0.7倍MIDI指定力度其他则为0.9|
|`Ptc`|音符的音高|这是决定音调的参数$P$表示此参数$n$表示其在MIDI中的编号$x$表示一定的音域偏移则计算公式为$P = 2^\frac{n-60-x}{12}$|
后四个参数决定了这个音的性质而前两个参数仅仅是为了决定音播放的时间
2. 延迟播放器
延迟播放器是通过我的世界游戏中指令方块的设置项延迟刻数来达到定位音符的效果**将所有的音符依照其播放时距离乐曲开始时的时间毫秒放在一个序列内再计算音符两两之间对应的时间差值转换为我的世界内对应的游戏刻数之后填入指令方块的设置中**
在音·创中由于此方式播放的音乐不需要用计分板所以播放指令是这样的
```mcfunction
execute Tg ~ ~ ~ playsound InstID @s ~ ~Ht ~ Vlct Ptc
```
|参数|说明|备注|
|--------|-----------|----------|
|`Tg`|播放对象|选择器或玩家名|
|`InstID`|声音效果ID|不同的声音ID可以对应不同的乐器详见转换[乐器对照表](./%E8%BD%AC%E6%8D%A2%E4%B9%90%E5%99%A8%E5%AF%B9%E7%85%A7%E8%A1%A8.md)|
|`Ht`|播放点对玩家的距离|通过距离来表达声音的响度$S$表示此参数`Ht`以Vol表示音量百分比则计算公式为$S = \frac{1}{Vol}-1$|
|`Vlct`|原生我的世界中规定的播放力度|这个参数是一个谜一样的存在似乎它的值毫不重要因为无论这个值是多少我们听起来都差不多当此音符所在MIDI通道为第一通道则这个值为0.7倍MIDI指定力度其他则为0.9|
|`Ptc`|音符的音高|这是决定音调的参数$P$表示此参数$n$表示其在MIDI中的编号$x$表示一定的音域偏移则计算公式为$P = 2^\frac{n-60-x}{12}$|
其中后四个参数决定了这个音的性质
由于这样的延迟数据是依赖于指令方块的设置项所以使用这种播放器所转换出的结果仅可以存储在包含方块NBT信息及方块实体NBT信息的结构文件中或者直接输出至世界
# 进度条自定义
因为我们提供了可以自动转换进度条的功能因此在这里给出进度条自定义参数的详细解释
请注意并非所有的演示样例程序都支持自定义进度条
一个进度条明显地**固定部分****可变部分**来构成而可变部分又包括了文字和图形两种当然我的世界里头的进度条可变的图形也就是那个这一点你需要了解因为后文中包含了很多这方面的概念需要你了解
进度条的自定义功能使用一个字符串来定义自己的样式其中包含众多**标识符**来表示可变部分
标识符如下注意大小写
| 标识符 | 指定的可变量 |
|---------|----------------|
| `%%N` | 乐曲名(即传入的文件名)|
| `%%s` | 当前计分板值 |
| `%^s` | 计分板最大值 |
| `%%t` | 当前播放时间 |
| `%^t` | 曲目总时长 |
| `%%%` | 当前进度比率 |
| `_` | 用以表示进度条占位|
表示进度条占位的 `_` 是用来标识你的进度条的也就是可变部分的唯一的图形部分
**样式定义字符串**的样例如下这也是默认的进度条的样式
` %%N [ %%s/%^s %%% __________ %%t|%^t]`
这是单独一行的进度条当然你也可以制作多行的如果是一行的输出时所使用的指令便是 `title`而如果是多行的话输出就会用 `titleraw` 作为进度条字幕
哦对了上面的只不过是样式定义同时还需要定义的是可变图形的部分也就是进度条上那个真正的
对于这个我们就采用了固定参数的方法对于一个进度条无非就是已经播放过的没播放过的两种形态所以使用一个元组来传入这两个参数就是最简单的了元组的格式也很简单`(str: 播放过的部分长啥样, str: 没播放过的部分长啥样)` 例如我们默认的进度的定义是这样的
`('§e=§r', '§7=§r')`
综合起来把这些参数传给函数需要一个参数整合你猜用的啥啊对对对我用的还是元组
我们的默认定义参数如下
`(r'%%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
*对了为了避免生成错误请尽量避免使用标识符作为定义样式字符串的其他部分*

View File

@ -0,0 +1,48 @@
<h1 align="center">· Musicreater</h1>
<h2 align="center">库版 Package Version</h2>
<p align="center">
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
</p>
# 生成文件的使用
*由于先前的 **读我文件**(README.md) 过于冗杂现另辟蹊径来给大家全方位的教程*
*这是本库所生成文件的使用声明不是使用本库的教程若要查看**本库的演示程序**使用教程可点击[此处](%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. 若想要重置某实体的播放可以将其播放用的计分板重置

View File

@ -0,0 +1,2 @@
# 暂无

26
msctPkgver/__init__.py Normal file
View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""一个简单的我的世界音频转换库
· 库版 (Musicreater)
是一款免费开源的针对我的世界的midi音乐转换库
Musicreater(·)
A free open source library used for convert midi file into formats that is suitable for **Minecraft**.
版权所有 © 2023 · 开发者
Copyright © 2023 all the developers of Musicreater
开源相关声明请见 ../License.md
Terms & Conditions: ../License.md
"""
# 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from .main import *
__version__ = "0.2.3"
__all__ = []
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"))

73
msctPkgver/exceptions.py Normal file
View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
"""
· 库版 (Musicreater Package Version)
是一款免费开源的针对我的世界基岩版的midi音乐转换库
Musicreater pkgver (Package Version · 库版)
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
版权所有 © 2023 · 开发者
Copyright © 2023 all the developers of Musicreater
开源相关声明请见 ../License.md
Terms & Conditions: ../License.md
"""
class MSCTBaseException(Exception):
"""音·创库版本的所有错误均继承于此"""
def __init__(self, *args):
super().__init__(*args)
def miao(
self,
):
for i in self.args:
print(i + "喵!")
def crash_it(self):
raise self
class CrossNoteError(MSCTBaseException):
"""同通道下同音符交叉出现所产生的错误"""
pass
class NotDefineTempoError(MSCTBaseException):
"""没有Tempo设定导致时间无法计算的错误"""
pass
class MidiDestroyedError(MSCTBaseException):
"""Midi文件损坏"""
pass
class ChannelOverFlowError(MSCTBaseException):
"""一个midi中含有过多的通道数量应≤16"""
pass
class NotDefineProgramError(MSCTBaseException):
"""没有Program设定导致没有乐器可以选择的错误"""
pass
class ZeroSpeedError(MSCTBaseException):
"""以0作为播放速度的错误"""
pass

179
msctPkgver/instConstants.py Normal file
View File

@ -0,0 +1,179 @@
pitched_instrument_list = {
0: ("note.harp", 6),
1: ("note.harp", 6),
2: ("note.pling", 6),
3: ("note.harp", 6),
4: ("note.pling", 6),
5: ("note.pling", 6),
6: ("note.harp", 6),
7: ("note.harp", 6),
8: ("note.share", 7), # 打击乐器无音域
9: ("note.harp", 6),
10: ("note.didgeridoo", 8),
11: ("note.harp", 6),
12: ("note.xylophone", 4),
13: ("note.chime", 4),
14: ("note.harp", 6),
15: ("note.harp", 6),
16: ("note.bass", 8),
17: ("note.harp", 6),
18: ("note.harp", 6),
19: ("note.harp", 6),
20: ("note.harp", 6),
21: ("note.harp", 6),
22: ("note.harp", 6),
23: ("note.guitar", 7),
24: ("note.guitar", 7),
25: ("note.guitar", 7),
26: ("note.guitar", 7),
27: ("note.guitar", 7),
28: ("note.guitar", 7),
29: ("note.guitar", 7),
30: ("note.guitar", 7),
31: ("note.bass", 8),
32: ("note.bass", 8),
33: ("note.bass", 8),
34: ("note.bass", 8),
35: ("note.bass", 8),
36: ("note.bass", 8),
37: ("note.bass", 8),
38: ("note.bass", 8),
39: ("note.bass", 8),
40: ("note.harp", 6),
41: ("note.harp", 6),
42: ("note.harp", 6),
43: ("note.harp", 6),
44: ("note.iron_xylophone", 6),
45: ("note.guitar", 7),
46: ("note.harp", 6),
47: ("note.harp", 6),
48: ("note.guitar", 7),
49: ("note.guitar", 7),
50: ("note.bit", 6),
51: ("note.bit", 6),
52: ("note.harp", 6),
53: ("note.harp", 6),
54: ("note.bit", 6),
55: ("note.flute", 5),
56: ("note.flute", 5),
57: ("note.flute", 5),
58: ("note.flute", 5),
59: ("note.flute", 5),
60: ("note.flute", 5),
61: ("note.flute", 5),
62: ("note.flute", 5),
63: ("note.flute", 5),
64: ("note.bit", 6),
65: ("note.bit", 6),
66: ("note.bit", 6),
67: ("note.bit", 6),
68: ("note.flute", 5),
69: ("note.harp", 6),
70: ("note.harp", 6),
71: ("note.flute", 5),
72: ("note.flute", 5),
73: ("note.flute", 5),
74: ("note.harp", 6),
75: ("note.flute", 5),
76: ("note.harp", 6),
77: ("note.harp", 6),
78: ("note.harp", 6),
79: ("note.harp", 6),
80: ("note.bit", 6),
81: ("note.bit", 6),
82: ("note.bit", 6),
83: ("note.bit", 6),
84: ("note.bit", 6),
85: ("note.bit", 6),
86: ("note.bit", 6),
87: ("note.bit", 6),
88: ("note.bit", 6),
89: ("note.bit", 6),
90: ("note.bit", 6),
91: ("note.bit", 6),
92: ("note.bit", 6),
93: ("note.bit", 6),
94: ("note.bit", 6),
95: ("note.bit", 6),
96: ("note.bit", 6),
97: ("note.bit", 6),
98: ("note.bit", 6),
99: ("note.bit", 6),
100: ("note.bit", 6),
101: ("note.bit", 6),
102: ("note.bit", 6),
103: ("note.bit", 6),
104: ("note.harp", 6),
105: ("note.banjo", 6),
106: ("note.harp", 6),
107: ("note.harp", 6),
108: ("note.harp", 6),
109: ("note.harp", 6),
110: ("note.harp", 6),
111: ("note.guitar", 7),
112: ("note.harp", 6),
113: ("note.bell", 4),
114: ("note.harp", 6),
115: ("note.cow_bell", 5),
116: ("note.bd", 7), # 打击乐器无音域
117: ("note.bass", 8),
118: ("note.bit", 6),
119: ("note.bd", 7), # 打击乐器无音域
120: ("note.guitar", 7),
121: ("note.harp", 6),
122: ("note.harp", 6),
123: ("note.harp", 6),
124: ("note.harp", 6),
125: ("note.hat", 7), # 打击乐器无音域
126: ("note.bd", 7), # 打击乐器无音域
127: ("note.snare", 7), # 打击乐器无音域
}
percussion_instrument_list = {
34: ("note.bd", 7),
35: ("note.bd", 7),
36: ("note.hat", 7),
37: ("note.snare", 7),
38: ("note.snare", 7),
39: ("note.snare", 7),
40: ("note.hat", 7),
41: ("note.snare", 7),
42: ("note.hat", 7),
43: ("note.snare", 7),
44: ("note.snare", 7),
45: ("note.bell", 4),
46: ("note.snare", 7),
47: ("note.snare", 7),
48: ("note.bell", 4),
49: ("note.hat", 7),
50: ("note.bell", 4),
51: ("note.bell", 4),
52: ("note.bell", 4),
53: ("note.bell", 4),
54: ("note.bell", 4),
55: ("note.bell", 4),
56: ("note.snare", 7),
57: ("note.hat", 7),
58: ("note.chime", 4),
59: ("note.iron_xylophone", 6),
60: ("note.bd", 7),
61: ("note.bd", 7),
62: ("note.xylophone", 4),
63: ("note.xylophone", 4),
64: ("note.xylophone", 4),
65: ("note.hat", 7),
66: ("note.bell", 4),
67: ("note.bell", 4),
68: ("note.hat", 7),
69: ("note.hat", 7),
70: ("note.flute", 5),
71: ("note.flute", 5),
72: ("note.hat", 7),
73: ("note.hat", 7),
74: ("note.xylophone", 4),
75: ("note.hat", 7),
76: ("note.hat", 7),
77: ("note.xylophone", 4),
78: ("note.xylophone", 4),
79: ("note.bell", 4),
80: ("note.bell", 4), }

217
msctPkgver/magicmain.py Normal file
View File

@ -0,0 +1,217 @@
# -*- coding: utf-8 -*-
# 音·创 开发交流群 861684859
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可
"""
· 库版 (Musicreater Package Version)
是一款免费开源的针对我的世界基岩版的midi音乐转换库
注意除了此源文件以外任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
Musicreater pkgver (Package Version · 库版)
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
Note! Except for this source file, all the files in this repository and this project are licensed under Apache License 2.0
Copyright 2022 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an 'AS IS' BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
def _toCmdList_m1(
self,
scoreboardname: str = "mscplay",
volume: float = 1.0,
speed: float = 1.0) -> list:
"""
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表
:param scoreboardname: 我的世界的计分板名称
:param volume: 音量注意这里的音量范围为(0,1]如果超出将被处理为正确值其原理为在距离玩家 (1 / volume -1) 的地方播放音频
:param speed: 速度注意这里的速度指的是播放倍率其原理为在播放音频的时候每个音符的播放时间除以 speed
:return: tuple(命令列表, 命令个数, 计分板最大值)
"""
tracks = []
if volume > 1:
volume = 1
if volume <= 0:
volume = 0.001
commands = 0
maxscore = 0
for i, track in enumerate(self.midi.tracks):
ticks = 0
instrumentID = 0
singleTrack = []
for msg in track:
ticks += msg.time
# print(msg)
if msg.is_meta:
if msg.type == "set_tempo":
tempo = msg.tempo
else:
if msg.type == "program_change":
# print("TT")
instrumentID = msg.program
if msg.type == "note_on" and msg.velocity != 0:
nowscore = round(
(ticks * tempo)
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
)
maxscore = max(maxscore, nowscore)
soundID, _X = self.__Inst2soundID_withX(instrumentID)
singleTrack.append(
"execute @a[scores={" +
str(scoreboardname) +
"=" +
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)}")
commands += 1
if len(singleTrack) != 0:
tracks.append(singleTrack)
return [tracks, commands, maxscore]
# ============================
import mido
class NoteMessage:
def __init__(self, channel, pitch, velocity, startT, lastT, midi, now_bpm, change_bpm=None):
self.channel = channel
self.note = pitch
self.velocity = velocity
self.startTime = startT
self.lastTime = lastT
self.tempo = now_bpm # 这里要程序实现获取bpm可以参考我的程序
def mt2gt(mt, tpb_a, bpm_a):
return mt / tpb_a / bpm_a * 60
self.startTrueTime = mt2gt(self.startTime, midi.ticks_per_beat, self.tempo) # / 20
# delete_extra_zero(round_up())
if change_bpm is not None:
self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, change_bpm) # / 20
else:
self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, self.tempo) # / 20
# delete_extra_zero(round_up())
print((self.startTime * self.tempo) / (midi.ticks_per_beat * 50000))
def __str__(self):
return "noteMessage channel=" + str(self.channel) + " note=" + str(self.note) + " velocity=" + \
str(self.velocity) + " startTime=" + str(self.startTime) + " lastTime=" + str(self.lastTime) + \
" startTrueTime=" + str(self.startTrueTime) + " lastTrueTime=" + str(self.lastTrueTime)
def load(mid: mido.MidiFile):
type_ = [False, False, False] # note_off / note_on+0 / mixed
is_tempo = False
# 预检
for i, track in enumerate(mid.tracks):
for msg in track:
# print(msg)
if msg.is_meta is not True:
if msg.type == 'note_on' and msg.velocity == 0:
type_[1] = True
elif msg.type == "note_off":
type_[0] = True
if msg.is_meta is True and msg.type == "set_tempo":
is_tempo = True
if is_tempo is not True:
raise Exception("这个mid没有可供计算时间的tempo事件")
if type_[0] is True and type_[1] is True:
type_[2] = True
type_[1] = False
type_[0] = False
print(type_)
bpm = 0
recent_change_bpm = 0
is_change_bpm = False
# 实检
for i, track in enumerate(mid.tracks):
noteOn = []
trackS = []
ticks = 0
for msg in track:
print(msg)
ticks += msg.time
print(ticks)
if msg.is_meta is True and msg.type == "set_tempo":
recent_change_bpm = bpm
bpm = 60000000 / msg.tempo
is_change_bpm = True
if msg.type == 'note_on' and msg.velocity != 0:
noteOn.append([msg, msg.note, ticks])
if type_[1] is True:
if msg.type == 'note_on' and msg.velocity == 0:
for u in noteOn:
index = 0
if u[1] == msg.note:
lastMessage = u[0]
lastTick = u[2]
break
index += 1
print(lastTick)
if is_change_bpm and recent_change_bpm != 0:
trackS.append(NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
mid, recent_change_bpm, bpm))
is_change_bpm = False
else:
trackS.append(
NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
mid, bpm))
# print(noteOn)
# print(index)
try:
noteOn.pop(index)
except IndexError:
noteOn.pop(index - 1)
print(trackS)
for j in trackS:
print(j)
if __name__ == '__main__':
load(mido.MidiFile("test.mid"))

1434
msctPkgver/main.py Normal file

File diff suppressed because it is too large Load Diff

222
msctPkgver/utils.py Normal file
View File

@ -0,0 +1,222 @@
import math
import os
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 compress_zipfile(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 form_command_block_in_BDX_bytes(
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 bottem_side_length_of_smallest_square_bottom_box(total: int, maxHeight: int):
"""给定总方块数量和最大高度,返回所构成的图形外切正方形的边长
:param total: 总方块数量
:param maxHeight: 最大高度
:return: 外切正方形的边长 int"""
return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
def to_BDX_bytes(
commands: list,
max_height: int = 64,
):
"""
:param commands: 指令列表(指令, 延迟)
:param max_height: 生成结构最大高度
:return 成功与否成功返回(True,未经过压缩的源,结构占用大小)失败返回(False,str失败原因)
"""
_sideLength = bottem_side_length_of_smallest_square_bottom_box(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 += form_command_block_in_BDX_bytes(
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],
)

47
poem.txt Normal file
View File

@ -0,0 +1,47 @@
> 是谁把科技的领域布满政治的火药
>
> 是谁把纯净的蓝天染上暗淡的沉灰
>
> 中国人民无不热爱自己伟大的祖国
>
> 我们不会忘记屈辱历史留下的惨痛
>
> 我们希望世界和平
>
> 我们希望获得世界的尊重
>
> 愿世上再也没有战争
>
> 无论是热还是冷
>
> 无论是经济还是政治
>
> 让美妙的和平的优雅的音乐响彻世界
>
> ——金羿
> 2022 5 7
> Who has dropped political gunpowder into the technology
>
> Who has dyed clear blue sky into the dark grey
>
> All Chinese people love our great homeland
>
> We *WILL* remember the remain pain of the humiliating history
>
> We love the whole world but in peace
>
> We love everyone but under respect
>
> It is to be hoped that the war ends forever
>
> Whatever it is cold or hot
>
> Whatever it is economical or political
>
> Just let the wonderful music of peace surround the world
>
> ---- Eilles Wan
> 7/5 2022

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
Brotli==1.0.9
mido==1.2.10