mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-01-08 12:52:11 +00:00
Compare commits
78 Commits
beewarewin
...
v0.2.0.0-D
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
887394570b | ||
|
|
c62806d470 | ||
|
|
d21c26d632 | ||
|
|
26ec42a71d | ||
|
|
245e2fa1ec | ||
|
|
e70fc806be | ||
|
|
72a3715722 | ||
|
|
fd3d27d596 | ||
|
|
3d283bfded | ||
|
|
7d9b63b9fe | ||
|
|
82850a3d74 | ||
|
|
629cfa402b | ||
|
|
0818957f51 | ||
|
|
954a30f722 | ||
|
|
96e6bc2f7a | ||
|
|
ca0e56e771 | ||
|
|
8fe71dbe0d | ||
|
|
97f334789e | ||
|
|
d2a6ce2529 | ||
|
|
066e0b0cac | ||
|
|
052142ac08 | ||
|
|
59c481f6da | ||
|
|
53c17f0328 | ||
|
|
ed28fc4866 | ||
|
|
320114533d | ||
|
|
aa210ac678 | ||
|
|
c4dd7b1ce8 | ||
|
|
99509be48c | ||
|
|
073ae827ab | ||
|
|
58b312554d | ||
|
|
55eeddb108 | ||
|
|
9d4a75cd41 | ||
|
|
882ce96b90 | ||
|
|
9093a66639 | ||
|
|
b48a66115a | ||
|
|
db20a87ae9 | ||
|
|
69eebd25a9 | ||
|
|
89ef3bcb55 | ||
|
|
f08a2ff9be | ||
|
|
9f8694ef14 | ||
|
|
81272a1166 | ||
|
|
a83052bd5d | ||
|
|
2fcfdca0a0 | ||
|
|
bcaeb129a5 | ||
|
|
36b639f029 | ||
|
|
4b241dfc0b | ||
|
|
255cc84ef3 | ||
|
|
c04b622297 | ||
|
|
b6a63a794e | ||
|
|
7c0dd218b2 | ||
|
|
19bbb92cff | ||
|
|
26ee16f071 | ||
|
|
05eb0c05ec | ||
|
|
5d2e0582c3 | ||
|
|
d3e0f78d2c | ||
|
|
79a2dfb5b1 | ||
|
|
bf3367c7e4 | ||
|
|
c91f5cf2f9 | ||
|
|
d8ea747ef1 | ||
|
|
39148a6c76 | ||
|
|
0e3eb394ab | ||
|
|
f0dedabe1a | ||
|
|
dda78ab35f | ||
|
|
5b6ff5ee68 | ||
|
|
fcb1a25227 | ||
|
|
81eb8e5376 | ||
|
|
7e13b22d46 | ||
|
|
07e153f215 | ||
|
|
908f622433 | ||
|
|
5f7ca0859f | ||
|
|
32ae868c34 | ||
|
|
ce441e4905 | ||
|
|
3dc099af7e | ||
|
|
cf7e51595e | ||
|
|
737b2d5f07 | ||
|
|
143de0bb37 | ||
|
|
17f9fa7ffc | ||
|
|
1bc1c6485b |
66
.gitignore
vendored
66
.gitignore
vendored
@@ -1,66 +0,0 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# OSX useful to ignore
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# IntelliJ Idea family of suites
|
||||
.idea
|
||||
*.iml
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
## mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# Briefcase build directories
|
||||
iOS/
|
||||
macOS/
|
||||
windows/
|
||||
android/
|
||||
linux/
|
||||
django/
|
||||
BIN
AutoInstaller/MSCT Auto Installer.exe
Normal file
BIN
AutoInstaller/MSCT Auto Installer.exe
Normal file
Binary file not shown.
221
AutoInstaller/MSCT Auto Installer.py
Normal file
221
AutoInstaller/MSCT Auto Installer.py
Normal file
@@ -0,0 +1,221 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿("Eilles Wan")
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
音·创自动安装器 (Musicreater Auto Installer)
|
||||
对音·创的自动安装提供支持的独立软件
|
||||
Musicreater Auto Installer (音·创自动安装器)
|
||||
A software that used for installing Musicreater automatically
|
||||
|
||||
Copyright 2022 Team-Ryoun
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
from sys import platform
|
||||
from platform import architecture
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from os import system as srun
|
||||
from os import walk, rename, remove, path, chdir, listdir
|
||||
from shutil import rmtree, move
|
||||
|
||||
|
||||
if platform == "win32":
|
||||
|
||||
nowpath = __file__[: len(__file__) - __file__[len(__file__) :: -1].index('\\')]
|
||||
|
||||
if srun('python -V'):
|
||||
|
||||
print('\033[7m{}\033[0m'.format("正在下载python\nDownloading Python"))
|
||||
|
||||
try:
|
||||
urllib.request.urlretrieve(
|
||||
"https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"
|
||||
if architecture()[0] == "32bit"
|
||||
else "https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe",
|
||||
"./pythonInstaller.exe",
|
||||
)
|
||||
# urllib.request.urlretrieve("https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe","./pythonInstaller.exe")
|
||||
except Exception as E:
|
||||
input(str(E) + "\n自动下载失败,按下回车取消")
|
||||
exit()
|
||||
|
||||
print('正在安装python\nInstalling Python')
|
||||
|
||||
# open('install.bat','w').write(f'.\\pythonInstaller.exe /passive InstallAllUsers=0 TargetDir="{nowpath}python38" DefaultJustForMeTargetDir="{nowpath}python38" AssociateFiles=0 CompileAll=1 PrependPath=0 Shortcuts=0 Include_doc=0 Include_launcher=0 InstallLauncherAllUsers=0 Include_test=0 Include_tools=0')
|
||||
|
||||
srun(
|
||||
f'.\\pythonInstaller.exe /passive InstallAllUsers=1 AssociateFiles=1 CompileAll=1 PrependPath=1 Shortcuts=1 Include_doc=0 Include_exe=1 Include_pip=1 Include_lib=1 Include_tcltk=1 Include_launcher=1 InstallLauncherAllUsers=1 Include_test=0 Include_tools=0'
|
||||
)
|
||||
|
||||
remove('./pythonInstaller.exe')
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("正在下载pip安装工具\nDownloading get-pip tool"))
|
||||
|
||||
# try:
|
||||
# urllib.request.urlretrieve(
|
||||
# "https://bootstrap.pypa.io/get-pip.py", "./python38/get-pip.py"
|
||||
# )
|
||||
# except Exception as E:
|
||||
# input(str(E) + "\n自动下载失败,按下回车取消")
|
||||
# exit()
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("正在下载pip\nDownloading pip"))
|
||||
|
||||
# chdir('./python38')
|
||||
# srun(r'".\python.exe get-pip.py')
|
||||
|
||||
# print('\033[7m{}\033[0m'.format('正在安装pip\nInstalling pip'))
|
||||
|
||||
# for dire in listdir('./Lib/site-packages/'):
|
||||
# move('./Lib/site-packages/'+dire,'./'+dire)
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("完成!"))
|
||||
|
||||
# chdir('../')
|
||||
|
||||
try:
|
||||
choseurl = int(
|
||||
input(
|
||||
'\033[7m{}\033[0m'.format(
|
||||
"""请选择 音·创 下载源,默认为0
|
||||
Please choose a download source of Musicreater(default 0)
|
||||
[0] 私有服务器<暂无> | Private Server<Haven't been built>
|
||||
[1] Gitee
|
||||
[2] Github\n:"""
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as E:
|
||||
print('\033[7m{}\033[0m'.format(str(E) + "\n将使用默认源\nUsing default source"))
|
||||
choseurl = 0
|
||||
|
||||
myurl = ""
|
||||
Giteeurl = "https://gitee.com/EillesWan/Musicreater/repository/blazearchive/master.zip?Expires=1647771436&Signature=%2BkqLHwmvzScCd4cPQDP0LHLpqeZUxOrOv17QpRy%2FTzs%3D"
|
||||
Githuburl = (
|
||||
"https://codeload.github.com/EillesWan/Musicreater/zip/refs/heads/master"
|
||||
)
|
||||
|
||||
url = (
|
||||
myurl
|
||||
if choseurl == 0
|
||||
else Giteeurl
|
||||
if choseurl == 1
|
||||
else Githuburl
|
||||
if choseurl == 2
|
||||
else myurl
|
||||
)
|
||||
|
||||
print('\033[7m{}\033[0m'.format("正在下载音·创\nDownloading Musicreater"))
|
||||
|
||||
try:
|
||||
urllib.request.urlretrieve(url, "./master.zip")
|
||||
except Exception as E:
|
||||
input('\033[0{}\033[0m'.format(str(E) + "\n自动下载失败,按下回车取消"))
|
||||
exit()
|
||||
|
||||
print('\033[7m{}\033[0m'.format("安装音·创\nInstalling Musicreater"))
|
||||
|
||||
zipfile.ZipFile("./master.zip", "r").extractall()
|
||||
|
||||
remove("./master.zip")
|
||||
|
||||
try:
|
||||
rmtree("./Musicreater")
|
||||
except:
|
||||
pass
|
||||
|
||||
rename("./Musicreater-master/", "./Musicreater/")
|
||||
|
||||
elif platform == 'linux':
|
||||
srun("sudo apt-get install python3")
|
||||
srun("sudo apt-get install python3-pip")
|
||||
srun("sudo apt-get install git")
|
||||
try:
|
||||
choseurl = int(
|
||||
input(
|
||||
'\033[0{}\033[0m'.format(
|
||||
"""请选择 音·创 下载源,默认为1
|
||||
Please choose a download source of Musicreater(default 1)
|
||||
[1] Gitee
|
||||
[2] Github\n:"""
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as E:
|
||||
print(str(E) + "\n将使用默认源\nUsing default source")
|
||||
choseurl = 1
|
||||
|
||||
url = (
|
||||
"https://gitee.com/EillesWan/Musicreater.git"
|
||||
if choseurl == 1
|
||||
else "https://github.com/EillesWan/Musicreater.git"
|
||||
if choseurl == 2
|
||||
else "https://gitee.com/EillesWan/Musicreater.git"
|
||||
)
|
||||
srun(f"sudo git clone {url}")
|
||||
|
||||
|
||||
print('\033[7m{}\033[0m'.format("编译音·创\nCompiling Musicreater"))
|
||||
|
||||
if platform == "linux":
|
||||
srun("python3 -O -m compileall -b ./Musicreater/")
|
||||
elif platform == "win32":
|
||||
srun("python -O -m compileall -b ./Musicreater/")
|
||||
|
||||
for parent, dirnames, filenames in walk("./Musicreater"):
|
||||
for filename in filenames:
|
||||
if filename[-3:] == ".py":
|
||||
fn = path.join(parent, filename)
|
||||
remove(fn)
|
||||
print(f"删除文件 {fn}")
|
||||
for dirname in dirnames:
|
||||
if dirname == "__pycache__":
|
||||
pn = path.join(parent, dirname)
|
||||
rmtree(pn)
|
||||
print(f"删除目录 {pn}")
|
||||
|
||||
|
||||
print(
|
||||
'\033[7m{}\033[0m'.format(
|
||||
"""您可以开始使用音·创了
|
||||
我们将在后台为您安装各项支持库
|
||||
您可以运行Musicreater文件夹中的Musicreater.pyc文件来运行音·创
|
||||
|
||||
You can use Musicreater now,
|
||||
We will setup the libraries ineed for you in background,
|
||||
You can now open Musicreater.PYC in the directory of ./Musicreater to run Musicreater
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if platform == "linux":
|
||||
srun("python3 ./Musicreater/补全库.pyc")
|
||||
elif platform == "win32":
|
||||
srun("python ./Musicreater/补全库.pyc")
|
||||
13
LICENSE
13
LICENSE
@@ -175,18 +175,8 @@
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -199,3 +189,4 @@
|
||||
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.
|
||||
|
||||
|
||||
69
Musicreater.New.py
Normal file
69
Musicreater.New.py
Normal file
@@ -0,0 +1,69 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
音·创 (Musicreater)
|
||||
一款免费开源的 《我的世界:基岩版》 音乐制作软件
|
||||
Musicreater (音·创)
|
||||
A free opensource software which is used for creating all kinds of musics in Minecraft
|
||||
|
||||
Copyright 2022 Team-Ryoun
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
|
||||
from msctspt.bugReporter import version
|
||||
|
||||
__ver__ = f'{version.version[1]} {version.version[0]}'
|
||||
__author__ = '金羿Eilles'
|
||||
|
||||
from msctLib.display import *
|
||||
|
||||
from msctLib.function import *
|
||||
|
||||
from msctLib.data import uniteIO
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __main__():
|
||||
|
||||
disp()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__()
|
||||
1997
Musicreater.py
Normal file
1997
Musicreater.py
Normal file
File diff suppressed because it is too large
Load Diff
102
README.md
102
README.md
@@ -1,49 +1,115 @@
|
||||
# 音·创 Musicreater
|
||||
|
||||
[](https://choosealicense.com/licenses/apache-2.0/)
|
||||
[](https://space.bilibili.com/397369002/)
|
||||
[](https://space.bilibili.com/604072474)
|
||||
[](https://github.com/psf/black)
|
||||
|
||||
|
||||
|
||||
### 介绍
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
|
||||
音·创 Musicreater 是由凌天之云创新应用软件开发团队开发的一款免费开源的 **《我的世界:基岩版》** 音乐制作软件
|
||||
|
||||
欢迎加群:861684859
|
||||
|
||||
### 作者
|
||||
|
||||
金羿 Eilles:我的世界基岩版指令师,个人开发者,B站不知名UP主,在校高中生。
|
||||
|
||||
诸葛亮与八卦阵 bgArray:我的世界基岩版玩家,喜欢编程和音乐,深圳初一学生。
|
||||
|
||||
### 软件架构
|
||||
|
||||
软件采用Python作为第一语言,目前还没有使用其他语言辅助。使用BeeWare作为图形库兼容安卓。
|
||||
软件采用 *Python* 作为第一语言,目前还没有使用其他语言辅助。使用 *Tkinter* 为图形库。
|
||||
|
||||
尽量全平台支持
|
||||
支持 Windows7+ 以及各个支持 Python3.8 的 Linux
|
||||
|
||||
***各位开发人员注意!!!多语言支持请使用函数`_`加载文字!!!如需补充,请在简体中文的语言文件(zh-CN.lang)中补充!!!***
|
||||
|
||||
|
||||
### 安装教程
|
||||
|
||||
#### Windows
|
||||
下载音·创自动安装器,将其放在你希望安装音·创的位置,运行后将自动安装。
|
||||
|
||||
即将到来。
|
||||
提示:下载源最好选择2GitHub。
|
||||
|
||||
### 从源代码运行教程
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
#### Android
|
||||
|
||||
即将到来。
|
||||
|
||||
### 使用说明
|
||||
|
||||
1. 直接运行就好
|
||||
2. 有不懂的问题来群里问
|
||||
3. 请理解英文表述
|
||||
2. 看得懂简体中文字的不一定全会用
|
||||
3. 最好要懂一点点英文
|
||||
|
||||
|
||||
### 诸葛亮与八卦阵的说明(不必要)
|
||||
|
||||
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导入音轨且用新方法解析,
|
||||
然后再使用 *音创*->函数(包)->下面的四个新函数
|
||||
|
||||
### 致谢
|
||||
|
||||
1. 感谢由 [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”等 带来的我的世界websocket服务器功能
|
||||
2. 感谢 昀梦<QQ1515399885> 找出指令生成错误bug并指正
|
||||
2. 感谢 昀梦\<QQ1515399885\> 找出指令生成错误bug并指正
|
||||
3. 感谢由 Charlie_Ping “查理平” 带来的bdx转换功能
|
||||
4. 感谢由 CMA_2401PT 提供的 BDXWorkShop作为.bdx结构的操作指导
|
||||
5. 感谢广大群友为此程序提供的测试等支持
|
||||
6. 若您为我找出了错误但您的名字没有显示在此列表中,请联系我!
|
||||
4. 感谢由 CMA_2401PT 带来的 BDXWorkShop 供本程序对于bdx操作的指导
|
||||
5. 感谢由 Miracle Plume “神羽” \<QQshenyu40403\>带来的羽音缭绕基岩版音色资源包
|
||||
6. 感谢 Arthur Morgan 对本程序的排错提出了最大的支持
|
||||
7. 感谢广大群友为此程序提供的测试等支持
|
||||
8. 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
|
||||
|
||||
|
||||
### 作者<金羿>联系方式
|
||||
### 作者\<*金羿*\>(W-YI)联系方式
|
||||
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray) 联系方式
|
||||
|
||||
1. QQ 4740437765
|
||||
12
README.rst
12
README.rst
@@ -1,12 +0,0 @@
|
||||
Musicreater
|
||||
===========
|
||||
|
||||
**This cross-platform app was generated by** `Briefcase`_ **- part of**
|
||||
`The BeeWare Project`_. **If you want to see more tools like Briefcase, please
|
||||
consider** `becoming a financial member of BeeWare`_.
|
||||
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
|
||||
.. _`Briefcase`: https://github.com/beeware/briefcase
|
||||
.. _`The BeeWare Project`: https://beeware.org/
|
||||
.. _`becoming a financial member of BeeWare`: https://beeware.org/contributing/membership
|
||||
166
README_en.md
166
README_en.md
@@ -1,52 +1,114 @@
|
||||
# Musicreater
|
||||
|
||||
### Introduction
|
||||
Musicreater(音·创) is an Eilles(*W-YI*)'s app that is used for creating musics in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Welcome to join our QQ group: 861684859
|
||||
|
||||
### Framework
|
||||
|
||||
Use *Python* to develop, use *BeeWare* as a Windows Library.
|
||||
|
||||
We are trying to support every platform.
|
||||
|
||||
|
||||
### Tutorials
|
||||
|
||||
#### Windows
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
#### Linux
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
#### Android
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
### Instructions
|
||||
|
||||
1. Just make u understand the Chinese
|
||||
2. If u dont understand, u can come to the QQ group or email me to ask questions
|
||||
3. The English Edition is comming soon.
|
||||
|
||||
### Thanks
|
||||
|
||||
1. Thank [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”and so on for the function of Creating the Websocket Server for Minecraft: Bedrock Edition.
|
||||
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. Thanks for a lot of groupmates who support me and help me to test the program.
|
||||
6. If u have give me some help but u haven't been in the list, please contact me.
|
||||
|
||||
|
||||
### Contact *Eilles(W-YI)*(金羿)
|
||||
|
||||
1. QQ 2647547478
|
||||
2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. WeChat WYI_DoctorYI
|
||||
# Musicreater
|
||||
|
||||
[](https://choosealicense.com/licenses/apache-2.0/)
|
||||
[](https://space.bilibili.com/397369002/)
|
||||
[](https://space.bilibili.com/604072474)
|
||||
[](https://github.com/psf/black)
|
||||
|
||||
### Introduction
|
||||
|
||||
Musicreater(音·创) is an Eilles(*W-YI*)'s app that is used for creating musics in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Welcome to join our QQ group: 861684859
|
||||
|
||||
### Author
|
||||
|
||||
Eilles (金羿):The main author, who developed the most and especially the principal parts of Musicreater, and its predecessors, which has been called as "*Minecraft Function Music Maker*", "*Note Fun Creater*", "*Note World Creater*"(now ,they are united as ***Musicreater***!)
|
||||
|
||||
bgArray "诸葛亮与八卦阵": Fix bugs, improve code aesthetics, add new functions, change data format, etc.
|
||||
|
||||
### Framework
|
||||
|
||||
Using *Python* to develop, using Tkinter as a graphics library.
|
||||
|
||||
Support Windows7+ && Linux (that supports Python3.8)
|
||||
|
||||
***ATTENTION TO DEVELOPERS!!! TO SUPPORT DIFFERENT LANGUAGES, PLEASE USE CONSTANT `READABLETEXT` TO OUTPUT!!! IF YOU NEED TO SUPPLEMENT, PLEASE ADD THEM IN SIMPLEFIED CHINESE\'S LANGUAGE FILE(zhCN.py), WHEATHER WHAT LANGUAGE YOU USE!!!***
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
Download the *[MSCT Auto Installer]()*, 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*
|
||||
|
||||
Tips: You'd better choose the 2GitHub download source
|
||||
|
||||
### Run with Source Code
|
||||
|
||||
#### Windows
|
||||
|
||||
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 installation,double 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
|
||||
|
||||
1. Just make u understand the Chinese
|
||||
2. If u dont understand, u can come to the QQ group or email me to ask questions
|
||||
3. The English Edition is comming soon.
|
||||
|
||||
|
||||
### Explanation of 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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
### Contact *Eilles(W-YI)*(金羿)
|
||||
|
||||
1. QQ 2647547478
|
||||
2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. WeChat WYI_DoctorYI
|
||||
|
||||
### Contact *bgArray*(诸葛亮与八卦阵)
|
||||
|
||||
1. QQ 4740437765
|
||||
@@ -1 +0,0 @@
|
||||
briefcase dev
|
||||
@@ -1,60 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os,shutil
|
||||
from sys import platform
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print("更新执行位置...")
|
||||
if platform == 'win32':
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')]+'src\\')
|
||||
print("更新执行位置,当前文件位置"+__file__)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('/')]+'src/')
|
||||
except:
|
||||
pass
|
||||
print("其他平台:"+platform+"更新执行位置,当前文件位置"+__file__)
|
||||
print('完成!')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import toga,amulet
|
||||
except:
|
||||
print("You'd better install the libraries of this app\nNow, we're helping you with this.")
|
||||
from src.musicreater.msctspt.bugReporter import version
|
||||
version.installLibraries(version)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if platform == 'win32':
|
||||
os.system("python ./Musicreater.py")
|
||||
elif platform == 'linux':
|
||||
os.system("python3 ./Musicreater.py")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
if os.path.exists("./log/"):
|
||||
shutil.rmtree("./log/")
|
||||
if os.path.exists("./logs/"):
|
||||
shutil.rmtree("./logs/")
|
||||
if os.path.exists("./cache/"):
|
||||
shutil.rmtree("./cache/")
|
||||
except:
|
||||
print("无法清除日志及临时文件")
|
||||
BIN
bgArrayLib/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/bpm.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/bpm.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/bpm.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/bpm.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/compute.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/compute.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/compute.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/compute.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/namesConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/namesConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/reader.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/reader.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/reader.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/reader.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc
Normal file
Binary file not shown.
67
bgArrayLib/bpm.py
Normal file
67
bgArrayLib/bpm.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import mido
|
||||
import numpy
|
||||
|
||||
'''
|
||||
bpm
|
||||
bites per minutes
|
||||
每分钟的拍数
|
||||
'''
|
||||
|
||||
def mt2gt(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60)
|
||||
|
||||
|
||||
def get(mid:mido.MidiFile) -> int:
|
||||
'''传入一个 MidiFile, 返回其音乐的bpm
|
||||
:param mid : mido.MidFile
|
||||
mido库识别的midi文件数据
|
||||
:return bpm : int
|
||||
'''
|
||||
# mid = mido.MidiFile(mf)
|
||||
long = mid.length
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = 20
|
||||
gotV = 0
|
||||
|
||||
for track in mid.tracks:
|
||||
global_time = 0
|
||||
for msg in track:
|
||||
global_time += msg.time
|
||||
if msg.type == "note_on" and msg.velocity > 0:
|
||||
gotV = mt2gt(global_time, tpb, bpm)
|
||||
errorV = numpy.fabs(gotV - long)
|
||||
last_dic = {bpm: errorV}
|
||||
if last_dic.get(bpm) > errorV:
|
||||
last_dic = {bpm: errorV}
|
||||
bpm += 2
|
||||
|
||||
while True:
|
||||
for track in mid.tracks:
|
||||
global_time = 0
|
||||
for msg in track:
|
||||
global_time += msg.time
|
||||
if msg.type == "note_on" and msg.velocity > 0:
|
||||
gotV = mt2gt(global_time, tpb, bpm)
|
||||
errorV = numpy.fabs(gotV - long)
|
||||
try:
|
||||
if last_dic.get(bpm - 2) > errorV:
|
||||
last_dic = {bpm: errorV}
|
||||
except TypeError:
|
||||
pass
|
||||
bpm += 2
|
||||
if bpm >= 252:
|
||||
break
|
||||
print(list(last_dic.keys())[0])
|
||||
return list(last_dic.keys())[0]
|
||||
|
||||
|
||||
def compute(mid:mido.MidiFile):
|
||||
answer = 60000000/mid.ticks_per_beat
|
||||
print(answer)
|
||||
return answer
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mid = mido.MidiFile(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\Bad style - Time back.mid")
|
||||
get(mid)
|
||||
compute(mid)
|
||||
40
bgArrayLib/compute.py
Normal file
40
bgArrayLib/compute.py
Normal file
@@ -0,0 +1,40 @@
|
||||
def round_up(num, power=0):
|
||||
"""
|
||||
实现精确四舍五入,包含正、负小数多种场景
|
||||
:param num: 需要四舍五入的小数
|
||||
:param power: 四舍五入位数,支持0-∞
|
||||
:return: 返回四舍五入后的结果
|
||||
"""
|
||||
try:
|
||||
print(1 / 0)
|
||||
except ZeroDivisionError:
|
||||
digit = 10 ** power
|
||||
num2 = float(int(num * digit))
|
||||
# 处理正数,power不为0的情况
|
||||
if num >= 0 and power != 0:
|
||||
tag = num * digit - num2 + 1 / (digit * 10)
|
||||
if tag >= 0.5:
|
||||
return (num2 + 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理正数,power为0取整的情况
|
||||
elif num >= 0 and power == 0:
|
||||
tag = num * digit - int(num)
|
||||
if tag >= 0.5:
|
||||
return (num2 + 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理负数,power为0取整的情况
|
||||
elif power == 0 and num < 0:
|
||||
tag = num * digit - int(num)
|
||||
if tag <= -0.5:
|
||||
return (num2 - 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理负数,power不为0的情况
|
||||
else:
|
||||
tag = num * digit - num2 - 1 / (digit * 10)
|
||||
if tag <= -0.5:
|
||||
return (num2 - 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
24
bgArrayLib/instrumentConstant.py
Normal file
24
bgArrayLib/instrumentConstant.py
Normal file
@@ -0,0 +1,24 @@
|
||||
instrument_list = {'0': 'harp', '1': 'harp', '2': 'pling', '3': 'harp', '4': 'pling', '5': 'pling', '6': 'harp',
|
||||
'7': 'harp',
|
||||
'8': 'share', '9': 'harp', '10': 'didgeridoo', '11': 'harp', '12': 'xylophone', '13': 'chime',
|
||||
'14': 'harp', '15': 'harp', '16': 'bass', '17': 'harp', '18': 'harp', '19': 'harp', '20': 'harp',
|
||||
'21': 'harp', '22': 'harp', '23': 'guitar', '24': 'guitar', '25': 'guitar', '26': 'guitar',
|
||||
'27': 'guitar', '28': 'guitar', '29': 'guitar', '30': 'guitar', '31': 'bass', '32': 'bass',
|
||||
'33': 'bass',
|
||||
'34': 'bass', '35': 'bass', '36': 'bass', '37': 'bass', '38': 'bass', '39': 'bass', '40': 'harp',
|
||||
'41': 'harp', '42': 'harp', '43': 'harp', '44': 'iron_xylophone', '45': 'guitar', '46': 'harp',
|
||||
'47': 'harp', '48': 'guitar', '49': 'guitar', '50': 'bit', '51': 'bit', '52': 'harp', '53': 'harp',
|
||||
'54': 'bit', '55': 'flute', '56': 'flute', '57': 'flute', '58': 'flute', '59': 'flute',
|
||||
'60': 'flute',
|
||||
'61': 'flute', '62': 'flute', '63': 'flute', '64': 'bit', '65': 'bit', '66': 'bit', '67': 'bit',
|
||||
'68': 'flute', '69': 'harp', '70': 'harp', '71': 'flute', '72': 'flute', '73': 'flute', '74': 'harp',
|
||||
'75': 'flute', '76': 'harp', '77': 'harp', '78': 'harp', '79': 'harp', '80': 'bit', '81': 'bit',
|
||||
'82': 'bit', '83': 'bit', '84': 'bit', '85': 'bit', '86': 'bit', '87': 'bit', '88': 'bit',
|
||||
'89': 'bit',
|
||||
'90': 'bit', '91': 'bit', '92': 'bit', '93': 'bit', '94': 'bit', '95': 'bit', '96': 'bit',
|
||||
'97': 'bit',
|
||||
'98': 'bit', '99': 'bit', '100': 'bit', '101': 'bit', '102': 'bit', '103': 'bit', '104': 'harp',
|
||||
'105': 'banjo', '106': 'harp', '107': 'harp', '108': 'harp', '109': 'harp', '110': 'harp',
|
||||
'111': 'guitar', '112': 'harp', '113': 'bell', '114': 'harp', '115': 'cow_bell', '116': 'basedrum',
|
||||
'117': 'bass', '118': 'bit', '119': 'basedrum', '120': 'guitar', '121': 'harp', '122': 'harp',
|
||||
'123': 'harp', '124': 'harp', '125': 'hat', '126': 'basedrum', '127': 'snare'}
|
||||
92
bgArrayLib/namesConstant.py
Normal file
92
bgArrayLib/namesConstant.py
Normal file
@@ -0,0 +1,92 @@
|
||||
zip_name = {-1: '-1.Acoustic_Kit_打击乐.zip', 0: '0.Acoustic_Grand_Piano_大钢琴.zip', 1: '1.Bright_Acoustic_Piano_亮音大钢琴.zip',
|
||||
10: '10.Music_Box_八音盒.zip', 100: '100.FX_brightness_合成特效-亮音.zip', 101: '101.FX_goblins_合成特效-小妖.zip',
|
||||
102: '102.FX_echoes_合成特效-回声.zip', 103: '103.FX_sci-fi_合成特效-科幻.zip', 104: '104.Sitar_锡塔尔.zip',
|
||||
105: '105.Banjo_班卓.zip', 106: '106.Shamisen_三味线.zip', 107: '107.Koto_筝.zip', 108: '108.Kalimba_卡林巴.zip',
|
||||
109: '109.Bagpipe_风笛.zip', 11: '11.Vibraphone_电颤琴.zip', 110: '110.Fiddle_古提琴.zip', 111: '111.Shanai_唢呐.zip',
|
||||
112: '112.Tinkle_Bell_铃铛.zip', 113: '113.Agogo_拉丁打铃.zip', 114: '114.Steel_Drums_钢鼓.zip',
|
||||
115: '115.Woodblock_木块.zip', 116: '116.Taiko_Drum_太鼓.zip', 117: '117.Melodic_Tom_嗵鼓.zip',
|
||||
118: '118.Synth_Drum_合成鼓.zip', 119: '119.Reverse_Cymbal_镲波形反转.zip', 12: '12.Marimba_马林巴.zip',
|
||||
13: '13.Xylophone_木琴.zip', 14: '14.Tubular_Bells_管钟.zip', 15: '15.Dulcimer_扬琴.zip',
|
||||
16: '16.Drawbar_Organ_击杆风琴.zip', 17: '17.Percussive_Organ_打击型风琴.zip', 18: '18.Rock_Organ_摇滚风琴.zip',
|
||||
19: '19.Church_Organ_管风琴.zip', 2: '2.Electric_Grand_Piano_电子大钢琴.zip', 20: '20.Reed_Organ_簧风琴.zip',
|
||||
21: '21.Accordion_手风琴.zip', 22: '22.Harmonica_口琴.zip', 23: '23.Tango_Accordian_探戈手风琴.zip',
|
||||
24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.zip', 25: '25.Acoustic_Guitar(steel)_钢弦吉他.zip',
|
||||
26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.zip', 27: '27.Electric_Guitar_(clean)_清音电吉他.zip',
|
||||
28: '28.Electric_Guitar_(muted)_弱音电吉他.zip', 29: '29.Overdriven_Guitar_驱动音效吉他.zip',
|
||||
3: '3.Honky-Tonk_Piano_酒吧钢琴.zip', 30: '30.Distortion_Guitar_失真音效吉他.zip', 31: '31.Guitar_Harmonics_吉他泛音.zip',
|
||||
32: '32.Acoustic_Bass_原声贝司.zip', 33: '33.Electric_Bass(finger)_指拨电贝司.zip',
|
||||
34: '34.Electric_Bass(pick)_拨片拨电贝司.zip', 35: '35.Fretless_Bass_无品贝司.zip', 36: '36.Slap_Bass_A_击弦贝司A.zip',
|
||||
37: '37.Slap_Bass_B_击弦贝司B.zip', 38: '38.Synth_Bass_A_合成贝司A.zip', 39: '39.Synth_Bass_B_合成贝司B.zip',
|
||||
4: '4.Electric_Piano_1_电钢琴A.zip', 40: '40.Violin_小提琴.zip', 41: '41.Viola_中提琴.zip', 42: '42.Cello_大提琴.zip',
|
||||
43: '43.Contrabass_低音提琴.zip', 44: '44.Tremolo_Strings_弦乐震音.zip', 45: '45.Pizzicato_Strings_弦乐拨奏.zip',
|
||||
46: '46.Orchestral_Harp_竖琴.zip', 47: '47.Timpani_定音鼓.zip', 48: '48.String_Ensemble_A_弦乐合奏A.zip',
|
||||
49: '49.String_Ensemble_B_弦乐合奏B.zip', 5: '5.Electric_Piano_2_电钢琴B.zip', 50: '50.SynthStrings_A_合成弦乐A.zip',
|
||||
51: '51.SynthStrings_B_合成弦乐B.zip', 52: '52.Choir_Aahs_合唱“啊”音.zip', 53: '53.Voice_Oohs_人声“哦”音.zip',
|
||||
54: '54.Synth_Voice_合成人声.zip', 55: '55.Orchestra_Hit_乐队打击乐.zip', 56: '56.Trumpet_小号.zip',
|
||||
57: '57.Trombone_长号.zip', 58: '58.Tuba_大号.zip', 59: '59.Muted_Trumpet_弱音小号.zip',
|
||||
6: '6.Harpsichord_拨弦古钢琴.zip', 60: '60.French_Horn_圆号.zip', 61: '61.Brass_Section_铜管组.zip',
|
||||
62: '62.Synth_Brass_A_合成铜管A.zip', 63: '63.Synth_Brass_A_合成铜管B.zip', 64: '64.Soprano_Sax_高音萨克斯.zip',
|
||||
65: '65.Alto_Sax_中音萨克斯.zip', 66: '66.Tenor_Sax_次中音萨克斯.zip', 67: '67.Baritone_Sax_上低音萨克斯.zip',
|
||||
68: '68.Oboe_双簧管.zip', 69: '69.English_Horn_英国管.zip', 7: '7.Clavinet_击弦古钢琴.zip', 70: '70.Bassoon_大管.zip',
|
||||
71: '71.Clarinet_单簧管.zip', 72: '72.Piccolo_短笛.zip', 73: '73.Flute_长笛.zip', 74: '74.Recorder_竖笛.zip',
|
||||
75: '75.Pan_Flute_排笛.zip', 76: '76.Bottle_Blow_吹瓶口.zip', 77: '77.Skakuhachi_尺八.zip', 78: '78.Whistle_哨.zip',
|
||||
79: '79.Ocarina_洋埙.zip', 8: '8.Celesta_钢片琴.zip', 80: '80.Lead_square_合成主音-方波.zip',
|
||||
81: '81.Lead_sawtooth_合成主音-锯齿波.zip', 82: '82.Lead_calliope_lead_合成主音-汽笛风琴.zip',
|
||||
83: '83.Lead_chiff_lead_合成主音-吹管.zip', 84: '84.Lead_charang_合成主音5-吉他.zip', 85: '85.Lead_voice_合成主音-人声.zip',
|
||||
86: '86.Lead_fifths_合成主音-五度.zip', 87: '87.Lead_bass+lead_合成主音-低音加主音.zip', 88: '88.Pad_new_age_合成柔音-新时代.zip',
|
||||
89: '89.Pad_warm_合成柔音-暖音.zip', 9: '9.Glockenspiel_钟琴.zip', 90: '90.Pad_polysynth_合成柔音-复合成.zip',
|
||||
91: '91.Pad_choir_合成柔音-合唱.zip', 92: '92.Pad_bowed_合成柔音-弓弦.zip', 93: '93.Pad_metallic_合成柔音-金属.zip',
|
||||
94: '94.Pad_halo_合成柔音-光环.zip', 95: '95.Pad_sweep_合成柔音-扫弦.zip', 96: '96.FX_rain_合成特效-雨.zip',
|
||||
97: '97.FX_soundtrack_合成特效-音轨.zip', 98: '98.FX_crystal_合成特效-水晶.zip', 99: '99.FX_atmosphere_合成特效-大气.zip'}
|
||||
|
||||
mcpack_name = {-1: '-1.Acoustic_Kit_打击乐.mcpack', 0: '0.Acoustic_Grand_Piano_大钢琴.mcpack',
|
||||
1: '1.Bright_Acoustic_Piano_亮音大钢琴.mcpack', 10: '10.Music_Box_八音盒.mcpack',
|
||||
100: '100.FX_brightness_合成特效-亮音.mcpack', 101: '101.FX_goblins_合成特效-小妖.mcpack',
|
||||
102: '102.FX_echoes_合成特效-回声.mcpack', 103: '103.FX_sci-fi_合成特效-科幻.mcpack', 104: '104.Sitar_锡塔尔.mcpack',
|
||||
105: '105.Banjo_班卓.mcpack', 106: '106.Shamisen_三味线.mcpack', 107: '107.Koto_筝.mcpack',
|
||||
108: '108.Kalimba_卡林巴.mcpack', 109: '109.Bagpipe_风笛.mcpack', 11: '11.Vibraphone_电颤琴.mcpack',
|
||||
110: '110.Fiddle_古提琴.mcpack', 111: '111.Shanai_唢呐.mcpack', 112: '112.Tinkle_Bell_铃铛.mcpack',
|
||||
113: '113.Agogo_拉丁打铃.mcpack', 114: '114.Steel_Drums_钢鼓.mcpack', 115: '115.Woodblock_木块.mcpack',
|
||||
116: '116.Taiko_Drum_太鼓.mcpack', 117: '117.Melodic_Tom_嗵鼓.mcpack', 118: '118.Synth_Drum_合成鼓.mcpack',
|
||||
119: '119.Reverse_Cymbal_镲波形反转.mcpack', 12: '12.Marimba_马林巴.mcpack', 13: '13.Xylophone_木琴.mcpack',
|
||||
14: '14.Tubular_Bells_管钟.mcpack', 15: '15.Dulcimer_扬琴.mcpack', 16: '16.Drawbar_Organ_击杆风琴.mcpack',
|
||||
17: '17.Percussive_Organ_打击型风琴.mcpack', 18: '18.Rock_Organ_摇滚风琴.mcpack',
|
||||
19: '19.Church_Organ_管风琴.mcpack', 2: '2.Electric_Grand_Piano_电子大钢琴.mcpack',
|
||||
20: '20.Reed_Organ_簧风琴.mcpack', 21: '21.Accordion_手风琴.mcpack', 22: '22.Harmonica_口琴.mcpack',
|
||||
23: '23.Tango_Accordian_探戈手风琴.mcpack', 24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.mcpack',
|
||||
25: '25.Acoustic_Guitar(steel)_钢弦吉他.mcpack', 26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.mcpack',
|
||||
27: '27.Electric_Guitar_(clean)_清音电吉他.mcpack', 28: '28.Electric_Guitar_(muted)_弱音电吉他.mcpack',
|
||||
29: '29.Overdriven_Guitar_驱动音效吉他.mcpack', 3: '3.Honky-Tonk_Piano_酒吧钢琴.mcpack',
|
||||
30: '30.Distortion_Guitar_失真音效吉他.mcpack', 31: '31.Guitar_Harmonics_吉他泛音.mcpack',
|
||||
32: '32.Acoustic_Bass_原声贝司.mcpack', 33: '33.Electric_Bass(finger)_指拨电贝司.mcpack',
|
||||
34: '34.Electric_Bass(pick)_拨片拨电贝司.mcpack', 35: '35.Fretless_Bass_无品贝司.mcpack',
|
||||
36: '36.Slap_Bass_A_击弦贝司A.mcpack', 37: '37.Slap_Bass_B_击弦贝司B.mcpack', 38: '38.Synth_Bass_A_合成贝司A.mcpack',
|
||||
39: '39.Synth_Bass_B_合成贝司B.mcpack', 4: '4.Electric_Piano_1_电钢琴A.mcpack', 40: '40.Violin_小提琴.mcpack',
|
||||
41: '41.Viola_中提琴.mcpack', 42: '42.Cello_大提琴.mcpack', 43: '43.Contrabass_低音提琴.mcpack',
|
||||
44: '44.Tremolo_Strings_弦乐震音.mcpack', 45: '45.Pizzicato_Strings_弦乐拨奏.mcpack',
|
||||
46: '46.Orchestral_Harp_竖琴.mcpack', 47: '47.Timpani_定音鼓.mcpack', 48: '48.String_Ensemble_A_弦乐合奏A.mcpack',
|
||||
49: '49.String_Ensemble_B_弦乐合奏B.mcpack', 5: '5.Electric_Piano_2_电钢琴B.mcpack',
|
||||
50: '50.SynthStrings_A_合成弦乐A.mcpack', 51: '51.SynthStrings_B_合成弦乐B.mcpack',
|
||||
52: '52.Choir_Aahs_合唱“啊”音.mcpack', 53: '53.Voice_Oohs_人声“哦”音.mcpack', 54: '54.Synth_Voice_合成人声.mcpack',
|
||||
55: '55.Orchestra_Hit_乐队打击乐.mcpack', 56: '56.Trumpet_小号.mcpack', 57: '57.Trombone_长号.mcpack',
|
||||
58: '58.Tuba_大号.mcpack', 59: '59.Muted_Trumpet_弱音小号.mcpack', 6: '6.Harpsichord_拨弦古钢琴.mcpack',
|
||||
60: '60.French_Horn_圆号.mcpack', 61: '61.Brass_Section_铜管组.mcpack', 62: '62.Synth_Brass_A_合成铜管A.mcpack',
|
||||
63: '63.Synth_Brass_A_合成铜管B.mcpack', 64: '64.Soprano_Sax_高音萨克斯.mcpack', 65: '65.Alto_Sax_中音萨克斯.mcpack',
|
||||
66: '66.Tenor_Sax_次中音萨克斯.mcpack', 67: '67.Baritone_Sax_上低音萨克斯.mcpack', 68: '68.Oboe_双簧管.mcpack',
|
||||
69: '69.English_Horn_英国管.mcpack', 7: '7.Clavinet_击弦古钢琴.mcpack', 70: '70.Bassoon_大管.mcpack',
|
||||
71: '71.Clarinet_单簧管.mcpack', 72: '72.Piccolo_短笛.mcpack', 73: '73.Flute_长笛.mcpack',
|
||||
74: '74.Recorder_竖笛.mcpack', 75: '75.Pan_Flute_排笛.mcpack', 76: '76.Bottle_Blow_吹瓶口.mcpack',
|
||||
77: '77.Skakuhachi_尺八.mcpack', 78: '78.Whistle_哨.mcpack', 79: '79.Ocarina_洋埙.mcpack',
|
||||
8: '8.Celesta_钢片琴.mcpack', 80: '80.Lead_square_合成主音-方波.mcpack', 81: '81.Lead_sawtooth_合成主音-锯齿波.mcpack',
|
||||
82: '82.Lead_calliope_lead_合成主音-汽笛风琴.mcpack', 83: '83.Lead_chiff_lead_合成主音-吹管.mcpack',
|
||||
84: '84.Lead_charang_合成主音5-吉他.mcpack', 85: '85.Lead_voice_合成主音-人声.mcpack',
|
||||
86: '86.Lead_fifths_合成主音-五度.mcpack', 87: '87.Lead_bass+lead_合成主音-低音加主音.mcpack',
|
||||
88: '88.Pad_new_age_合成柔音-新时代.mcpack', 89: '89.Pad_warm_合成柔音-暖音.mcpack', 9: '9.Glockenspiel_钟琴.mcpack',
|
||||
90: '90.Pad_polysynth_合成柔音-复合成.mcpack', 91: '91.Pad_choir_合成柔音-合唱.mcpack',
|
||||
92: '92.Pad_bowed_合成柔音-弓弦.mcpack', 93: '93.Pad_metallic_合成柔音-金属.mcpack',
|
||||
94: '94.Pad_halo_合成柔音-光环.mcpack', 95: '95.Pad_sweep_合成柔音-扫弦.mcpack', 96: '96.FX_rain_合成特效-雨.mcpack',
|
||||
97: '97.FX_soundtrack_合成特效-音轨.mcpack', 98: '98.FX_crystal_合成特效-水晶.mcpack',
|
||||
99: '99.FX_atmosphere_合成特效-大气.mcpack'}
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(zip_name[0])
|
||||
133
bgArrayLib/pitchStrConstant.py
Normal file
133
bgArrayLib/pitchStrConstant.py
Normal file
@@ -0,0 +1,133 @@
|
||||
pitch = {
|
||||
'0': '0.0220970869120796',
|
||||
'1': '0.0234110480761981',
|
||||
'2': '0.0248031414370031',
|
||||
'3': '0.0262780129766786',
|
||||
'4': '0.0278405849418856',
|
||||
'5': '0.0294960722713029',
|
||||
'6': '0.03125',
|
||||
'7': '0.033108221698728',
|
||||
'8': '0.0350769390096679',
|
||||
'9': '0.037162722343835',
|
||||
'10': '0.0393725328092148',
|
||||
'11': '0.0417137454428136',
|
||||
'12': '0.0441941738241592',
|
||||
'13': '0.0468220961523963',
|
||||
'14': '0.0496062828740062',
|
||||
'15': '0.0525560259533572',
|
||||
'16': '0.0556811698837712',
|
||||
'17': '0.0589921445426059',
|
||||
'18': '0.0625',
|
||||
'19': '0.066216443397456',
|
||||
'20': '0.0701538780193358',
|
||||
'21': '0.0743254446876701',
|
||||
'22': '0.0787450656184296',
|
||||
'23': '0.0834274908856271',
|
||||
'24': '0.0883883476483184',
|
||||
'25': '0.0936441923047926',
|
||||
'26': '0.0992125657480125',
|
||||
'27': '0.105112051906714',
|
||||
'28': '0.111362339767542',
|
||||
'29': '0.117984289085212',
|
||||
'30': '0.125',
|
||||
'31': '0.132432886794912',
|
||||
'32': '0.140307756038672',
|
||||
'33': '0.14865088937534',
|
||||
'34': '0.157490131236859',
|
||||
'35': '0.166854981771254',
|
||||
'36': '0.176776695296637',
|
||||
'37': '0.187288384609585',
|
||||
'38': '0.198425131496025',
|
||||
'39': '0.210224103813429',
|
||||
'40': '0.222724679535085',
|
||||
'41': '0.235968578170423',
|
||||
'42': '0.25',
|
||||
'43': '0.264865773589824',
|
||||
'44': '0.280615512077343',
|
||||
'45': '0.29730177875068',
|
||||
'46': '0.314980262473718',
|
||||
'47': '0.333709963542509',
|
||||
'48': '0.353553390593274',
|
||||
'49': '0.37457676921917',
|
||||
'50': '0.39685026299205',
|
||||
'51': '0.420448207626857',
|
||||
'52': '0.44544935907017',
|
||||
'53': '0.471937156340847',
|
||||
'54': '0.5',
|
||||
'55': '0.529731547179648',
|
||||
'56': '0.561231024154687',
|
||||
'57': '0.594603557501361',
|
||||
'58': '0.629960524947437',
|
||||
'59': '0.667419927085017',
|
||||
'60': '0.707106781186548',
|
||||
'61': '0.749153538438341',
|
||||
'62': '0.7937005259841',
|
||||
'63': '0.840896415253715',
|
||||
'64': '0.890898718140339',
|
||||
'65': '0.943874312681694',
|
||||
'66': '1',
|
||||
'67': '1.0594630943593',
|
||||
'68': '1.12246204830937',
|
||||
'69': '1.18920711500272',
|
||||
'70': '1.25992104989487',
|
||||
'71': '1.33483985417003',
|
||||
'72': '1.4142135623731',
|
||||
'73': '1.49830707687668',
|
||||
'74': '1.5874010519682',
|
||||
'75': '1.68179283050743',
|
||||
'76': '1.78179743628068',
|
||||
'77': '1.88774862536339',
|
||||
'78': '2',
|
||||
'79': '2.11892618871859',
|
||||
'80': '2.24492409661875',
|
||||
'81': '2.37841423000544',
|
||||
'82': '2.51984209978975',
|
||||
'83': '2.66967970834007',
|
||||
'84': '2.82842712474619',
|
||||
'85': '2.99661415375336',
|
||||
'86': '3.1748021039364',
|
||||
'87': '3.36358566101486',
|
||||
'88': '3.56359487256136',
|
||||
'89': '3.77549725072677',
|
||||
'90': '4',
|
||||
'91': '4.23785237743718',
|
||||
'92': '4.48984819323749',
|
||||
'93': '4.75682846001088',
|
||||
'94': '5.03968419957949',
|
||||
'95': '5.33935941668014',
|
||||
'96': '5.65685424949238',
|
||||
'97': '5.99322830750673',
|
||||
'98': '6.3496042078728',
|
||||
'99': '6.72717132202972',
|
||||
'100': '7.12718974512272',
|
||||
'101': '7.55099450145355',
|
||||
'102': '8',
|
||||
'103': '8.47570475487436',
|
||||
'104': '8.97969638647498',
|
||||
'105': '9.51365692002177',
|
||||
'106': '10.079368399159',
|
||||
'107': '10.6787188333603',
|
||||
'108': '11.3137084989848',
|
||||
'109': '11.9864566150135',
|
||||
'110': '12.6992084157456',
|
||||
'111': '13.4543426440594',
|
||||
'112': '14.2543794902454',
|
||||
'113': '15.1019890029071',
|
||||
'114': '16',
|
||||
'115': '16.9514095097487',
|
||||
'116': '17.95939277295',
|
||||
'117': '19.0273138400435',
|
||||
'118': '20.158736798318',
|
||||
'119': '21.3574376667206',
|
||||
'120': '22.6274169979695',
|
||||
'121': '23.9729132300269',
|
||||
'122': '25.3984168314912',
|
||||
'123': '26.9086852881189',
|
||||
'124': '28.5087589804909',
|
||||
'125': '30.2039780058142',
|
||||
'126': '32',
|
||||
'127': '33.9028190194974',
|
||||
'128': '35.9187855458999',
|
||||
'129': '38.0546276800871',
|
||||
'130': '40.3174735966359',
|
||||
'131': '42.7148753334411'}
|
||||
148
bgArrayLib/reader.py
Normal file
148
bgArrayLib/reader.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from nmcsup.log import log
|
||||
import pickle
|
||||
|
||||
|
||||
class Note:
|
||||
def __init__(self, channel, pitch, velocity, time, time_position, instrument):
|
||||
self.channel = channel
|
||||
self.pitch = pitch
|
||||
self.velocity = velocity
|
||||
self.delay = time
|
||||
self.time_position = time_position
|
||||
self.instrument = instrument
|
||||
self.CD = "d"
|
||||
|
||||
def get_CD(self, start, end):
|
||||
if end - start > 1.00:
|
||||
self.CD = "c"
|
||||
else:
|
||||
self.CD = "d"
|
||||
|
||||
|
||||
def midiNewReader(midfile: str):
|
||||
import mido
|
||||
# from msctspt.threadOpera import NewThread
|
||||
from bgArrayLib.bpm import get
|
||||
|
||||
def Time(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60 * 20)
|
||||
|
||||
Notes = []
|
||||
tracks = []
|
||||
note_list = []
|
||||
close = []
|
||||
on = []
|
||||
off = []
|
||||
instruments = []
|
||||
isPercussion = False
|
||||
try:
|
||||
mid = mido.MidiFile(midfile)
|
||||
except Exception:
|
||||
log("找不到文件或无法读取文件" + midfile)
|
||||
return False
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = get(mid)
|
||||
# 解析
|
||||
# def loadMidi(track1):
|
||||
for track in mid.tracks:
|
||||
overallTime = 0.0
|
||||
instrument = 0
|
||||
for i in track:
|
||||
overallTime += i.time
|
||||
try:
|
||||
if i.channel != 9:
|
||||
# try:
|
||||
# log("event_type(事件): " + str(i.type) + " channel(音轨): " + str(i.channel) +
|
||||
# " note/pitch(音高): " +
|
||||
# str(i[2]) +
|
||||
# " velocity(力度): " + str(i.velocity) + " time(间隔时间): " + str(i.time) +
|
||||
# " overallTime/globalTime/timePosition: " + str(overallTime) + " \n")
|
||||
# except AttributeError:
|
||||
# log("event_type(事件): " + str(i.type) + " thing(内容):" + str(i) + " \n")
|
||||
if 'program_change' in str(i):
|
||||
instrument = i.program
|
||||
if instrument > 119: # 音色不够
|
||||
pass
|
||||
else:
|
||||
instruments.append(i.program)
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
# print(i.note)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
tracks.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
note_list.append(
|
||||
[i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument])
|
||||
on.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
if 'note_off' in str(i) or 'note_on' in str(i) and i.velocity == 0:
|
||||
# print(i)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm))])
|
||||
close.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
off.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
except AttributeError:
|
||||
pass
|
||||
if 'note_on' in str(i) and i.channel == 9:
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
# print(i.note)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)])
|
||||
tracks.append([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)])
|
||||
note_list.append([i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1])
|
||||
on.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
isPercussion = True
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
Notes.append(tracks)
|
||||
if instruments is []:
|
||||
instruments.append(0)
|
||||
instruments = list(set(instruments))
|
||||
with open("1.pkl", 'wb') as b:
|
||||
pickle.dump([instruments, isPercussion], b)
|
||||
|
||||
# for j, track in enumerate(mid.tracks):
|
||||
# th = NewThread(loadMidi, (track,))
|
||||
# th.start()
|
||||
# Notes.append(th.getResult())
|
||||
|
||||
# print(Notes)
|
||||
print(Notes.__len__())
|
||||
# print(note_list)
|
||||
print(instruments)
|
||||
return Notes
|
||||
# return [Notes, note_list]
|
||||
|
||||
|
||||
def midiClassReader(midfile: str):
|
||||
import mido
|
||||
from bgArrayLib.bpm import get
|
||||
|
||||
def Time(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60 * 20)
|
||||
|
||||
Notes = []
|
||||
tracks = []
|
||||
try:
|
||||
mid = mido.MidiFile(filename=midfile,clip=True)
|
||||
except Exception:
|
||||
log("找不到文件或无法读取文件" + midfile)
|
||||
return False
|
||||
log("midi已经载入了。")
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = get(mid)
|
||||
for track in mid.tracks:
|
||||
overallTime = 0.0
|
||||
instrument = 0
|
||||
for i in track:
|
||||
overallTime += i.time
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
tracks.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
Notes.append(tracks)
|
||||
print(Notes.__len__())
|
||||
return Notes
|
||||
131
bgArrayLib/sy_resourcesPacker.py
Normal file
131
bgArrayLib/sy_resourcesPacker.py
Normal file
@@ -0,0 +1,131 @@
|
||||
import os
|
||||
import pickle
|
||||
# import tkinter.filedialog
|
||||
# from namesConstant import zip_name
|
||||
# from namesConstant import mcpack_name
|
||||
import bgArrayLib.namesConstant
|
||||
import shutil
|
||||
zipN = bgArrayLib.namesConstant.zip_name
|
||||
mpN = bgArrayLib.namesConstant.mcpack_name
|
||||
|
||||
manifest = {
|
||||
"format_version": 1,
|
||||
"header": {
|
||||
"name": "羽音缭绕-midiout_25.5--音创使用",
|
||||
"description": "羽音缭绕-midiout_25.0--音创使用",
|
||||
"uuid": "c1adbda4-3b3e-4e5b-a57e-cde8ac80ee19",
|
||||
"version": [25, 5, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "羽音缭绕-midiout_25.0--音创使用",
|
||||
"type": "resources",
|
||||
"uuid": "c13455d5-b9f3-47f2-9706-c05ad86b3180 ",
|
||||
"version": [25, 5, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def resources_pathSetting(newPath: str = ""):
|
||||
if not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath == "":
|
||||
return [False, 1] # 1:没有路径文件
|
||||
elif newPath != "": # not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and
|
||||
path = newPath
|
||||
print(path)
|
||||
with open("./bgArrayLib/resourcesPath.rpposi", 'w') as w:
|
||||
w.write(path)
|
||||
if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 1] # 1:都有
|
||||
elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path):
|
||||
return [True, path, 2] # 2:有pack
|
||||
elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 3] # 3:有zip
|
||||
else:
|
||||
return [False, 2] # 2:路径文件指示错误
|
||||
if os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath == "":
|
||||
with open("./bgArrayLib/resourcesPath.rpposi", 'r') as f:
|
||||
path = f.read()
|
||||
if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 1] # 1:都有
|
||||
elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path):
|
||||
return [True, path, 2] # 2:有pack
|
||||
elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 3] # 3:有zip
|
||||
else:
|
||||
return [False, 2] # 2:路径文件指示错误
|
||||
|
||||
|
||||
def choose_resources():
|
||||
global zipN
|
||||
global mpN
|
||||
back_list = []
|
||||
try:
|
||||
with open(r"1.pkl", 'rb') as rb:
|
||||
instrument = list(pickle.load(rb))
|
||||
print(instrument)
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
with open(r"./nmcsup/1.pkl", 'rb') as rb:
|
||||
instrument = list(pickle.load(rb))
|
||||
print(instrument)
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
path = resources_pathSetting()
|
||||
if path.__len__() == 2:
|
||||
return path
|
||||
else:
|
||||
dataT = path[2]
|
||||
pathT = path[1]
|
||||
if dataT == 1:
|
||||
if instrument[1] is True:
|
||||
index = zipN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
elif dataT == 2:
|
||||
if instrument[1] is True:
|
||||
index = mpN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + str(mpN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
elif dataT == 3:
|
||||
if instrument[1] is True:
|
||||
index = zipN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
|
||||
|
||||
def scatteredPack(path):
|
||||
pack_list = choose_resources()
|
||||
print(pack_list)
|
||||
print(path)
|
||||
# os.close("L:/0WorldMusicCreater-MFMS new edition")
|
||||
# shutil.copy("L:\\shenyu\\音源的资源包\\羽音缭绕-midiout_25.0\\mcpack(国际版推荐)格式_25.0\\0.Acoustic_Grand_Piano_大钢琴.mcpack",
|
||||
# "L:/0WorldMusicCreater-MFMS new edition")
|
||||
for i in pack_list:
|
||||
shutil.copy(i, path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# print(resources_pathSetting(r"L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0"))
|
||||
choose_resources()
|
||||
170
fcwslib/__init__.py
Normal file
170
fcwslib/__init__.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:2个---未解决;警告(二级)错误:2个;语法(一级)错误:17个
|
||||
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = []
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
'''
|
||||
Fuckcraft Websocket Library (FCWSLIB)
|
||||
A library to develop minecraft websocket server easily.
|
||||
|
||||
Copyright (C) 2021 Fuckcraft
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
'''
|
||||
|
||||
from main import *
|
||||
|
||||
# import os
|
||||
import json
|
||||
import uuid
|
||||
# import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
# ----
|
||||
# 没毛病,我讨厌两种人:一种是要我写注释的人,一种是给我代码看但没有写注释的人。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
print(webscket)
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
command = {
|
||||
'rawtext': [
|
||||
{
|
||||
'text': '[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
@@ -1,141 +1,160 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw']
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
command = {
|
||||
'rawtext':[
|
||||
{
|
||||
'text':'[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw']
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
'''
|
||||
Fuckcraft Websocket Library (FCWSLIB)
|
||||
A library to develop minecraft websocket server easily.
|
||||
|
||||
Copyright (C) 2021 Fuckcraft
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
'''
|
||||
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 我个人不负责这块的质量,因为他们逼迫我违心的写了这段代码
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
command = {
|
||||
'rawtext':[
|
||||
{
|
||||
'text':'[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
||||
BIN
fcwslib/版权声明.png
Normal file
BIN
fcwslib/版权声明.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
BIN
languages/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
languages/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
languages/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/enGB.cpython-38.pyc
Normal file
BIN
languages/__pycache__/enGB.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/lang.cpython-38.pyc
Normal file
BIN
languages/__pycache__/lang.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/lang.cpython-39.pyc
Normal file
BIN
languages/__pycache__/lang.cpython-39.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/zhCN.cpython-38.pyc
Normal file
BIN
languages/__pycache__/zhCN.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/zhCN.cpython-39.pyc
Normal file
BIN
languages/__pycache__/zhCN.cpython-39.pyc
Normal file
Binary file not shown.
5
languages/autosave.tmp.txt
Normal file
5
languages/autosave.tmp.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
zh-CN
|
||||
简体中文 中国大陆
|
||||
Simplified Chinese, Chinese Mainland
|
||||
简体中文 中国大陆
|
||||
|
||||
99
languages/const2string.py
Normal file
99
languages/const2string.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
'''此功能已废弃'''
|
||||
|
||||
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
# -----------------------------分割线-----------------------------
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:12个
|
||||
# 目前我的Pycharm并没有显示任何错误,有错误可以向:
|
||||
# bgArray 诸葛亮与八卦阵
|
||||
# QQ 474037765 或最好加入:音·创 开发交流群 861684859
|
||||
# ------------------------- split line-----------------------------
|
||||
# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022
|
||||
# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597
|
||||
# At present, my Pycham does not display any errors. If there are errors, you can report them to me
|
||||
# Bgarray Zhuge Liang and Bagua array
|
||||
# QQ 474037765 or better join: Musicreater development exchange group 861684859
|
||||
# ------------------------- split line-----------------------------
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
# 将程序中用双引号""括起来的字符串
|
||||
# 转为字符串列表 list[str, str, ...]
|
||||
# 方便进行语言翻译支持。
|
||||
|
||||
import sys
|
||||
startWith = 0
|
||||
|
||||
|
||||
def __main__():
|
||||
textList = []
|
||||
for fileName in sys.argv[1:]:
|
||||
print('读取文件: {}'.format(fileName))
|
||||
fileText = []
|
||||
for line in open(fileName, 'r', encoding='utf-8'):
|
||||
while line.count('"') >= 2:
|
||||
# 只有上帝看得懂我在写什么。
|
||||
if line[
|
||||
line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])] in textList:
|
||||
thisText = textList.index(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
|
||||
else:
|
||||
thisText = len(textList)
|
||||
textList.append(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
|
||||
line = line.replace(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])],
|
||||
'READABLETEXT[{}]'.format(thisText + startWith)
|
||||
)
|
||||
fileText.append(line)
|
||||
|
||||
open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText)
|
||||
|
||||
outFile = open('lang__.py', 'w', encoding='utf-8')
|
||||
outFile.write('''# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
''')
|
||||
for i in range(len(textList)):
|
||||
outFile.write(" {}:{},\n".format(i + startWith, textList[i]))
|
||||
outFile.write('}')
|
||||
outFile.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__()
|
||||
180
languages/enGB.py
Normal file
180
languages/enGB.py
Normal file
@@ -0,0 +1,180 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译的文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
'Translator': (("Eilles Wan (金羿)", True),),
|
||||
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
0: "ERROR❌",
|
||||
1: "TIPS❗",
|
||||
2: "Clearing log(this wont be in the file)",
|
||||
3: "Could not clear the temporary files or logs",
|
||||
4: "saved",
|
||||
5: "New Musicreater Project",
|
||||
6: "Select old-type project",
|
||||
7: "Select Musicreater Project",
|
||||
8: "Cant open:{}, please check if youve entered the right name",
|
||||
9: "Musicreat - About",
|
||||
10: "Musicreater",
|
||||
11: "Ver. {}",
|
||||
12: """Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""",
|
||||
13: "OK",
|
||||
14: "Inpute Notes",
|
||||
15: (("- Developers -", False),
|
||||
("Eilles Wan (金羿)", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
|
||||
("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False)),
|
||||
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
16: "- Translators -",
|
||||
# 17:"",
|
||||
18: "QQ Group: 861684859",
|
||||
19: "Musicreater - Help",
|
||||
20: "Select sound file",
|
||||
21: "Select MIDI file",
|
||||
22: "Select NoteText file",
|
||||
23: "Get Note info",
|
||||
24: "Write in Note info: {}",
|
||||
25: "Select generating file",
|
||||
26: "Select generating folder",
|
||||
27: "Select generating .mcpack file",
|
||||
28: "Input position info",
|
||||
29: "Select generating world folder",
|
||||
30: "Select generating Function Pack",
|
||||
31: "Select .mcfunction file ",
|
||||
32: "Select .bdx file ",
|
||||
33: "DONE✔",
|
||||
34: "Input playing rate",
|
||||
35: "Generating",
|
||||
36: "Select a world folder",
|
||||
37: "Make sure",
|
||||
38: "Generate .RyStruct file",
|
||||
39: "FAILED❌",
|
||||
40: "Report message inpution",
|
||||
41: "Musicreater - {}",
|
||||
42: "ExecutingEntityName: {}",
|
||||
43: "ScoreboardName: {}",
|
||||
44: "Instrument: {}",
|
||||
45: "TrackName: {}",
|
||||
46: "PackName: {}",
|
||||
47: "MusicTitle: {}",
|
||||
48: "IsRepeat?: {}",
|
||||
49: "Player'sTargetSelector: {}",
|
||||
50: "Modify Main Option",
|
||||
51: "Modify Track Option",
|
||||
52: "Default Instrument: Enter English\n",
|
||||
53: "Open...",
|
||||
54: "Open Old Project...",
|
||||
55: "Save",
|
||||
56: "Save as...",
|
||||
57: "Exit",
|
||||
58: "File",
|
||||
59: "Load tracks from sound",
|
||||
60: "Load tracks from Midi",
|
||||
61: "Load tracks from Text",
|
||||
62: "Input notes to track",
|
||||
63: "Edit",
|
||||
64: "Generate file...",
|
||||
65: "Generate function pack...",
|
||||
66: "Generate .mcpack file...",
|
||||
67: "Functions(Pack)",
|
||||
68: "Save music as blocks into a map",
|
||||
69: "Save music as blocks into a exist map...",
|
||||
70: "Save music as commands into a map",
|
||||
71: "Save music as commands into a exist map...",
|
||||
72: "Save music as notebox into a map",
|
||||
73: "Save music as notebox into a exist map...",
|
||||
74: "World",
|
||||
75: "Generate a function that fits current music...",
|
||||
76: "Export selected track as commands in .bdx...",
|
||||
77: "Export .bdx file from map...",
|
||||
78: "Export .RyStruct file from map...",
|
||||
79: "Load functions into a world...",
|
||||
80: "Separate long .mcfunction file into small ones and set them into a world as a chain...",
|
||||
81: "Additional Functions",
|
||||
82: "Show generating result",
|
||||
83: "Set a websocket server on localhost:8080 and play the selected track",
|
||||
84: "Experimental Functions",
|
||||
85: "Clear log file",
|
||||
86: "Clear save file(obsolete)",
|
||||
87: "Help",
|
||||
88: "About",
|
||||
89: "Send a bug report",
|
||||
90: "Q&A",
|
||||
91: "Main Options",
|
||||
92: "Export music as .BDX...",
|
||||
93: "请输入指令链生成最高相对高度(≥5)",
|
||||
94: "❌You should input a number which is not lower then 4, please reinput again.",
|
||||
95: "Structure",
|
||||
96: "Reset Main Options",
|
||||
97: "Track Options",
|
||||
# 98:"",
|
||||
# 99:"",
|
||||
# 100:"",
|
||||
# 101:"",
|
||||
102: "Delete Selected Track",
|
||||
# 103:"",
|
||||
# 104:"",
|
||||
|
||||
105: "Error with finding or reading file😢:{}",
|
||||
106: "Project is unsaved, save before close?",
|
||||
107: "Saved in: {}",
|
||||
108: ("Musicreater 0.0.X Project","Musicreater 0.1+ Project","Musicreater 0.1+ TESTver Project"),
|
||||
109: "Any Type",
|
||||
110: "NoteFunCreater Project",
|
||||
111: "MMFM (V0.0.6) Project",
|
||||
112: "All Types",
|
||||
113: ".MP3 file(piano sound)",
|
||||
114: "Midi file",
|
||||
115: "Text file",
|
||||
116: "Position Inpution",
|
||||
117: "Format Error❌, please Reinput!",
|
||||
118: ".MCFUNCTION",
|
||||
119: "The position of the ChainCB for execution:",
|
||||
# 120: "",
|
||||
121: "您的函数文件不大于一万条指令,无需进行分割操作。",
|
||||
122: "请输入执行链生成相对坐标:",
|
||||
123: "FastBuilder Structure",
|
||||
124: "Done!\n{}",
|
||||
125: "一秒,音乐走几拍?",
|
||||
126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放",
|
||||
127: "请输入区域选择的开始坐标:",
|
||||
128: "请输入区域选择的结束坐标:",
|
||||
129: "Whether air block remain when export?",
|
||||
130: "Musicreater Structure",
|
||||
131: "Done😃\n{}",
|
||||
132: "Failed❌\n{}\n{}",
|
||||
133: "Have not developed yet...",
|
||||
134: "Your name",
|
||||
135: "Your contact",
|
||||
136: "Your description of Problem",
|
||||
137: "Log file will be cleared when you exit.",
|
||||
138: "Log file will NOT be cleared when you exit.",
|
||||
139: "修改包名",
|
||||
140: "修改音乐标题",
|
||||
141: "修改玩家选择器\n注意!要加上中括号“[]”",
|
||||
142: "修改本音轨的执行实体名",
|
||||
143: "修改本音轨所用的积分板",
|
||||
144: "修改本音轨所用乐器",
|
||||
145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?",
|
||||
146: "修改本音轨生成的文件名",
|
||||
# -----2022.1.25更新
|
||||
147: "生成新文件至...",
|
||||
148: "从midi导入音轨且用新方法解析",
|
||||
149: "Open New: Musicreater Project...",
|
||||
150: "保存为新项目",
|
||||
151: "另存为新项...",
|
||||
152: "(开发调试)关闭本次日志记录",
|
||||
153: "生成新函数包至...",
|
||||
154: "生成新函数附加包文件至...",
|
||||
155: "生成新函数附加包文件,并将神羽资源包以散包形式放置至...",
|
||||
156: "Select [MiraclePlumeResourcePack]...",
|
||||
157: "没有路径文件(.rpposi文件),请仔细阅读Readme或先试用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 方法添加路径文件吧!",
|
||||
158: "有路径文件(.rpposi文件),但路径指示错误,请仔细阅读Readme或先用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 更改路径!",
|
||||
159: "更改路径文件(.rpposi文件)成功!!",
|
||||
160: "从midi导入音轨且用类方法解析",
|
||||
161: "打开 类方法: 音·创项目...",
|
||||
162: "保存为类方法项目",
|
||||
163: "另存为类方法项...",
|
||||
|
||||
}
|
||||
203
languages/lang.py
Normal file
203
languages/lang.py
Normal file
@@ -0,0 +1,203 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
'''对于音·创的语言支持兼语言文件编辑器'''
|
||||
|
||||
"""
|
||||
Copyright 2022 Team-Ryoun
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
DEFAULTLANGUAGE = 'zh-CN'
|
||||
|
||||
LANGUAGELIST = {
|
||||
# 第一个是语言的中文名称和地区
|
||||
# 第二个是语言的英文名称和地区
|
||||
# 第三个是语言的本地名称和地区
|
||||
'zh-CN': (
|
||||
"简体中文 中国大陆",
|
||||
"Simplified Chinese - China Mainland",
|
||||
"简体中文 中国大陆",
|
||||
),
|
||||
'zh-TW': (
|
||||
"繁体中文 中国台湾省",
|
||||
"Traditional Chinese - Taiwan, China",
|
||||
"正體中文,中国台灣省",
|
||||
),
|
||||
# 'zh-HK': (
|
||||
# "繁体中文 香港",
|
||||
# "Traditional Chinese - the Hong Kong Special Administrative Region",
|
||||
# "繁體中文,香港特別行政區",
|
||||
# ),
|
||||
# 'zh-MO': (
|
||||
# "繁体中文 澳门",
|
||||
# "Traditional Chinese - the Macao Special Administrative Region",
|
||||
# "繁體中文,澳門特別行政區",
|
||||
# ),
|
||||
'en-GB': (
|
||||
"英语 英国",
|
||||
"British English - the United Kingdom",
|
||||
"British English - the United Kingdom",
|
||||
),
|
||||
'zh-ME' : (
|
||||
"喵喵文 中国大陆",
|
||||
"Meow Catsese - China Mainland"
|
||||
"喵喵喵~ 祖国喵~"
|
||||
)
|
||||
}
|
||||
|
||||
# 对于旧版本音·创的语言支持
|
||||
# 重构之后将停止使用
|
||||
try:
|
||||
from languages.zhCN import READABLETEXT
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
from msctLib.log import log
|
||||
|
||||
def __loadLanguage(languageFilename: str):
|
||||
with open(languageFilename, 'r', encoding='utf-8') as languageFile:
|
||||
_text = {}
|
||||
for line in languageFile:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
line = line.split(' ', 1)
|
||||
_text[line[0]] = line[1].replace('\n', '')
|
||||
langkeys = _text.keys()
|
||||
with open(languageFilename.replace(languageFilename[-10:-5], 'zh-CN'), 'r', encoding='utf-8') as defaultLangFile:
|
||||
for line in defaultLangFile:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
line = line.split(' ', 1)
|
||||
if not line[0] in langkeys:
|
||||
_text[line[0]] = line[1].replace('\n', '')
|
||||
from msctLib.log import log
|
||||
log(f'丢失对于 {line[0]} 的本地化文本', 'WARRING')
|
||||
langkeys = _text.keys()
|
||||
return _text
|
||||
|
||||
|
||||
if not DEFAULTLANGUAGE == 'zh-CN':
|
||||
if DEFAULTLANGUAGE in LANGUAGELIST.keys():
|
||||
_TEXT = __loadLanguage('./languages/' + DEFAULTLANGUAGE + '.lang')
|
||||
else:
|
||||
raise KeyError(f'无法打开默认语言{DEFAULTLANGUAGE}')
|
||||
|
||||
|
||||
def wordTranslate(singleWord: str, debug: bool = False):
|
||||
import requests
|
||||
try:
|
||||
return \
|
||||
requests.post('https://fanyi.baidu.com/sug', data={'kw': f'{singleWord}'}).json()['data'][0]['v'].split(
|
||||
'; ')[0]
|
||||
except:
|
||||
log(f"无法翻译文本{singleWord}", level='WARRING', isPrinted=debug)
|
||||
return None
|
||||
|
||||
|
||||
def _(text: str, debug: bool = False):
|
||||
try:
|
||||
return _TEXT[text]
|
||||
except:
|
||||
if debug:
|
||||
raise KeyError(f'无法找到翻译文本{text}')
|
||||
else:
|
||||
log(f'无法找到本地化文本{text}','ERROR')
|
||||
return ''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 启动语言编辑器
|
||||
import tkinter as tk
|
||||
from tkinter.filedialog import askopenfilename as askfilen
|
||||
|
||||
LANGNAME = _('LANGLOCALNAME')
|
||||
|
||||
|
||||
def _changeDefaultLang():
|
||||
global _TEXT
|
||||
global DEFAULTLANGUAGE
|
||||
|
||||
fileName = askfilen(title='选择所翻译的语言文件', initialdir=r'./',
|
||||
filetypes=[('音·创语言文件', '.lang'), ('所有文件', '*')],
|
||||
defaultextension='.lang',
|
||||
initialfile='.lang')
|
||||
_TEXT = __loadLanguage(fileName)
|
||||
DEFAULTLANGUAGE = _('LANGKEY')
|
||||
LANGNAME = _('LANGLOCALNAME')
|
||||
|
||||
orignText = ''
|
||||
transText = ''
|
||||
for i, j in _TEXT.items():
|
||||
orignText += i + '\n'
|
||||
transText += j + '\n'
|
||||
|
||||
Origntextbar.insert('end', orignText)
|
||||
Translatetextbar.insert('end', transText)
|
||||
|
||||
global setlangbutton
|
||||
setlangbutton['text'] = f'对标语言{LANGNAME}'
|
||||
|
||||
|
||||
def _autoSave(event=None):
|
||||
with open('autosave.tmp.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(Translatetextbar.get(1.0, 'end'))
|
||||
print(str(event))
|
||||
|
||||
|
||||
root = tk.Tk()
|
||||
|
||||
root.geometry('600x500')
|
||||
|
||||
root.bind("<Motion>", _autoSave)
|
||||
|
||||
nowText = ''
|
||||
|
||||
Orignrame = tk.Frame(root, bd=2)
|
||||
Translaterame = tk.Frame(root, bd=2)
|
||||
|
||||
Orignscrollbar = tk.Scrollbar(Orignrame)
|
||||
Origntextbar = tk.Text(Orignrame, width=35, height=40)
|
||||
|
||||
Translatetextbar = tk.Text(Translaterame, width=40, height=37, undo=True)
|
||||
Translatescrollbar = tk.Scrollbar(Translaterame)
|
||||
|
||||
def ctrlZ():
|
||||
Translatetextbar.edit_undo()
|
||||
Translatetextbar.bind("<Control-z>", ctrlZ)
|
||||
|
||||
def ctrlY():
|
||||
Translatetextbar.edit_redo()
|
||||
Translatetextbar.bind("<Control-y>", ctrlY)
|
||||
|
||||
tk.Button(Translaterame, text='保存', command=_autoSave).pack(side='bottom', fill='x')
|
||||
|
||||
tk.Label(Orignrame, text='中文原文').pack(side='top')
|
||||
Origntextbar.pack(side='left', fill='y')
|
||||
Orignscrollbar.pack(side='left', fill='y')
|
||||
|
||||
setlangbutton = tk.Button(Translaterame, text=f'对标语言{LANGNAME}', command=_changeDefaultLang)
|
||||
setlangbutton.pack(side='top')
|
||||
Translatescrollbar.pack(side='right', fill='y')
|
||||
Translatetextbar.pack(side='right', fill='y')
|
||||
|
||||
Orignscrollbar.config(command=Origntextbar.yview)
|
||||
Origntextbar.config(yscrollcommand=Orignscrollbar.set)
|
||||
|
||||
Translatescrollbar.config(command=Translatetextbar.yview)
|
||||
Translatetextbar.config(yscrollcommand=Translatescrollbar.set)
|
||||
|
||||
Orignrame.pack(side='left')
|
||||
Translaterame.pack(side='right')
|
||||
|
||||
tk.mainloop()
|
||||
16
languages/zh-CN.lang
Normal file
16
languages/zh-CN.lang
Normal file
@@ -0,0 +1,16 @@
|
||||
# 音·创 本地化语言文件
|
||||
# 使用 空格 把键与对应文本隔开
|
||||
# 使用 井字符 在每一行的开头编写注释
|
||||
# 注意!井字符请开头放,切勿含有空格
|
||||
# 也切勿在正文结尾放!
|
||||
LANGKEY zh-CN
|
||||
LANGCHINESENAME 简体中文 中国大陆
|
||||
LANGENGLIFHNAME Simplified Chinese, Chinese Mainland
|
||||
LANGLOCALNAME 简体中文 中国大陆
|
||||
MSCT 音·创
|
||||
F音创 音·创 Musicreater
|
||||
关于 音·创 - 关于
|
||||
凌云pairs 凌天之云创新我的世界开发团队\n×\n凌天之云创新计算机应用软件开发团队
|
||||
开发者 - 开发人员 -
|
||||
译者 - 翻译人员 -
|
||||
确定 确定
|
||||
17
languages/zh-ME.lang
Normal file
17
languages/zh-ME.lang
Normal file
@@ -0,0 +1,17 @@
|
||||
# 音创创喵的 本地化语言文件
|
||||
# 使用 空格 把键与对应文本隔开
|
||||
# 使用 井字符 在每一行的开头编写注释
|
||||
# 注意!井字符请开头放,切勿含有空格
|
||||
# 也切勿在正文结尾放!
|
||||
LANGKEY zh-ME
|
||||
LANGCHINESENAME 喵喵文 中国大陆
|
||||
LANGENGLIFHNAME Meow Catsese, China Mainland
|
||||
LANGLOCALNAME 喵喵喵~ 祖国喵~
|
||||
TRANSLATERS 金羿,Email EillesWan@outlook.com,QQ 2647547478
|
||||
MSCT 音创创喵~
|
||||
F音创 音·创 Musicreater
|
||||
关于 音创创喵的主人们
|
||||
凌云pairs 凌天之云创新我的世界开发团队\n×\n凌天之云创新计算机应用软件开发团队
|
||||
开发者 ~ 主人们 ~
|
||||
译者 ~ 爸爸妈妈们 ~
|
||||
确定 好哒~
|
||||
185
languages/zhCN.py
Normal file
185
languages/zhCN.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
'Translator': (("金羿 Eilles 原稿", True),),
|
||||
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
0: "错误❌",
|
||||
1: "提示❗",
|
||||
2: "清除log(此句不载入日志)",
|
||||
3: "无法清除日志及临时文件",
|
||||
4: "已存储",
|
||||
5: "新建 音·创 项目",
|
||||
6: "请选择旧类型的项目",
|
||||
7: "请选择 音·创 项目",
|
||||
8: "无法打开文件:{},请查看您是否输入正确",
|
||||
9: "音·创 - 关于",
|
||||
10: "音·创 Musicreater",
|
||||
11: "当前版本:{}",
|
||||
12: """凌云我的世界开发团队\n×\n凌云计算机应用软件开发团队""",
|
||||
13: "确定",
|
||||
14: "请输入音符",
|
||||
15: (("- 开发者 -", False),
|
||||
("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
|
||||
("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False),
|
||||
),
|
||||
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
16: "- 翻译者 -",
|
||||
# 17:"",
|
||||
18: "讨论群: 861684859",
|
||||
19: "音·创 - 帮助",
|
||||
20: "请选择钢琴声音的音乐文件",
|
||||
21: "请选择 MIDI 文件",
|
||||
22: "请选择 音符文本 文件",
|
||||
23: "获取音符信息",
|
||||
24: "音符数据写入{}",
|
||||
25: "请选择文件生成的位置",
|
||||
26: "请选择文件夹生成的位置",
|
||||
27: "请选择.mcpack文件生成的位置",
|
||||
28: "坐标信息输入",
|
||||
29: "请选择世界文件夹生成的位置",
|
||||
30: "请选择函数包生成的位置",
|
||||
31: "请选择 .mcfunction 文件",
|
||||
32: "请选择需要生成的.bdx文件",
|
||||
33: "完成✔",
|
||||
34: "输入播放速度",
|
||||
35: "创建中",
|
||||
36: "请选择世界文件夹所在的位置",
|
||||
37: "请确认",
|
||||
38: "生成.RyStruct文件",
|
||||
39: "失败❌",
|
||||
40: "邮件反馈信息输入",
|
||||
41: "音·创 - {}",
|
||||
42: "执行实体名:{}",
|
||||
43: "使用计分板:{}",
|
||||
44: "所用的乐器:{}",
|
||||
45: "当前音轨名:{}",
|
||||
46: "包名:{}",
|
||||
47: "音乐标题:{}",
|
||||
48: "是否重复:{}",
|
||||
49: "玩家选择器:{}",
|
||||
50: "修改主设置",
|
||||
51: "修改节设置",
|
||||
52: "游戏内置乐器如下:请输入英文\n",
|
||||
53: "打开音·创项目...",
|
||||
54: "打开旧项目...",
|
||||
55: "保存项目",
|
||||
56: "另存为...",
|
||||
57: "退出",
|
||||
58: "文件",
|
||||
59: "从钢琴MP3导入音轨",
|
||||
60: "从midi导入音轨",
|
||||
61: "从文本文件导入音轨",
|
||||
62: "输入音符至音轨",
|
||||
63: "编辑",
|
||||
64: "生成文件至...",
|
||||
65: "生成函数包至...",
|
||||
66: "生成附加包文件至...",
|
||||
67: "函数(包)",
|
||||
68: "将音乐以方块存储生成地图",
|
||||
69: "将音乐以方块存储载入地图…",
|
||||
70: "将音乐以指令存储生成地图",
|
||||
71: "将音乐以指令存储载入地图…",
|
||||
72: "将音乐以音符盒存储生成地图",
|
||||
73: "将音乐以音符盒存储载入地图…",
|
||||
74: "世界",
|
||||
75: "生成符合当前音乐的函数播放器…",
|
||||
76: "将选中音轨以指令存储生成.bdx文件…",
|
||||
77: "由地图导出至.bdx文件…",
|
||||
78: "由地图导出至.RyStruct文件…",
|
||||
79: "将函数载入世界…",
|
||||
80: "将大函数分割并建立执行链…",
|
||||
81: "辅助功能",
|
||||
82: "展示生成结果",
|
||||
83: "建立位于localhost:8080上的websocket服务器播放选中音轨",
|
||||
84: "实验性功能",
|
||||
85: "清除日志文件",
|
||||
86: "清除早期版本的存储文件",
|
||||
87: "帮助",
|
||||
88: "关于",
|
||||
89: "发送错误日志反馈",
|
||||
90: "帮助与疑问",
|
||||
91: "音乐总设置(项目设置)",
|
||||
# =============================================================此处有新增
|
||||
92: "将音乐导出为BDX",
|
||||
93: "请输入指令链生成最高相对高度(≥5)",
|
||||
94: "您输入的数据有误❌,相对高度请输入一个不小于4的值,请重新输入。",
|
||||
95: "结构操作",
|
||||
96: "重置项目设置",
|
||||
97: "当前音轨设置(段落设置)",
|
||||
# 98:"",
|
||||
# 99:"",
|
||||
# 100:"",
|
||||
# 101:"",
|
||||
102: "删除选中音轨",
|
||||
# 103:"",
|
||||
# 104:"",
|
||||
105: "找不到或无法读取文件😢:{}",
|
||||
106: "您当前的项目已修改但未存储,是否先保存当前项目?",
|
||||
107: "项目已经存储至:{}",
|
||||
108: ("音·创0.0.X工程文件", "音·创0.1+工程文件", "音·创0.1+TEST工程文件"),
|
||||
109: "任意类型",
|
||||
110: "函数音创工程文件",
|
||||
111: "MMFM0.0.6版本工程文件",
|
||||
112: "全部类型",
|
||||
113: "钢琴声音的音频文件",
|
||||
114: "Midi文件",
|
||||
115: "文本文件",
|
||||
116: "请输入坐标:",
|
||||
117: "您输入的格式有误❌,请重新输入。",
|
||||
118: "我的世界指令函数文件",
|
||||
119: "请输入执行链生成坐标:",
|
||||
# 120: "",
|
||||
121: "您的函数文件不大于一万条指令,无需进行分割操作。",
|
||||
122: "请输入执行链生成相对坐标:",
|
||||
123: "FastBuilder结构文件",
|
||||
124: "转换结束!\n{}",
|
||||
125: "一秒,音乐走几拍?",
|
||||
126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放",
|
||||
127: "请输入区域选择的开始坐标:",
|
||||
128: "请输入区域选择的结束坐标:",
|
||||
129: "所选区块导出时是否需要保留空气方块?",
|
||||
130: "音·创结构文件",
|
||||
131: "文件已生成\n{}",
|
||||
132: "文件无法生成\n{}\n{}",
|
||||
133: "本功能尚未开发。",
|
||||
134: "您的称呼",
|
||||
135: "您的联系方式",
|
||||
136: "您对问题的描述",
|
||||
137: "在程序结束后将清除日志及临时文件信息。",
|
||||
138: "在程序结束后将不会清除日志及临时文件信息。",
|
||||
139: "修改包名",
|
||||
140: "修改音乐标题",
|
||||
141: "修改玩家选择器\n注意!要加上中括号“[]”",
|
||||
142: "修改本音轨的执行实体名",
|
||||
143: "修改本音轨所用的积分板",
|
||||
144: "修改本音轨所用乐器",
|
||||
145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?",
|
||||
146: "修改本音轨生成的文件名",
|
||||
# -----2022.1.25更新
|
||||
147: "生成乐器文件至...",
|
||||
148: "从midi导入音轨且用新方法解析",
|
||||
# 149: "打开 新: 音·创项目...",
|
||||
# 150: "保存为新项目",
|
||||
# 151: "另存为新项...",
|
||||
152: "(开发调试)关闭本次日志记录",
|
||||
153: "生成乐器函数包至...",
|
||||
154: "生成乐器函数附加包文件至...",
|
||||
155: "生成乐器函数附加包文件,并将神羽资源包以散包形式放置至...",
|
||||
156: "[神羽资源包位置选择]:选择文件夹...",
|
||||
157: "没有路径文件(.rpposi文件),请仔细阅读Readme或先试用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 方法添加路径文件吧!",
|
||||
158: "有路径文件(.rpposi文件),但路径指示错误,请仔细阅读Readme或先用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 更改路径!",
|
||||
159: "更改路径文件(.rpposi文件)成功!!",
|
||||
160: "从midi导入音轨且用类方法解析",
|
||||
# 161: "打开 类方法: 音·创项目...",
|
||||
# 162: "保存为类方法项目",
|
||||
# 163: "另存为类方法项...",
|
||||
164: "生成新文件至...",
|
||||
165: "生成新函数包至...",
|
||||
166: "生成新函数附加包文件至...",
|
||||
167: "!!!这个midi文件读取不了,mido解析报错!!!"
|
||||
|
||||
}
|
||||
BIN
msctLib/UI设计图.pdn
Normal file
BIN
msctLib/UI设计图.pdn
Normal file
Binary file not shown.
BIN
msctLib/UI设计图.png
Normal file
BIN
msctLib/UI设计图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
msctLib/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/data.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/data.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/display.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/display.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/function.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/function.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/log.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/log.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/bugExecution.exe
Normal file
BIN
msctLib/bugExecution.exe
Normal file
Binary file not shown.
50
msctLib/buildIN.py
Normal file
50
msctLib/buildIN.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""音·创的核心内置组件功能集合"""
|
||||
|
||||
|
||||
|
||||
class version:
|
||||
libraries = (
|
||||
'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin',
|
||||
'pyinstaller', 'py7zr','websockets', 'torch', 'requests'
|
||||
)
|
||||
"""当前所需库"""
|
||||
|
||||
version = ('0.2.0', 'Delta',)
|
||||
"""当前版本"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.libraries = version.libraries
|
||||
"""当前所需库"""
|
||||
|
||||
self.version = version.version
|
||||
"""当前版本"""
|
||||
|
||||
|
||||
def installLibraries(self,index:str = 'https://pypi.tuna.tsinghua.edu.cn/simple'):
|
||||
"""安装全部开发用库"""
|
||||
from sys import platform
|
||||
import os
|
||||
if platform == 'win32':
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"python -m pip install {i} -i {index}")
|
||||
elif platform == 'linux':
|
||||
os.system("sudo apt-get install python3-pip")
|
||||
os.system("sudo apt-get install python3-tk")
|
||||
os.system("sudo apt-get install python3-tkinter")
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"sudo python3 -m pip install {i} -i {index}")
|
||||
|
||||
|
||||
def __call__(self):
|
||||
'''直接安装库,顺便返回一下当前版本'''
|
||||
self.installLibraries()
|
||||
return self.version
|
||||
151
msctLib/data.py
Normal file
151
msctLib/data.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
import pickle
|
||||
import json
|
||||
from typing import Any, Iterable
|
||||
|
||||
|
||||
|
||||
|
||||
class pickleIO:
|
||||
|
||||
def __init__(self,fileName:str,data: Any = None) -> None:
|
||||
'''简单的pickle操作功能'''
|
||||
self.file = fileName
|
||||
if data:
|
||||
self._data = data
|
||||
else:
|
||||
with open (self.file, 'rb') as f:
|
||||
self._data = pickle.load(f)
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入pickle'''
|
||||
with open (self.file, 'wb') as f:
|
||||
pickle.dump(self._data, f)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
with open (self.file, 'rb') as f:
|
||||
self._data = pickle.load(f)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
if self._data is None:
|
||||
raise ValueError('无可用值载入或值为None')
|
||||
else:
|
||||
return self._data
|
||||
|
||||
|
||||
|
||||
class jsonIO:
|
||||
|
||||
def __init__(self,fileName:str,data: Any = None) -> None:
|
||||
'''简单的json操作功能'''
|
||||
self.file = fileName
|
||||
if data:
|
||||
self._data = data
|
||||
else:
|
||||
with open (self.file, 'r', encoding='utf-8') as f:
|
||||
self._data = json.load(f)
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入json'''
|
||||
with open (self.file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self._data, f)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
with open (self.file, 'r', encoding='utf-8') as f:
|
||||
self._data = json.load(f)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
return self._data
|
||||
|
||||
|
||||
class uniteIO:
|
||||
|
||||
def __init__(self,fileName:str,fileType = None,data: Any = None) -> None:
|
||||
'''简单的文件数据IO操作功能'''
|
||||
self.filename = fileName
|
||||
if not fileType is None:
|
||||
self._type = fileType
|
||||
else:
|
||||
try:
|
||||
with open (self.filename, 'r', encoding='utf-8') as f:
|
||||
self._type = json
|
||||
except:
|
||||
with open (self.file, 'rb') as f:
|
||||
self._type = pickle
|
||||
|
||||
|
||||
|
||||
if not data is None:
|
||||
self._data = data
|
||||
else:
|
||||
self._data = self.load()
|
||||
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入文件'''
|
||||
if self._type == json:
|
||||
self._wfile = open(self.filename, 'w', encoding='utf-8')
|
||||
elif self._type == pickle:
|
||||
self._wfile = open(self.file, 'wb')
|
||||
self._type.dump(self._data, self._wfile)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
if self._type == json:
|
||||
self._rfile = open(self.filename, 'r', encoding='utf-8')
|
||||
elif self._type == pickle:
|
||||
self._rfile = open(self.file, 'rb')
|
||||
self._data = self._type.load(self._rfile)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
return self._data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from sys import argv
|
||||
|
||||
if argv[1]:
|
||||
input(uniteIO(argv[1]).data)
|
||||
297
msctLib/display.py
Normal file
297
msctLib/display.py
Normal file
@@ -0,0 +1,297 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''音·创的GUI窗口界面显示库
|
||||
:若要使用其他界面显示,请详见:
|
||||
:开发说明|指南'''
|
||||
|
||||
|
||||
import tkinter as tk
|
||||
import tkinter.simpledialog as sdialog
|
||||
import tkinter.filedialog as fdialog
|
||||
from msctLib.log import log
|
||||
|
||||
|
||||
DEFAULTBLUE = (0, 137, 242)
|
||||
WEAKBLUE = (0, 161, 231)
|
||||
LIGHTBLUE = (38, 226, 255)
|
||||
RED = (255, 52, 50)
|
||||
PURPLE = (171, 112, 255)
|
||||
GREEN = (0, 255, 33)
|
||||
WHITE = (242, 244, 246)
|
||||
BLACK = (18, 17, 16)
|
||||
|
||||
|
||||
backgroundColor = WHITE
|
||||
frontgroundColor = BLACK
|
||||
loadingColor = DEFAULTBLUE
|
||||
errorColor = RED
|
||||
okColor = GREEN
|
||||
tipsColor = PURPLE
|
||||
|
||||
# 注:UI界面字体、代码字体
|
||||
fontPattern = ('DengXian Light', 'Fira Code')
|
||||
|
||||
|
||||
class disp:
|
||||
'''音·创 的基本Tk窗口显示库'''
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
root: tk.Tk = tk.Tk(),
|
||||
debug: bool = False,
|
||||
title: str = '音·创',
|
||||
geometry: str = '0x0',
|
||||
iconbitmap: tuple = ('', ''),
|
||||
menuWidget: dict = {},
|
||||
wordView: str = '音·创 Musicreater',
|
||||
buttons: list = [],
|
||||
settingBox: list = [],
|
||||
notemap: list = [],
|
||||
) -> None:
|
||||
'''使用参数建立基本的 音·创 窗口
|
||||
:param root 根窗口
|
||||
:param debug 是否将日志输出到控制台
|
||||
:param title 窗口标题
|
||||
wordview: str #言论部分显示的字样
|
||||
button: list = [ # 操作按钮部分
|
||||
dict = {
|
||||
按钮名称 : tuple(按钮图标,执行函数)
|
||||
},
|
||||
],
|
||||
settingbox: list = [ # 设置部分显示的字样及其对应的设置函数
|
||||
(
|
||||
设置名称:str,
|
||||
值类型:tuple,
|
||||
显示内容:str,
|
||||
设置操作函数:<function>,
|
||||
)
|
||||
],
|
||||
map: list = [ # 一首曲目的音符数据
|
||||
音符数据
|
||||
]
|
||||
'''
|
||||
|
||||
self.root = root
|
||||
self.title = title
|
||||
self.geometry = geometry
|
||||
self.menuWidget = menuWidget
|
||||
self.wordView = wordView
|
||||
self.buttons = buttons
|
||||
self.settingBox = settingBox
|
||||
self.notemap = notemap
|
||||
|
||||
self.setTitle(title, debug)
|
||||
self.setGeometry(geometry, debug)
|
||||
self.setIcon(*iconbitmap, debug=debug)
|
||||
|
||||
self.setMenu(menuWidget)
|
||||
|
||||
self.initWidget(wordView, buttons, settingBox, notemap)
|
||||
|
||||
# 设定函数部分
|
||||
def setTitle(self, title: str = '', debug: bool = False) -> None:
|
||||
'''设置窗口标题'''
|
||||
self.root.title = title
|
||||
if debug:
|
||||
log(f"设置窗口标题{title}")
|
||||
|
||||
def setGeometry(self, geometry: str = '0x0', debug: bool = False) -> None:
|
||||
'''设置窗口大小'''
|
||||
self.root.geometry(geometry)
|
||||
if debug:
|
||||
log(f"设置窗口大小{geometry}")
|
||||
|
||||
def setIcon(
|
||||
self, bitmap: str = './musicreater.ico', default: str = '', debug: bool = False
|
||||
) -> None:
|
||||
'''设置窗口图标
|
||||
注意,default参数仅在Windows下有效,其意为将所有没有图标的窗口设置默认图标
|
||||
如果在非Windows环境使用default参数,一个Error将被升起'''
|
||||
if not debug:
|
||||
try:
|
||||
if default:
|
||||
self.root.iconbitmap(bitmap, default)
|
||||
log(f'设置图标为{bitmap},默认为{default}')
|
||||
else:
|
||||
self.root.iconbitmap(bitmap)
|
||||
log(f'设置图标为{bitmap}')
|
||||
return True
|
||||
except Exception as e:
|
||||
log(str(e), 'ERROR')
|
||||
return False
|
||||
else:
|
||||
self.root.iconbitmap(bitmap, default)
|
||||
return
|
||||
|
||||
def setMenu(self, menuWidgets: dict = {}, debug: bool = False) -> None:
|
||||
'''设置根菜单'''
|
||||
if not menuWidgets:
|
||||
# 如果传入空参数则返回当前菜单
|
||||
try:
|
||||
return self.RootMenu
|
||||
except Exception as E:
|
||||
if debug:
|
||||
raise E
|
||||
else:
|
||||
log('无法读取菜单信息', 'WARRING')
|
||||
# 如果不是空参数则新建菜单
|
||||
self.RootMenu = {}
|
||||
self.mainMenuBar = tk.Menu(self.root)
|
||||
for menuName, menuCmd in menuWidgets.items():
|
||||
# 取得一个菜单名和一堆菜单函数及其显示名称
|
||||
menu = tk.Menu(self.mainMenuBar, tearoff=0)
|
||||
for cmdName, cmdFunc in menuCmd.items():
|
||||
if cmdName:
|
||||
menu.add_command(label=cmdName, command=cmdFunc)
|
||||
else:
|
||||
menu.add_separator()
|
||||
self.mainMenuBar.add_cascade(label=menuName, menu=menu)
|
||||
self.RootMenu[menuName] = menu
|
||||
self.root.config(menu=self.mainMenuBar)
|
||||
|
||||
def addMenu(self, menuRoot: str = '', menuLabel: str = '', menuCommand=None):
|
||||
'''增加一个菜单项
|
||||
:param menuRoot : str
|
||||
菜单的根菜单,即所属的菜单上的文字
|
||||
:param menuLabel : str
|
||||
所需要增加的项目显示的文字
|
||||
:param menuCommand : <function>
|
||||
'''
|
||||
if menuRoot in self.RootMenu.keys:
|
||||
# 如果已经有父菜单
|
||||
if menuLabel:
|
||||
# 增加菜单指令
|
||||
self.RootMenu[menuRoot].add_command(
|
||||
label=menuLabel, command=menuCommand
|
||||
)
|
||||
else:
|
||||
# 增加分隔栏
|
||||
self.RootMenu[menuRoot].add_separator()
|
||||
else:
|
||||
# 没有父菜单则新增一个父菜单
|
||||
menu = tk.Menu(self.mainMenuBar, tearoff=False)
|
||||
if menuLabel:
|
||||
menu.add_command(label=menuLabel, command=menuCommand)
|
||||
else:
|
||||
menu.add_separator()
|
||||
self.mainMenuBar.add_cascade(label=menuRoot, menu=menu)
|
||||
self.RootMenu[menuRoot] = menu
|
||||
|
||||
def initWidget(
|
||||
self,
|
||||
wordView: str = '音·创 Musicreater',
|
||||
buttons: list = [],
|
||||
settingBox: list = [],
|
||||
notemap: list = [],
|
||||
) -> None:
|
||||
'''设置窗口小部件,分为:
|
||||
:言·论 WordView
|
||||
:快捷按钮面板 ButtonBar
|
||||
:设置框 SettingBar
|
||||
:音轨框 TrackBar
|
||||
:各个音轨的显示框 TrackFrame
|
||||
:信息显示版 InfoBar
|
||||
'''
|
||||
self._wordviewBar = tk.Label(self.root, bg='white', fg='black', text=wordView)
|
||||
|
||||
self.setWordView(wordView)
|
||||
|
||||
def setWordView(self, text: str) -> None:
|
||||
self._wordviewBar['text'] = text
|
||||
|
||||
# 预置函数部分
|
||||
def authorMenu(
|
||||
authors: tuple = (
|
||||
('金羿', 'Email EillesWan@outlook.com', 'QQ 2647547478'),
|
||||
('诸葛亮与八卦阵', 'QQ 474037765'),
|
||||
),
|
||||
translaters: tuple = None,
|
||||
):
|
||||
'''自定义作者界面'''
|
||||
from languages.lang import _
|
||||
from languages.lang import DEFAULTLANGUAGE
|
||||
from msctLib.buildIN import version
|
||||
|
||||
aabw = tk.Tk()
|
||||
aabw.title(_('关于'))
|
||||
aabw.geometry('550x600') # 像素
|
||||
tk.Label(aabw, text='', font=('', 15)).pack()
|
||||
tk.Label(aabw, text=_('F音创'), font=('', 35)).pack()
|
||||
tk.Label(
|
||||
aabw,
|
||||
text='{} {}'.format(version.version[1] + version.version[0]),
|
||||
font=('', 15),
|
||||
).pack()
|
||||
# pack 的side可以赋值为LEFT RTGHT TOP BOTTOM
|
||||
# grid 的row 是列数、column是行排,注意,这是针对空间控件本身大小来的,即是指向当前控件的第几个。
|
||||
# place的 x、y是(x,y)坐标
|
||||
tk.Label(
|
||||
aabw,
|
||||
image=tk.PhotoImage(file='./resources/RyounLogo.png'),
|
||||
width=200,
|
||||
height=200,
|
||||
).pack()
|
||||
tk.Label(aabw, text=_('凌云pairs'), font=('', 20)).pack()
|
||||
tk.Label(aabw, text='', font=('', 15)).pack()
|
||||
tk.Label(aabw, text=_('开发者'), font=('', 15)).pack()
|
||||
for i in authors:
|
||||
for j in i:
|
||||
tk.Label(
|
||||
aabw,
|
||||
text=j,
|
||||
font=(
|
||||
'',
|
||||
17 if i.index(j) == 0 else 15,
|
||||
'bold' if i.index(j) == 0 else '',
|
||||
),
|
||||
).pack()
|
||||
tk.Label(aabw, text='', font=('', 5)).pack()
|
||||
if DEFAULTLANGUAGE != 'zh-CN':
|
||||
tk.Label(aabw, text=_('译者'), font=('', 15)).pack()
|
||||
for i in _('TRANSLATERS').split(';'):
|
||||
for j in i.split(','):
|
||||
tk.Label(
|
||||
aabw,
|
||||
text=j,
|
||||
font=(
|
||||
'',
|
||||
17 if i.split(',').index(j) == 0 else 15,
|
||||
'bold' if i.split(',').index(j) == 0 else '',
|
||||
),
|
||||
).pack()
|
||||
|
||||
def exitAboutWindow():
|
||||
aabw.destroy()
|
||||
|
||||
tk.Button(aabw, text=_('确定'), command=exitAboutWindow).pack()
|
||||
|
||||
aabw.mainloop()
|
||||
|
||||
|
||||
class ProgressBar:
|
||||
def __init__(
|
||||
self,
|
||||
root: tk.Tk = tk.Tk(),
|
||||
style: tuple = (DEFAULTBLUE, BLACK, WHITE),
|
||||
type: bool = False,
|
||||
info: str = '',
|
||||
debug: bool = False,
|
||||
) -> None:
|
||||
'''建立一个进度条或者加载等待界面
|
||||
:param root : tk.Tk
|
||||
建立进度条的根窗口
|
||||
:param style : tuple
|
||||
设置主题颜色,第一个参数为进度条或者等待转圈圈的颜色,第二个参数为前景色,第三个是背景色
|
||||
:param type : bool
|
||||
类型,为 False 时为进度条,为 True 时为等待板
|
||||
:param info : str
|
||||
显示的附加信息
|
||||
:param debug : bool
|
||||
是否输出日志到控制台'''
|
||||
self.root = root
|
||||
|
||||
|
||||
if __name__ == '__mian__':
|
||||
import os
|
||||
|
||||
os.chdir('../')
|
||||
disp.authorMenu()
|
||||
6
msctLib/function.py
Normal file
6
msctLib/function.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''音·创的内置功能库
|
||||
:若要加入其他功能,详见:
|
||||
:开发说明|指南'''
|
||||
|
||||
|
||||
82
msctLib/log.py
Normal file
82
msctLib/log.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""音·创的日志消息处理"""
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个
|
||||
|
||||
# 对开发者说的话:
|
||||
#
|
||||
# 请不要修改这里的日志,日志是给开发者和专业人士看的
|
||||
# 而不是给普通用户看的,因此,没必要使用开发者自己也
|
||||
# 不习惯的日志系统,比如说,之前诸葛亮与八卦阵 (bgArray)
|
||||
# 用了 logging 库来改写我原来的日志支持,但是我反
|
||||
# 而找不到我想要的信息了,所以,日志系统给我们开发者
|
||||
# 自己看得好就可以了昂,真的别改了。而且,诸葛八卦改
|
||||
# 了之后并没有多好,喵喵喵,所以我就换回来了。我知道
|
||||
# logging 库比较常用,而且功能也好,但是我们毕竟没
|
||||
# 这个必要,就别用那个库了昂,球球了~
|
||||
# ——金羿 Eilles
|
||||
# 2022 03 09
|
||||
|
||||
# To ALL the developers who will change this part:
|
||||
#
|
||||
# Please do NOT change anything in this file!
|
||||
# The log file is only for developers or
|
||||
# someone who knows a lot about our program
|
||||
# to see, but not the common users. So it
|
||||
# is NOT NECESSARY to use a logging system
|
||||
# that we do not familiar or we do not like.
|
||||
# Take bgAray “诸葛亮与八卦阵” as a example,
|
||||
# he once change this `log.py` into
|
||||
# logging-library-based log support system.
|
||||
# But after the change had done, I could NOT
|
||||
# find useful infomation according to the
|
||||
# log file... So use this file but not to
|
||||
# make changes PLEASE!!! I know some libraries
|
||||
# like logging is usually better than the
|
||||
# simple system in this file and it is normal
|
||||
# to use but, I think it is not necessery,
|
||||
# so PLEASE DO NOT USE OTHER LIBs TO
|
||||
# OVERWRITE MY LIBRARY, THANKS.
|
||||
# ——Eilles 金羿
|
||||
# 03/09/2022
|
||||
|
||||
|
||||
|
||||
import datetime,os
|
||||
|
||||
#载入日志功能
|
||||
StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7]
|
||||
'''字符串型的程序开始时间'''
|
||||
|
||||
|
||||
def log(info:str = '',level : str = 'INFO', isPrinted:bool = False):
|
||||
'''将信息连同当前时间载入日志
|
||||
:param info : str
|
||||
日志信息
|
||||
:param level : str['INFO','WARRING','ERROR','CRASH']
|
||||
或 int[ 1, 2, 3, 4 ]
|
||||
信息等级
|
||||
:param isPrinted : bool
|
||||
是否在控制台打印
|
||||
|
||||
:return bool
|
||||
表示是否完成任务'''
|
||||
|
||||
if type(level) == type(1):
|
||||
level = ['INFO','WARRING','ERROR','CRASH'][level-1]
|
||||
|
||||
try:
|
||||
|
||||
if not os.path.exists('./log/'):
|
||||
os.makedirs('./log/')
|
||||
|
||||
outputinfo = f'{str(datetime.datetime.now())[11:19]}-[{level}] {info}'
|
||||
|
||||
with open('./log/'+StrStartTime+'.msct.log', 'a',encoding='UTF-8') as f:
|
||||
f.write(outputinfo+'\n')
|
||||
|
||||
if isPrinted:
|
||||
print(outputinfo)
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
25
msctLib/settings.py
Normal file
25
msctLib/settings.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
DEFAULTBLUE = (0, 137, 242)
|
||||
WEAKBLUE = (0, 161, 231)
|
||||
LIGHTBLUE = (38, 226, 255)
|
||||
RED = (255, 52, 50)
|
||||
PURPLE = (171, 112, 255)
|
||||
GREEN = (0, 255, 33)
|
||||
WHITE = (242, 244, 246)
|
||||
BLACK = (18, 17, 16)
|
||||
|
||||
settings = {
|
||||
'language' : 'zh-CN',
|
||||
'theme' : {
|
||||
'' : '',
|
||||
},
|
||||
}
|
||||
|
||||
class msctSetting:
|
||||
def __init__(self,**settings) -> None:
|
||||
pass
|
||||
|
||||
def __call__(self, **kwds):
|
||||
pass
|
||||
127
msctLib/开发说明兼指南.md
Normal file
127
msctLib/开发说明兼指南.md
Normal file
@@ -0,0 +1,127 @@
|
||||
开发说明\|指南
|
||||
==============
|
||||
|
||||
此文件旨在使后期欲参与开发之人员减轻其开发负担,同时也为了我们正在开发的人员详细说明功能与用法
|
||||
掌握开发指南之后,在调用函数等的过程中将会更加方便
|
||||
|
||||
文件结构
|
||||
--------
|
||||
|
||||
从主文件调用display.py以实现显示,调用functions.py以使用功能
|
||||
|
||||
functions.py中会调取./addon/目录下的全部功能文件,这些功能文件必须先由./addon/addons.pkl来预先定义好
|
||||
|
||||
详细说明
|
||||
--------
|
||||
|
||||
### msctLib
|
||||
|
||||
用于支持主要功能
|
||||
|
||||
#### display.py
|
||||
|
||||
1. class disp
|
||||
|
||||
- 参数
|
||||
|
||||
1. `**kwgs`对窗口的基础设定 `{ '组件名称' : 函数自设定 }` 例如:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ python
|
||||
{
|
||||
'version': '0.0.1', # version指的是当前配置格式的版本
|
||||
'title': "音·创",
|
||||
'geometry': '1200x900',
|
||||
'iconbitmap': ('./resources/musicreater.ico', './resources/musicreater.ico'),
|
||||
'menu' : { #对setMenu有特殊说明
|
||||
'文件': {
|
||||
'新建': <function>,
|
||||
'打开': <function>,
|
||||
},
|
||||
},
|
||||
'widget': { #对窗口部件又详细说明
|
||||
'wordview':{
|
||||
'text':'言·论',
|
||||
},
|
||||
'settingbox':{}, #后文详细说明
|
||||
'tracklist':{},
|
||||
'operation':{},
|
||||
'map':{},
|
||||
},
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- 函数
|
||||
|
||||
1. `setMenu`对菜单的基础设定
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ python
|
||||
{
|
||||
菜单名 : {
|
||||
选项名 : 选项函数
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
注:
|
||||
`菜单名` : `str` 显示在菜单上的字符串
|
||||
`选项名` : `str` 显示在菜单选项上的字符串
|
||||
`选项函数` : `function` 菜单调取的函数(无返回值,无入参)
|
||||
当 `选项名` 的布尔值判定为 `False` 的时候,无论 `选项函数` 为何,皆插入一段分割线,但 `选项函数` 不得为空
|
||||
|
||||
2. `setWidget`对窗口部件的放置
|
||||
```python
|
||||
wordview: dict = { #言论部分显示的字样
|
||||
'text': str = 显示内容,
|
||||
# ... 即可用 tk.Label 的参数
|
||||
},
|
||||
button: list = [
|
||||
dict = {
|
||||
按钮名称 : tuple(按钮图标,执行函数)
|
||||
},
|
||||
],
|
||||
settingbox: list = [ #设置部分显示的字样及其对应的设置函数
|
||||
(
|
||||
设置名称:str,
|
||||
值类型:tuple,
|
||||
显示内容:str,
|
||||
设置操作函数:<function>,
|
||||
)
|
||||
],
|
||||
map: list = [
|
||||
音符数据
|
||||
]
|
||||
```
|
||||
注:
|
||||
|
||||
上文中,值类型可以是如下几个项
|
||||
1. `('str',)` 字符串类型,使用文本框输入数据
|
||||
2. `('bool',)` 布尔类型,使用复选框输入数据
|
||||
3. `('num',最小值:int,最大值:int,步长:int = 1)` 数值类型,使用数值滑动条输入数据
|
||||
4. `('list',列表项:list)` 单选类型,即列表中多选一,使用单选框输入数据
|
||||
|
||||
值得注意的是,在kwgs中修改的部件设置,可以在其变量中读取或热修改,对应的变量如下
|
||||
|
||||
| 参数 | 对应类中的变量 | 变量类型 | 说明 |
|
||||
|------------|------------------|---------------------------|---------------------|
|
||||
| wordview | wordview | str | 显示在 言·论 区域的文字 |
|
||||
| button | button | list[dict{}] | 操作按钮 |
|
||||
| settingbox | settings | list[ Any ] | 设置项目中的值 |
|
||||
| tracklist | tracknum | tuple(int,int) | 当前选择到的音轨与音轨总数|
|
||||
| map | notes | list[ class Note ] | 当前的音符列表 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 这里是全局设置
|
||||
'name' : str, #项目名,即包名
|
||||
'title': str, #音乐名称
|
||||
'repeation': bool, #是否开启重复播放
|
||||
'player_selection': str, #玩家选择器,用于选择播放的的玩家
|
||||
# 下面是音轨独立设置
|
||||
'track_name': str, #此音轨的名字
|
||||
'track_sbname': str, #此音轨所使用的计分板
|
||||
- 变量
|
||||
使用类中的变量可以对类中的内容进行实时修改
|
||||
49
msctplugin/pluginLoader.py
Normal file
49
msctplugin/pluginLoader.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''此文件为音·创的插件加载程序,为了满足各平台需求,使用的是CLI界面'''
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
Copyright 2022 Eilles Wan (金羿)
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
print("""
|
||||
音·创 插件管理
|
||||
Musicreater PLUGINS Management
|
||||
""")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
msctspt/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/bugReporter.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/bugReporter.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/bugReporter.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/bugReporter.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/funcOpera.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/funcOpera.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/funcOpera.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/funcOpera.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/threadOpera.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/threadOpera.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/threadOpera.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/threadOpera.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/transfer.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/transfer.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/transfer.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/transfer.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/values.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/values.cpython-38.pyc
Normal file
Binary file not shown.
@@ -1,215 +1,218 @@
|
||||
import os
|
||||
import brotli
|
||||
|
||||
'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码'''
|
||||
|
||||
|
||||
class BdxConverter:
|
||||
__header = "BD@"
|
||||
__bin_header = b"BDX"
|
||||
__generator_author = b"&Charlie_Ping"
|
||||
|
||||
keys = {
|
||||
# x--, x++, addSmallX(-128~127), addX(-32768~32767), addBigX(-2147483648~2147483647)
|
||||
"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"],
|
||||
"end": b"\x58",
|
||||
"isSigned": b"\x5a",
|
||||
"placeCommandBlockWithData": b"\x1b",
|
||||
"placeBlock": b"\x07"
|
||||
}
|
||||
|
||||
def __init__(self, file_path: str, author: str, blocks):
|
||||
self.author = author
|
||||
self.blocks = blocks
|
||||
self.file_path = file_path
|
||||
self.direction = [0, 0, 0]
|
||||
self.block_type = self.get_block_type
|
||||
self.__file = self.create_and_upload_file
|
||||
|
||||
@property
|
||||
def get_block_type(self):
|
||||
"""
|
||||
blocks
|
||||
[
|
||||
{
|
||||
"direction": [x: int, y: int, z: int],
|
||||
block_name: str,
|
||||
particular_value: int,
|
||||
}
|
||||
]
|
||||
:return: list 给出的所有方块种类名称
|
||||
"""
|
||||
block_type = set()
|
||||
for block in self.blocks:
|
||||
block_type.add(block["block_name"])
|
||||
block_type = list(block_type)
|
||||
return block_type
|
||||
|
||||
@property
|
||||
def create_and_upload_file(self):
|
||||
"""
|
||||
(瞎用property? 害怕
|
||||
创建一个bdx文件
|
||||
要close!
|
||||
:return: 一个文件对象
|
||||
"""
|
||||
_dir = os.path.dirname(self.file_path)
|
||||
if not os.path.isdir(_dir):
|
||||
os.makedirs(_dir)
|
||||
_bytes = self.__bin_header
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.author.encode("utf-8") + self.__generator_author
|
||||
for i in self.block_type:
|
||||
_bytes += b"\x00\x01"
|
||||
_bytes += bytes(i, encoding="utf-8")
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.upload_blocks()
|
||||
_bytes += b"X"
|
||||
with open(self.file_path, "w+") as f:
|
||||
f.write("BD@")
|
||||
f.close()
|
||||
with open(self.file_path, "ab+") as f:
|
||||
f.write(brotli.compress(_bytes))
|
||||
f.close()
|
||||
return
|
||||
def upload_blocks(self):
|
||||
"""
|
||||
计算差值
|
||||
写入移动过程
|
||||
写入方块
|
||||
更新差值
|
||||
:return:
|
||||
"""
|
||||
_types = b""
|
||||
for block in self.blocks:
|
||||
# print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]")
|
||||
diff = self.move_pointer(self.direction, block["direction"])
|
||||
_types += diff
|
||||
if block["block_name"] in ["command_block",
|
||||
"chain_command_block",
|
||||
"repeating_command_block"]:
|
||||
_types += self.obtain_command_block(block)
|
||||
else:
|
||||
_types += self.obtain_universal_block(block)
|
||||
self.direction = block["direction"]
|
||||
return _types
|
||||
|
||||
def move_pointer(self, direction: list, new_direction):
|
||||
"""
|
||||
给出 两个[x, y, z]坐标,返回pointer的移动过程
|
||||
:param direction: 坐标 1
|
||||
:param new_direction: 坐标 2
|
||||
:return: bytes
|
||||
"""
|
||||
_bytes = b""
|
||||
for i, sign in enumerate(["x", "y", "z"]):
|
||||
# print(f"<{sign}> 新-旧={new_direction[i]-direction[i]}")
|
||||
distance = new_direction[i] - direction[i]
|
||||
if distance == 0:
|
||||
# print("距离是0?跳过了")
|
||||
continue
|
||||
_bytes += self.obtain_pointer_type(distance, sign)
|
||||
# print(f"向 {sign} 运动了 {distance} 格子")
|
||||
return _bytes
|
||||
|
||||
@classmethod
|
||||
def obtain_pointer_type(cls, num: int, coordinate: str):
|
||||
"""
|
||||
|
||||
用于确定辅助玩家以某一数据类型走指定长度
|
||||
|
||||
-1 -> 0
|
||||
1 -> 1
|
||||
[128, 127] -> 2
|
||||
[-32768, 32767] -> 3
|
||||
[-2147483648, 2147483647] -> 4
|
||||
:param num:
|
||||
:param coordinate: 坐标轴种类,x y 或 z
|
||||
:return:
|
||||
"""
|
||||
if num == 0:
|
||||
return
|
||||
pointer = 0
|
||||
condition = (num != -1, # byte=0, pointer=1
|
||||
num < -1 or num > 1, # byte=1, pointer=2
|
||||
num < -128 or num > 127, # byte=2, pointer=3
|
||||
num < -32768 or num > 32767, # byte=4, pointer=4
|
||||
)
|
||||
for i in condition:
|
||||
if i:
|
||||
pointer += 1
|
||||
pointer_type = cls.keys[coordinate][pointer]
|
||||
|
||||
byte_len = 2 ** (pointer - 2)
|
||||
if byte_len >= 1:
|
||||
num_byte = num.to_bytes(byte_len, byteorder="big", signed=True)
|
||||
return pointer_type + num_byte
|
||||
return pointer_type
|
||||
|
||||
def obtain_universal_block(self, block):
|
||||
"""
|
||||
给定一个方块, 返回此方块在这个bdx中的id和方块data
|
||||
:param block: {block_name: str,particular_value: int}
|
||||
:return: bytes
|
||||
"""
|
||||
block_id = b"\x07" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
return block_header
|
||||
|
||||
def obtain_command_block(self, block):
|
||||
"""
|
||||
给定一个命令方块,返回命令方块各种数据
|
||||
:param block: {
|
||||
"direction": [x: int, y: int, z: int]
|
||||
"block_name": str,
|
||||
"particular_value": int,
|
||||
"impluse": int, # unsigned_int32
|
||||
"command": str,
|
||||
"customName": str,
|
||||
"lastOutput": str, # 没特殊要求写个\x00就得了
|
||||
"tickdelay": int, # int32
|
||||
"executeOnFirstTick": int, # 1 bytes
|
||||
"trackOutput": int, # 1 bytes
|
||||
"conditional": int, # 1 bytes
|
||||
"needRedstone": int # 1 bytes
|
||||
}
|
||||
:return: bytes of command_block
|
||||
"""
|
||||
|
||||
block_id = b"\x1b" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
for i in [
|
||||
block["impluse"].to_bytes(4, byteorder="big", signed=False),
|
||||
bytes(block["command"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["customName"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["lastOutput"], encoding="utf-8") + b"\x00",
|
||||
block["tickdelay"].to_bytes(4, byteorder="big", signed=True),
|
||||
block["executeOnFirstTick"].to_bytes(1, byteorder="big"),
|
||||
block["trackOutput"].to_bytes(1, byteorder="big"),
|
||||
block["conditional"].to_bytes(1, byteorder="big"),
|
||||
block["needRedstone"].to_bytes(1, byteorder="big")
|
||||
]:
|
||||
block_header += i
|
||||
return block_header
|
||||
|
||||
if __name__ == '__main__':
|
||||
block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5},
|
||||
{"direction": [1, 5, 1], "block_name": "stained_glass", "particular_value": 7},
|
||||
{"direction": [2, 4, 1], "block_name": "command_block", "particular_value": 3,
|
||||
"impluse": 0,
|
||||
"command": "say A generator test",
|
||||
"customName": "test",
|
||||
"lastOutput": "",
|
||||
"tickdelay": 24,
|
||||
"executeOnFirstTick": 0,
|
||||
"trackOutput": 0,
|
||||
"conditional": 0,
|
||||
"needRedstone": 1
|
||||
},
|
||||
{"direction": [3, 4, 1], "block_name": "concrete", "particular_value": 6},
|
||||
{"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}]
|
||||
bdx = BdxConverter("./test02.bdx", "Charlie_Ping",block)
|
||||
import os
|
||||
import brotli
|
||||
|
||||
'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码'''
|
||||
|
||||
|
||||
class BdxConverter:
|
||||
__header = "BD@"
|
||||
__bin_header = b"BDX"
|
||||
__generator_author = b"&Musicreater"
|
||||
|
||||
keys = {
|
||||
# x--, x++, addSmallX(-128~127), addX(-32768~32767), addBigX(-2147483648~2147483647)
|
||||
"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"],
|
||||
"end": b"\x58",
|
||||
"isSigned": b"\x5a",
|
||||
"placeCommandBlockWithData": b"\x1b",
|
||||
"placeBlock": b"\x07"
|
||||
}
|
||||
|
||||
def __init__(self, file_path: str, author: str, blocks):
|
||||
self.author = author
|
||||
self.blocks = blocks
|
||||
self.file_path = file_path
|
||||
self.direction = [0, 0, 0]
|
||||
self.block_type = self.get_block_type
|
||||
self.__file = self.create_and_upload_file
|
||||
|
||||
@property
|
||||
def get_block_type(self):
|
||||
"""
|
||||
blocks
|
||||
[
|
||||
{
|
||||
"direction": [x: int, y: int, z: int],
|
||||
block_name: str,
|
||||
particular_value: int,
|
||||
}
|
||||
]
|
||||
:return: list 给出的所有方块种类名称
|
||||
"""
|
||||
block_type = set()
|
||||
for block in self.blocks:
|
||||
block_type.add(block["block_name"])
|
||||
block_type = list(block_type)
|
||||
return block_type
|
||||
|
||||
@property
|
||||
def create_and_upload_file(self):
|
||||
"""
|
||||
创建一个bdx文件
|
||||
:return: 一个文件对象
|
||||
"""
|
||||
_dir = os.path.dirname(self.file_path)
|
||||
if not os.path.isdir(_dir):
|
||||
os.makedirs(_dir)
|
||||
_bytes = self.__bin_header
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.author.encode("utf-8") + self.__generator_author
|
||||
for i in self.block_type:
|
||||
_bytes += b"\x00\x01"
|
||||
_bytes += bytes(i, encoding="utf-8")
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.upload_blocks()
|
||||
_bytes += b"X"
|
||||
with open(self.file_path, "w+") as f:
|
||||
f.write("BD@")
|
||||
f.close()
|
||||
with open(self.file_path, "ab+") as f:
|
||||
f.write(brotli.compress(_bytes))
|
||||
f.close()
|
||||
return open(self.file_path,'a+')
|
||||
|
||||
def upload_blocks(self):
|
||||
"""
|
||||
计算差值
|
||||
写入移动过程
|
||||
写入方块
|
||||
更新差值
|
||||
:return:
|
||||
"""
|
||||
_types = b""
|
||||
|
||||
|
||||
for block in self.blocks:
|
||||
# print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]")
|
||||
diff = self.move_pointer(self.direction, block["direction"])
|
||||
_types += diff
|
||||
if block["block_name"] in ["command_block",
|
||||
"chain_command_block",
|
||||
"repeating_command_block"]:
|
||||
_types += self.obtain_command_block(block)
|
||||
else:
|
||||
_types += self.obtain_universal_block(block)
|
||||
self.direction = block["direction"]
|
||||
|
||||
|
||||
return _types
|
||||
|
||||
def move_pointer(self, direction: list, new_direction):
|
||||
"""
|
||||
给出 两个[x, y, z]坐标,返回pointer的移动过程
|
||||
:param direction: 坐标 1
|
||||
:param new_direction: 坐标 2
|
||||
:return: bytes
|
||||
"""
|
||||
_bytes = b""
|
||||
for i, sign in enumerate(["x", "y", "z"]):
|
||||
# print(f"<{sign}> 新-旧={new_direction[i]-direction[i]}")
|
||||
distance = new_direction[i] - direction[i]
|
||||
if distance == 0:
|
||||
# print("距离是0?跳过了")
|
||||
continue
|
||||
_bytes += self.obtain_pointer_type(distance, sign)
|
||||
# print(f"向 {sign} 运动了 {distance} 格子")
|
||||
return _bytes
|
||||
|
||||
@classmethod
|
||||
def obtain_pointer_type(cls, num: int, coordinate: str):
|
||||
"""
|
||||
|
||||
用于确定辅助玩家以某一数据类型走指定长度
|
||||
|
||||
-1 -> 0
|
||||
1 -> 1
|
||||
[128, 127] -> 2
|
||||
[-32768, 32767] -> 3
|
||||
[-2147483648, 2147483647] -> 4
|
||||
:param num:
|
||||
:param coordinate: 坐标轴种类,x y 或 z
|
||||
:return:
|
||||
"""
|
||||
if num == 0:
|
||||
return
|
||||
pointer = 0
|
||||
condition = (num != -1, # byte=0, pointer=1
|
||||
num < -1 or num > 1, # byte=1, pointer=2
|
||||
num < -128 or num > 127, # byte=2, pointer=3
|
||||
num < -32768 or num > 32767, # byte=4, pointer=4
|
||||
)
|
||||
for i in condition:
|
||||
if i:
|
||||
pointer += 1
|
||||
pointer_type = cls.keys[coordinate][pointer]
|
||||
|
||||
byte_len = 2 ** (pointer - 2)
|
||||
if byte_len >= 1:
|
||||
num_byte = num.to_bytes(byte_len, byteorder="big", signed=True)
|
||||
return pointer_type + num_byte
|
||||
return pointer_type
|
||||
|
||||
def obtain_universal_block(self, block):
|
||||
"""
|
||||
给定一个方块, 返回此方块在这个bdx中的id和方块data
|
||||
:param block: {block_name: str,particular_value: int}
|
||||
:return: bytes
|
||||
"""
|
||||
block_id = b"\x07" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
return block_header
|
||||
|
||||
def obtain_command_block(self, block):
|
||||
"""
|
||||
给定一个命令方块,返回命令方块各种数据
|
||||
:param block: {
|
||||
"direction": [x: int, y: int, z: int]
|
||||
"block_name": str,
|
||||
"particular_value": int,
|
||||
"impluse": int, # unsigned_int32
|
||||
"command": str,
|
||||
"customName": str,
|
||||
"lastOutput": str, # 没特殊要求写个\x00就得了
|
||||
"tickdelay": int, # int32
|
||||
"executeOnFirstTick": int, # 1 bytes
|
||||
"trackOutput": int, # 1 bytes
|
||||
"conditional": int, # 1 bytes
|
||||
"needRedstone": int # 1 bytes
|
||||
}
|
||||
:return: bytes of command_block
|
||||
"""
|
||||
|
||||
block_id = b"\x1b" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
for i in [
|
||||
block["impluse"].to_bytes(4, byteorder="big", signed=False),
|
||||
bytes(block["command"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["customName"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["lastOutput"], encoding="utf-8") + b"\x00",
|
||||
block["tickdelay"].to_bytes(4, byteorder="big", signed=True),
|
||||
block["executeOnFirstTick"].to_bytes(1, byteorder="big"),
|
||||
block["trackOutput"].to_bytes(1, byteorder="big"),
|
||||
block["conditional"].to_bytes(1, byteorder="big"),
|
||||
block["needRedstone"].to_bytes(1, byteorder="big")
|
||||
]:
|
||||
block_header += i
|
||||
return block_header
|
||||
|
||||
if __name__ == '__main__':
|
||||
block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5},
|
||||
{"direction": [1, 5, 1], "block_name": "stained_glass", "particular_value": 7},
|
||||
{"direction": [2, 4, 1], "block_name": "command_block", "particular_value": 3,
|
||||
"impluse": 0,
|
||||
"command": "say A generator test",
|
||||
"customName": "test",
|
||||
"lastOutput": "",
|
||||
"tickdelay": 24,
|
||||
"executeOnFirstTick": 0,
|
||||
"trackOutput": 0,
|
||||
"conditional": 0,
|
||||
"needRedstone": 1
|
||||
},
|
||||
{"direction": [3, 4, 1], "block_name": "concrete", "particular_value": 6},
|
||||
{"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}]
|
||||
bdx = BdxConverter("./test02.bdx", "Charlie_Ping",block)
|
||||
137
msctspt/bugReporter.py
Normal file
137
msctspt/bugReporter.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能"""
|
||||
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:1个;语法(一级)错误:72个
|
||||
import os
|
||||
|
||||
|
||||
def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||
import zipfile
|
||||
"""使用compression指定的算法打包目录为zip文件\n
|
||||
默认算法为DEFLATED(8),可用算法如下:\n
|
||||
STORED = 0\n
|
||||
DEFLATED = 8\n
|
||||
BZIP2 = 12\n
|
||||
LZMA = 14\n
|
||||
"""
|
||||
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
|
||||
print(filename)
|
||||
pathfile = os.path.join(parent, filename)
|
||||
arcname = pathfile[pre_len:].strip(os.path.sep) # 相对路径
|
||||
zipf.write(pathfile, arcname)
|
||||
|
||||
zipf.close()
|
||||
del zipf, pre_len
|
||||
|
||||
|
||||
# 以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942
|
||||
|
||||
|
||||
class report:
|
||||
"""发送报告以及相应的任务处理"""
|
||||
|
||||
def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''):
|
||||
""":param senderName 发送者名称
|
||||
:param senderContact 发送者联系方式
|
||||
:param describetion 问题描述"""
|
||||
self.senderName = senderName
|
||||
self.senderContact = senderContact
|
||||
self.describetion = describetion
|
||||
if not self.senderName:
|
||||
self.senderName = 'Unknown'
|
||||
if not self.senderContact:
|
||||
self.senderContact = 'None'
|
||||
|
||||
def emailReport(self):
|
||||
"""使用E-mail方法发送当前的日志和临时文件等"""
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.header import Header
|
||||
from nmcsup.log import log
|
||||
log("发送错误报告")
|
||||
import os
|
||||
log("添加标题与正文")
|
||||
msg = MIMEMultipart()
|
||||
# 发送者与接收者显示名称
|
||||
msg["From"] = Header(self.senderName, 'utf-8')
|
||||
msg["To"] = Header("W-YI (QQ2647547478)", 'utf-8')
|
||||
# 标题
|
||||
msg["Subject"] = '音·创 - 来自 ' + self.senderName + ' 的错误报告'
|
||||
# 正文
|
||||
msg.attach(
|
||||
MIMEText("来自" + self.senderName + "( " + self.senderContact + " )的错误描述:\n" + self.describetion,
|
||||
'utf-8'))
|
||||
log("添加完毕,正在生成压缩包...")
|
||||
makeZip("./", "Temps&Logs.zip", exceptFile="Temps&Logs.zip")
|
||||
attafile = MIMEText(str(open("Temps&Logs.zip", 'rb').read()), "base64", 'gb2312')
|
||||
attafile["Content-Type"] = 'application/octet-stream'
|
||||
attafile["Content-Disposition"] = 'attachmentfilename="BugReport_from_' + self.senderName + '.zip"'
|
||||
msg.attach(attafile)
|
||||
log("完毕,准备发送")
|
||||
try:
|
||||
smtp = smtplib.SMTP()
|
||||
smtp.connect("smtp.163.com")
|
||||
# smtp.login("RyounDevTeam@163.com","RyounDaiYi99")
|
||||
# SIQQKQQYCZRVIDFJ是授权密码
|
||||
smtp.login("RyounDevTeam@163.com", "SIQQKQQYCZRVIDFJ")
|
||||
smtp.sendmail("RyounDevTeam@163.com", ["RyounDevTeam@163.com", ], msg.as_string())
|
||||
log("错误汇报邮件已发送")
|
||||
except smtplib.SMTPException as e:
|
||||
log("错误汇报邮件发送失败:\n" + str(e))
|
||||
log("清空内存和临时文件")
|
||||
del msg, attafile
|
||||
os.remove("./Temps&Logs.zip")
|
||||
|
||||
|
||||
class version:
|
||||
libraries = (
|
||||
'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin',
|
||||
'pyinstaller', 'py7zr','websockets', 'torch', 'requests'
|
||||
)
|
||||
"""当前所需库"""
|
||||
|
||||
version = ('0.2.0', 'Delta',)
|
||||
"""当前版本"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.libraries = version.libraries
|
||||
"""当前所需库"""
|
||||
|
||||
self.version = version.version
|
||||
"""当前版本"""
|
||||
|
||||
|
||||
def installLibraries(self,index:str = 'https://pypi.tuna.tsinghua.edu.cn/simple'):
|
||||
"""安装全部开发用库"""
|
||||
from sys import platform
|
||||
import os
|
||||
if platform == 'win32':
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"python -m pip install {i} -i {index}")
|
||||
elif platform == 'linux':
|
||||
os.system("sudo apt-get install python3-pip")
|
||||
os.system("sudo apt-get install python3-tk")
|
||||
os.system("sudo apt-get install python3-tkinter")
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"sudo python3 -m pip install {i} -i {index}")
|
||||
|
||||
|
||||
def __call__(self):
|
||||
'''直接安装库,顺便返回一下当前版本'''
|
||||
self.installLibraries()
|
||||
return self.version
|
||||
422
msctspt/funcOpera.py
Normal file
422
msctspt/funcOpera.py
Normal file
@@ -0,0 +1,422 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""音·创 的函数操作和一些其他功能"""
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:91个
|
||||
|
||||
|
||||
from nmcsup.log import log
|
||||
|
||||
|
||||
def delPart(Data, starter, ender, includeStart: bool = True, includend: bool = True):
|
||||
"""删除序列从starter物件到ender物件之间的部分\n
|
||||
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n
|
||||
starter与ender若为None则默认从首或尾开始"""
|
||||
try:
|
||||
if starter is None:
|
||||
includeStart = True
|
||||
starter = Data[0]
|
||||
if ender is None:
|
||||
includend = True
|
||||
ender = Data[len(Data) - 1]
|
||||
if includend:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender)]
|
||||
else:
|
||||
return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender)]
|
||||
else:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender) - 1]
|
||||
else:
|
||||
return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender) - 1]
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
def keepart(Data, starter, ender, includeStart: bool = True, includend: bool = True):
|
||||
"""保留序列从starter物件到ender物件之间的部分\n
|
||||
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n
|
||||
starter与ender若为None则默认从首或尾开始"""
|
||||
try:
|
||||
if starter is None:
|
||||
includeStart = True
|
||||
starter = Data[0]
|
||||
if ender is None:
|
||||
includend = True
|
||||
ender = Data[len(Data) - 1]
|
||||
if includend:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):Data.index(ender) + 1]
|
||||
else:
|
||||
return Data[Data.index(starter) + 1:Data.index(ender) + 1]
|
||||
else:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):Data.index(ender)]
|
||||
else:
|
||||
return Data[Data.index(starter) + 1:Data.index(ender)]
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
def lenFunction(fun) -> int:
|
||||
"""取得函数指令部分长度,即忽略#开头的注释"""
|
||||
try:
|
||||
f = 0
|
||||
for i in fun:
|
||||
if i.replace(" ", '')[0] == '#':
|
||||
f += 1
|
||||
return len(fun) - f
|
||||
except:
|
||||
return -1
|
||||
|
||||
|
||||
def funSplit(bigFile, maxCmdLen: int = 10000):
|
||||
"""分割bigFile大的函数文件,bigFile需要读入文件流\n
|
||||
返回的部分,每行指令皆带有行尾换行符\\n\n
|
||||
返回-1为大小低于maxCmdLen最长函数指令长度"""
|
||||
bigFile = bigFile.readlines()
|
||||
if lenFunction(bigFile) < maxCmdLen:
|
||||
return -1
|
||||
part = []
|
||||
parts = []
|
||||
h = 0
|
||||
for i in bigFile:
|
||||
if i.replace(" ", '')[0] == '#':
|
||||
part.append(i + '\n')
|
||||
else:
|
||||
part.append(i + '\n')
|
||||
h += 1
|
||||
if h >= 10000:
|
||||
parts.append(part)
|
||||
part = []
|
||||
h = 0
|
||||
return parts
|
||||
|
||||
|
||||
def makeFuncFiles(musicset, path='./'):
|
||||
"""在指定目录下生成函数文件"""
|
||||
from nmcsup.trans import Note2Cmd
|
||||
commands = []
|
||||
starts = []
|
||||
log("=========================正在在此处生成文件:" + path)
|
||||
maxlen = -1
|
||||
for i in range(len(musicset['musics'])):
|
||||
log('写入第' + str(i) + '个数据')
|
||||
commands.append("scoreboard players add @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\"] " +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + " 1\n")
|
||||
commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'][
|
||||
'PlayerSelect'] + " title " + musicset['mainset']['MusicTitle'] + "\n")
|
||||
commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'][
|
||||
'PlayerSelect'] + " subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\n")
|
||||
if len(musicset['musics'][i]['notes']) > maxlen:
|
||||
maxlen = len(musicset['musics'][i]['notes'])
|
||||
starts.append("scoreboard objectives add " + musicset['musics'][i]['set']['ScoreboardName'] + " dummy\n")
|
||||
starts.append("summon armor_stand " + musicset['musics'][i]['set']['EntityName'] + '\n')
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w',
|
||||
encoding='UTF-8') as f:
|
||||
f.writelines(Note2Cmd(musicset['musics'][i]['notes'], musicset['musics'][i]['set']['ScoreboardName'],
|
||||
musicset['musics'][i]['set']['Instrument'], musicset['mainset']['PlayerSelect'],
|
||||
True))
|
||||
if musicset['mainset']['IsRepeat']:
|
||||
log("增加重复语句")
|
||||
for i in range(len(musicset['musics'])):
|
||||
commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + "=" + str(
|
||||
(maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][
|
||||
'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n")
|
||||
log("增加版权语句")
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
log("写入支持文件")
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(commands)
|
||||
log("写入开始文件")
|
||||
with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(starts)
|
||||
del commands, starts, maxlen
|
||||
log("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeFunDir(musicset, path='./'):
|
||||
"""在指定目录下生成函数包文件夹"""
|
||||
import os
|
||||
import uuid
|
||||
log("=============================生成函数包文件夹")
|
||||
# note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support',
|
||||
# MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp'
|
||||
try:
|
||||
os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
except FileExistsError:
|
||||
log("目录已有无需创建")
|
||||
pass
|
||||
# 判断文件皆存在
|
||||
if not (os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/manifest.json")):
|
||||
log("创建manifest.json以及world_behavior_packs.json")
|
||||
behaviorUuid = uuid.uuid4()
|
||||
with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f:
|
||||
f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]")
|
||||
p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \
|
||||
"/manifest.json"
|
||||
with open(p, "w") as f:
|
||||
f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" +
|
||||
musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str(
|
||||
behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":"
|
||||
" [ 0, 0, 1 ],\n \"uuid\": \"" + str(
|
||||
uuid.uuid4()) + "\"\n }\n ]\n}")
|
||||
makeFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions/")
|
||||
log("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeNewFuncFiles(musicset, path='./', isProsess:bool = False):
|
||||
"""在指定目录下生成函数文件"""
|
||||
from msctspt.transfer import newList_conversion_SinglePlayer
|
||||
commands = []
|
||||
starts = []
|
||||
starts.__len__()
|
||||
starts.append("scoreboard objectives add " + musicset['musics'][0]['set']['ScoreboardName'] + " dummy\n")
|
||||
# starts.append("summon armor_stand " + musicset['musics'][0]['set']['EntityName'] + '\n')
|
||||
# starts.append("scoreboard objectives setdisplay sidebar " + musicset['musics'][0]['set']['ScoreboardName'] + '\n')
|
||||
# starts.append("scoreboard players set @e[type=armor_stand, name=\"" + musicset['musics'][0]['set']['EntityName'] +"\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 0" + '\n')
|
||||
|
||||
log("=========================正在在此处生成文件:" + path)
|
||||
|
||||
# commands.append("scoreboard players add @e[name=\"" + musicset['musics'][0]['set']['EntityName'] + "\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 1\n")
|
||||
maxlen = -1
|
||||
for i in range(len(musicset['musics'])):
|
||||
log('写入第' + str(i) + '个数据')
|
||||
|
||||
if len(musicset['musics'][i]['notes']) > maxlen:
|
||||
maxlen = len(musicset['musics'][i]['notes'])
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w',
|
||||
encoding='UTF-8') as f:
|
||||
f.writelines(newList_conversion_SinglePlayer(musicset['musics'][i]['notes'],
|
||||
musicset['musics'][i]['set']['ScoreboardName'],
|
||||
musicset['musics'][i]['set']['Instrument']))
|
||||
if musicset['mainset']['IsRepeat']:
|
||||
log("增加重复语句")
|
||||
for i in range(len(musicset['musics'])):
|
||||
commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + "=" + str(
|
||||
(maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][
|
||||
'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n")
|
||||
log("增加版权语句")
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n")
|
||||
starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n")
|
||||
log("写入支持文件")
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(commands)
|
||||
log("写入开始文件")
|
||||
with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(starts)
|
||||
del commands, starts, maxlen
|
||||
log("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeNewFunDir(musicset, path='./'):
|
||||
"""在指定目录下生成函数包文件夹"""
|
||||
import os
|
||||
import uuid
|
||||
log("=============================生成函数包文件夹")
|
||||
# note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support',
|
||||
# MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp'
|
||||
try:
|
||||
os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
except FileExistsError:
|
||||
log("目录已有无需创建")
|
||||
pass
|
||||
# 判断文件皆存在
|
||||
if not (os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/manifest.json")):
|
||||
log("创建manifest.json以及world_behavior_packs.json")
|
||||
behaviorUuid = uuid.uuid4()
|
||||
with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f:
|
||||
f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]")
|
||||
p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \
|
||||
"/manifest.json"
|
||||
with open(p, "w") as f:
|
||||
f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" +
|
||||
musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str(
|
||||
behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":"
|
||||
" [ 0, 0, 1 ],\n \"uuid\": \"" + str(
|
||||
uuid.uuid4()) + "\"\n }\n ]\n}")
|
||||
makeNewFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions/")
|
||||
log("完成============================")
|
||||
|
||||
|
||||
def makeClassFuncFiles(musicset, path='./'):
|
||||
"""在指定目录下生成函数文件"""
|
||||
from msctspt.transfer import classList_conversion_SinglePlayer
|
||||
commands = []
|
||||
starts = []
|
||||
starts.__len__()
|
||||
starts.append("scoreboard objectives add " + musicset['musics'][0]['set']['ScoreboardName'] + " dummy\n")
|
||||
starts.append("summon armor_stand " + musicset['musics'][0]['set']['EntityName'] + '\n')
|
||||
starts.append("scoreboard objectives setdisplay sidebar " + musicset['musics'][0]['set']['ScoreboardName'] + '\n')
|
||||
starts.append("scoreboard players set @e[type=armor_stand, name=\"" + musicset['musics'][0]['set']['EntityName'] +
|
||||
"\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 0" + '\n')
|
||||
log("=========================正在在此处生成文件:" + path)
|
||||
commands.append("scoreboard players add @e[name=\"" + musicset['musics'][0]['set']['EntityName'] + "\"] " +
|
||||
musicset['musics'][0]['set']['ScoreboardName'] + " 1\n")
|
||||
maxlen = -1
|
||||
for i in range(len(musicset['musics'])):
|
||||
log('写入第' + str(i) + '个数据')
|
||||
# commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
# musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset']
|
||||
# [
|
||||
# 'PlayerSelect'] + " title " + musicset['mainset']['MusicTitle'] + "\n")
|
||||
# commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
# musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset']
|
||||
# [
|
||||
# 'PlayerSelect'] + " subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\n")
|
||||
if len(musicset['musics'][i]['notes']) > maxlen:
|
||||
maxlen = len(musicset['musics'][i]['notes'])
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w',
|
||||
encoding='UTF-8') as f:
|
||||
f.writelines(classList_conversion_SinglePlayer(musicset['musics'][i]['notes'],
|
||||
musicset['musics'][i]['set']['ScoreboardName'],
|
||||
musicset['mainset']['PlayerSelect'],
|
||||
True))
|
||||
if musicset['mainset']['IsRepeat']:
|
||||
log("增加重复语句")
|
||||
for i in range(len(musicset['musics'])):
|
||||
commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" +
|
||||
musicset['musics'][i]['set']['ScoreboardName'] + "=" + str(
|
||||
(maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][
|
||||
'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n")
|
||||
log("增加版权语句")
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n")
|
||||
starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n")
|
||||
log("写入支持文件")
|
||||
with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(commands)
|
||||
log("写入开始文件")
|
||||
with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(starts)
|
||||
del commands, starts, maxlen
|
||||
log("完成============================")
|
||||
|
||||
|
||||
def makeClassFunDir(musicset, path='./'):
|
||||
"""在指定目录下生成函数包文件夹"""
|
||||
import os
|
||||
import uuid
|
||||
log("=============================生成函数包文件夹")
|
||||
# note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support',
|
||||
# MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp'
|
||||
try:
|
||||
os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions")
|
||||
except FileExistsError:
|
||||
log("目录已有无需创建")
|
||||
pass
|
||||
# 判断文件皆存在
|
||||
if not (os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists(
|
||||
path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/manifest.json")):
|
||||
log("创建manifest.json以及world_behavior_packs.json")
|
||||
behaviorUuid = uuid.uuid4()
|
||||
with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f:
|
||||
f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]")
|
||||
p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \
|
||||
"/manifest.json"
|
||||
with open(p, "w") as f:
|
||||
f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" +
|
||||
musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str(
|
||||
behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][
|
||||
'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":"
|
||||
" [ 0, 0, 1 ],\n \"uuid\": \"" + str(
|
||||
uuid.uuid4()) + "\"\n }\n ]\n}")
|
||||
makeClassFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
|
||||
'PackName'] + "/functions/")
|
||||
log("完成============================")
|
||||
|
||||
|
||||
"""
|
||||
这里是往事,用于记载一些用不到的功能
|
||||
|
||||
#存在于 Musicreater.py 播放(试听)音乐
|
||||
def PlayNote(Notes, t=480): # Notes是音符列表,t是一拍占有的毫秒数
|
||||
tkinter.messagebox.showinfo(title='提示!', message="播放发音不一定标准\n说不定还会坏音响/(ㄒoㄒ)/~~qwq\n请注意。")
|
||||
import winsound
|
||||
import time
|
||||
from nmcsup.trans import mcnote2freq
|
||||
Notes = mcnote2freq(Notes)
|
||||
for frequency, duration in Notes:
|
||||
log("播放:"+str([int(frequency), int(duration*t)]))
|
||||
if int(frequency) != 0:
|
||||
winsound.Beep(int(frequency), int(duration*t))
|
||||
elif int(frequency) == 0:
|
||||
time.sleep(duration*t/1000)
|
||||
|
||||
#同上,执行播放命令
|
||||
def PlayOne():
|
||||
log("试听")
|
||||
tkinter.messagebox.showwarning(title="警告⚠", message="试听音质可能引起您的不适,更可能引起您的扬声器的不适,请酌情播放。")
|
||||
global NowMusic
|
||||
PlayNote(dataset[0]['musics'][NowMusic]['notes'])
|
||||
|
||||
|
||||
|
||||
#同上,是早期 MinecraftMusicFunctionMaker.py (函数音创)的代码转移至音·创时的注解
|
||||
n2c(dataset[0]['musics'][i]['notes'],EntityName=dataset[0]['musics'][i]['set']['EntityName'],ScoreboardName=dataset[0]['
|
||||
musics'][i]['set']['ScoreboardName'],PlayerSelect=dataset[0]['mainset']['PlayerSelect'],Instrument=dataset[0]['musics']
|
||||
i]['set']["Instrument"])
|
||||
|
||||
|
||||
"""
|
||||
@@ -1,27 +1,27 @@
|
||||
|
||||
|
||||
|
||||
import threading
|
||||
|
||||
|
||||
class NewThread(threading.Thread):
|
||||
'''新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值'''
|
||||
def __init__(self, func, args=()):
|
||||
super(NewThread, self).__init__()
|
||||
self.func = func
|
||||
self.args = args
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
def getResult(self):
|
||||
threading.Thread.join(self) # 等待线程执行完毕
|
||||
try:
|
||||
return self.result
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
#
|
||||
# ————————————————
|
||||
# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014
|
||||
# ————————————————
|
||||
|
||||
|
||||
|
||||
import threading
|
||||
|
||||
|
||||
class NewThread(threading.Thread):
|
||||
'''新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值'''
|
||||
def __init__(self, func, args=()):
|
||||
super(NewThread, self).__init__()
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.result = None
|
||||
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
|
||||
def getResult(self):
|
||||
threading.Thread.join(self) # 等待线程执行完毕
|
||||
return self.result
|
||||
|
||||
#
|
||||
# ————————————————
|
||||
# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014
|
||||
# ————————————————
|
||||
#
|
||||
569
msctspt/transfer.py
Normal file
569
msctspt/transfer.py
Normal file
@@ -0,0 +1,569 @@
|
||||
"""音·创 的转换工具库"""
|
||||
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:4个--未解决1个;语法(一级)错误:302个
|
||||
|
||||
|
||||
# 可序列化对象,即可迭代对象
|
||||
from typing import Iterable
|
||||
|
||||
import amulet
|
||||
|
||||
from amulet.api.block import Block
|
||||
from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc
|
||||
from amulet_nbt import TAG_String as ts
|
||||
from nmcsup.log import log
|
||||
|
||||
|
||||
def hans2pinyin(hans, style=3):
|
||||
"""将汉字字符串转化为拼音字符串"""
|
||||
from pypinyin import lazy_pinyin
|
||||
result = lazy_pinyin(hans=hans, style=style)
|
||||
final = ''
|
||||
for i in result:
|
||||
final += i
|
||||
return final
|
||||
|
||||
|
||||
def classList_conversion_SinglePlayer(List: list, ScoreboardName: str, playerSelection: str = '',
|
||||
isProsess: bool = False) -> list:
|
||||
from bgArrayLib.compute import round_up
|
||||
from bgArrayLib.pitchStrConstant import pitch
|
||||
from bgArrayLib.instrumentConstant import instrument_list
|
||||
commands = []
|
||||
length = len(List)
|
||||
j = 1
|
||||
print(List)
|
||||
for k in range(len(List)):
|
||||
i = List[k][0]
|
||||
print(i)
|
||||
print(type(i))
|
||||
try:
|
||||
commands.append(
|
||||
f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}="
|
||||
f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~{127 - i.velocity} "
|
||||
f"~ playsound note.{instrument_list.get(str(i.instrument))} @s ~ ~ ~ "
|
||||
f"1000 {pitch.get(str(i.pitch))} 1000\n")
|
||||
if isProsess:
|
||||
commands.append(
|
||||
f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}="
|
||||
f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~ ~ "
|
||||
f"title @s actionbar §e▶ 播放中: §a{j}/{length} || {int(j / length * 1000) / 10}\n")
|
||||
j += 1
|
||||
except Exception:
|
||||
pass
|
||||
# a += List[i][1]
|
||||
# commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
print(commands)
|
||||
return commands
|
||||
|
||||
|
||||
def newList_conversion_SinglePlayer(List: list, ScoreboardName: str, playerSelection: str = '',
|
||||
isProsess: bool = False) -> list:
|
||||
from bgArrayLib.compute import round_up
|
||||
commands = []
|
||||
length = len(List)
|
||||
j = 1
|
||||
print(List)
|
||||
for k in range(len(List)):
|
||||
i = List[k][0]
|
||||
print(i)
|
||||
print(type(i))
|
||||
try:
|
||||
if i.instrument > 119:
|
||||
pass
|
||||
else:
|
||||
commands.append(
|
||||
f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}="
|
||||
f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~{127 - i.velocity} "
|
||||
f"~ playsound {i.instrument}{i.CD}.{i.pitch} @s ~ ~ ~ 1000 1.0 1000\n")
|
||||
if isProsess:
|
||||
commands.append(
|
||||
f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}="
|
||||
f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~ ~ "
|
||||
f"title @s actionbar §e▶ 播放中: §a{j}/{length} || {int(j / length * 1000) / 10}\n")
|
||||
j += 1
|
||||
except:
|
||||
pass
|
||||
# a += List[i][1]
|
||||
# commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
print(commands)
|
||||
return commands
|
||||
|
||||
|
||||
def classList_conversion(List: list, ScoreboardName: str, isProsess: bool = False) -> list:
|
||||
from bgArrayLib.compute import round_up
|
||||
commands = []
|
||||
length = len(List)
|
||||
j = 1
|
||||
print(List)
|
||||
for k in range(len(List)):
|
||||
i = List[k][0]
|
||||
print(i)
|
||||
print(type(i))
|
||||
try:
|
||||
if i.instrument > 119:
|
||||
pass
|
||||
else:
|
||||
commands.append("execute @e[scores={" +
|
||||
ScoreboardName + "=" + str(round_up(i.time_position)).replace(".0", "") + "}] ~ ~" +
|
||||
str(127 - i.velocity) +
|
||||
" ~ playsound " +
|
||||
str(i.instrument) +
|
||||
str(i.CD) + "." +
|
||||
str(i.pitch)
|
||||
+ " @a ~ ~ ~ 1000 1.0 1000\n")
|
||||
if isProsess:
|
||||
commands.append("execute @a"" ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" +
|
||||
str(round_up(i.time_position)).replace(".0", "") +
|
||||
"}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a" +
|
||||
str(j) + "/" + str(length) + " || " + str(int(j / length * 1000) / 10) + "\n")
|
||||
j += 1
|
||||
except AttributeError:
|
||||
pass
|
||||
# a += List[i][1]
|
||||
# commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
print(commands)
|
||||
return commands
|
||||
|
||||
|
||||
def formCmdBlock(direction: Iterable, command: str, particularValue: int, impluse: int = 0, condition: bool = False,
|
||||
needRedstone: bool = True, tickDelay: int = 0, customName: str = '', lastOutput: str = '',
|
||||
executeOnFirstTick: bool = False, trackOutput: bool = True):
|
||||
"""
|
||||
使用指定项目返回指定的指令方块格式字典
|
||||
:param direction: `list[x: int, y: int, z: int]`
|
||||
方块位置
|
||||
: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`
|
||||
悬浮字
|
||||
:param lastOutput: `str`
|
||||
上次输出字符串,注意此处需要留空
|
||||
:param executeOnFirstTick: `bool`
|
||||
执行第一个已选项(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行)
|
||||
:param trackOutput: `bool`
|
||||
是否输出
|
||||
|
||||
:return: 指令方块字典结构,如下
|
||||
"""
|
||||
'''
|
||||
:param block: {
|
||||
"direction": [x: int, y: int, z: int] #方块位置
|
||||
"block_name": str, #方块名称(无需指定,默认为command_block)
|
||||
"particular_value": int, #方块特殊值
|
||||
"impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32
|
||||
"command": str, #指令
|
||||
"customName": str, #悬浮字
|
||||
"lastOutput": str, #上次输出
|
||||
"tickdelay": int, #方块延时 int32
|
||||
"executeOnFirstTick": int, #执行第一个选项 1 bytes
|
||||
"trackOutput": int, #是否输出 1 bytes
|
||||
"conditional": int, #是否有条件 1 bytes
|
||||
"needRedstone": int #是否需要红石 1 bytes
|
||||
}
|
||||
'''
|
||||
return {"direction": direction,
|
||||
"block_name": "command_block",
|
||||
"particular_value": particularValue,
|
||||
"impluse": impluse,
|
||||
"command": command,
|
||||
"customName": customName,
|
||||
"lastOutput": lastOutput,
|
||||
"tickdelay": tickDelay,
|
||||
"executeOnFirstTick": executeOnFirstTick,
|
||||
"trackOutput": trackOutput,
|
||||
"conditional": condition,
|
||||
"needRedstone": needRedstone
|
||||
}
|
||||
|
||||
|
||||
def note2bdx(filePath: str, dire: list, Notes: list, ScoreboardName: str, Instrument: str,
|
||||
PlayerSelect: str = '', isProsess: bool = False, height: int = 200):
|
||||
"""使用方法同Note2Cmd
|
||||
:param 参数说明:
|
||||
filePath: 生成.bdx文件的位置
|
||||
dire: 指令方块在地图中生成的起始位置(相对位置)
|
||||
Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表
|
||||
例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes'])
|
||||
ScoreboardName: 用于执行的计分板名称
|
||||
Instrument: 播放的乐器
|
||||
PlayerSelect: 执行的玩家选择器
|
||||
isProsess: 是否显示进度条(会很卡)
|
||||
height: 生成结构的最高高度
|
||||
:return 返回一个BdxConverter类,同时在指定位置生成.bdx文件"""
|
||||
|
||||
from nmcsup.trans import Note2Cmd
|
||||
from msctspt.bdxOpera_CP import BdxConverter
|
||||
cmd = Note2Cmd(Notes, ScoreboardName, Instrument, PlayerSelect, isProsess)
|
||||
cdl = []
|
||||
|
||||
for i in cmd:
|
||||
if '#' in i:
|
||||
if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''):
|
||||
cdl.append(i[:i.index('#')])
|
||||
else:
|
||||
cdl.append(i)
|
||||
i = 0
|
||||
down = False
|
||||
blocks = [formCmdBlock(dire, cdl.pop(0), 1, 1)]
|
||||
dire[1] += 1
|
||||
for j in cdl:
|
||||
if dire[1] + i > height:
|
||||
dire[0] += 1
|
||||
i = 0
|
||||
down = not down
|
||||
if dire[1] + i == height:
|
||||
blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 5, 2, False, False))
|
||||
else:
|
||||
if down:
|
||||
blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 0, 2, False, False))
|
||||
else:
|
||||
blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 1, 2, False, False))
|
||||
i += 1
|
||||
del i, cdl, down, cmd
|
||||
return BdxConverter(filePath, 'Build by RyounMusicreater', blocks)
|
||||
|
||||
|
||||
|
||||
def music2cmdBlocks(direction: Iterable, music: dict, isProsess: bool = False, height: int = 200,
|
||||
isSquare: bool = False):
|
||||
"""使用方法同Note2Cmd
|
||||
:param 参数说明:
|
||||
filePath: 生成.bdx文件的位置
|
||||
dire: 指令方块在地图中生成的起始位置(相对位置)
|
||||
music: 详见 Musicreater.py - dataset[0]
|
||||
isProsess: 是否显示进度条(会很卡)
|
||||
height: 生成结构的最高高度
|
||||
isSquare: 生成的结构是否需要遵循生成正方形原则
|
||||
:return 返回一个列表,其中包含了音乐生成的所有的指令方块数据"""
|
||||
from msctspt.threadOpera import NewThread
|
||||
|
||||
allblocks = []
|
||||
'''需要放置的方块'''
|
||||
baseDire = direction
|
||||
|
||||
direction = list(direction)
|
||||
|
||||
def trackDealing(direction,track):
|
||||
blocks = []
|
||||
cmdList = classList_conversion_SinglePlayer(track['notes'], track['set']['ScoreboardName'],
|
||||
music['mainset']['PlayerSelect'], isProsess)
|
||||
if len(cmdList) == 0:
|
||||
return
|
||||
elif cmdList is []:
|
||||
return
|
||||
dire = direction
|
||||
down = False
|
||||
'''当前是否为向下的阶段?'''
|
||||
# 开头的指令方块
|
||||
blocks.append(formCmdBlock(dire,
|
||||
f"scoreboard players add @a{music['mainset']['PlayerSelect']} "
|
||||
f"{track['set']['ScoreboardName']} 1",
|
||||
1, 1))
|
||||
dire[1] += 1
|
||||
blocks.append(formCmdBlock(dire, cmdList.pop(0), 2, needRedstone=False))
|
||||
dire[1] += 1
|
||||
# :0 下 无条件
|
||||
# :1 上 无条件
|
||||
# :2 z轴负方向 无条件
|
||||
# :3 z轴正方向 无条件
|
||||
# :4 x轴负方向 无条件
|
||||
# :5 x轴正方向 无条件
|
||||
for cmd in cmdList:
|
||||
blocks.append(formCmdBlock(dire, cmd, 5 if (down is False and dire[1] == height + direction[1]) or (
|
||||
down and dire[1] == direction + 1) else 0 if down else 1, 2, needRedstone=False))
|
||||
if down:
|
||||
if dire[1] > direction[1] + 1:
|
||||
dire[1] -= 1
|
||||
else:
|
||||
if dire[1] < height + direction[1]:
|
||||
dire[1] += 1
|
||||
|
||||
if (down is False and dire[1] == height + direction[1]) or (down and dire[1] == direction + 1):
|
||||
down = not down
|
||||
dire[0] += 1
|
||||
return blocks
|
||||
|
||||
threads = []
|
||||
for track in music['musics']:
|
||||
threads.append(NewThread(trackDealing,(direction,track)))
|
||||
threads[threads.__len__()-1].start()
|
||||
direction[2] += 2
|
||||
|
||||
for th in threads:
|
||||
allblocks += th.getResult()
|
||||
|
||||
return allblocks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def music2BDX(filePath: str, direction: Iterable, music: dict, isProsess: bool = False, height: int = 200,
|
||||
isSquare: bool = False):
|
||||
"""使用方法同Note2Cmd
|
||||
:param 参数说明:
|
||||
filePath: 生成.bdx文件的位置
|
||||
dire: 指令方块在地图中生成的起始位置(相对位置)
|
||||
music: 详见 Musicreater.py - dataset[0]
|
||||
isProsess: 是否显示进度条(会很卡)
|
||||
height: 生成结构的最高高度
|
||||
isSquare: 生成的结构是否需要遵循生成正方形原则
|
||||
:return 返回一个BdxConverter类,同时在指定位置生成.bdx文件"""
|
||||
from msctspt.bdxOpera_CP import BdxConverter
|
||||
return BdxConverter(filePath, 'Build by Ryoun Musicreater', music2cmdBlocks(direction,music,isProsess,height,isSquare)
|
||||
)
|
||||
|
||||
|
||||
def note2webs(Notes: list, Instrument: str, speed: float = 5.0, PlayerSelect: str = '', isProsess: bool = False):
|
||||
"""传入音符,在oaclhost:8080上建立websocket服务器以供我的世界connect/wssever指令连接
|
||||
:param 参数说明:
|
||||
Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表
|
||||
例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes'])
|
||||
Instrument: 播放的乐器
|
||||
speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍
|
||||
PlayerSelect: 执行的玩家选择器
|
||||
isProsess: 是否显示进度条
|
||||
:return None"""
|
||||
|
||||
import time
|
||||
import fcwslib
|
||||
# import asyncio
|
||||
from nmcsup.log import log
|
||||
from nmcsup.vers import VER
|
||||
|
||||
async def run_server(websocket): # , path
|
||||
log('服务器连接创建')
|
||||
await fcwslib.tellraw(websocket, '已连接服务器——音·创' + VER[1] + VER[0] + ' 作者:金羿(W-YI)')
|
||||
length = len(Notes)
|
||||
j = 1
|
||||
for i in range(len(Notes)):
|
||||
await fcwslib.send_command(websocket,
|
||||
f'execute @a{PlayerSelect} ~ ~ ~ playsound {Instrument} @s ~ ~ ~ 1000 '
|
||||
f'{Notes[i][0]} 1000')
|
||||
if isProsess:
|
||||
await fcwslib.send_command(websocket,
|
||||
'execute @a' + PlayerSelect + ' ~ ~ ~ title @s actionbar §e▶ 播放中: §a' +
|
||||
str(
|
||||
j) + '/' + str(length) + ' || ' + str(int(j / length * 1000) / 10))
|
||||
j += 1
|
||||
time.sleep(Notes[i][1] / speed)
|
||||
|
||||
fcwslib.run_server(run_server)
|
||||
|
||||
|
||||
def note2RSworld(world: str, startpos: list, notes: list, instrument: str, speed: float = 2.5,
|
||||
posadder: Iterable = (1, 0, 0), baseblock: str = 'stone'): # -> bool
|
||||
"""传入音符,生成以音符盒存储的红石音乐
|
||||
:param 参数说明:
|
||||
world: 地图文件的路径
|
||||
startpos: list[int,int,int] 开始生成的坐标
|
||||
notes: list[list[float,float]] 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ]
|
||||
格式存储的音符列表 例如Musicreater.py的dataset[0]['musics'][NowMusic]['notes']
|
||||
instrument: 播放的乐器
|
||||
speed: 一拍占多少个中继器延迟(红石刻/rt)
|
||||
posadder: list[int,int,int] 坐标增加规律,即红石的延长时按照此增加规律增加坐标
|
||||
baseblock: 在中继器下垫着啥方块呢~
|
||||
:return 是否生成成功
|
||||
"""
|
||||
|
||||
from msctspt.values import height2note, instuments
|
||||
|
||||
def formNoteBlock(note: int, instrument1: str = 'note.harp', powered: bool = False):
|
||||
"""生成音符盒方块
|
||||
:param powered:
|
||||
:param instrument1:
|
||||
:param note: 0~24
|
||||
:return Block()"""
|
||||
if powered:
|
||||
powered = 'true'
|
||||
else:
|
||||
powered = 'false'
|
||||
return Block('universal_minecraft', 'notebooks',
|
||||
{"instrument": ts(instrument1.replace("note.", '')), 'note': ts(str(note)),
|
||||
'powered': ts(powered)})
|
||||
|
||||
def formRepeater(delay: int, facing: str, locked: bool = False, powered: bool = False):
|
||||
"""生成中继器方块
|
||||
:param powered:
|
||||
:param locked:
|
||||
:param facing:
|
||||
:param delay: 1~4
|
||||
:return Block()"""
|
||||
if powered:
|
||||
powered = 'true'
|
||||
else:
|
||||
powered = 'false'
|
||||
if locked:
|
||||
locked = 'true'
|
||||
else:
|
||||
locked = 'false'
|
||||
return Block('universal_minecraft', 'repeater',
|
||||
{"delay": ts(str(delay)), 'facing': ts(facing), 'locked': ts(locked), 'powered': ts(powered)})
|
||||
|
||||
level = amulet.load_level(world)
|
||||
|
||||
def setblock(block: Block, pos: list):
|
||||
"""pos : list[int,int,int]"""
|
||||
cx, cz = bc2cc(pos[0], pos[2])
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
|
||||
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(block)
|
||||
chunk.changed = True
|
||||
|
||||
# 1拍 x 2.5 rt
|
||||
def placeNoteBlock():
|
||||
for i in notes:
|
||||
error = True
|
||||
try:
|
||||
setblock(formNoteBlock(height2note[i[0]], instrument), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
setblock(Block("universal_minecraft", instuments[i[0]][1]), startpos)
|
||||
error = False
|
||||
except ValueError:
|
||||
log("无法放置音符:" + str(i) + '于' + str(startpos))
|
||||
setblock(Block("universal_minecraft", baseblock), startpos)
|
||||
setblock(Block("universal_minecraft", baseblock), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
finally:
|
||||
if error is True:
|
||||
log("无法放置音符:" + str(i) + '于' + str(startpos))
|
||||
setblock(Block("universal_minecraft", baseblock), startpos)
|
||||
setblock(Block("universal_minecraft", baseblock), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
delay = int(i[1] * speed + 0.5)
|
||||
if delay <= 4:
|
||||
startpos[0] += 1
|
||||
setblock(formRepeater(delay, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
setblock(Block("universal_minecraft", baseblock), startpos)
|
||||
else:
|
||||
for j in range(int(delay / 4)):
|
||||
startpos[0] += 1
|
||||
setblock(formRepeater(4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
setblock(Block("universal_minecraft", baseblock), startpos)
|
||||
if delay % 4 != 0:
|
||||
startpos[0] += 1
|
||||
setblock(formRepeater(delay % 4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
|
||||
setblock(Block("universal_minecraft", baseblock), startpos)
|
||||
startpos[0] += posadder[0]
|
||||
startpos[1] += posadder[1]
|
||||
startpos[2] += posadder[2]
|
||||
|
||||
# e = True
|
||||
try:
|
||||
placeNoteBlock()
|
||||
# e = False
|
||||
except: # ValueError
|
||||
log("无法放置方块了,可能是因为区块未加载叭")
|
||||
# finally:
|
||||
# if e:
|
||||
# log("无法放置方块了,可能是因为区块未加载叭")
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
class ryStruct:
|
||||
|
||||
def __init__(self, world: str) -> None:
|
||||
|
||||
self.RyStruct = dict()
|
||||
self._world = world
|
||||
self._level = amulet.load_level(world)
|
||||
|
||||
def reloadLevel(self):
|
||||
# e = True
|
||||
try:
|
||||
self._level = amulet.load_level(self.world)
|
||||
# e = False
|
||||
except: # ValueError
|
||||
log("无法重载地图")
|
||||
# finally:
|
||||
# if e:
|
||||
# log("无法重载地图")
|
||||
|
||||
def closeLevel(self):
|
||||
# e = True
|
||||
try:
|
||||
self._level.close()
|
||||
# e = False
|
||||
except: # ValueError
|
||||
log("无法关闭地图")
|
||||
# finally:
|
||||
# if e:
|
||||
# log("无法重载地图")
|
||||
|
||||
def world2Rys(self, startp: list, endp: list, includeAir: bool = False):
|
||||
"""将世界转换为RyStruct字典,注意,此函数运行成功后将关闭地图,若要打开需要运行 reloadLevel
|
||||
:param startp: [x,y,z] 转化的起始坐标
|
||||
:param endp : [x,y,z] 转换的终止坐标,注意,终止坐标需要大于起始坐标,且最终结果包含终止坐标
|
||||
:param includeAir : bool = False 是否包含空气,即空气是否在生成之时覆盖地图内容
|
||||
:return dict RyStruct """
|
||||
|
||||
level = self._level
|
||||
|
||||
for x in range(startp[0], endp[0] + 1):
|
||||
for y in range(startp[1], endp[1] + 1):
|
||||
for z in range(startp[2], endp[2] + 1):
|
||||
|
||||
RyStructBlock = dict()
|
||||
|
||||
cx, cz = bc2cc(x, z)
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
universal_block = chunk.block_palette[chunk.blocks[x - 16 * cx, y, z - 16 * cz]]
|
||||
if universal_block == Block("universal_minecraft", "air") and includeAir:
|
||||
continue
|
||||
universal_block_entity = chunk.block_entities.get((x, y, z), None)
|
||||
|
||||
RyStructBlock["block"] = str(universal_block)
|
||||
RyStructBlock["blockEntity"] = str(universal_block_entity)
|
||||
|
||||
log("载入方块数据" + str(RyStructBlock))
|
||||
|
||||
self.RyStruct[(x, y, z)] = RyStructBlock
|
||||
|
||||
level.close()
|
||||
|
||||
return self.RyStruct
|
||||
|
||||
|
||||
"""
|
||||
RyStruct = {
|
||||
(0,0,0) = {
|
||||
"block": str 完整的方块结构
|
||||
"blockEntity": str | 'None'
|
||||
}
|
||||
}
|
||||
"""
|
||||
56
msctspt/values.py
Normal file
56
msctspt/values.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:40个
|
||||
|
||||
instuments = {
|
||||
'note.banjo': ['班卓琴', 'hay_block'],
|
||||
'note.bass': ['贝斯', 'planks'],
|
||||
'note.bassattack': ['低音鼓/贝斯', 'log'],
|
||||
'note.bd': ['底鼓', 'stone'], # 即basedrum
|
||||
'note.bell': ['铃铛/钟琴', 'gold_block'],
|
||||
'note.bit': ['比特/“芯片”(方波)', 'emerald_block'],
|
||||
'note.chime': ['管钟', 'packed_ice'],
|
||||
'note.cow_bell': ['牛铃', 'soul_sand'],
|
||||
'note.didgeridoo': ['迪吉里杜管', 'pumpkin'],
|
||||
'note.flute': ['长笛', 'clay'],
|
||||
'note.guitar': ['吉他', 'wool'],
|
||||
'note.harp': ['竖琴/钢琴', 'concrete'], # 任意其他类型的方块皆可
|
||||
'note.hat': ['击鼓沿/架子鼓', 'glass'],
|
||||
'note.iron_xylophone': ['“铁木琴”(颤音琴)', 'iron_block'],
|
||||
'note.pling': ['“扣弦”(电钢琴)', 'glowstone'],
|
||||
'note.snare': ['小军鼓', 'sand'],
|
||||
'note.xylophone': ['木琴', 'bone_block']
|
||||
}
|
||||
'''乐器对照表\n
|
||||
乐器英文:[中文, 对应音符盒下方块名称]
|
||||
注:方块仅取一个'''
|
||||
|
||||
height2note = {
|
||||
0.5: 0,
|
||||
0.53: 1,
|
||||
0.56: 2,
|
||||
0.6: 3,
|
||||
0.63: 4,
|
||||
0.67: 5,
|
||||
0.7: 6,
|
||||
0.75: 7,
|
||||
0.8: 8,
|
||||
0.84: 9,
|
||||
0.9: 10,
|
||||
0.94: 11,
|
||||
1.0: 12,
|
||||
|
||||
1.05: 13,
|
||||
1.12: 14,
|
||||
1.2: 15,
|
||||
1.25: 16,
|
||||
1.33: 17,
|
||||
1.4: 18,
|
||||
1.5: 19,
|
||||
1.6: 20,
|
||||
1.7: 21,
|
||||
1.8: 22,
|
||||
1.9: 23,
|
||||
2.0: 24,
|
||||
}
|
||||
'''音高对照表\n
|
||||
MC音高:音符盒音调'''
|
||||
@@ -1,72 +1,72 @@
|
||||
从此日志开始,我的世界函数音乐构建更名为 函数音创 NoteFunCreater(谐音NotFun[狗头]),版本号更为0.1.0开始
|
||||
|
||||
注意,运行此文件需要第三方库:
|
||||
1. mido 用于对midi文件的解码
|
||||
2. py7zr 用于对7z压缩包的压缩与解压等(需pycparser, cffi, texttable, pyzstd, pyppmd, pycryptodomex, multivolumefile, brotli, bcj-cffi支持) -(从0.1.3开始不需要)
|
||||
3. zipfile 用于自动生成函数包的压缩
|
||||
4. pystray 用于支持窗口任务栏
|
||||
5. pillow (相当于Python2的PIL)用于绘图
|
||||
|
||||
|
||||
0.1.0
|
||||
2021 7 10 - 2021 7 12
|
||||
1.程序窗口化
|
||||
2.仅支持基本的菜单操作
|
||||
3.程序文件皆储存至其相应目录下
|
||||
4.程序./bin/目录下文件将会自动防修改
|
||||
5.删除了彩蛋
|
||||
|
||||
|
||||
0.1.1
|
||||
2021 7 14
|
||||
1.新增版本辨别的提示
|
||||
2.窗口中显示歌曲信息
|
||||
|
||||
|
||||
0.1.2
|
||||
2021 7 14 - 2021 7 15
|
||||
1.在没运行过的机器上会自动安装库
|
||||
2.从midi导入时不会删除其他音轨
|
||||
3.改进UI样式
|
||||
4.支持对于单个音轨设置的修改以及音乐主设置的修改
|
||||
5.当未保存便退出时,会询问存储
|
||||
6.新增加载进度提示
|
||||
|
||||
|
||||
0.1.3
|
||||
2021 7 15 - 2021 7 19
|
||||
1.不再从文件中读取音符及乐器信息(所以包更小了)
|
||||
2.改进UI
|
||||
3.修复了修改玩家选择器时变更了音乐标题的bug
|
||||
4.新增删除当前选定音轨按钮
|
||||
5.新增重置设置按钮(将音乐总设置设置为开始时的设置)
|
||||
6.运用多线程加载函数与文件等,程序运行效率更高
|
||||
7.修复变量作用域混淆问题
|
||||
|
||||
|
||||
0.1.3.1
|
||||
2021 7 19
|
||||
1.修复了菜单中无法退出程序的问题
|
||||
|
||||
|
||||
0.1.4
|
||||
2021 7 22
|
||||
1.支持显示指令于列表中
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TO-DO
|
||||
1.支持从midi文件的元信息中收取音符信息并自动生成
|
||||
2.支持生成zip函数包
|
||||
3.支持使用WebSocket接口自动播放已编辑的音乐
|
||||
4.可以编辑多个项目
|
||||
5.能够自动将一个长串的音乐分成多个函数文件
|
||||
6.支持用户导入自己的乐器
|
||||
7.支持汇报崩溃记录(通过邮件附件的方式)
|
||||
8.支持播放字幕
|
||||
9.支持任务栏角标与通知
|
||||
10.将控制台版本的彩蛋移植到此版本,开启了任务栏
|
||||
从此日志开始,我的世界函数音乐构建更名为 函数音创 NoteFunCreater(谐音NotFun[狗头]),版本号更为0.1.0开始
|
||||
|
||||
注意,运行此文件需要第三方库:
|
||||
1. mido 用于对midi文件的解码
|
||||
2. py7zr 用于对7z压缩包的压缩与解压等(需pycparser, cffi, texttable, pyzstd, pyppmd, pycryptodomex, multivolumefile, brotli, bcj-cffi支持) -(从0.1.3开始不需要)
|
||||
3. zipfile 用于自动生成函数包的压缩
|
||||
4. pystray 用于支持窗口任务栏
|
||||
5. pillow (相当于Python2的PIL)用于绘图
|
||||
|
||||
|
||||
0.1.0
|
||||
2021 7 10 - 2021 7 12
|
||||
1.程序窗口化
|
||||
2.仅支持基本的菜单操作
|
||||
3.程序文件皆储存至其相应目录下
|
||||
4.程序./bin/目录下文件将会自动防修改
|
||||
5.删除了彩蛋
|
||||
|
||||
|
||||
0.1.1
|
||||
2021 7 14
|
||||
1.新增版本辨别的提示
|
||||
2.窗口中显示歌曲信息
|
||||
|
||||
|
||||
0.1.2
|
||||
2021 7 14 - 2021 7 15
|
||||
1.在没运行过的机器上会自动安装库
|
||||
2.从midi导入时不会删除其他音轨
|
||||
3.改进UI样式
|
||||
4.支持对于单个音轨设置的修改以及音乐主设置的修改
|
||||
5.当未保存便退出时,会询问存储
|
||||
6.新增加载进度提示
|
||||
|
||||
|
||||
0.1.3
|
||||
2021 7 15 - 2021 7 19
|
||||
1.不再从文件中读取音符及乐器信息(所以包更小了)
|
||||
2.改进UI
|
||||
3.修复了修改玩家选择器时变更了音乐标题的bug
|
||||
4.新增删除当前选定音轨按钮
|
||||
5.新增重置设置按钮(将音乐总设置设置为开始时的设置)
|
||||
6.运用多线程加载函数与文件等,程序运行效率更高
|
||||
7.修复变量作用域混淆问题
|
||||
|
||||
|
||||
0.1.3.1
|
||||
2021 7 19
|
||||
1.修复了菜单中无法退出程序的问题
|
||||
|
||||
|
||||
0.1.4
|
||||
2021 7 22
|
||||
1.支持显示指令于列表中
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TO-DO
|
||||
1.支持从midi文件的元信息中收取音符信息并自动生成
|
||||
2.支持生成zip函数包
|
||||
3.支持使用WebSocket接口自动播放已编辑的音乐
|
||||
4.可以编辑多个项目
|
||||
5.能够自动将一个长串的音乐分成多个函数文件
|
||||
6.支持用户导入自己的乐器
|
||||
7.支持汇报崩溃记录(通过邮件附件的方式)
|
||||
8.支持播放字幕
|
||||
9.支持任务栏角标与通知
|
||||
10.将控制台版本的彩蛋移植到此版本,开启了任务栏
|
||||
11.可编辑音符
|
||||
@@ -1,36 +1,36 @@
|
||||
世界音创(NoteMapCreater)是金羿开发的一款用于生成我的世界中各类有关音乐的物件的软件
|
||||
软件禁止商用,源代码始终公开,如使用未经授权的音乐经过此软件生成的任何物件侵犯了他人权利与本软件及其作者无关
|
||||
|
||||
Copyright © W-YI 2021
|
||||
|
||||
开头,特别感谢:
|
||||
KCINE:提供Cinemusicedit函数包(虽然函数包没怎么用过)
|
||||
Charlie_Ping:提供MusiCreaterBot(音乐地图生成QQ机器人)源码核心以及时不时的催更(虽然源码没有抄)
|
||||
金羿(作者本人):提供NoteFunCreater(函数音创)的制作经验以及时不时的摸鱼(虽然不是很支持函数音创)
|
||||
广大群友:高效的催更作业让我以蜗牛的速度前进
|
||||
|
||||
Alpha 0.0.0
|
||||
2021 8 1 - 2021 8 10
|
||||
1.确定了大概的功能
|
||||
2.不支持无参数传入
|
||||
3.可以查看帮助,但是帮助大多功能没实现
|
||||
4.可以从格式文本、midi文件、钢琴声音MP3导入音轨
|
||||
5.可以生成一些方块到世界里,但是没有播放器(半支持bw开关)
|
||||
5.提供了修改文件地址的方法,但是不能修改
|
||||
|
||||
Alpha 0.0.1
|
||||
2021 8 10
|
||||
1.可以从函数音创的工程文件读取音轨
|
||||
2.可以新建一个空白世界来生成
|
||||
3.支持修改输出文件地址
|
||||
4.支持修改输出方块起始位置
|
||||
5.支持指定播放乐器,执行实体,执行积分板,播放玩家选择器
|
||||
6.可以生成指令音乐地图(完全支持-w开关)
|
||||
|
||||
Beta 0.0.0
|
||||
2021 8 X?
|
||||
1.除了-nw 和 -f 开关不支持以外都支持了
|
||||
|
||||
Beta 0.0.1
|
||||
2021 8 19
|
||||
1.修复了大量bug
|
||||
世界音创(NoteMapCreater)是金羿开发的一款用于生成我的世界中各类有关音乐的物件的软件
|
||||
软件禁止商用,源代码始终公开,如使用未经授权的音乐经过此软件生成的任何物件侵犯了他人权利与本软件及其作者无关
|
||||
|
||||
Copyright © W-YI 2021
|
||||
|
||||
开头,特别感谢:
|
||||
KCINE:提供Cinemusicedit函数包(虽然函数包没怎么用过)
|
||||
Charlie_Ping:提供MusiCreaterBot(音乐地图生成QQ机器人)源码核心以及时不时的催更(虽然源码没有抄)
|
||||
金羿(作者本人):提供NoteFunCreater(函数音创)的制作经验以及时不时的摸鱼(虽然不是很支持函数音创)
|
||||
广大群友:高效的催更作业让我以蜗牛的速度前进
|
||||
|
||||
Alpha 0.0.0
|
||||
2021 8 1 - 2021 8 10
|
||||
1.确定了大概的功能
|
||||
2.不支持无参数传入
|
||||
3.可以查看帮助,但是帮助大多功能没实现
|
||||
4.可以从格式文本、midi文件、钢琴声音MP3导入音轨
|
||||
5.可以生成一些方块到世界里,但是没有播放器(半支持bw开关)
|
||||
5.提供了修改文件地址的方法,但是不能修改
|
||||
|
||||
Alpha 0.0.1
|
||||
2021 8 10
|
||||
1.可以从函数音创的工程文件读取音轨
|
||||
2.可以新建一个空白世界来生成
|
||||
3.支持修改输出文件地址
|
||||
4.支持修改输出方块起始位置
|
||||
5.支持指定播放乐器,执行实体,执行积分板,播放玩家选择器
|
||||
6.可以生成指令音乐地图(完全支持-w开关)
|
||||
|
||||
Beta 0.0.0
|
||||
2021 8 X?
|
||||
1.除了-nw 和 -f 开关不支持以外都支持了
|
||||
|
||||
Beta 0.0.1
|
||||
2021 8 19
|
||||
1.修复了大量bug
|
||||
0
nmcsup/__init__.py
Normal file
0
nmcsup/__init__.py
Normal file
BIN
nmcsup/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
nmcsup/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
nmcsup/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/const.cpython-38.pyc
Normal file
BIN
nmcsup/__pycache__/const.cpython-38.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/const.cpython-39.pyc
Normal file
BIN
nmcsup/__pycache__/const.cpython-39.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/log.cpython-38.pyc
Normal file
BIN
nmcsup/__pycache__/log.cpython-38.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/log.cpython-39.pyc
Normal file
BIN
nmcsup/__pycache__/log.cpython-39.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/nmcreader.cpython-38.pyc
Normal file
BIN
nmcsup/__pycache__/nmcreader.cpython-38.pyc
Normal file
Binary file not shown.
BIN
nmcsup/__pycache__/nmcreader.cpython-39.pyc
Normal file
BIN
nmcsup/__pycache__/nmcreader.cpython-39.pyc
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user