mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-07-24 17:22:32 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a9d04606f9 | |||
| 3113eb53fa | |||
| d13923f053 | |||
| 889f59dd1c | |||
| 38518337d3 | |||
| 2b096f6c48 | |||
| 01a7cfe6ac | |||
| ddad8eaa5e | |||
| d5c4e5c874 |
-66
@@ -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/
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
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]
|
||||
|
||||
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.
|
||||
@@ -1,49 +1,24 @@
|
||||
# 音·创 Musicreater
|
||||
|
||||
### 介绍
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
|
||||
欢迎加群:861684859
|
||||
|
||||
### 软件架构
|
||||
|
||||
软件采用Python作为第一语言,目前还没有使用其他语言辅助。使用BeeWare作为图形库兼容安卓。
|
||||
|
||||
尽量全平台支持
|
||||
|
||||
|
||||
### 安装教程
|
||||
|
||||
#### Windows
|
||||
|
||||
即将到来。
|
||||
|
||||
#### Linux
|
||||
|
||||
即将到来。
|
||||
|
||||
#### Android
|
||||
|
||||
即将到来。
|
||||
|
||||
### 使用说明
|
||||
|
||||
1. 直接运行就好
|
||||
2. 有不懂的问题来群里问
|
||||
3. 请理解英文表述
|
||||
|
||||
### 致谢
|
||||
|
||||
1. 感谢由 [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”等 带来的我的世界websocket服务器功能
|
||||
2. 感谢 昀梦<QQ1515399885> 找出指令生成错误bug并指正
|
||||
3. 感谢由 Charlie_Ping “查理平” 带来的bdx转换功能
|
||||
4. 感谢由 CMA_2401PT 提供的 BDXWorkShop作为.bdx结构的操作指导
|
||||
5. 感谢广大群友为此程序提供的测试等支持
|
||||
6. 若您为我找出了错误但您的名字没有显示在此列表中,请联系我!
|
||||
|
||||
|
||||
### 作者<金羿>联系方式
|
||||
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
# ***NOTICE*** 请注意
|
||||
|
||||
## ***FOR UPDATING FILES IN HERE(GitHub)*** 此处编辑请注意
|
||||
|
||||
> We have setted a automatic mirror between Gitee(a Chinese native Code Hosting Platform).
|
||||
> That means you should check whether there is another update on Gitee if you want to get file(s) updated on GitHub.
|
||||
> If a update is pushed on Gitee and not been pushed into GitHub yet,
|
||||
> A push will **COVERED** by the another one, which branch to deleted is under indeterminacy, maybe both destoried is possible.
|
||||
> So we STRONG suggest not to push updates here in GitHub.
|
||||
> But if you want to, make sure that in 30min, there is NOT ANY pushes in this repository on Gitee.
|
||||
>
|
||||
> 由于我们建立了对于 Gitee 和 GitHub 之间的双向更新镜像,
|
||||
> 如果您需要在此处(GitHub处)进行更新之前请三思,我们非常建议你在 Gitee 上更新而不是 GitHub。
|
||||
> 就我个人而言,仅仅是使用 GitHub 是非常愚蠢的,特别是因为使用的代码托管平台不同而放弃对于一个项目的热情更是令人不可理喻。
|
||||
> 这种崇洋媚外的心理是不当的,尽管你会说,GitHub 在某些方面做的确实比 Gitee 好太多;但是也要考虑另外的一些方面,就是我们这个小项目用的用不上的问题。
|
||||
> 如果需要切换一个主要的代码托管平台,我们会有自己的选择;但正如其名,代码托管平台只是托管一下代码,我认为我有必要自行地决定我的智慧结晶使用如何的服务。
|
||||
> 况且,使用的服务是独立于代码托管之外的,并不妨碍你在哪更新,除非你一年四季开着 VPN 而访问不上 Gitee,不过这几乎不可能,因为 Gitee 的服务器是阿里巴巴的。
|
||||
> 言归正传,在 GitHub 更新之前,你需要首先检查:在30分钟内是否有其他的更新在 Gitee 上提出,如果有则不要在此时提交更新。
|
||||
> 否则会产生非常严重的后果,运气好可以合到一起去,运气不好,完蛋了,有可能两个更新**全都没了**。
|
||||
|
||||
IF YOU WANT TO TAKE PART IN THE DEVELOPMENT OF THIS PROJECT, PLEASE CONTACT EILLES,
|
||||
and [Musicreater on Gitee](https://gitee.com/EillesWan/Musicreater/) is here, if you like to update here on GitHub, you **MUST** check it before.
|
||||
|
||||
若欲加入开发,联系金羿非常重要,[Gitee上的音·创](https://gitee.com/EillesWan/Musicreater/)也在这里,如果你一意孤行想要在这里更新的话,**必须、一定、确保**看过了Gitee上的更新状况。
|
||||
|
||||
-12
@@ -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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -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("无法清除日志及临时文件")
|
||||
@@ -1,49 +0,0 @@
|
||||
[tool.briefcase]
|
||||
project_name = "Musicreater"
|
||||
bundle = "com.ryoun.musicreater"
|
||||
version = "0.0.1"
|
||||
url = "https://musicreater.ryoun.com/musicreater"
|
||||
license = "Apache Software License"
|
||||
author = 'Eilles Wan'
|
||||
author_email = "W-YI_DoctorYI@outlook.com"
|
||||
|
||||
[tool.briefcase.app.musicreater]
|
||||
formal_name = "Musicreater"
|
||||
description = "Musicreater is an Eilles's app that is used for creating musics in Minecraft: Bedrock Edition"
|
||||
icon = "src/musicreater/resources/musicreater"
|
||||
sources = ['src/musicreater']
|
||||
requires = []
|
||||
|
||||
|
||||
[tool.briefcase.app.musicreater.macOS]
|
||||
requires = [
|
||||
'toga-cocoa>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.linux]
|
||||
requires = [
|
||||
'toga-gtk>=0.3.0.dev20',
|
||||
]
|
||||
system_requires = [
|
||||
'libgirepository1.0-dev',
|
||||
'libcairo2-dev',
|
||||
'libpango1.0-dev',
|
||||
'libwebkitgtk-3.0-0',
|
||||
'gir1.2-webkit-3.0',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.windows]
|
||||
requires = [
|
||||
'toga-winforms>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
# Mobile deployments
|
||||
[tool.briefcase.app.musicreater.iOS]
|
||||
requires = [
|
||||
'toga-iOS>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.android]
|
||||
requires = [
|
||||
'toga-android>=0.3.0.dev20',
|
||||
]
|
||||
-1401
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
briefcase
|
||||
@@ -1,10 +0,0 @@
|
||||
Metadata-Version: 2.1
|
||||
Briefcase-Version: 0.3.5
|
||||
Name: musicreater
|
||||
Formal-Name: Musicreater
|
||||
App-ID: com.ryoun.musicreater.musicreater
|
||||
Version: 0.0.1
|
||||
Home-page: https://musicreater.ryoun.com/musicreater
|
||||
Author: Eilles Wan
|
||||
Author-email: W-YI_DoctorYI@outlook.com
|
||||
Summary: Musicreater is an Eilles's app that is used for creating musics in Minecraft: Bedrock Edition
|
||||
@@ -1,364 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import threading
|
||||
import sys
|
||||
|
||||
from musicreater.msctspt.threadOpera import NewThread
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
from musicreater.nmcsup.log import log
|
||||
|
||||
__version__ = version.version[1]+version.version[0]
|
||||
__author__ = 'W-YI (金羿)'
|
||||
|
||||
|
||||
log("系统工作————————加载变量及函数")
|
||||
|
||||
|
||||
print("更新执行位置...")
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')])
|
||||
log("更新执行位置,当前文件位置"+__file__)
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__) -
|
||||
__file__[len(__file__)::-1].index('/')])
|
||||
except:
|
||||
pass
|
||||
log("其他平台:"+sys.platform+"更新执行位置,当前文件位置"+__file__)
|
||||
print('完成!')
|
||||
|
||||
|
||||
|
||||
print('建立变量,存入内存,载入字典常量函数')
|
||||
|
||||
# 主体部分
|
||||
|
||||
# 支持多文件同时操作
|
||||
|
||||
# dataset[{ 'mainset':{ 'x':'y' }, 'musics': [ { 'set' :{ 'A':'B' } , 'note' : [ [ 'a' , b ], ] }, ] }, ]
|
||||
|
||||
# 编辑:
|
||||
# 修改主设置: dataset[第几个项目]['mainset']['什么设置'] = '设置啥'
|
||||
# 修改音乐: dataset[第几个项目]['musics'][第几个音轨]['notes'][第几个音符][音符还是时间(0,1)] = 改成啥
|
||||
# 修改音轨设置: dataset[第几个项目]['musics'][第几个音轨]['set']['什么设置'] = '设置啥'
|
||||
#
|
||||
# 新增音轨: dataset[第几个项目]['musics'].append(datasetmodelpart)
|
||||
#
|
||||
'''
|
||||
dataset=[
|
||||
{
|
||||
'mainset':{
|
||||
'PackName':"Ryoun",
|
||||
'MusicTitle':'Noname',
|
||||
'IsRepeat':False,
|
||||
'PlayerSelect':''
|
||||
},
|
||||
'musics':[
|
||||
{
|
||||
'set':{
|
||||
'EntityName':'music_support',
|
||||
'ScoreboardName':'music_support',
|
||||
'Instrument':'harp',
|
||||
'FileName':"Music"
|
||||
},
|
||||
'notes':[
|
||||
[0.0,1.0],
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
'''
|
||||
|
||||
global dataset
|
||||
|
||||
dataset = [
|
||||
{
|
||||
'mainset': {
|
||||
'PackName': "Ryoun",
|
||||
'MusicTitle': 'Noname',
|
||||
'IsRepeat': False,
|
||||
'PlayerSelect': ''
|
||||
},
|
||||
'musics': [
|
||||
{
|
||||
'set': {
|
||||
'EntityName': 'MusicSupport',
|
||||
'ScoreboardName': 'MusicSupport',
|
||||
'Instrument': 'note.harp',
|
||||
'FileName': "Music"
|
||||
},
|
||||
'notes': [
|
||||
[0.0, 1.0],
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
global is_new_file
|
||||
global is_save
|
||||
global ProjectName
|
||||
global NowMusic
|
||||
|
||||
is_new_file = True
|
||||
is_save = True
|
||||
ProjectName = ''
|
||||
NowMusic = 0
|
||||
|
||||
def DMM(): # 反回字典用于编辑
|
||||
datasetmodelpart = {
|
||||
'set': {
|
||||
'EntityName': 'MusicSupport',
|
||||
'ScoreboardName': 'MusicSupport',
|
||||
'Instrument': 'note.harp',
|
||||
'FileName': "Music"
|
||||
},
|
||||
'notes': []
|
||||
}
|
||||
return datasetmodelpart
|
||||
|
||||
print("完成")
|
||||
|
||||
# 菜单命令
|
||||
print('加载菜单命令...')
|
||||
|
||||
def exitapp(cmd):
|
||||
|
||||
log("程序正常退出", False)
|
||||
global is_save
|
||||
if is_save == False:
|
||||
if '/s' in cmd:
|
||||
saveProject()
|
||||
else:
|
||||
print("您尚未保存,请使用 /s 开关保存并退出")
|
||||
return False
|
||||
|
||||
try:
|
||||
global dataset
|
||||
del dataset
|
||||
except:
|
||||
pass
|
||||
|
||||
if '/c' in cmd:
|
||||
print("清除log(此句不载入日志)")
|
||||
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("无法清除日志及临时文件")
|
||||
|
||||
exit()
|
||||
|
||||
print('退出函数加载完成!')
|
||||
|
||||
print("载入文件读取函数")
|
||||
|
||||
def ReadFile(fn: str):
|
||||
from nmcsup.nmcreader import ReadFile as fileRead
|
||||
k = fileRead(fn)
|
||||
if k == False:
|
||||
log("找不到"+fn)
|
||||
return False
|
||||
else:
|
||||
return k
|
||||
|
||||
def ReadMidi(midfile: str):
|
||||
from nmcsup.nmcreader import ReadMidi as midiRead
|
||||
k = midiRead(midfile)
|
||||
if k == False:
|
||||
log("找不到"+midfile)
|
||||
return False
|
||||
else:
|
||||
return k
|
||||
|
||||
print('完成!')
|
||||
|
||||
print("载入命令函数")
|
||||
|
||||
def saveProject(cmd: list):
|
||||
global is_new_file
|
||||
if '/a' in cmd:
|
||||
log("另存项目")
|
||||
ProjectName = cmd[cmd.index('/a')+1]
|
||||
else:
|
||||
if is_new_file:
|
||||
print("初次存储请使用 /a 开关规定存储文件名")
|
||||
log("文件未保存")
|
||||
return False
|
||||
|
||||
log("存储文件:"+ProjectName)
|
||||
with open(ProjectName, 'w', encoding='utf-8') as f:
|
||||
json.dump(dataset[0], f)
|
||||
global is_save
|
||||
is_save = True
|
||||
|
||||
print('保存项目函数加载完成!')
|
||||
|
||||
def loadMusic(cmd: list):
|
||||
if '/mid' in cmd:
|
||||
th = NewThread(ReadMidi, (cmd[cmd.index('/mid')+1],))
|
||||
th.start()
|
||||
|
||||
def midiSPT(th):
|
||||
for i in th.getResult():
|
||||
datas = DMM()
|
||||
datas['notes'] = i
|
||||
dataset[0]['musics'].append(datas)
|
||||
del th
|
||||
global is_save
|
||||
is_save = False
|
||||
threading.Thread(target=midiSPT, args=(th,)).start()
|
||||
del th
|
||||
elif '/txt' in cmd:
|
||||
th = NewThread(ReadFile, (cmd[cmd.index('/txt')+1],))
|
||||
th.start()
|
||||
|
||||
def midiSPT(th):
|
||||
for i in th.getResult():
|
||||
datas = DMM()
|
||||
datas['notes'] = i
|
||||
dataset[0]['musics'].append(datas)
|
||||
del th
|
||||
global is_save
|
||||
is_save = False
|
||||
threading.Thread(target=midiSPT, args=(th,)).start()
|
||||
elif '/input' in cmd:
|
||||
datas = []
|
||||
for i in cmd[cmd.index('/input')+1:]:
|
||||
datas.append([str(i), 1.0])
|
||||
from nmcsup.trans import note2list
|
||||
datat = DMM()
|
||||
datat['notes'] = note2list(datas)
|
||||
dataset[0]['musics'].append(datat)
|
||||
del datas, datat
|
||||
global is_save
|
||||
is_save = False
|
||||
else:
|
||||
log("无参数,无法读入。")
|
||||
print("请查看帮助文件查看指令格式。")
|
||||
return False
|
||||
|
||||
print('音轨载入函数加载完成!')
|
||||
|
||||
def funBuild(cmd: list):
|
||||
if '/file' in cmd:
|
||||
from msctspt.funcOpera import makeFuncFiles
|
||||
makepath = cmd[cmd.index('/file')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
makeFuncFiles(dataset[0], makepath)
|
||||
elif '/directory' in cmd:
|
||||
from msctspt.funcOpera import makeFunDir
|
||||
makepath = cmd[cmd.index('/directory')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
makeFunDir(dataset[0], makepath)
|
||||
elif '/mcpack' in cmd:
|
||||
import zipfile
|
||||
from msctspt.funcOpera import makeFunDir
|
||||
makepath = cmd[cmd.index('/mcpack')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
|
||||
if not os.path.exists('./temp/'):
|
||||
os.makedirs('./temp/')
|
||||
makeFunDir(dataset[0], './temp/')
|
||||
shutil.move('./temp/'+dataset[0]['mainset']['PackName'] +
|
||||
"Pack/behavior_packs/"+dataset[0]['mainset']['PackName']+"/functions", './')
|
||||
shutil.move('./temp/'+dataset[0]['mainset']['PackName'] + "Pack/behavior_packs/" +
|
||||
dataset[0]['mainset']['PackName']+"/manifest.json", './')
|
||||
with zipfile.ZipFile(makepath+dataset[0]['mainset']['PackName']+'.mcpack', "w") as zipobj:
|
||||
for i in os.listdir('./functions/'):
|
||||
zipobj.write('./functions/'+i)
|
||||
zipobj.write('./manifest.json')
|
||||
shutil.move('./functions', './temp/')
|
||||
shutil.move('./manifest.json', './temp/')
|
||||
shutil.rmtree("./temp/")
|
||||
else:
|
||||
log("无参数,无法读入。")
|
||||
print("请查看帮助文件查看指令格式。")
|
||||
return False
|
||||
|
||||
print("函数建立函数加载完成")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __main__():
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.system("cls")
|
||||
else:
|
||||
os.system("clear")
|
||||
|
||||
if sys.platform in ('win32', 'linux'):
|
||||
print("您当前的运行环境为标准桌面,您可以打开 Musicreater.py 运行窗口模式的 音·创")
|
||||
print("您也可以输入 win 指令在不退出命令行模式的同时打开窗口模式\n")
|
||||
|
||||
print(__author__+" 音·创 —— 当前核心版本 "+__version__+'\n')
|
||||
|
||||
nowWorkPath = os.path.split(os.path.realpath(__file__))[0]
|
||||
|
||||
while True:
|
||||
|
||||
strcmd = input("MSCT "+nowWorkPath+">")
|
||||
cmd = strcmd.lower().split(' ')
|
||||
|
||||
if cmd[0] == 'exit':
|
||||
exitapp(cmd[1:])
|
||||
elif cmd[0] == 'save':
|
||||
saveProject(cmd[1:])
|
||||
elif cmd[0] == 'load':
|
||||
loadMusic(cmd[1:])
|
||||
elif cmd[0] == 'win':
|
||||
def run(cmd):
|
||||
os.system(cmd)
|
||||
if sys.platform == 'win32':
|
||||
NewThread(run, ("python "+os.path.split(os.path.realpath(__file__))
|
||||
[0]+"/Musicreater.py",)).start()
|
||||
else:
|
||||
NewThread(run, ("python3 "+os.path.split(os.path.realpath(__file__))
|
||||
[0]+"/Musicreater.py",)).start()
|
||||
elif cmd[0] == 'chdir':
|
||||
nowWorkPath = os.path.realpath(cmd[1])
|
||||
os.chdir(nowWorkPath)
|
||||
elif cmd[0] == 'build':
|
||||
funBuild(cmd[1:])
|
||||
else:
|
||||
os.system(strcmd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__
|
||||
@@ -1,4 +0,0 @@
|
||||
from musicreater.app import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main().main_loop()
|
||||
@@ -1,133 +0,0 @@
|
||||
"""
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
"""
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
import toga
|
||||
from toga.style import Pack
|
||||
from toga.style.pack import COLUMN, ROW
|
||||
|
||||
from musicreater.Cmd_Msct import *
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
|
||||
from musicreater.resources.ChineseLang import LANGUAGE
|
||||
|
||||
|
||||
|
||||
__version__ = version.version[1]+version.version[0]
|
||||
__author__ = 'W-YI (金羿)'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')])
|
||||
log("更新执行位置,当前文件位置"+__file__)
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__) -
|
||||
__file__[len(__file__)::-1].index('/')])
|
||||
except:
|
||||
pass
|
||||
log("其他平台:"+sys.platform+"更新执行位置,当前文件位置"+__file__)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Musicreater(toga.App):
|
||||
'''音·创 本体\n
|
||||
W-YI 金羿\n
|
||||
QQ 2647547478\n
|
||||
音·创 开发交流群 861684859\n
|
||||
Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com\n
|
||||
版权所有 Team-Ryoun 金羿\n
|
||||
若需转载或借鉴 请附作者\n
|
||||
'''
|
||||
|
||||
|
||||
|
||||
def startup(self):
|
||||
|
||||
|
||||
# Start to draw the window
|
||||
|
||||
main_box = toga.Box(style=Pack(direction=COLUMN))
|
||||
|
||||
self.noticeLabel = toga.Label('MSCT >>>',style=Pack(padding=(0, 5)))
|
||||
|
||||
self.inputBox = toga.TextInput(style=Pack(flex=1))
|
||||
#dispImage = toga.ImageView("./resources/oddevenmatrix.png")
|
||||
|
||||
cmd_box = toga.Box(style=Pack(direction=ROW, padding=5))
|
||||
|
||||
cmd_box.add(self.noticeLabel)
|
||||
cmd_box.add(self.inputBox)
|
||||
# cmd_box.add(dispImage)
|
||||
|
||||
button = toga.Button(
|
||||
LANGUAGE['main']['run'],
|
||||
on_press=self.showMessage,
|
||||
style=Pack(padding=5)
|
||||
)
|
||||
|
||||
|
||||
main_box.add(cmd_box)
|
||||
main_box.add(button)
|
||||
|
||||
|
||||
self.main_window = toga.MainWindow(title=self.formal_name)
|
||||
self.main_window.content = main_box
|
||||
self.main_window.show()
|
||||
|
||||
self.main_window.info_dialog('',"{} {} —— {} {}".format(__author__,LANGUAGE['main']['name'],LANGUAGE['main']['version'],__version__))
|
||||
|
||||
self.nowWorkPath = os.path.split(os.path.realpath(__file__))[0]
|
||||
|
||||
|
||||
def showMessage(self, widget):
|
||||
|
||||
strcmd = self.inputBox.value
|
||||
|
||||
cmd = strcmd.lower().split(' ')
|
||||
|
||||
if cmd[0] == 'exit':
|
||||
if exitapp(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'save':
|
||||
if saveProject(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'load':
|
||||
if loadMusic(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'chdir':
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['NotAvailable'])
|
||||
return
|
||||
nowWorkPath = os.path.realpath(cmd[1])
|
||||
os.chdir(nowWorkPath)
|
||||
elif cmd[0] == 'build':
|
||||
if funBuild(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
else:
|
||||
return
|
||||
os.system(strcmd)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
return Musicreater()
|
||||
@@ -1,141 +0,0 @@
|
||||
#!/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()
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
00:13:19 更新执行位置,当前文件位置F:\W-YI\Programming\音·创\程序\src\musicreater\Cmd_Msct.py
|
||||
00:13:19 更新执行位置,当前文件位置F:\W-YI\Programming\音·创\程序\src\musicreater\app.py
|
||||
@@ -1,173 +0,0 @@
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
本软件源代码依照Apache软件协议公开。
|
||||
|
||||
Copyright © W-YI 2021
|
||||
|
||||
本软件是金羿前作函数音创和世界音创的集合版本,同时增加了大量功能更新。
|
||||
|
||||
|
||||
To-Do
|
||||
1.可以导出自定义的结构文件用于存储要导入地图中的结构
|
||||
2.进度条
|
||||
3.可以将音乐写入音符盒(红乐)
|
||||
4.更换tk库为briefcase库,支持安卓系统
|
||||
5.支持自动给音符盒绑定更多的音色
|
||||
6.可以由.schematic文件导入地图,亦可反向处理
|
||||
7.支持自定义指令方块区域的长宽高等
|
||||
8.支持自定义创建websockeet服务器播放音乐(感谢由 Fuckcraft <https://github.com/fuckcraft> “鸣凤鸽子”等 带来的我的世界websocket服务器功能)
|
||||
9.支持使用红石播放指令音乐
|
||||
10.支持采用延时的播放器
|
||||
11.支持使用bdx导出结构
|
||||
12.支持采用tp的方法播放
|
||||
13.支持识别曲谱图片解析音乐
|
||||
14.支持使用瀑布流的方式播放音乐
|
||||
15.帮助菜单
|
||||
16.多语言
|
||||
17.支持自动搜寻地图目录位置(网易&微软)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
新更新日志
|
||||
|
||||
Beta 0.0.4.3
|
||||
2021 11 3~2021 12 26
|
||||
1.不断改进包以及代码可读性
|
||||
2.修正部分源码错误
|
||||
3.修正部分格式错误
|
||||
4.加强对Linux系统的支持
|
||||
5.新增命令行模式
|
||||
6.代码中新增大量注释
|
||||
|
||||
|
||||
Beta 0.0.4 ~ Beta 0.0.4.2
|
||||
2021 11 20 ~ 2021 11 21
|
||||
1.完全支持Linux系统
|
||||
2.支持以.RyStruct导出结构
|
||||
3.修复大量bug
|
||||
4.支持拖拽打开(参数1为.msct文件)
|
||||
|
||||
|
||||
Beta 0.0.3.1~0.0.3.5
|
||||
2021 11 1~2021 11 2
|
||||
1.更新部分提示信息使之更加科学
|
||||
2.强制性限制不得使用非Win32平台打开此程序
|
||||
3.支持在Windwos7上使用此程序(发现错误并解决:DLL缺失MSVCP140.dll)
|
||||
4.开始对结构导出进行部分支持
|
||||
5.发现红乐写入的错误,正在排查修复
|
||||
|
||||
|
||||
|
||||
|
||||
Beta 0.0.3
|
||||
2021 10 29 ~ 2021 10 31
|
||||
1.修改部分窗口排版
|
||||
2.修复指令载入地图的结构的错误
|
||||
3.修复指令生成出现的指令错误(感谢 昀梦<QQ1515399885> 找出bug并指正)
|
||||
4.支持生成红石音乐(以音符盒存储的音乐),并写入地图
|
||||
5.修复了生成指令音乐导致的错误
|
||||
6.修复bdx文件y轴过长导致无法生成完毕的错误,现在bdx的y轴为200格
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Beta 0.0.2
|
||||
2021 10 25
|
||||
1.修复了邮件发送错误报告无法生成压缩包的问题
|
||||
2.修复了导入音轨时无法获得进程返回值的问题
|
||||
3.修复了.bdx文件生成时无法选择文件的问题
|
||||
4.修复了生成指令音乐(计分板)没有起始方块的问题
|
||||
5.新增了创建Websocket的功能,可以在localhost:8080创建websocket服务器播放音乐(感谢由 Fuckcraft <https://gitee.com/fuckcraft> “鸣凤鸽子”等 带来的我的世界websocket服务器功能(fcwslib) )
|
||||
6.解决了打包成可执行文件时无法正常退出的问题
|
||||
|
||||
|
||||
|
||||
Beta 0.0.1
|
||||
2021 10月
|
||||
1.支持生成.bdx文件(感谢由 Charlie_Ping “查理平” 带来的bdx转换功能)
|
||||
2.逐步增强对安卓系统的支持
|
||||
3.逐步放弃对Windows的强行要求
|
||||
4.逐步提升性能,增加多线程
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Alpha部分更新日志
|
||||
|
||||
Alpha 0.0.0
|
||||
2021 8 20
|
||||
1.集合了 函数音创0.1.4.1 与 世界音创Beta0.0.1 的功能于本应用
|
||||
2.新增了可以生成 .mcpack 包的方法
|
||||
|
||||
Alpha 0.0.1
|
||||
2021 8 25
|
||||
1.新增两个彩蛋(就是函数音创命令行模式的彩蛋
|
||||
|
||||
Alpha 0.0.1.1
|
||||
2021 8 25
|
||||
1.修复大量已知问题
|
||||
2.修复了部分彩蛋bug,但是程序仍然不会正常退出
|
||||
3.菜单界面优化
|
||||
|
||||
Alpha 0.0.1.2
|
||||
2021.8.29
|
||||
1.修复大量已知问题
|
||||
2.现在可以操作指令文件了
|
||||
3.窗口界面优化
|
||||
|
||||
Alpha 0.0.2
|
||||
2021 9 5
|
||||
1.修复部分已知问题
|
||||
2.指令链导入之时仅生成链式方块且允许折转
|
||||
3.[Dev]正在逐步支持结构导出
|
||||
|
||||
Alpha 0.0.3
|
||||
2021 9 7
|
||||
1.修复指令链转入世界的摆放错误
|
||||
2.指令存储的音乐(包括函数)支持不同玩家不同的播放
|
||||
3.支持播放进度条
|
||||
4.删除彩蛋任务栏图标
|
||||
4.[Dev]已确定导出结构格式
|
||||
|
||||
Alpha 0.0.3.1
|
||||
2021 9 11
|
||||
1.取消输入玩家选择器时不会出现bug了
|
||||
2.删除日志文件修改为删除临时文件
|
||||
3.可以删除用于确认档案存在的文件了
|
||||
|
||||
Alpha 0.0.4
|
||||
2021 10 4-5
|
||||
1.可以将大函数导入世界(以一条链执行多个函数的方式)
|
||||
2.关闭了试听音乐的功能,但是保留其函数于funOpera.py中
|
||||
3.修改部分代码,减少更多bug
|
||||
4.发现指令链转入世界的摆放错误,但是没改正
|
||||
|
||||
1.0.3
|
||||
2021 10 5-6
|
||||
1.解决一些已知问题
|
||||
2.解决了文件读取造成的字符编码问题
|
||||
3.使用PyPinyin库将汉字转化为拼音首字母
|
||||
|
||||
Alpha 0.0.4.1
|
||||
2021 10 9
|
||||
1.将清除日志功能设置为结束后统一清除,避免了清除过程中文件占用导致的问题
|
||||
|
||||
Alpha 0.0.5
|
||||
2021 10 10
|
||||
1.支持使用邮件方式发送错误报告(日志)
|
||||
|
||||
Alpha 0.0.5.1
|
||||
1.修复了邮件发送错误报告无法发送的问题
|
||||
2.修复了打包成.exe文件之后无法正常退出的问题
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
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)
|
||||
@@ -1,134 +0,0 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
'''提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能'''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None):
|
||||
'''使用compression指定的算法打包目录为zip文件\n
|
||||
默认算法为DEFLATED(8),可用算法如下:\n
|
||||
STORED = 0\n
|
||||
DEFLATED = 8\n
|
||||
BZIP2 = 12\n
|
||||
LZMA = 14\n
|
||||
'''
|
||||
import os, zipfile
|
||||
zipf = zipfile.ZipFile(outFilename, 'w',compression)
|
||||
pre_len = len(os.path.dirname(sourceDir))
|
||||
for parent, dirnames, filenames in os.walk(sourceDir):
|
||||
for filename in filenames:
|
||||
if filename == exceptFile:
|
||||
continue;
|
||||
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 musicreater.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,'plain','utf-8'));
|
||||
log("添加完毕,正在生成压缩包...")
|
||||
makeZip("./","Temps&Logs.zip",exceptFile="Temps&Logs.zip");
|
||||
attafile=MIMEText(open("Temps&Logs.zip",'rb').read(),"base64",'gb2312');
|
||||
attafile["Content-Type"] = 'application/octet-stream';
|
||||
attafile["Content-Disposition"] = 'attachment;filename="BugReport_from_'+self.senderName+'.zip"';
|
||||
msg.attach(attafile);
|
||||
log("完毕,准备发送")
|
||||
try:
|
||||
smtp = smtplib.SMTP()
|
||||
smtp.connect("smtp.163.com");
|
||||
#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','briefcase','toga','pyinstaller','py7zr','websockets','torch')
|
||||
'''当前开发所需库'''
|
||||
|
||||
version = ('0.0.0','Gamma',)
|
||||
'''当前版本'''
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.libraries = version.libraries
|
||||
'''当前开发所需库'''
|
||||
|
||||
self.version = version.version
|
||||
'''当前版本'''
|
||||
|
||||
def installLibraries(self):
|
||||
'''安装全部开发用库'''
|
||||
from sys import platform
|
||||
import os
|
||||
if platform == 'win32':
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
except:
|
||||
pass;
|
||||
for i in self.libraries:
|
||||
print("安装库:"+i)
|
||||
os.system("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
elif platform == 'linux':
|
||||
os.system("sudo apt-get install python3-pip")
|
||||
os.system("sudo apt-get install python3-tkinter")
|
||||
for i in self.libraries:
|
||||
print("安装库:"+i)
|
||||
os.system("sudo python3 -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""音·创 的函数操作和一些其他功能"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 == None:
|
||||
includeStart = True;
|
||||
starter = Data[0];
|
||||
if ender == 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 == None:
|
||||
includeStart = True;
|
||||
starter = Data[0];
|
||||
if ender == 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:
|
||||
l = 0;
|
||||
for i in fun:
|
||||
if i.replace(" ",'')[0] == '#':
|
||||
l += 1;
|
||||
return len(fun)-l;
|
||||
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 = [];
|
||||
l = 0;
|
||||
for i in bigFile:
|
||||
if i.replace(" ",'')[0] == '#':
|
||||
part.append(i+'\n');
|
||||
else:
|
||||
part.append(i+'\n');
|
||||
l += 1;
|
||||
if l >= 10000:
|
||||
parts.append(part)
|
||||
part = [];
|
||||
l = 0;
|
||||
return parts;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeFuncFiles(musicset, path='./'):
|
||||
from musicreater.nmcsup.log import log
|
||||
'''在指定目录下生成函数文件'''
|
||||
from musicreater.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='./'):
|
||||
from musicreater.nmcsup.log import log
|
||||
'''在指定目录下生成函数包文件夹'''
|
||||
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:
|
||||
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]")
|
||||
with open(path+musicset['mainset']['PackName']+"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/manifest.json", "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("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
这里是往事,用于记载一些用不到的功能
|
||||
|
||||
#存在于 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 +0,0 @@
|
||||
|
||||
|
||||
|
||||
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
|
||||
# ————————————————
|
||||
#
|
||||
@@ -1,308 +0,0 @@
|
||||
"""音·创 的转换工具库"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,condition:bool=False,needRedstone:bool=True,tickDelay:int=0,customName:str='',lastOutput:str='',executeOnFirstTick:bool=False,trackOutput:bool=True):
|
||||
"""
|
||||
使用指定项目返回指定的指令方块格式字典
|
||||
: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: 指令方块字典结构
|
||||
"""
|
||||
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 musicreater.msctspt.transfer import formCmdBlock
|
||||
from musicreater.nmcsup.trans import Note2Cmd
|
||||
from musicreater.msctspt.bdxOpera_CP import BdxConverter
|
||||
cmd = Note2Cmd(Notes,ScoreboardName,Instrument, PlayerSelect,isProsess)
|
||||
cdl = []
|
||||
for i in cmd:
|
||||
try:
|
||||
if (i[:i.index('#')].replace(' ','') != '\n') and(i[:i.index('#')].replace(' ','') != ''):
|
||||
cdl.append(i[:i.index('#')])
|
||||
except:
|
||||
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 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 musicreater.nmcsup.log import log
|
||||
from musicreater.nmcsup.vers import VER
|
||||
|
||||
async def run_server(websocket, path):
|
||||
log('服务器连接创建')
|
||||
await fcwslib.tellraw(websocket, '已连接服务器——音·创'+VER[1]+VER[0]+' 作者:金羿(W-YI)')
|
||||
if isProsess:
|
||||
length = len(Notes)
|
||||
j = 1;
|
||||
for i in range(len(Notes)):
|
||||
await fcwslib.send_command(websocket,'execute @a'+PlayerSelect+' ~ ~ ~ playsound '+Instrument+' @s ~ ~ ~ 1000 '+str(Notes[i][0])+' 1000')
|
||||
if isProsess:
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 note2RSworld(world:str,startpos:list,notes:list,instrument:str,speed:float = 2.5,posadder:list = [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 musicreater.msctspt.values import height2note,instuments
|
||||
|
||||
|
||||
def formNoteBlock(note:int,instrument:str='note.harp',powered:bool = False):
|
||||
'''生成音符盒方块
|
||||
:param note: 0~24
|
||||
:return Block()'''
|
||||
if powered:
|
||||
powered = 'true';
|
||||
else:
|
||||
powered = 'false';
|
||||
return Block('universal_minecraft','noteblock',{"instrument":ts(instrument.replace("note.",'')),'note':ts(str(note)),'powered':ts(powered)})
|
||||
|
||||
def formRepeater(delay:int,facing:str,locked:bool=False,powered:bool=False):
|
||||
'''生成中继器方块
|
||||
: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:
|
||||
try :
|
||||
setblock(formNoteBlock(height2note[i[0]],instrument),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
setblock(Block("universal_minecraft",instuments[i[0]][1]),startpos)
|
||||
except :
|
||||
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 i 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]
|
||||
try:
|
||||
placeNoteBlock()
|
||||
except:
|
||||
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):
|
||||
try:
|
||||
self._level = amulet.load_level(self.world)
|
||||
except:
|
||||
log("无法重载地图")
|
||||
|
||||
def closeLevel(self):
|
||||
try:
|
||||
self._level.close()
|
||||
except:
|
||||
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'
|
||||
}
|
||||
}
|
||||
'''
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
|
||||
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 +0,0 @@
|
||||
从此日志开始,我的世界函数音乐构建更名为 函数音创 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 +0,0 @@
|
||||
世界音创(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
|
||||
@@ -1,320 +0,0 @@
|
||||
"""音创系列的音符对照表 以及一系列常数"""
|
||||
|
||||
|
||||
|
||||
notes = {
|
||||
'....A' : [0.074, 27.5, 'wood', 8],
|
||||
'....A#' : [0.0787, 29.135, 'wood', 9],
|
||||
'....B' : [0.083, 30.868, 'wood', 10],
|
||||
'...C' : [0.088, 32.703, 'wood', 11],
|
||||
'...C#' : [0.094, 34.648, 'wood', 12],
|
||||
'...D' : [0.1, 36.708, 'wood', 13],
|
||||
'...D#' : [0.105, 38.891, 'log', 0],
|
||||
'...E' : [0.11, 41.203, 'log', 1],
|
||||
'...F' : [0.12, 43.654, 'log', 2],
|
||||
'...F#' : [0.125, 46.249, 'wood', 0],
|
||||
'...G' : [0.13, 48.999, 'wood', 1],
|
||||
'...G#' : [0.14, 51.913, 'wood', 2],
|
||||
'...A' : [0.15, 55.0, 'wood', 3],
|
||||
'...A#' : [0.16, 58.27, 'wood', 4],
|
||||
'...B' : [0.17, 61.735, 'wood', 5],
|
||||
'..C' : [0.18, 65.406, 'wool', 0],
|
||||
'..C#' : [0.19, 69.296, 'wool', 1],
|
||||
'..D' : [0.2, 73.416, 'wool', 2],
|
||||
'..D#' : [0.21, 77.782, 'wool', 3],
|
||||
'..E' : [0.22, 82.407, 'wool', 4],
|
||||
'..F' : [0.235, 87.307, 'wool', 5],
|
||||
'..F#' : [0.25, 92.499, 'concretepowder', 0],
|
||||
'..G' : [0.26, 97.999, 'concretepowder', 1],
|
||||
'..G#' : [0.28, 103.826, 'concretepowder', 2],
|
||||
'..A' : [0.3, 110.0, 'concretepowder', 3],
|
||||
'..A#' : [0.31, 116.541, 'concretepowder', 4],
|
||||
'..B' : [0.33, 123.471, 'concretepowder', 5],
|
||||
'.C' : [0.35, 130.813, 'concretepowder', 6],
|
||||
'.C#' : [0.37, 138.591, 'concretepowder', 7],
|
||||
'.D' : [0.4, 146.832, 'concretepowder', 8],
|
||||
'.D#' : [0.42, 155.563, 'concretepowder', 9],
|
||||
'.E' : [0.44, 164.814, 'concretepowder', 10],
|
||||
'.F' : [0.47, 174.614, 'concretepowder', 11],
|
||||
'.F#' : [0.5, 184.997, 'concretepowder', 12],
|
||||
'.G' : [0.53, 195.998, 'concretepowder', 13],
|
||||
'.G#' : [0.56, 207.652, 'concretepowder', 14],
|
||||
'.A' : [0.6, 220.0, 'concretepowder', 15],
|
||||
'.A#' : [0.63, 233.082, 'concrete', 0],
|
||||
'.B' : [0.67, 246.942, 'concrete', 1],
|
||||
'C' : [0.7, 261.626, 'concrete', 2],
|
||||
'C#' : [0.75, 277.183, 'concrete', 3],
|
||||
'D' : [0.8, 293.665, 'concrete', 4],
|
||||
'D#' : [0.84, 311.127, 'concrete', 5],
|
||||
'E' : [0.9, 329.628, 'concrete', 6],
|
||||
'F' : [0.94, 349.228, 'concrete', 7],
|
||||
'F#' : [1.0, 369.994, 'concrete', 8],
|
||||
'G' : [1.05, 391.995, 'concrete', 9],
|
||||
'G#' : [1.12, 415.305, 'concrete', 10],
|
||||
'A' : [1.2, 440.0, 'concrete', 11],
|
||||
'A#' : [1.25, 466.164, 'concrete', 12],
|
||||
'B' : [1.33, 493.883, 'concrete', 13],
|
||||
'`C' : [1.4, 523.251, 'concrete', 14],
|
||||
'`C#' : [1.5, 554.365, 'concrete', 15],
|
||||
'`D' : [1.6, 587.33, 'stained_hardened_clay', 0],
|
||||
'`D#' : [1.7, 622.254, 'stained_hardened_clay', 1],
|
||||
'`E' : [1.8, 659.255, 'stained_hardened_clay', 2],
|
||||
'`F' : [1.9, 698.456, 'stained_hardened_clay', 3],
|
||||
'`F#' : [2.0, 739.989, 'stained_hardened_clay', 4],
|
||||
'`G' : [2.1, 783.991, 'stained_hardened_clay', 5],
|
||||
'`G#' : [2.24, 830.609, 'stained_hardened_clay', 6],
|
||||
'`A' : [2.4, 880.0, 'stained_hardened_clay', 7],
|
||||
'`A#' : [2.5, 932.328, 'stained_hardened_clay', 8],
|
||||
'`B' : [2.67, 987.767, 'stained_hardened_clay', 9],
|
||||
'``C' : [2.83, 1046.502, 'stained_hardened_clay', 10],
|
||||
'``C#' : [3.0, 1108.731, 'stained_hardened_clay', 11],
|
||||
'``D' : [3.17, 1174.659, 'stained_hardened_clay', 12],
|
||||
'``D#' : [3.36, 1244.508, 'stained_hardened_clay', 13],
|
||||
'``E' : [3.56, 1318.51, 'stained_hardened_clay', 14],
|
||||
'``F' : [3.78, 1396.913, 'stained_hardened_clay', 15],
|
||||
'``F#' : [4.0, 1479.978, 'white_glazed_terracotta', 0],
|
||||
'``G' : [4.24, 1567.982, 'orange_glazed_terracotta', 0],
|
||||
'``G#' : [4.5, 1661.219, 'magenta_glazed_terracotta', 0],
|
||||
'``A' : [4.76, 1760.0, 'light_blue_glazed_terracotta', 0],
|
||||
'``A#' : [5.04, 1864.655, 'yellow_glazed_terracotta', 0],
|
||||
'``B' : [5.34, 1975.533, 'lime_glazed_terracotta', 0],
|
||||
'```C' : [5.66, 2093.005, 'pink_glazed_terracotta', 0],
|
||||
'```C#' : [6.0, 2217.461, 'gray_glazed_terracotta', 0],
|
||||
'```D' : [6.35, 2349.318, 'silver_glazed_terracotta', 0],
|
||||
'```D#' : [6.73, 2489.016, 'cyan_glazed_terracotta', 0],
|
||||
'```E' : [7.13, 2637.02, 'purple_glazed_terracotta', 0],
|
||||
'```F' : [7.55, 2793.826, 'blue_glazed_terracotta', 0],
|
||||
'```F#' : [8.0, 2959.955, 'brown_glazed_terracotta', 0],
|
||||
'```G' : [8.47, 3135.963, 'green_glazed_terracotta', 0],
|
||||
'```G#' : [8.98, 3322.438, 'red_glazed_terracotta', 0],
|
||||
'```A' : [9.51, 3520.0, 'black_glazed_terracotta', 0],
|
||||
'```A#' : [10.08, 3729.31, 'stained_glass', 0],
|
||||
'```B' : [10.68, 3951.066, 'stained_glass', 1],
|
||||
'````C' : [11.31, 4186.009, 'stained_glass', 2],
|
||||
'0' : [0.0, 0.0, 'glass', 0]
|
||||
}
|
||||
'''音符对照表\n
|
||||
音符:[MC音调, 声音频率, 方块名称, 数据值]'''
|
||||
|
||||
|
||||
|
||||
|
||||
#方块
|
||||
'''
|
||||
blocks = {
|
||||
0.074 : ['stained_glass', 3],
|
||||
0.0787 : ['stained_glass', 4],
|
||||
0.083 : ['stained_glass', 5],
|
||||
0.088 : ['stained_glass', 6],
|
||||
0.094 : ['stained_glass', 7],
|
||||
0.1 : ['stained_glass', 8],
|
||||
0.105 : ['stained_glass', 9],
|
||||
0.11 : ['stained_glass', 10],
|
||||
0.12 : ['stained_glass', 11],
|
||||
0.125 : ['stained_glass', 12],
|
||||
0.13 : ['stained_glass', 13],
|
||||
0.14 : ['stained_glass', 14],
|
||||
0.15 : ['stained_glass', 15],
|
||||
0.16 : ['wool', 0],
|
||||
0.17 : ['wool', 1],
|
||||
0.18 : ['wool', 2],
|
||||
0.19 : ['wool', 3],
|
||||
0.2 : ['wool', 4],
|
||||
0.21 : ['wool', 5],
|
||||
0.22 : ['wool', 6],
|
||||
0.235 : ['wool', 7],
|
||||
0.25 : ['concretepowder', 0],
|
||||
0.26 : ['concretepowder', 1],
|
||||
0.28 : ['concretepowder', 2],
|
||||
0.3 : ['concretepowder', 3],
|
||||
0.31 : ['concretepowder', 4],
|
||||
0.33 : ['concretepowder', 5],
|
||||
0.35 : ['concretepowder', 6],
|
||||
0.37 : ['concretepowder', 7],
|
||||
0.4 : ['concretepowder', 8],
|
||||
0.42 : ['concretepowder', 9],
|
||||
0.44 : ['concretepowder', 10],
|
||||
0.47 : ['concretepowder', 11],
|
||||
0.5 : ['concretepowder', 12],
|
||||
0.53 : ['concretepowder', 13],
|
||||
0.56 : ['concretepowder', 14],
|
||||
0.6 : ['concretepowder', 15],
|
||||
0.63 : ['concrete', 0],
|
||||
0.67 : ['concrete', 1],
|
||||
0.7 : ['concrete', 2],
|
||||
0.75 : ['concrete', 3],
|
||||
0.8 : ['concrete', 4],
|
||||
0.84 : ['concrete', 5],
|
||||
0.9 : ['concrete', 6],
|
||||
0.94 : ['concrete', 7],
|
||||
1.0 : ['concrete', 8],
|
||||
1.05 : ['concrete', 9],
|
||||
1.12 : ['concrete', 10],
|
||||
1.2 : ['concrete', 11],
|
||||
1.25 : ['concrete', 12],
|
||||
1.33 : ['concrete', 13],
|
||||
1.4 : ['concrete', 14],
|
||||
1.5 : ['concrete', 15],
|
||||
1.6 : ['stained_hardened_clay', 0],
|
||||
1.7 : ['stained_hardened_clay', 1],
|
||||
1.8 : ['stained_hardened_clay', 2],
|
||||
1.9 : ['stained_hardened_clay', 3],
|
||||
2.0 : ['stained_hardened_clay', 4],
|
||||
2.1 : ['stained_hardened_clay', 5],
|
||||
2.24 : ['stained_hardened_clay', 6],
|
||||
2.4 : ['stained_hardened_clay', 7],
|
||||
2.5 : ['stained_hardened_clay', 8],
|
||||
2.67 : ['stained_hardened_clay', 9],
|
||||
2.83 : ['stained_hardened_clay', 10],
|
||||
3.0 : ['stained_hardened_clay', 11],
|
||||
3.17 : ['stained_hardened_clay', 12],
|
||||
3.36 : ['stained_hardened_clay', 13],
|
||||
3.56 : ['stained_hardened_clay', 14],
|
||||
3.78 : ['stained_hardened_clay', 15],
|
||||
4.0 : ['stained_glass_pane', 0],
|
||||
4.24 : ['stained_glass_pane', 1],
|
||||
4.5 : ['stained_glass_pane', 2],
|
||||
4.76 : ['stained_glass_pane', 3],
|
||||
5.04 : ['stained_glass_pane', 4],
|
||||
5.34 : ['stained_glass_pane', 5],
|
||||
5.66 : ['stained_glass_pane', 6],
|
||||
6.0 : ['stained_glass_pane', 7],
|
||||
6.35 : ['stained_glass_pane', 8],
|
||||
6.73 : ['stained_glass_pane', 9],
|
||||
7.13 : ['stained_glass_pane', 10],
|
||||
7.55 : ['stained_glass_pane', 11],
|
||||
8.0 : ['stained_glass_pane', 12],
|
||||
8.47 : ['stained_glass_pane', 13],
|
||||
8.98 : ['stained_glass_pane', 14],
|
||||
9.51 : ['stained_glass_pane', 15],
|
||||
10.08 : ['stained_glass', 0],
|
||||
10.68 : ['stained_glass', 1],
|
||||
11.31 : ['stained_glass', 2],
|
||||
0.0 : ['glass', 0]
|
||||
}
|
||||
#向查理平致敬!!!!!
|
||||
'''
|
||||
|
||||
|
||||
Blocks = {
|
||||
0.074: 'barrel',
|
||||
0.0787: 'beacon',
|
||||
0.083: 'bedrock',
|
||||
0.088: 'black_glazed_terracotta',
|
||||
0.094: 'blast_furnace',
|
||||
0.1: 'blue_glazed_terracotta',
|
||||
0.105: 'blue_ice',
|
||||
0.11: 'bone_block',
|
||||
0.12: 'bookshelf',
|
||||
0.125: 'brick_block',
|
||||
0.13: 'brown_glazed_terracotta',
|
||||
0.14: 'cartography_table',
|
||||
0.15: 'carved_pumpkin',
|
||||
0.16: 'clay',
|
||||
0.17: 'coal_block',
|
||||
0.18: 'coal_ore',
|
||||
0.19: 'cobblestone',
|
||||
0.2: 'concrete',
|
||||
0.21: 'crafting_table',
|
||||
0.22: 'cyan_glazed_terracotta',
|
||||
0.235: 'diamond_block',
|
||||
0.25: 'diamond_ore',
|
||||
0.26: 'white_glazed_terracotta',
|
||||
0.28: 'dispenser',
|
||||
0.3: 'dried_kelp_block',
|
||||
0.31: 'dropper',
|
||||
0.33: 'emerald_block',
|
||||
0.35: 'emerald_ore',
|
||||
0.37: 'end_bricks',
|
||||
0.4: 'end_stone',
|
||||
0.42: 'fletching_table',
|
||||
0.44: 'furnace',
|
||||
0.47: 'glass',
|
||||
0.5: 'glowingobsidian',
|
||||
0.53: 'glowstone',
|
||||
0.56: 'gold_block',
|
||||
0.6: 'gold_ore',
|
||||
0.63: 'grass',
|
||||
0.67: 'gray_glazed_terracotta',
|
||||
0.7: 'green_glazed_terracotta',
|
||||
0.75: 'hardened_clay',
|
||||
0.8: 'hay_block',
|
||||
0.84: 'iron_block',
|
||||
0.9: 'iron_ore',
|
||||
0.94: 'jukebox',
|
||||
1.0: 'lapis_block',
|
||||
1.05: 'lapis_ore',
|
||||
1.12: 'light_blue_glazed_terracotta',
|
||||
1.2: 'lime_glazed_terracotta',
|
||||
1.25: 'lit_pumpkin',
|
||||
1.33: 'log',
|
||||
1.4: 'loom',
|
||||
1.5: 'magenta_glazed_terracotta',
|
||||
1.6: 'magma',
|
||||
1.7: 'melon_block',
|
||||
1.8: 'web',
|
||||
1.9: 'mossy_cobblestone',
|
||||
2.0: 'nether_brick',
|
||||
2.1: 'nether_wart_block',
|
||||
2.24: 'netherrack',
|
||||
2.4: 'noteblock',
|
||||
2.5: 'observer',
|
||||
2.67: 'obsidian',
|
||||
2.83: 'orange_glazed_terracotta',
|
||||
3.0: 'pink_glazed_terracotta',
|
||||
3.17: 'piston',
|
||||
3.36: 'planks',
|
||||
3.56: 'prismarine',
|
||||
3.78: 'pumpkin',
|
||||
4.0: 'purple_glazed_terracotta',
|
||||
4.24: 'purpur_block',
|
||||
4.5: 'quartz_block',
|
||||
4.76: 'quartz_ore',
|
||||
5.04: 'red_glazed_terracotta',
|
||||
5.34: 'red_nether_brick',
|
||||
5.66: 'red_sandstone',
|
||||
6.0: 'redstone_block',
|
||||
6.35: 'yellow_glazed_terracotta',
|
||||
6.73: 'sandstone',
|
||||
7.13: 'stonebrick',
|
||||
7.55: 'silver_glazed_terracotta',
|
||||
8.0: 'slime',
|
||||
8.47: 'smithing_table',
|
||||
8.98: 'smoker',
|
||||
9.51: 'smooth_stone',
|
||||
10.08: 'snow',
|
||||
10.68: 'soul_sand',
|
||||
11.31: 'sponge',
|
||||
0.0: 'stone'
|
||||
}
|
||||
'''频率对照表\n
|
||||
MC音调:方块名称'''
|
||||
|
||||
|
||||
|
||||
# 乐器
|
||||
Instuments = {
|
||||
'note.banjo' : '班卓',
|
||||
'note.bass' : '低音',
|
||||
'note.bassattack' : '贝斯',
|
||||
'note.bd' : '鼓声',
|
||||
'note.bell' : '铃声',
|
||||
'note.bit' : '比特',
|
||||
'note.cow_bell' : '牛铃',
|
||||
'note.didgeridoo' : '迪吉',
|
||||
'note.flute' : '长笛',
|
||||
'note.guitar' : '吉他',
|
||||
'note.harp' : '竖琴',
|
||||
'note.hat' : '架鼓',
|
||||
'note.chime' : '钟声',
|
||||
'note.iron_xylophone' : '铁琴',
|
||||
'note.pling' : '叮叮',
|
||||
'note.snare' : '响弦',
|
||||
'note.xylophone' : '木琴'
|
||||
}
|
||||
'''乐器对照表\n
|
||||
乐器英文:中文
|
||||
翻译:雪莹工坊Fun-Fer'''
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
"""提供对于音创系列的日志"""
|
||||
|
||||
import datetime,os
|
||||
|
||||
#载入日志功能
|
||||
StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7]
|
||||
'''字符串型的程序开始时间'''
|
||||
|
||||
|
||||
def log(info:str = '',isPrinted:bool = True):
|
||||
'''将信息连同当前时间载入日志'''
|
||||
if not os.path.exists('./log/'):
|
||||
os.makedirs('./log/')
|
||||
with open('./log/'+StrStartTime+'.msct.log', 'a',encoding='UTF-8') as f:
|
||||
f.write(str(datetime.datetime.now())[11:19]+' '+info+'\n')
|
||||
if isPrinted:
|
||||
print(str(datetime.datetime.now())[11:19]+' '+info)
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
"""音创系列的文件读取功能"""
|
||||
|
||||
|
||||
|
||||
|
||||
from musicreater.nmcsup.log import log
|
||||
from musicreater.nmcsup.const import notes
|
||||
|
||||
|
||||
|
||||
#从格式文本文件读入一个音轨并存入一个列表
|
||||
def ReadFile(fn : str) -> list:
|
||||
from musicreater.nmcsup.trans import note2list
|
||||
log('打开'+fn+"并读取音符")
|
||||
try:
|
||||
nat = open(fn, 'r', encoding='UTF-8').read().split(" ")
|
||||
del fn
|
||||
except:
|
||||
log("找不到读取目标文件")
|
||||
return False
|
||||
Notes = []
|
||||
log(str(nat)+"已读取")
|
||||
for i in range(int(len(nat)/2)):
|
||||
Notes.append([nat[i*2], float(nat[i*2+1])])
|
||||
Notes = note2list(Notes)
|
||||
log('音符数据更新'+str(Notes))
|
||||
return [Notes,]
|
||||
|
||||
|
||||
#从midi读入多个音轨,返回多个音轨列表
|
||||
def ReadMidi(midfile : str ) -> list:
|
||||
import mido
|
||||
from musicreater.msctspt.threadOpera import NewThread
|
||||
Notes = []
|
||||
try:
|
||||
mid = mido.MidiFile(midfile)
|
||||
except:
|
||||
log("找不到文件或无法读取文件"+midfile)
|
||||
return False
|
||||
# 解析
|
||||
ks = list(notes.values())
|
||||
def loadMidi(track):
|
||||
datas = []
|
||||
for i in track:
|
||||
if i.is_meta:
|
||||
log('元信息'+str(i))
|
||||
pass # 不处理元信息
|
||||
elif 'note_on' in str(i):
|
||||
msg = str(i).replace("note=", '').replace("time=", '').split(" ")
|
||||
log('音符on消息,处理后:'+str(msg))
|
||||
if msg[4] == '0':
|
||||
datas.append([ks[int(msg[2])-20][0], 1.0])
|
||||
log('延续时间0tick--:添加音符'+str([ks[int(msg[2])-20][0], 1.0]))
|
||||
else:
|
||||
datas.append([ks[int(msg[2])-20][0], float(msg[4])/480])
|
||||
log('延续时间'+msg[4]+'tick--:添加音符' +str([ks[int(msg[2])-20][0], float(msg[4])/480]))
|
||||
del msg
|
||||
log('音符增加'+str(datas))
|
||||
return datas
|
||||
for j, track in enumerate(mid.tracks):
|
||||
th = NewThread(loadMidi,(track,))
|
||||
th.start()
|
||||
Notes.append(th.getResult())
|
||||
del ks
|
||||
return Notes
|
||||
|
||||
|
||||
|
||||
|
||||
def ReadOldProject(fn:str) -> list:
|
||||
import json
|
||||
from musicreater.nmcsup.trans import note2list
|
||||
log("读取文件:"+fn)
|
||||
try:
|
||||
with open(fn, 'r', encoding='UTF-8') as c:
|
||||
dataset = json.load(c)
|
||||
except:
|
||||
print('找不到文件:'+fn+",请查看您是否输入正确")
|
||||
log("丢失"+fn)
|
||||
return False
|
||||
for i in range(len(dataset['musics'])):
|
||||
dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes'])
|
||||
#返回 音轨列表 选择器
|
||||
return dataset
|
||||
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
|
||||
"""音创系列的转换功能"""
|
||||
|
||||
|
||||
|
||||
from nmcsup.log import log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
|
||||
def note2list(Notes : list) -> list:
|
||||
from musicreater.nmcsup.const import notes
|
||||
def change(base):
|
||||
enwo = {
|
||||
'a': 'A',
|
||||
'b': 'B',
|
||||
'c': 'C',
|
||||
'd': "D",
|
||||
"e": "E",
|
||||
'f': 'F',
|
||||
'g': "G"
|
||||
}
|
||||
nuwo = {
|
||||
'6': 'A',
|
||||
'7': 'B',
|
||||
'1': 'C',
|
||||
'2': "D",
|
||||
"3": "E",
|
||||
'4': 'F',
|
||||
'5': "G"
|
||||
}
|
||||
for k, v in enwo.items():
|
||||
if k in base:
|
||||
base = base.replace(k, v)
|
||||
for k, v in nuwo.items():
|
||||
if k in base:
|
||||
base = base.replace(k, v)
|
||||
return base
|
||||
res = []
|
||||
log(" === 音符列表=>音调列表")
|
||||
for i in Notes:
|
||||
s2 = change(i[0])
|
||||
log(' === 正在操作音符'+i[0]+'->'+s2)
|
||||
if s2 in notes.keys():
|
||||
log(" === 找到此音符,加入:"+str(notes[s2][0]))
|
||||
res.append([notes[s2][0], float(i[1])])
|
||||
else:
|
||||
log(' === '+s2+'不在音符表内,此处自动替换为 休止符0 ')
|
||||
res.append(['0', float(i[1])])
|
||||
log(' === 最终反回'+str(res))
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
def mcnote2freq(Notes):
|
||||
from musicreater.nmcsup.const import notes
|
||||
mcnback = {}
|
||||
for i,j in notes.items():
|
||||
mcnback[j[0]] = i
|
||||
res = []
|
||||
log(" === 我的世界音调表=>频率列表")
|
||||
for i in Notes:
|
||||
log(' === 正在操作音符'+i[0]+'->'+mcnback[i[0]])
|
||||
res.append([notes[mcnback[i[0]]][1], float(i[1])])
|
||||
log(' === 最终反回'+str(res))
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#MP3文件转midi文件
|
||||
def Mp32Mid(mp3File, midFile):
|
||||
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
|
||||
# 加载
|
||||
(audio, _) = load_audio(mp3File, sr=sample_rate, mono=True)
|
||||
# 实例化并转换
|
||||
PianoTranscription(device="cpu").transcribe(audio, midFile)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入一个音符列表转为指令列表
|
||||
def Note2Cmd(Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False) -> list:
|
||||
commands = []
|
||||
a = 0.0
|
||||
if isProsess:
|
||||
length = len(Notes)
|
||||
j = 1
|
||||
for i in range(len(Notes)):
|
||||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ playsound "+Instrument+" @s ~ ~ ~ 1000 "+str(Notes[i][0])+" 1000\n")
|
||||
a += Notes[i][1]
|
||||
if isProsess:
|
||||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a"+str(j)+"/"+str(length)+" || "+str(int(j/length*1000)/10)+"\n")
|
||||
j+=1
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
return commands
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import amulet
|
||||
import amulet_nbt
|
||||
from amulet.api.block import Block
|
||||
from amulet.api.block_entity import BlockEntity
|
||||
from amulet.utils.world_utils import block_coords_to_chunk_coords
|
||||
from amulet_nbt import TAG_String,TAG_Compound,TAG_Byte
|
||||
|
||||
|
||||
|
||||
#简单载入方块
|
||||
#level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
|
||||
|
||||
|
||||
|
||||
#转入指令列表与位置信息转至世界
|
||||
def Cmd2World(cmd:list,world:str,dire:list):
|
||||
'''将指令以命令链的形式载入世界\n
|
||||
cmd指令列表位为一个序列,中包含指令字符串\n
|
||||
world为地图所在位置,需要指向文件夹,dire为指令方块生成之位置'''
|
||||
level = amulet.load_level(world)
|
||||
cdl = []
|
||||
for i in cmd:
|
||||
try:
|
||||
if (i[:i.index('#')].replace(' ','') != '\n') and(i[:i.index('#')].replace(' ','') != ''):
|
||||
cdl.append(i[:i.index('#')])
|
||||
except:
|
||||
cdl.append(i)
|
||||
i = 0
|
||||
#第一个是特殊
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("repeating")})
|
||||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1],dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(0),'Command': TAG_String(cdl.pop(0))}) })))
|
||||
chunk.blocks[offset_x, dire[1], offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
|
||||
chunk.changed = True
|
||||
#集体上移
|
||||
dire[1]+=1;
|
||||
#真正开始
|
||||
down = False
|
||||
for j in cdl:
|
||||
if dire[1]+i >= 255:
|
||||
dire[0]+=1
|
||||
i=0
|
||||
down = not down
|
||||
#定义此方块
|
||||
if dire[1]+i == 254 :
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('east'),'mode':TAG_String("chain")})
|
||||
else:
|
||||
if down:
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('down'),'mode':TAG_String("chain")})
|
||||
else:
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("chain")})
|
||||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||||
#获取区块
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||||
if down:
|
||||
#定义方块实体
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],254-i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||||
|
||||
#将方块加入世界
|
||||
chunk.blocks[offset_x, 254-i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], 254-i, dire[2])] = universal_block_entity
|
||||
else:
|
||||
#定义方块实体
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1]+i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||||
|
||||
#将方块加入世界
|
||||
chunk.blocks[offset_x, dire[1]+i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], dire[1]+i, dire[2])] = universal_block_entity
|
||||
#设置为已更新区块
|
||||
chunk.changed = True
|
||||
i+=1
|
||||
del i, cdl
|
||||
#保存世界并退出
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#音符转成方块再加载到世界里头
|
||||
def Blocks2World(world:str,dire:list,Datas:list):
|
||||
from musicreater.nmcsup.const import Blocks
|
||||
level = amulet.load_level(world)
|
||||
i = 0
|
||||
def setblock(block:str,pos:list):
|
||||
'''pos : list[int,int,int]'''
|
||||
cx, cz = block_coords_to_chunk_coords(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("minecraft",block))
|
||||
chunk.changed = True
|
||||
for j in Datas:
|
||||
if dire[1]+1 >= 255:
|
||||
i = 0
|
||||
dire[0]+=1
|
||||
setblock(Blocks[j[0]],[dire[0],dire[1]+i,dire[2]])
|
||||
i = int(i+j[1]+0.5) #四舍五入
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入音符列表制作播放器指令
|
||||
def Notes2Player(Note,dire:list,CmdData:dict):
|
||||
'''传入音符列表、坐标、指令数据,生成播放器指令'''
|
||||
Notes = {}
|
||||
for i in Note:
|
||||
Notes[i[0]] = ''
|
||||
Notes = list(Notes.keys())
|
||||
from musicreater.nmcsup.const import Blocks
|
||||
Cmds = []
|
||||
for j in Notes:
|
||||
Cmds.append('execute @e[x='+str(dire[0])+',y='+str(dire[1])+',z='+str(dire[2])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ detect ~ ~ ~ '+Blocks[j]+' 0 execute @a '+CmdData['Pls']+' ~ ~ ~ playsound '+CmdData['Ins']+' @s ~ ~ ~ 1000 '+str(j)+' 1000\n')
|
||||
Cmds+=['#本函数由 金羿 音·创 生成\n','execute @e[y='+str(dire[1])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ tp ~ ~1 ~\n','execute @e[y=255,dy=100,name='+CmdData['Ent']+'] ~ ~ ~ tp ~1 '+str(dire[1])+' ~\n','#音·创 开发交流群 861684859']
|
||||
return Cmds
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入音符列表生成方块至世界
|
||||
def Datas2BlkWorld(NoteData,world:str,dire:list):
|
||||
for i in range(len(NoteData)):
|
||||
Blocks2World(world,[dire[0],dire[1],dire[2]+i],NoteData[i])
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
"""音创系列版本号和版本操作函数"""
|
||||
|
||||
|
||||
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
|
||||
|
||||
#以下下两个值请在 msctspt/bugReporter 的version类中修改
|
||||
VER = version.version
|
||||
'''当前版本'''
|
||||
|
||||
LIBS = version.libraries
|
||||
'''当前所需库'''
|
||||
|
||||
|
||||
|
||||
#判断版本、临时文件与补全库
|
||||
def compver(ver1, ver2):
|
||||
"""
|
||||
传入不带英文的版本号,特殊情况:"10.12.2.6.5">"10.12.2.6"
|
||||
:param ver1: 版本号1
|
||||
:param ver2: 版本号2
|
||||
:return: ver1< = >ver2返回-1/0/1
|
||||
"""
|
||||
list1 = str(ver1).split(".")
|
||||
list2 = str(ver2).split(".")
|
||||
# 循环次数为短的列表的len
|
||||
for i in range(len(list1)) if len(list1) < len(list2) else range(len(list2)):
|
||||
if int(list1[i]) == int(list2[i]):
|
||||
pass
|
||||
elif int(list1[i]) < int(list2[i]):
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
# 循环结束,哪个列表长哪个版本号高
|
||||
if len(list1) == len(list2):
|
||||
return 0
|
||||
elif len(list1) < len(list2):
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
#
|
||||
# ————————————————
|
||||
# 版权声明:上面的函数compver为CSDN博主「基友死得早」的原创文章中的函数,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
# 原文链接:https://blog.csdn.net/tinyjm/article/details/93514261
|
||||
# ————————————————
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
def InstallLibs(now,LIBS):
|
||||
'''比对库信息并安装库'''
|
||||
from os import system as run
|
||||
for i in LIBS:
|
||||
if not i in now:
|
||||
print("安装库:"+i)
|
||||
run("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
|
||||
|
||||
def chkver(ver = VER,libs = LIBS):
|
||||
'''通过文件比对版本信息并安装库'''
|
||||
if not os.path.exists(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct'):
|
||||
print("新安装库")
|
||||
os.makedirs(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
|
||||
f.write(ver[0]+'\n')
|
||||
for i in libs:
|
||||
f.write(i+'\n')
|
||||
InstallLibs([],libs)
|
||||
else:
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'r') as f:
|
||||
v = f.readlines()
|
||||
cp = compver(ver[0], v[0])
|
||||
if cp != 0:
|
||||
InstallLibs(v[1:],libs)
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
|
||||
f.write(ver[0]+'\n')
|
||||
for i in libs:
|
||||
f.write(i+'\n')
|
||||
del cp
|
||||
|
||||
|
||||
def resetver():
|
||||
'''重置版本信息'''
|
||||
import shutil
|
||||
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
LANGUAGE = {
|
||||
'main':{
|
||||
"name":"音·创",
|
||||
"version":"当前版本",
|
||||
"run":"执行指令",
|
||||
},
|
||||
'command':{
|
||||
"NotAvailable":"此指令不可用。",
|
||||
"FormatError":"指令格式错误,请查看 命令行操作.md 以查阅指令。"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 441 KiB |
@@ -1,11 +0,0 @@
|
||||
生命灵动 当用激情跃起奋发之力
|
||||
奇偶数阵
|
||||
学海无涯 应用爱意徜徉
|
||||
在生命的起源寻找灵魂的慰藉
|
||||
纪念那一段辉煌灿烂的青春年华
|
||||
以梦想为驱使 创造属于自己的未来
|
||||
集青春之力 绽放爱意之花
|
||||
那个曾与我相伴的人 依稀在我的心头留恋
|
||||
我爱你 我 爱 你
|
||||
你是我灵魂中绽放出最艳丽的花朵
|
||||
心之所向 意之所属
|
||||
@@ -1,34 +0,0 @@
|
||||
# Musicreater 音·创 命令行模式
|
||||
|
||||
为了对后期安卓的兼容,先支持命令行
|
||||
|
||||
## 命令列表
|
||||
|
||||
### exit \[/s\] \[/c\]
|
||||
|
||||
- ```/s``` 保存并退出
|
||||
- ```/c``` 清除日志
|
||||
|
||||
### save \[/a \<fileName\>\]
|
||||
|
||||
- ```/a <文件名>``` 指定文件名保存
|
||||
|
||||
### load \[/\<loadMethod: input|txt|mid\> \<text|fileName\>\]
|
||||
|
||||
- ```/input <文本>``` 输入音符
|
||||
- ```/txt <文件名>``` 从文本载入音符
|
||||
- ```/mid <文件名>``` 解析midi文件载入音符
|
||||
|
||||
### win
|
||||
|
||||
- 开启窗口模式的 音·创(仅支持的系统下有效)
|
||||
|
||||
### chdir \<direction\>
|
||||
|
||||
- 切换当前工作目录
|
||||
|
||||
### build \[/\<buildMethod: file|directory|mcpack\> \<direction\>\]
|
||||
|
||||
- ```/file <目录位置>``` 在指定目录生成函数文件(散装)
|
||||
- ```/directory <目录位置>``` 在指定目录生成一个附加包目录
|
||||
- ```/mcpack <目录位置>``` 在指定目录生成一个.mcpack附加包
|
||||
@@ -1,29 +0,0 @@
|
||||
# -*- conding: utf8 -*-
|
||||
|
||||
import os
|
||||
from src.musicreater.msctspt.funcOpera import keepart
|
||||
|
||||
|
||||
l = 0
|
||||
|
||||
|
||||
|
||||
for path,dir_list,file_list in os.walk(r"./") :
|
||||
for file_name in file_list:
|
||||
if keepart(file_name,'.',None) == '.py':
|
||||
file = os.path.join(path, file_name)
|
||||
print("得到文件名:"+str(file))
|
||||
for i in open(file,'r',encoding="utf-8"):
|
||||
code = i.replace(' ','').replace('\n','')
|
||||
try:
|
||||
code -= code[code.index('#'):]
|
||||
except:
|
||||
pass;
|
||||
if code:
|
||||
print("\t"+code)
|
||||
l+=1
|
||||
else:
|
||||
pass;
|
||||
|
||||
input("\n最终代码行数为:"+str(l))
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
{
|
||||
"mainset": {
|
||||
"PackName": "RyounTeamSong",
|
||||
"MusicTitle": "RyounUp",
|
||||
"IsRepeat": false,
|
||||
"PlayerSelect": ""
|
||||
},
|
||||
"musics": [
|
||||
{
|
||||
"set": {
|
||||
"EntityName": "MusicSupport",
|
||||
"ScoreboardName": "MusicSupport",
|
||||
"Instrument": "harp",
|
||||
"FileName": "RyounUp_RyounTeamSong"
|
||||
},
|
||||
"notes": [
|
||||
[
|
||||
".5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
".6",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
".5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"6",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
".5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
".6",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"6",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
".5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user