From 64292a21b34e8425c6ca4edcb64440d63562c524 Mon Sep 17 00:00:00 2001 From: EillesWan Date: Wed, 11 May 2022 21:34:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=80=E7=82=B9=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Musicreater.New.py | 120 - Musicreater.New.update.py | 54 + Musicreater.main.py | 425 ---- Musicreater.py | 2005 ----------------- fcwslib/__init__.py | 170 -- fcwslib/main.py | 160 -- fcwslib/版权声明.png | Bin 68955 -> 0 bytes msctLib/buildIN.py | 4 +- msctspt/__init__.py | 0 msctspt/__pycache__/__init__.cpython-37.pyc | Bin 139 -> 0 bytes msctspt/__pycache__/__init__.cpython-38.pyc | Bin 149 -> 0 bytes msctspt/__pycache__/__init__.cpython-39.pyc | Bin 191 -> 0 bytes .../__pycache__/bdxOpera_CP.cpython-38.pyc | Bin 6194 -> 0 bytes .../__pycache__/bdxOpera_CP.cpython-39.pyc | Bin 6372 -> 0 bytes .../__pycache__/bugReporter.cpython-37.pyc | Bin 4406 -> 0 bytes .../__pycache__/bugReporter.cpython-38.pyc | Bin 4430 -> 0 bytes .../__pycache__/bugReporter.cpython-39.pyc | Bin 4612 -> 0 bytes msctspt/__pycache__/funcOpera.cpython-38.pyc | Bin 10610 -> 0 bytes msctspt/__pycache__/funcOpera.cpython-39.pyc | Bin 11157 -> 0 bytes .../__pycache__/threadOpera.cpython-37.pyc | Bin 977 -> 0 bytes .../__pycache__/threadOpera.cpython-38.pyc | Bin 1003 -> 0 bytes .../__pycache__/threadOpera.cpython-39.pyc | Bin 1045 -> 0 bytes msctspt/__pycache__/transfer.cpython-38.pyc | Bin 17537 -> 0 bytes msctspt/__pycache__/transfer.cpython-39.pyc | Bin 16319 -> 0 bytes msctspt/__pycache__/values.cpython-38.pyc | Bin 1453 -> 0 bytes msctspt/bdxOpera_CP.py | 216 -- msctspt/bugReporter.py | 93 - msctspt/funcOpera.py | 422 ---- msctspt/threadOpera.py | 27 - msctspt/transfer.py | 577 ----- msctspt/values.py | 56 - nmcsup/EptWorld.zip | Bin 19085 -> 0 bytes nmcsup/MMFM Cpp E Develop Log.txt | 62 - nmcsup/MMFM Py E Development Log.txt | 126 -- nmcsup/NFC Dev Log.txt | 72 - nmcsup/NMC Dev Log.txt | 36 - nmcsup/__init__.py | 0 nmcsup/__pycache__/__init__.cpython-37.pyc | Bin 138 -> 0 bytes nmcsup/__pycache__/__init__.cpython-38.pyc | Bin 148 -> 0 bytes nmcsup/__pycache__/__init__.cpython-39.pyc | Bin 165 -> 0 bytes nmcsup/__pycache__/const.cpython-38.pyc | Bin 6179 -> 0 bytes nmcsup/__pycache__/const.cpython-39.pyc | Bin 10275 -> 0 bytes nmcsup/__pycache__/log.cpython-37.pyc | Bin 1695 -> 0 bytes nmcsup/__pycache__/log.cpython-38.pyc | Bin 1710 -> 0 bytes nmcsup/__pycache__/log.cpython-39.pyc | Bin 1747 -> 0 bytes nmcsup/__pycache__/nmcreader.cpython-38.pyc | Bin 2836 -> 0 bytes nmcsup/__pycache__/nmcreader.cpython-39.pyc | Bin 2879 -> 0 bytes nmcsup/__pycache__/trans.cpython-38.pyc | Bin 7168 -> 0 bytes nmcsup/__pycache__/vers.cpython-37.pyc | Bin 2077 -> 0 bytes nmcsup/__pycache__/vers.cpython-38.pyc | Bin 2081 -> 0 bytes nmcsup/__pycache__/vers.cpython-39.pyc | Bin 2160 -> 0 bytes nmcsup/const.py | 312 --- nmcsup/log.py | 71 - nmcsup/nmcreader.py | 128 -- nmcsup/trans.py | 246 -- nmcsup/vers.py | 86 - 查看代码数.py => 《作者的自我激励》.py | 48 +- 57 files changed, 80 insertions(+), 5436 deletions(-) delete mode 100644 Musicreater.New.py create mode 100644 Musicreater.New.update.py delete mode 100644 Musicreater.main.py delete mode 100644 Musicreater.py delete mode 100644 fcwslib/__init__.py delete mode 100644 fcwslib/main.py delete mode 100644 fcwslib/版权声明.png delete mode 100644 msctspt/__init__.py delete mode 100644 msctspt/__pycache__/__init__.cpython-37.pyc delete mode 100644 msctspt/__pycache__/__init__.cpython-38.pyc delete mode 100644 msctspt/__pycache__/__init__.cpython-39.pyc delete mode 100644 msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc delete mode 100644 msctspt/__pycache__/bdxOpera_CP.cpython-39.pyc delete mode 100644 msctspt/__pycache__/bugReporter.cpython-37.pyc delete mode 100644 msctspt/__pycache__/bugReporter.cpython-38.pyc delete mode 100644 msctspt/__pycache__/bugReporter.cpython-39.pyc delete mode 100644 msctspt/__pycache__/funcOpera.cpython-38.pyc delete mode 100644 msctspt/__pycache__/funcOpera.cpython-39.pyc delete mode 100644 msctspt/__pycache__/threadOpera.cpython-37.pyc delete mode 100644 msctspt/__pycache__/threadOpera.cpython-38.pyc delete mode 100644 msctspt/__pycache__/threadOpera.cpython-39.pyc delete mode 100644 msctspt/__pycache__/transfer.cpython-38.pyc delete mode 100644 msctspt/__pycache__/transfer.cpython-39.pyc delete mode 100644 msctspt/__pycache__/values.cpython-38.pyc delete mode 100644 msctspt/bdxOpera_CP.py delete mode 100644 msctspt/bugReporter.py delete mode 100644 msctspt/funcOpera.py delete mode 100644 msctspt/threadOpera.py delete mode 100644 msctspt/transfer.py delete mode 100644 msctspt/values.py delete mode 100644 nmcsup/EptWorld.zip delete mode 100644 nmcsup/MMFM Cpp E Develop Log.txt delete mode 100644 nmcsup/MMFM Py E Development Log.txt delete mode 100644 nmcsup/NFC Dev Log.txt delete mode 100644 nmcsup/NMC Dev Log.txt delete mode 100644 nmcsup/__init__.py delete mode 100644 nmcsup/__pycache__/__init__.cpython-37.pyc delete mode 100644 nmcsup/__pycache__/__init__.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/__init__.cpython-39.pyc delete mode 100644 nmcsup/__pycache__/const.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/const.cpython-39.pyc delete mode 100644 nmcsup/__pycache__/log.cpython-37.pyc delete mode 100644 nmcsup/__pycache__/log.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/log.cpython-39.pyc delete mode 100644 nmcsup/__pycache__/nmcreader.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/nmcreader.cpython-39.pyc delete mode 100644 nmcsup/__pycache__/trans.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/vers.cpython-37.pyc delete mode 100644 nmcsup/__pycache__/vers.cpython-38.pyc delete mode 100644 nmcsup/__pycache__/vers.cpython-39.pyc delete mode 100644 nmcsup/const.py delete mode 100644 nmcsup/log.py delete mode 100644 nmcsup/nmcreader.py delete mode 100644 nmcsup/trans.py delete mode 100644 nmcsup/vers.py rename 查看代码数.py => 《作者的自我激励》.py (96%) diff --git a/Musicreater.New.py b/Musicreater.New.py deleted file mode 100644 index 6f2cd82..0000000 --- a/Musicreater.New.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- - - -# W-YI 金羿 -# QQ 2647547478 -# 音·创 开发交流群 861684859 -# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com -# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") -# 若需转载或借鉴 请附作者 - - -""" -音·创 (Musicreater) -一款免费开源的 《我的世界:基岩版》 音乐制作软件 -Musicreater (音·创) -A free opensource software which is used for creating all kinds of musics in Minecraft - - Copyright 2022 Team-Ryoun - - Licensed under the Apache License, Version 2.0 (the 'License'); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 - - -# 下面为正文 - -# 一定会好起来的 - - -from msctLib.buildIN import version - -__ver__ = f'{version.version[1]} {version.version[0]}' -__author__ = '金羿Eilles' - -import msctLib.display as disp - -from msctLib.function import * - -from msctLib.data import uniteIO - - -hb = r''' __ __ - /\ \/\ \ - \ \ \_\ \ __ _____ _____ __ __ - \ \ _ \ /'__`\ /\ '__`\ /\ '__`\ /\ \/\ \ - \ \ \ \ \ /\ \L\.\_\ \ \L\ \\ \ \L\ \\ \ \_\ \ - \ \_\ \_\\ \__/.\_\\ \ ,__/ \ \ ,__/ \/`____ \ - \/_/\/_/ \/__/\/_/ \ \ \/ \ \ \/ `/___/> \ - \ \_\ \ \_\ /\___/ - \/_/ \/_/ \/__/ - ____ __ __ __ - /\ _`\ __ /\ \__ /\ \ /\ \ - \ \ \L\ \ /\_\ _ __ \ \ ,_\\ \ \___ \_\ \ __ __ __ - \ \ _ <'\/\ \ /\`'__\\ \ \/ \ \ _ `\ /'_` \ /'__`\ /\ \/\ \ - \ \ \L\ \\ \ \\ \ \/ \ \ \_ \ \ \ \ \ /\ \L\ \ /\ \L\.\_\ \ \_\ \ - \ \____/ \ \_\\ \_\ \ \__\ \ \_\ \_\\ \___,_\\ \__/.\_\\/`____ \ - \/___/ \/_/ \/_/ \/__/ \/_/\/_/ \/__,_ / \/__/\/_/ `/___/> \ - /\___/ - \/__/ ''' - - -def __main__(): - import datetime, time, random, os, sys, zhdate - - if datetime.date.today().month == 4 and datetime.date.today().day == 3: - if sys.platform == 'win32': - os.system('color 4e') - os.system('cls') - for i in range(len(hb)): - print(hb[i], end='', flush=True) - time.sleep(random.random() * 0.001) - input("金羿 生日快乐!") - elif '三月初五' in zhdate.ZhDate.today().chinese(): - input('缅怀先祖 祭祀忠勇 勿忘国耻 振兴中华') - - else: - - def test(): - print('!!!', end=' ') - - def test2(): - print('???', end=' ') - - window = disp.disp( - disp.root, - geometry='1200x800', - menuWidget={ - '文件': {'新建': test, '打开': test}, - '编辑': {'撤销': test, '重做': test}, - '视图': {'缩放': test}, - '帮助': {'关于': disp.authorWindowStarter}, - }, - title='音·创 0.2 测试中', - buttons=[ - { - '新建': ('', test2), - '打开': ('', test2) - }, - { - '测试': ('', test2) - } - ], - debug=True, - ) - - - -if __name__ == '__main__': - __main__() diff --git a/Musicreater.New.update.py b/Musicreater.New.update.py new file mode 100644 index 0000000..9f84942 --- /dev/null +++ b/Musicreater.New.update.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + + +# 金羿 Eilles +# QQ 2647547478 +# 音·创 开发交流群 861684859 +# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com +# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") +# 若需转载或借鉴 请附作者 + + +""" +音·创 (Musicreater) +一款免费开源的 《我的世界:基岩版》 音乐制作软件 +Musicreater (音·创) +A free opensource software which is used for creating all kinds of musics in Minecraft + + Copyright 2022 Team-Ryoun + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照 Apache 2.0 软件协议公开 + + +# 下面为正文 + +# 一定会好起来的 + + +from msctLib.buildIN import version + +__ver__ = f'{version.version[1]} {version.version[0]}' +__author__ = '金羿Eilles' + + + +def __main__(): + pass + + + +if __name__ == '__main__': + __main__() diff --git a/Musicreater.main.py b/Musicreater.main.py deleted file mode 100644 index 005e76c..0000000 --- a/Musicreater.main.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- coding: utf-8 -*- -'''音·创的Tkinter GUI窗口界面显示主程序 -:若要使用其他界面显示,请详见: -:开发说明|指南''' - - -import tkinter as tk -import tkinter.simpledialog as sdialog -import tkinter.filedialog as fdialog -from msctLib.log import log - - -DEFAULTBLUE = (0, 137, 242) -# 0089F2 - -WEAKBLUE = (0, 161, 231) -LIGHTBLUE = (38, 226, 255) -# 26E2FF - -RED = (255, 52, 50) -# FF3432 - -PURPLE = (171, 112, 255) -# AB70FF - -GREEN = (0, 255, 33) -# 00FF21 - -WHITE = (242, 244, 246) -# F2F4F6 - -BLACK = (18, 17, 16) -# 121110 - - -backgroundColor = WHITE -frontgroundColor = BLACK -loadingColor = DEFAULTBLUE -errorColor = RED -okColor = GREEN -tipsColor = PURPLE - -# 注:UI界面字体、代码字体 -fontPattern = ('DengXian Light', 'Fira Code') - - - -# ========================================================= -# 设定函数部分 -# ========================================================= - -def setTitle(__root, title_: str = '') -> None: - '''设置窗口标题 - :param title: str 窗口标题''' - - if title: - self.title = title_ - __root.title(self.title) - if self.debug: - log(f"设置窗口标题 {self.title}") - -def setGeometry(__root, geometry: str = '0x0') -> None: - '''设置窗口大小 - :param geometry: str 窗口大小''' - __root.geometry(geometry) - if self.debug: - log(f"设置窗口大小{geometry}") - -def setIcon(__root, bitmap: str = './musicreater.ico', default: str = '') -> bool: - '''设置窗口图标 - :param bitmap: str 图标路径 - :param default: str 设置对于全局的默认图标路径 - 注意,default参数仅在Windows下有效,其意为将所有没有图标的窗口设置默认图标。如果在非Windows环境使用default参数,将会引发一个错误 - :retuen bool 是否成功设置图标''' - - try: - if default: - __root.iconbitmap(bitmap, default) - log(f'设置图标为{bitmap},默认为{default}') - else: - __root.iconbitmap(bitmap) - log(f'设置图标为{bitmap}') - return True - except Exception as e: - log(str(e), 'ERROR') - if self.debug: - raise e - return False - -def setMenu(__root) -> None: - '''设置根菜单''' - if not self.menuWidgets: - # 如果传入空参数则返回当前菜单 - try: - return self._RootMenu - except Exception as E: - if self.debug: - raise E - log('无法读取菜单信息', 'WARRING') - # 如果不是空参数则新建菜单 - log('新建一个菜单') - - self._RootMenu = {} - self._mainMenuBar = tk.Menu(__root) - for menuName, menuCmd in self.menuWidgets.items(): - # 取得一个菜单名和一堆菜单函数及其显示名称 - menu = tk.Menu(self._mainMenuBar, tearoff=0) - for cmdName, cmdFunc in menuCmd.items(): - if cmdName: - menu.add_command(label=cmdName, command=cmdFunc) - log('菜单项 -- ' + cmdName) - else: - menu.add_separator() - log('分隔符 -- 分隔符') - self._mainMenuBar.add_cascade(label=menuName, menu=menu) - self._RootMenu[menuName] = menu - log('计入一个菜单 -- ' + menuName) - __root.config(menu=self._mainMenuBar) - log('菜单设置完毕') - -def addMenu(menuRoot: str = '', menuLabel: str = '', menuCommand=None): - '''增加一个菜单项 - :param menuRoot : str - 菜单的根菜单,即所属的菜单上的文字 - :param menuLabel : str - 所需要增加的项目显示的文字 - :param menuCommand : - ''' - if menuRoot in self._RootMenu.keys: - # 如果已经有父菜单 - if menuLabel: - # 增加菜单指令 - self._RootMenu[menuRoot].add_command( - label=menuLabel, command=menuCommand - ) - else: - # 增加分隔栏 - self._RootMenu[menuRoot].add_separator() - else: - # 没有父菜单则新增一个父菜单 - menu = tk.Menu(self._mainMenuBar, tearoff=False) - if menuLabel: - menu.add_command(label=menuLabel, command=menuCommand) - else: - menu.add_separator() - self._mainMenuBar.add_cascade(label=menuRoot, menu=menu) - self._RootMenu[menuRoot] = menu - -def initWidget(__root) -> None: - '''设置窗口小部件,分为: - :言·论 WordView - :快捷按钮面板 ButtonBar - :设置框 SettingBar - :音轨框 TrackBar - :各个音轨的显示框 TrackFrame - :信息显示版 InfoBar - ''' - self._wordviewBar = tk.Label( - __root, - bg='black', - fg='white', - text=self.wordView, - font=(fontPattern[0], 30), - ) - # 定义 言·论 版面 - log('言·论版面设置完成') - - self._infoBar = tk.Label( - __root, - bg='white', - fg='black', - text=self.infoBar, - font=(fontPattern[0], 10), - ) - # 定义 信息显示版 - log('信息显示版设置完成') - - self._buttonBar = tk.Frame( - __root, - bd=2, - ) - # 定义 快捷按钮面板. 注意!这里是以一个Frame为容器,而不是一个Button列表,后面的版面也以Frame容器居多 - - self.setButtonBar(self.buttons) - - self._wordviewBar.pack(side='top', fill='x') - self._buttonBar.pack(side='top', fill='x') - - self._infoBar.pack(side='bottom', fill='x') - -def setButtonBar( - self, - buttonList: list = [], - defaultMissingTexturePath: str = './resources/uimage/missing_texture.png', - separatorButtonTexturePath: str = './resources/uimage/separator_line.png', -) -> None: - '''设置快捷按钮面板 - :param buttonList : list - 快捷按钮列表,每个元素为一个字典,字典的键为按钮名称,值为一个元组,元组中第一项为按钮的图标,第二项为按钮的回调函数 - ''' - - # 图标应该如下 - # 新建 打开 保存 | - - self._buttonBarList = [] - '''按钮对象列表,注意软件调用的时候千万别动!''' - - separatorimg = tk.PhotoImage(file=separatorButtonTexturePath) - - for buttons in buttonList: - # 循环每个按钮组 - for name, args in buttons.items(): - # 循环每个按钮 - try: - img = tk.PhotoImage(file=args[0]) - except: - log('载入图片失败,使用默认图片','WARNING') - if self.debug: - raise FileNotFoundError(f'图片{args[0]}不存在') - img = tk.PhotoImage(file=defaultMissingTexturePath) - button = tk.Button( - self._buttonBar, - text=name, - command=args[1], - image=img, - bd=2, - compound='center', - font=(fontPattern[0], 10), - ) - button.pack(side='left', padx=5, pady=5) - self._buttonBarList.append(button) - # 添加按钮 - tk.Label(self._buttonBar, image=separatorimg).pack( - side='left', padx=5, pady=5 - ) - -def setWordView(self, text: str) -> None: - '''重新设置言·论版的文字''' - self._wordviewBar['text'] = text - -def setInfoBar(self, text: str) -> None: - '''重新设置信息显示版的文字''' - self._infoBar['text'] = text - -# ========================================================= -# 预置函数部分 -# ========================================================= - -def authorWindowStarter( - authors: tuple = ( - ('金羿', 'Email EillesWan@outlook.com', 'QQ 2647547478'), - ('诸葛亮与八卦阵', 'QQ 474037765'), - ) -): - '''自定义作者界面''' - from languages.lang import _ - from languages.lang import DEFAULTLANGUAGE - from msctLib.buildIN import version - - authorWindow = tk.Tk() - authorWindow.title(_('关于')) - authorWindow.geometry('550x600') # 像素 - tk.Label(authorWindow, text='', font=('', 15)).pack() - tk.Label(authorWindow, text=_('F音创'), font=('', 35)).pack() - tk.Label( - authorWindow, - text='{} {}'.format(version.version[1] , version.version[0]), - font=('', 15), - ).pack() - # pack 的side可以赋值为LEFT RTGHT TOP BOTTOM - # grid 的row 是列数、column是行排,注意,这是针对空间控件本身大小来的,即是指向当前控件的第几个。 - # place的 x、y是(x,y)坐标 - rylogo = tk.PhotoImage(file='./resources/RyounLogo.png') - tk.Label( - authorWindow, - image=rylogo, - width=200, - height=200, - ).pack() - tk.Label(authorWindow, text=_('凌云pairs'), font=('', 20)).pack() - tk.Label(authorWindow, text='', font=('', 15)).pack() - tk.Label(authorWindow, text=_('开发者'), font=('', 15)).pack() - for i in authors: - for j in i: - tk.Label( - authorWindow, - text=j, - font=( - '', - 17 if i.index(j) == 0 else 15, - 'bold' if i.index(j) == 0 else '', - ), - ).pack() - tk.Label(authorWindow, text='', font=('', 5)).pack() - if DEFAULTLANGUAGE != 'zh-CN': - tk.Label(authorWindow, text=_('译者'), font=('', 15)).pack() - for i in _('TRANSLATERS').split(';'): - for j in i.split(','): - tk.Label( - authorWindow, - text=j, - font=( - '', - 17 if i.split(',').index(j) == 0 else 15, - 'bold' if i.split(',').index(j) == 0 else '', - ), - ).pack() - - def exitAboutWindow(): - authorWindow.destroy() - - tk.Button(authorWindow, text=_('确定'), command=exitAboutWindow).pack() - - authorWindow.mainloop() - - -class ProgressBar: - def __init__( - self, - root: tk.Tk = tk.Tk(), - style: tuple = (DEFAULTBLUE, BLACK, WHITE), - type: bool = False, - info: str = '', - debug: bool = False, - ) -> None: - '''建立一个进度条或者加载等待界面 - :param root : tk.Tk - 建立进度条的根窗口 - :param style : tuple - 设置主题颜色,第一个参数为进度条或者等待转圈圈的颜色,第二个参数为前景色,第三个是背景色 - :param type : bool - 类型,为 False 时为进度条,为 True 时为等待板 - :param info : str - 显示的附加信息 - :param debug : bool - 是否输出日志到控制台''' - self.root = root - - -# TODO -# 单选框与复选框 - - -if __name__ == '__mian__': - - # __root, - # debug: bool = False, - # title: str = '音·创', - # geometry: str = '0x0', - # iconbitmap: tuple = ('./resources/musicreater.ico', './resources/musicreater.ico'), - # menuWidget: dict = {}, - # wordView: str = '音·创 Musicreater', - # buttons: list = [], - # settingBox: list = [], - # notemap: list = [], - # infobar: str = '就绪', - - '''使用参数建立基本的 音·创 窗口 - :param root 根窗口 - :param debug 是否将日志输出到控制台 - :param title 窗口标题 - wordview: str #言论部分显示的字样 - button: list = [ # 操作按钮部分 - dict = { - 按钮名称 : tuple(按钮图标,执行函数) - }, - ], - settingbox: list = [ # 设置部分显示的字样及其对应的设置函数 - ( - 设置名称:str, - 值类型:tuple, - 显示内容:str, - 设置操作函数:, - ) - ], - map: list = [ # 一首曲目的音符数据 - 音符数据 - ] - :param infobar str 显示信息用 - ''' - - if debug: - log('载入参数') - - # 载入参量 注意!图标将不被载入参数 - - - self.title = title - '''窗口标题''' - - self.menuWidgets = menuWidget - '''菜单设定项''' - - self.wordView = wordView - '''言·论 所显示的文字''' - - self.buttons = buttons - '''快捷功能按钮''' - - self.settingBox = settingBox - '''设置框''' - - self.notemap = notemap - '''音符列表''' - - self.infoBar = infobar - '''信息显示版所显示的文字''' - - self.debug = debug - '''是否打开调试模式''' - - self.setTitle(__root,) - - self.setGeometry(__root, geometry) - self.setIcon(__root, *iconbitmap) - - self.setMenu(__root) - - self.initWidget(__root) - - self.start(__root) - -def start(self, __root) -> None: - # 启动主消息循环 - __root.mainloop() diff --git a/Musicreater.py b/Musicreater.py deleted file mode 100644 index b892c02..0000000 --- a/Musicreater.py +++ /dev/null @@ -1,2005 +0,0 @@ -# -*- coding: utf-8 -*- - - -# W-YI 金羿 -# QQ 2647547478 -# 音·创 开发交流群 861684859 -# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com -# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") -# 若需转载或借鉴 请附作者 - - -""" -音·创 (Musicreater) -一款免费开源的 《我的世界:基岩版》 音乐制作软件 -Musicreater (音·创) -A free opensource software which is used for creating all kinds of musics in Minecraft - - Copyright 2022 Team-Ryoun - - Licensed under the Apache License, Version 2.0 (the 'License'); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 - -# -----------------------------分割线----------------------------- -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:15个;语法(一级)错误:597个 -# 目前我的Pycharm并没有显示任何错误,有错误可以向 -# bgArray 诸葛亮与八卦阵 -# QQ 474037765 或最好加入:音·创 开发交流群 861684859 -# ------------------------- split line----------------------------- -# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022 -# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597 -# At present, my Pycham does not display any errors. If there are errors, you can report them to me -# Bgarray Zhuge Liang and Bagua array -# QQ 474037765 or better join: Musicreater development exchange group 861684859 -# ------------------------- split line----------------------------- - -# 下面为正文 - - -import json -import os -import shutil -import sys -import threading -import pickle -import tkinter as tk -import tkinter.filedialog -import tkinter.messagebox -import tkinter.simpledialog - -from languages.lang import * -from msctspt.threadOpera import NewThread -from nmcsup.vers import VER - -__version__ = VER[1] + VER[0] -__author__ = '金羿Eilles & 诸葛亮与八卦阵bgArray' - - -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': { - 'ReadMethod': 'old', - 'PackName': 'Ryoun', - 'MusicTitle': 'Noname', - 'IsRepeat': False, - 'PlayerSelect': '' - }, - 'musics': [ - { - 'set': { - 'EntityName': 'MusicSupport', - 'ScoreboardName': 'MusicSupport', - 'Instrument': 'note.harp', - 'FileName': 'Music' - }, - 'notes': [ - - ] - }, - ], - }, -] -'''一个项目中的全部数据。格式参照: -[ - { - 'mainset':{ - 'PackName':'Ryoun', - 'MusicTitle':'Noname', - 'IsRepeat':False, - 'PlayerSelect':'' - }, - 'musics':[ - { - 'set':{ - 'EntityName':'music_support', - 'ScoreboardName':'music_support', - 'Instrument':'harp', - 'FileName':'Music' - }, - 'notes':[ - - Note对象 - 或 - - [MC音调, 持续时间(s)] - ] - }, - ], - }, -] -''' - -is_new_file = True -'''这是否是一个新建的项目?''' - -is_save = True -'''当前项目是否已保存?''' - -ProjectName = '' -'''项目名称,即打开的msct文件名''' - -clearLog = False -'''是否在程序结束时移除日志''' - -NowMusic = 0 -'''当前音轨''' - -root = tk.Tk() -'''主窗口''' - - -def DMM(): # 反回字典用于编辑 - datasetmodelpart = { - 'set': { - 'EntityName': 'MusicSupport', - 'ScoreboardName': 'MusicSupport', - 'Instrument': 'note.harp', - 'FileName': 'Music' - }, - 'notes': [] - } - return datasetmodelpart - - -print('完成') - - -def __main__(): - """音·创 本体\n - W-YI 金羿\n - QQ 2647547478\n - 音·创 开发交流群 861684859\n - Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com\n - 版权所有 Team-Ryoun 金羿\n - 代码根据Apache 2.0 协议开源\n - 若需转载或借鉴 请附作者\n - """ - - print('音·创 正在启动……') - - print('载入日志功能...') - from msctLib.log import log - from nmcsup.log import end - print('完成!') - - print('更新执行位置...') - if sys.platform == 'win32': - try: - os.chdir(__file__[:len(__file__) - __file__[len(__file__)::-1].index('\\')]) - log('更新执行位置,当前文件位置 {}'.format(__file__)) - except FileNotFoundError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,所以既然是pass就随便填一个错误 - pass - else: - try: - os.chdir(__file__[:len(__file__) - __file__[len(__file__)::-1].index('/')]) - except Exception: - pass - log('其他平台:{} 更新执行位置,当前文件位置 {}'.format(sys.platform, __file__)) - print('完成!') - - # 读取文件 - - print('载入文件读取函数') - - def ReadFile(fn: str): # -> list - from nmcsup.nmcreader import ReadFile as fileRead - k = fileRead(fn) - if k is False: - tk.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[105].format(fn)) - return - else: - return k - - # 老的列表读取 - def ReadMidi(midfile: str): # -> str - from nmcsup.nmcreader import ReadMidi as midiRead - k = midiRead(midfile) - if k is False: - tk.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[105].format(midfile)) - return - else: - return k - - # 音色读取 - def LoadMidi(midfile: str): # -> str - from bgArrayLib.reader import midiNewReader - k = midiNewReader(midfile) - if k is False: - tk.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[105].format(midfile)) - return - else: - return k - - # 新的类读取 - def MidiAnalysisClass(midfile: str): - from bgArrayLib.reader import midiClassReader - k = midiClassReader(midfile) - if k is False: - tk.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[105].format(midfile)) - return - else: - return k - - print('完成!') - - # 菜单命令 - print('加载菜单命令...') - - def exitapp(): - global is_save - if is_save is not True: - if tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]): - SaveProject() - log('程序正常退出') - - if os.path.isfile("1.pkl"): - os.remove("1.pkl") - - try: - global dataset - del dataset - global root - root.destroy() - del root - except tkinter.TclError: - pass - - if clearLog: - print(READABLETEXT[2]) - # err = True - # try: - end() - if os.path.exists('./log/'): - shutil.rmtree('./log/') - if os.path.exists('./logs/'): - shutil.rmtree('./logs/') - if os.path.exists('./cache/'): - shutil.rmtree('./cache/') - if os.path.exists('./nmcsup/log/'): - shutil.rmtree('./nmcsup/log/') - if os.path.exists('./nmcsup/logs/'): - shutil.rmtree('./nmcsup/logs/') - # err = False - # except: - # print(READABLETEXT[3]) - # - # finally: - # if err is True: - # print(READABLETEXT[3]) - - exit() - - print('退出命令加载完成!') - - def SaveProject(): - global is_save - if is_new_file: - # 新的项目相等于另存为 - SaveAsProject() - return - else: - if dataset[0].get('mainset').get('ReadMethod') == "old": - # 旧项目旧存着吧 - log('存储已有文件:{}'.format(ProjectName)) - with open(ProjectName, 'w', encoding='utf-8') as f: - json.dump(dataset[0], f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(ProjectName)) - is_save = True - elif dataset[0].get('mainset').get('ReadMethod') == "class": # 这部分相当SaveClassProject()函数 - # if is_new_file: - # # 新的项目相等于另存为 - # SaveAsClassProject() - # return - # else: - with open(ProjectName, 'wb') as f: - pickle.dump(dataset, f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], - message=READABLETEXT[107].format(ProjectName)) - is_save = True - # return - elif dataset[0].get('mainset').get('ReadMethod') == "new": # 这部分相当于SaveNewProject()函数 - # if is_new_file: # 这部分相当于SaveAsNewProject()函数 - # # 新的项目相等于另存为 - # SaveAsNewProject() - # return - # else: - save_list = [dataset] - try: - with open("1.pkl", 'rb') as r: - save_list.append(pickle.load(r)) - except FileNotFoundError: - pass - with open(ProjectName, 'wb') as f: - pickle.dump(save_list, f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], - message=READABLETEXT[107].format(ProjectName)) - is_save = True - return - - print('保存项目命令加载完成!') - - def SaveAsProject(): - global is_save - if dataset[0].get('mainset').get('ReadMethod') == "old": - # 另存为项目 - fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', - filetypes=[(READABLETEXT[108][0], '.msct'), - (READABLETEXT[109], '*')], - defaultextension='Noname.msct') - if fn is None or fn == '': - return - try: - Project_Name = fn - with open(Project_Name, 'w', encoding='utf-8') as f: - json.dump(dataset[0], f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(Project_Name)) - is_save = True - except TypeError: - Project_Name = fn - with open(Project_Name, 'wb') as f: - pickle.dump(dataset[0], f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(Project_Name)) - is_save = True - elif dataset[0].get('mainset').get('ReadMethod') == "class": # 等于SaveAsNewProject()函数 - fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', - filetypes=[(READABLETEXT[108][1], '.msctn'), - (READABLETEXT[109], '*')], - defaultextension='Noname.msctn') - if fn is None or fn == '': - return - Project_Name = fn - with open(Project_Name, 'wb') as f: - pickle.dump(dataset, f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(Project_Name)) - - is_save = True - elif dataset[0].get('mainset').get('ReadMethod') == "new": # 等于SaveAsClassProject()函数 - fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', - filetypes=[(READABLETEXT[108][2], '.msctx'), - (READABLETEXT[109], '*')], - defaultextension='Noname.msctx') - if fn is None or fn == '': - return - Project_Name = fn - save_list = [dataset] - try: - with open("1.pkl", 'rb') as r: - save_list.append(pickle.load(r)) - except FileNotFoundError: - pass - print(save_list) - with open(Project_Name, 'wb') as f: - pickle.dump(save_list, f) - tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(Project_Name)) - is_save = True - - print('另存项目命令加载完成!') - - def openOldProject(): - global is_save - if is_save is not True: - result = tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]) - if result: - SaveProject() - fn = tkinter.filedialog.askopenfilename(title=READABLETEXT[6], initialdir=r'./', - filetypes=[(READABLETEXT[110], '.ry.nfc'), - (READABLETEXT[111], '.ry.mfm'), (READABLETEXT[112], '*')], - multiple=True) - if fn is None or fn == '': - return - else: - fn = fn[0] - from nmcsup.nmcreader import ReadOldProject - dataset[0] = ReadOldProject(fn) - - def openProject(): - global is_save - global dataset - if is_save is not True: - result = tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]) - if result: - SaveProject() - fn = tkinter.filedialog.askopenfilename(title=READABLETEXT[7], initialdir=r'./', - filetypes=[(READABLETEXT[108][0], '.msct'), - (READABLETEXT[108][1], '.msctn'), # msctn: 音创新文件(用类方法解析) - (READABLETEXT[108][2], '.msctx'), # msctx: 音创测试文件(用来支持多乐器解析) - (READABLETEXT[112], '*')], - multiple=True) - if fn is None or fn == '': - return - else: - fn = fn[0] - log("尝试打开:" + fn) - if str(fn)[str(fn).rfind("."):] == ".msct": # str(fn)[str(fn).rfind("."):] ->文件格式返回".xxx" - try: - try: - with open(fn, 'r', encoding='UTF-8') as C: - dataset[0] = json.load(C) - log("读取工程文件成功") - except UnicodeDecodeError: - print(READABLETEXT[8].format(fn)) - log('无法打开{}'.format(fn)) - return - except json.decoder.JSONDecodeError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # json.decoder.JSONDecodeError - print(READABLETEXT[8].format(fn)) - log('无法打开{}'.format(fn)) - return - elif str(fn)[str(fn).rfind("."):] == ".msctx": - try: - try: - with open(fn, 'rb') as C: - # print(pickle.load(C)) - read = pickle.load(C) # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # print(read) - dataset = read[0] - pkl1 = read[1] - log(f"读取新文件成功:\n{str(dataset[0])}") - with open("1.pkl", 'wb') as w: - pickle.dump(pkl1, w) - except KeyError: - with open(fn, 'rb') as C: - dataset[0] = pickle.load(C) - log(f"读取新文件成功:\n{str(dataset[0])}") - except pickle.UnpicklingError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # pickle.UnpicklingError - print(READABLETEXT[8].format(fn)) - log('无法打开{}'.format(fn)) - return - elif str(fn)[str(fn).rfind("."):] == ".msctn": - try: - try: - with open(fn, 'rb') as C: - # print(pickle.load(C)) - read = pickle.load(C) # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # print(read) - dataset = read - log("读取新文件成功") - except KeyError: - with open(fn, 'rb') as C: - dataset[0] = pickle.load(C) - log("读取新文件成功") - except pickle.UnpicklingError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # pickle.UnpicklingError - print(READABLETEXT[8].format(fn)) - log('无法打开{}'.format(fn)) - return - else: - return - global is_new_file - global ProjectName - is_new_file = False - ProjectName = fn - del fn - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - - print('打开项目命令加载完成!') - - def appabout(): - aabw = tk.Tk() - aabw.title(READABLETEXT[9]) - aabw.geometry('550x600') # 像素 - tk.Label(aabw, text='', font=('', 15)).pack() - tk.Label(aabw, text=READABLETEXT[10], font=('', 35)).pack() - tk.Label(aabw, text=READABLETEXT[11].format(VER[1] + VER[0]), font=('', 15)).pack() - # pack 的side可以赋值为LEFT RTGHT TOP BOTTOM - # grid 的row 是列数、column是行排,注意,这是针对空间控件本身大小来的,即是指向当前控件的第几个。 - # place的 x、y是(x,y)坐标 - # pic = tk.PhotoImage(file='./bin/pics/Ryoun_S.png') - # tk.Label(aabw, image=pic, width=200, height=200).pack() - # del pic - tk.Label(aabw, text='', font=('', 5)).pack() - tk.Label(aabw, text=READABLETEXT[12], font=('', 20)).pack() - tk.Label(aabw, text='', font=('', 15)).pack() - for i in READABLETEXT[15]: - tk.Label(aabw, text=i[0], font=('', 17 if i[1] else 15, 'bold' if i[1] else '')).pack() - tk.Label(aabw, text='', font=('', 5)).pack() - if DEFAULTLANGUAGE != 'zh-CN': - tk.Label(aabw, text=READABLETEXT[16], font=('', 15)).pack() - for i in READABLETEXT['Translator']: - tk.Label(aabw, text=i[0], font=('', 17 if i[1] else 15, 'bold' if i[1] else '')).pack() - - def exitAboutWindow(): - aabw.destroy() - - tk.Button(aabw, text=READABLETEXT[13], command=exitAboutWindow).pack() - - aabw.mainloop() - - print('关于命令加载完成!') - - def apphelp(): - def funcHelp(): - funTK = tk.Tk() - funTK.title("函数功能查询") - funTK.geometry('1200x1000') - thingLabel = tk.Label(funTK, text="函数功能查询", font=('', 20)) - thingLabel.pack() - aLabel = tk.Label(funTK, text="""文件:\n - 打开音·创项目...: 打开三种类型的音创文件(.msct, .msctn, .msctx)\n - 打开旧项目...: 打开两种类型的音创文件(.ry.nfc, .ry.mfm)\n - 保存项目: 自动选择保存类型,并保存为音创文件(.msct, .msctn, .msctx)\n - 另存为...: 自动选择另存为类型,并保存为音创文件(.msct, .msctn, .msctx)\n - 退出 : 退出程序\n\n - 编辑:\n - 从midi导入音轨: 以旧方法(列表方法)解析midi,如果你使用这个方法解析,意味着你选择.msct文件\n - 从midi导入音轨且用新方法解析: 以新方法(类方法)解析midi,并解析乐器信息,如果你使用这个方法解析,意味着你选择.msctx文件\n - 注意!!!这个功能暂时只用于支持雪莹乐器资源包,如果你不是为了这个,最好别用!\n - 从midi导入音轨且用类方法解析: 以类方法解析midi,如果你使用这个方法解析,意味着你选择.msctn文件\n - 注意!!!这个功能暂时在开发中!!!别用!\n - """, font=('宋体', 12)) - aLabel.pack() - - ahpw = tk.Tk() - ahpw.title(READABLETEXT[19]) - ahpw.geometry('400x600') # 像素 - tk.Label(ahpw, text="帮助", font=('楷体', 32)).grid(row=0, column=2) - tk.Button(ahpw, text="函数功能查询", command=funcHelp, font=('楷体', 20)).grid(row=1, column=1) - ahpw.mainloop() - - print('帮助命令加载完成!') - - def FromMP3(): - log('从MP3导入音乐') - mp3file = tkinter.filedialog.askopenfilename(title=READABLETEXT[20], initialdir=r'./', - filetypes=[(READABLETEXT[113], '.mp3 .m4a'), - (READABLETEXT[112], '*')], multiple=True) - if mp3file is None or mp3file == '': - log('取消') - return - else: - mp3file = mp3file[0] - from nmcsup.nmcreader import ReadMidi - from nmcsup.trans import Mp32Mid - if not os.path.exists('./Temp/'): - os.makedirs('./Temp/') - Mp32Mid(mp3file, './Temp/Trans.mid') - log('打开midi文件./Temp/Trans.mid') - th = NewThread(ReadMidi, ('./Temp/Trans.mid',)) - th.start() - del mp3file - - 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 - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - - threading.Thread(target=midiSPT, args=(th,)).start() - del th - - print('读MP3加载完成') - - def FromListMidi(): - log('从midi导入音乐') - midfile = tkinter.filedialog.askopenfilename(title=READABLETEXT[21], initialdir=r'./', - filetypes=[(READABLETEXT[114], '.mid .midi'), - (READABLETEXT[112], '*')], multiple=True) - if midfile is None or midfile == '': - log('取消') - return - else: - midfile = midfile[0] - th = NewThread(ReadMidi, (midfile,)) - th.start() - del midfile - - def midiSPT(th_): - try: - try: - for i in th_.getResult(): - datas = DMM() - datas['notes'] = i - dataset[0]['musics'].append(datas) - del th_ - global is_save - is_save = False - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - except OSError: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - except AttributeError: - try: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - except OSError: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - - threading.Thread(target=midiSPT, args=(th,)).start() - del th - - def FromNewMidi(): - log('从midi导入音乐并采用新读取方式') - midfile = tkinter.filedialog.askopenfilename(title=READABLETEXT[21], initialdir=r'./', - filetypes=[(READABLETEXT[114], '.mid .midi'), - (READABLETEXT[112], '*')], multiple=True) - if midfile is None or midfile == '': - log('取消') - return - else: - midfile = midfile[0] - th = NewThread(LoadMidi, (midfile,)) - th.start() - del midfile - - def midiSPT(th_): - try: - try: - for i in th_.getResult(): - datas = DMM() - datas['notes'] = i - dataset[0]['musics'].append(datas) - del th_ - global is_save - is_save = False - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - except OSError: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - except AttributeError: - try: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - except OSError: - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[167]) - - threading.Thread(target=midiSPT, args=(th,)).start() - del th - dataset[0]['mainset']['ReadMethod'] = "new" - - def FromClassMidi(): - log('从midi导入音乐并采用类读取方式') - midfile = tkinter.filedialog.askopenfilename(title=READABLETEXT[21], initialdir=r'./', - filetypes=[(READABLETEXT[114], '.mid .midi'), - (READABLETEXT[112], '*')], multiple=True) - if midfile is None or midfile == '': - log('取消') - return - else: - midfile = midfile[0] - th = NewThread(MidiAnalysisClass, (midfile,)) - th.start() - del midfile - - 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 - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - threading.Thread(target=midiSPT, args=(th,)).start() - del th - dataset[0]['mainset']['ReadMethod'] = "class" - - print('读midi命令加载完成!') - - def FromForm(): - log('从文本读入音轨') - fn = tkinter.filedialog.askopenfilename(title=READABLETEXT[22], initialdir=r'./', - filetypes=[(READABLETEXT[115], '.txt'), (READABLETEXT[112], '*')], - multiple=True) - if fn is None or fn == '': - log('取消') - return - else: - fn = fn[0] - th = NewThread(ReadFile, (fn,)) - 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 - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - - threading.Thread(target=midiSPT, args=(th,)).start() - - print('读txt命令加载完成!') - - def FromText(): - log('写入音符至音轨') - dat = tkinter.simpledialog.askstring(title=READABLETEXT[23], prompt=READABLETEXT[14], initialvalue='`1 .2 C') - if dat is None: - return - datas = [] - for i in dat.split(' '): - datas.append([str(i), 1.0]) - log(READABLETEXT[24].format(str(datas))) - from nmcsup.trans import note2list - datat = DMM() - datat['notes'] = note2list(datas) - dataset[0]['musics'].append(datat) - del datas, datat, dat - global is_save - is_save = False - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - - print('写入命令加载完成!') - print('开始加载列表生成函数函数。') - - def ShowCMD(): - log('展示指令') - global NowMusic - from nmcsup.trans import Note2Cmd - RefreshCMDList( - Note2Cmd(dataset[0]['musics'][NowMusic]['notes'], dataset[0]['musics'][NowMusic]['set']['ScoreboardName'], - dataset[0]['musics'][NowMusic]['set']['Instrument'], dataset[0]['mainset']['PlayerSelect'])) - - def MakeCMD(): - log('生成文件') - from msctspt.funcOpera import makeFuncFiles - file = tkinter.filedialog.askdirectory(title=READABLETEXT[25], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeFuncFiles(dataset[0], file + '/') - - def MakeCMDdir(): - log('生成函数包') - from msctspt.funcOpera import makeFunDir - file = tkinter.filedialog.askdirectory(title=READABLETEXT[26], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeFunDir(dataset[0], file + '/') - - def MakePackFile(): - file = tkinter.filedialog.askdirectory(title=READABLETEXT[27], initialdir=r'./') - if file is None or file == '': - log('取消') - return - import zipfile - - from msctspt.funcOpera import makeFunDir - log('生成附加包文件') - if not os.path.exists('./temp/'): - os.makedirs('./temp/') - makeFunDir(dataset[0], './temp/') - - shutil.move('./temp/{}Pack/behavior_packs/{}/functions'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - shutil.move('./temp/{}Pack/behavior_packs/{}/manifest.json'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - with zipfile.ZipFile('{}/{}.mcpack'.format(file, dataset[0]['mainset']['PackName']), 'w') as zipobj: - for i in os.listdir('./functions/'): - zipobj.write('./functions/{}'.format(i)) - zipobj.write('./manifest.json') - shutil.move('./functions', './temp/') - shutil.move('./manifest.json', './temp/') - shutil.rmtree('./temp/') - - print('完成加载列表生成函数函数。') - print('开始加载乐器类生成函数函数。') - - def MakeNewCMD(): - log('生成新文件') - from msctspt.funcOpera import makeNewFuncFiles - file = tkinter.filedialog.askdirectory(title=READABLETEXT[25], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeNewFuncFiles(dataset[0], file + '/') - - def MakeNewCMDdir(): - log('生成新函数包与材质包') - from msctspt.funcOpera import makeNewFunDir - file = tkinter.filedialog.askdirectory(title=READABLETEXT[26], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeNewFunDir(dataset[0], file + '/') - - def MakeNewFunctionPackFile(): - file = tkinter.filedialog.askdirectory(title=READABLETEXT[27], initialdir=r'./') - if file is None or file == '': - log('取消') - return - import zipfile - - from msctspt.funcOpera import makeNewFunDir - log('生成附加包文件') - if not os.path.exists('./temp/'): - os.makedirs('./temp/') - makeNewFunDir(dataset[0], './temp/') - - shutil.move('./temp/{}Pack/behavior_packs/{}/functions'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - shutil.move('./temp/{}Pack/behavior_packs/{}/manifest.json'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - with zipfile.ZipFile('{}/{}.mcpack'.format(file, dataset[0]['mainset']['PackName']), 'w') as zipobj: - for i in os.listdir('./functions/'): - zipobj.write('./functions/{}'.format(i)) - zipobj.write('./manifest.json') - shutil.move('./functions', './temp/') - shutil.move('./manifest.json', './temp/') - shutil.rmtree('./temp/') - - def MakeNewFunctionPack_ResourcesPacks_File(): # 这个是直接复制资源包(散包) - file = tkinter.filedialog.askdirectory(title=READABLETEXT[27], initialdir=r'./') - if file is None or file == '': - log('取消') - return - from bgArrayLib.sy_resourcesPacker import resources_pathSetting - result = resources_pathSetting() - print(result) - if result[0] is False: - if result[1] == 1: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[157]) - if result[1] == 2: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[158]) - return - else: - import zipfile - - from msctspt.funcOpera import makeNewFunDir - log('生成附加包文件') - if not os.path.exists('./temp/'): - os.makedirs('./temp/') - makeNewFunDir(dataset[0], './temp/') - - shutil.move('./temp/{}Pack/behavior_packs/{}/functions'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - shutil.move('./temp/{}Pack/behavior_packs/{}/manifest.json'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - with zipfile.ZipFile('{}/{}.mcpack'.format(file, dataset[0]['mainset']['PackName']), 'w') as zipobj: - for i in os.listdir('./functions/'): - zipobj.write('./functions/{}'.format(i)) - zipobj.write('./manifest.json') - shutil.move('./functions', './temp/') - shutil.move('./manifest.json', './temp/') - shutil.rmtree('./temp/') - from bgArrayLib.sy_resourcesPacker import scatteredPack - scatteredPack(file) - - print('完成加载乐器类生成函数函数。') - print('开始加载乐器音色资源绑定函数。') - - def changeResourcesPath(): - file = tkinter.filedialog.askdirectory(title=READABLETEXT[27], initialdir=r'./') - if file is None or file == '': - log('取消') - return - from bgArrayLib.sy_resourcesPacker import resources_pathSetting - result = resources_pathSetting(file) - print(result) - if result[0] is False: - if result[1] == 1: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[157]) - if result[1] == 2: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[158]) - else: - tkinter.messagebox.showinfo(title=READABLETEXT[1], message=READABLETEXT[159]) - - print('开始加载类生成函数函数。') - - def MakeClassCMD(): - log('生成类文件') - from msctspt.funcOpera import makeClassFuncFiles - file = tkinter.filedialog.askdirectory(title=READABLETEXT[25], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeClassFuncFiles(dataset[0], file + '/') - - def MakeClassCMDdir(): - log('生成类函数包与材质包') - from msctspt.funcOpera import makeClassFunDir - file = tkinter.filedialog.askdirectory(title=READABLETEXT[26], initialdir=r'./') - if file is None or file == '': - log('取消') - return - else: - makeClassFunDir(dataset[0], file + '/') - - def MakeClassFunctionPackFile(): - file = tkinter.filedialog.askdirectory(title=READABLETEXT[27], initialdir=r'./') - if file is None or file == '': - log('取消') - return - import zipfile - - from msctspt.funcOpera import makeClassFunDir - log('生成附加包文件') - if not os.path.exists('./temp/'): - os.makedirs('./temp/') - makeClassFunDir(dataset[0], './temp/') - - shutil.move('./temp/{}Pack/behavior_packs/{}/functions'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - shutil.move('./temp/{}Pack/behavior_packs/{}/manifest.json'.format(dataset[0]['mainset']['PackName'], - dataset[0]['mainset']['PackName']), './') - - with zipfile.ZipFile('{}/{}.mcpack'.format(file, dataset[0]['mainset']['PackName']), 'w') as zipobj: - for i in os.listdir('./functions/'): - zipobj.write('./functions/{}'.format(i)) - zipobj.write('./manifest.json') - shutil.move('./functions', './temp/') - shutil.move('./manifest.json', './temp/') - shutil.rmtree('./temp/') - - print('完成加载类生成函数函数。') - print('开始加载地图函数。') - - # 转为空方块世界 - def ToBlockWorldEpt(): - import zipfile - global dire - - from nmcsup.trans import Cmd2World, Datas2BlkWorld, Notes2Player - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - log('取消') - return - else: - Outdire = '{}/{}/'.format(Outdire[0], dataset[0]['mainset']['PackName']) - with zipfile.ZipFile('./nmcsup/EptWorld.zip') as zipobj: # , 'r' (参数等于默认时不写) - zipobj.extractall(Outdire) - NoteData = [] - for i in dataset[0]['musics']: - NoteData.append(i['notes']) - Datas2BlkWorld(NoteData, Outdire, dire) - del NoteData - for i in range(len(dataset[0]['musics'])): - Cmd2World(Notes2Player(dataset[0]['musics'][i]['notes'], [dire[0], dire[1], dire[2] + i], - {'Ent': dataset[0]['musics'][i]['set']['EntityName'], - 'Pls': dataset[0]['mainset']['PlayerSelect'], - 'Ins': dataset[0]['musics'][i]['set']['Instrument']}), Outdire, - [dire[0] - 5 - i, dire[1], dire[2]]) - del dire, Outdire - - # 转为已存在的方块世界 - def ToBlockWorld(): - from nmcsup.trans import Cmd2World, Datas2BlkWorld, Notes2Player - global dire - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - log('取消') - return - else: - Outdire += '/' - NoteData = [] - for i in dataset[0]['musics']: - NoteData.append(i['notes']) - Datas2BlkWorld(NoteData, Outdire, dire) - del NoteData - for i in range(len(dataset[0]['musics'])): - Cmd2World(Notes2Player(dataset[0]['musics'][i]['notes'], [dire[0], dire[1], dire[2] + i], - {'Ent': dataset[0]['musics'][i]['set']['EntityName'], - 'Pls': dataset[0]['mainset']['PlayerSelect'], - 'Ins': dataset[0]['musics'][i]['set']['Instrument']}), Outdire, - [dire[0] - 5 - i, dire[1], dire[2]]) - del dire, Outdire - - # 生成函数播放器 - def MakeFuncPlayer(): - global dire - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[30], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire = '{}/{}/'.format(Outdire, dataset[0]['mainset']['PackName']) - from nmcsup.trans import Notes2Player - for i in range(len(dataset[0]['musics'])): - open(Outdire + dataset[0]['musics'][i]['set']['FileName'] + '_' + str(i) + '.mcfunction', 'w', - encoding='utf-8').writelines( - Notes2Player(dataset[0]['musics'][i]['notes'], [dire[0], dire[1], dire[2] + i], - {'Ent': dataset[0]['musics'][i]['set']['EntityName'], - 'Pls': dataset[0]['mainset']['PlayerSelect'], - 'Ins': dataset[0]['musics'][i]['set']['Instrument']})) - - # 转为空指令世界 - def ToCmdWorldEpt(): - import zipfile - global dire - - from nmcsup.trans import Cmd2World, Note2Cmd - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire += '/' + dataset[0]['mainset']['PackName'] + '/' - with zipfile.ZipFile('./nmcsup/EptWorld.zip') as zipobj: # , 'r' (默认参数不用设置) - zipobj.extractall(Outdire) - for i in range(len(dataset[0]['musics'])): - Cmd2World(Note2Cmd(dataset[0]['musics'][i]['notes'], dataset[0]['musics'][i]['set']['ScoreboardName'], - dataset[0]['musics'][i]['set']['Instrument'], dataset[0]['mainset']['PlayerSelect'], - True), Outdire, [dire[0], dire[1], dire[2] + i]) - del dire, Outdire - - # 转为已存在的指令世界 - def ToCmdWorld(): - global dire - from nmcsup.trans import Cmd2World, Note2Cmd - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire += '/' - for i in range(len(dataset[0]['musics'])): - Cmd2World(Note2Cmd(dataset[0]['musics'][i]['notes'], dataset[0]['musics'][i]['set']['ScoreboardName'], - dataset[0]['musics'][i]['set']['Instrument'], dataset[0]['mainset']['PlayerSelect'], - True), Outdire, [dire[0], dire[1], dire[2] + i]) - del dire, Outdire - - # 函数输入指令块 - def func2World(): - from nmcsup.trans import Cmd2World - global dire - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire += '/' - Cmd2World(open(tkinter.filedialog.askopenfilename(title=READABLETEXT[31], initialdir=r'./', - filetypes=[(READABLETEXT[118], '.mcfunction'), - (READABLETEXT[112], '*')], multiple=True)[0], 'r', - encoding='utf-8').readlines(), Outdire, dire) - - # 大函数分割并载入执行链 - def bigFunc2World(): - log('分割大函数') - global dire - import uuid - - from msctspt.funcOpera import funSplit - from msctspt.transfer import hans2pinyin - from nmcsup.trans import Cmd2World - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[119], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - log('取消') - return - else: - Outdire += '/' - log('获得地图地址:' + Outdire) - fileName = tkinter.filedialog.askopenfilename(title=READABLETEXT[31], initialdir=r'./', - filetypes=[(READABLETEXT[118], '.mcfunction'), - (READABLETEXT[112], '*')], multiple=True) - if fileName is None or fileName == '': - log('取消') - return - else: - fileName = fileName[0] - log('获得文件名:' + fileName) - bigFile = open(fileName, 'r', encoding='utf-8') - parts = funSplit(bigFile) - if parts == -1: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[121]) - return - log('创建函数文件夹') - packName = fileName[len(fileName) - fileName[::-1].index('/'):fileName.index('.')] - packDire = hans2pinyin(packName) - try: - os.makedirs(Outdire + 'behavior_packs/' + packDire + '/functions/') - except FileExistsError: - log('已存在文件夹') - log('创建manifest.json以及world_behavior_packs.json') - behaviorUuid = uuid.uuid4() - if os.path.exists(Outdire + 'world_behavior_packs.json'): - with open(Outdire + 'world_behavior_packs.json', 'r') as f: - have = json.load(f) - have.append({'pack_id': str(behaviorUuid), 'version': [0, 0, 1]}) - with open(Outdire + 'world_behavior_packs.json', 'w', encoding='utf-8') as f: - json.dump(have, f) - del have - else: - with open(Outdire + 'world_behavior_packs.json', 'w', encoding='utf-8') as f: - f.write('[\n {\'pack_id\': \'' + str(behaviorUuid) + '\',\n \'version\': [ 0, 0, 1 ]}\n]') - with open(Outdire + 'behavior_packs/' + packDire + '/manifest.json', 'w') as f: - f.write( - '{\n \'format_version\': 1,\n \'header\': {\n \'description\': \'' + packName + - ' Pack : behavior pack\',\n \'version\': [ 0, 0, 1 ],\n \'name\': \'' + packName + - 'Pack\',\n \'uuid\': \'' + str( - behaviorUuid) + '\'\n },\n \'modules\': [\n {\n \'description\': \'' + packName + - ' Pack : behavior pack\',\n \'type\': ' - '\'data\',\n \'version\': [ 0, 0, 1 ],\n \'uuid\': \'' + str( - uuid.uuid4()) + '\'\n }\n ]\n}') # 要求文段不能过长 - cmdlist = [] - for i in parts: - open(Outdire + 'behavior_packs/' + packDire + '/functions/' + packDire + str( - parts.index(i) + 1) + '.mcfunction', 'w', encoding='utf-8').writelines(i) - cmdlist.append('function ' + packDire + str(parts.index(i) + 1)) - Cmd2World(cmdlist, Outdire, dire) - del cmdlist, behaviorUuid, Outdire, fileName, bigFile, parts, dire, packName, packDire - - def toScbBDXfile(): - log('单音轨转BDX') - from msctspt.transfer import note2bdx - global dire - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[122], - initialvalue='0 0 0') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - - fileName = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[32], initialdir=r'./', - filetypes=[(READABLETEXT[123], '.bdx'), - (READABLETEXT[112], '*')], - defaultextension=dataset[0]['mainset']['PackName'] + '.bdx', - initialfile=dataset[0]['mainset']['PackName'] + '.bdx') - if fileName is None or fileName == '': - log('取消') - return - - log('获得文件名:' + fileName) - - res = note2bdx(fileName, dire, dataset[0]['musics'][NowMusic]['notes'], - dataset[0]['musics'][NowMusic]['set']['ScoreboardName'], - dataset[0]['musics'][NowMusic]['set']['Instrument'], dataset[0]['mainset']['PlayerSelect']) - log('转换结束!\n' + str(res)) - tkinter.messagebox.showinfo(READABLETEXT[33], READABLETEXT[124].format(str(res))) - - def toBDXfile(): - log('整首歌转BDX') - from msctspt.transfer import music2BDX - global dire - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[122], - initialvalue='0 0 0') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - - fileName = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[32], initialdir=r'./', - filetypes=[(READABLETEXT[123], '.bdx'), - (READABLETEXT[112], '*')], - defaultextension=dataset[0]['mainset']['PackName'] + '.bdx', - initialfile=dataset[0]['mainset']['PackName'] + '.bdx') - - maxHeight = 200 - - while True: - maxHeight = tkinter.simpledialog.askinteger(title=READABLETEXT[28], - prompt=READABLETEXT[93], - initialvalue='200') - if maxHeight >= 5: - break - elif maxHeight is None: - log('取消') - return - else: - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[94]) - continue - - if fileName is None or fileName == '': - log('取消') - return - - log('获得文件名:' + fileName) - - res = music2BDX(fileName, dire, dataset[0], height = maxHeight ) - log('转换结束!\n' + str(res)) - tkinter.messagebox.showinfo(READABLETEXT[33], READABLETEXT[124].format(str(res))) - - def wsPlay(): - from msctspt.transfer import note2webs - spd = tkinter.simpledialog.askfloat(READABLETEXT[34], prompt=READABLETEXT[125], initialvalue='5.0') - tkinter.messagebox.showinfo(title=READABLETEXT[35], message=READABLETEXT[126]) - note2webs(dataset[0]['musics'][NowMusic]['notes'], dataset[0]['musics'][NowMusic]['set']['Instrument'], spd, - dataset[0]['mainset']['PlayerSelect']) - - def toRSworldEPT(): - import zipfile - global dire - dire = "" - - from msctspt.transfer import note2RSworld - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire += '/' + dataset[0]['mainset']['PackName'] + '/' - with zipfile.ZipFile('./nmcsup/EptWorld.zip') as zipobj: # , 'r'(默认参数不用写) - zipobj.extractall(Outdire) - for i in range(len(dataset[0]['musics'])): - note2RSworld(Outdire, dire, dataset[0]['musics'][i]['notes'], dataset[0]['musics'][i]['set']['Instrument']) - - del dire, Outdire - - def toRSworld(): - from msctspt.transfer import note2RSworld - global dire - dire = "" - while True: - try: - dire = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[116], - initialvalue='16 4 16') - if dire is None or dire == '': - return - dire = [int(dire.split(' ')[0]), int(dire.split(' ')[1]), int(dire.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') - if Outdire is None or Outdire == '': - return - else: - Outdire += '/' - for i in range(len(dataset[0]['musics'])): - note2RSworld(Outdire, dire, dataset[0]['musics'][i]['notes'], dataset[0]['musics'][i]['set']['Instrument']) - del dire, Outdire - - def world2RyStruct(): - global begp - global endp - outdir = tkinter.filedialog.askdirectory(title=READABLETEXT[36], initialdir=r'./') - if outdir is None or outdir == '': - return - else: - outdir += '/' - while True: - try: - begp = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[127], - initialvalue='16 4 16') - if begp is None or begp == '': - return - begp = [int(begp.split(' ')[0]), int(begp.split(' ')[1]), int(begp.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - while True: - try: - endp = tkinter.simpledialog.askstring(title=READABLETEXT[28], prompt=READABLETEXT[128], - initialvalue='16 4 16') - if endp is None or endp == '': - return - endp = [int(endp.split(' ')[0]), int(endp.split(' ')[1]), int(endp.split(' ')[2])] - except ValueError: # 测试完为ValueError,故修改语法 - tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) - continue - break - isAir = tkinter.messagebox.askyesno(READABLETEXT[37], READABLETEXT[129]) - fileName = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[38], initialdir=r'./', - filetypes=[(READABLETEXT[130], '.RyStruct'), - (READABLETEXT[112], '*')], - defaultextension='*.RyStruct', initialfile='*.RyStruct') - if fileName is None or fileName == '': - log('取消') - return - from msctspt.transfer import ryStruct - rys = ryStruct(outdir) - rys.world2Rys(begp, endp, isAir) - # error1 = True - try: - with open(fileName, 'w', encoding='utf-8') as f: - json.dump(rys.RyStruct, f, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - tkinter.messagebox.showinfo(READABLETEXT[33], READABLETEXT[131].format(fileName)) - # error1 = False - except: - tkinter.messagebox.showerror(READABLETEXT[39], READABLETEXT[132].format(fileName, str(rys.RyStruct))) - rys.closeLevel() - # finally: - # if error1 is True: - # tkinter.messagebox.showerror(READABLETEXT[39], READABLETEXT[132].format(fileName, str(rys.RyStruct))) - # rys.closeLevel() - - def world2BDX(): - tkinter.messagebox.showerror(READABLETEXT[0], READABLETEXT[133]) - - # 使用邮件反馈bug - def sendBugReport(): - from msctspt.bugReporter import report - name = tkinter.simpledialog.askstring(title=READABLETEXT[40], prompt=READABLETEXT[134]) - contact = tkinter.simpledialog.askstring(title=READABLETEXT[40], prompt=READABLETEXT[135]) - describetion = tkinter.simpledialog.askstring(title=READABLETEXT[40], prompt=READABLETEXT[136]) - report(name, contact, describetion).emailReport() - del name, contact, describetion - - def ClearLog(): - global clearLog - clearLog = not clearLog - if clearLog: - tkinter.messagebox.showinfo(READABLETEXT[33], READABLETEXT[137]) - else: - tkinter.messagebox.showinfo(READABLETEXT[33], READABLETEXT[138]) - - print('生成部分及其余命令加载完成!') - - print('完成!') - - # 窗口部分 - print('增加窗口元素...') - global root - global __version__ - - root.title(READABLETEXT[41].format(__version__)) - root.geometry('900x900') # 像素 - try: - root.iconbitmap(bitmap='./resources/musicreater.ico', default='./resources/musicreater.ico') - except: - pass - - print('完成!') - - print('加载点击与页面更新命令...') - - # 音轨菜单被点击 - - def MusicList_selected(event): - global NowMusic - NowMusic = ListMusicList.get(ListMusicList.curselection()) - log('刷新音轨' + str(NowMusic)) - RefreshMusic(NowMusic) - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - # 音符菜单被点击 - def NoteList_selected(event): - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - pass # 编辑音符操作 - - def CMDList_selected(event): - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - pass # 命令编辑操作 - - CMDList_selected("") # 保证函数使用 - # !!!!!上面这行在写完这个函数之后记得删!!!! - - print('菜单点击命令加载完成!') - - # 刷新音轨部分 - def RefreshMusic(Music=0): - LabelEntityName['text'] = READABLETEXT[42].format(dataset[0]['musics'][Music]['set']['EntityName']) - LabelScoreboardName['text'] = READABLETEXT[43].format(dataset[0]['musics'][Music]['set']['ScoreboardName']) - LabelInstrument['text'] = READABLETEXT[44].format(dataset[0]['musics'][Music]['set']['Instrument']) - LabelFileName['text'] = READABLETEXT[45].format(dataset[0]['musics'][Music]['set']['FileName']) - NoteList_var.set(()) # 为列表框设置新值 - for i in dataset[0]['musics'][Music]['notes']: - ListNoteList.insert(tk.END, str(i)) - - # 刷新主要部分 - def RefreshMain(): - LabelPackName['text'] = READABLETEXT[46].format(str(dataset[0]['mainset']['PackName'])) - # print(LabelPackName) - LabelMusicTitle['text'] = READABLETEXT[47].format(str(dataset[0]['mainset']['MusicTitle'])) - LabelIsRepeat['text'] = READABLETEXT[48].format(str(dataset[0]['mainset']['IsRepeat'])) - LabelPlayerSelect['text'] = READABLETEXT[49].format(str(dataset[0]['mainset']['PlayerSelect'])) - MusicList_var.set(()) # 为列表框设置新值 - for i in range(len(dataset[0]['musics'])): - ListMusicList.insert(tk.END, i) - global NowMusic - NowMusic = 0 - - def RefreshCMDList(CMDList): - ListCMDList.delete(tk.END) - for i in CMDList: - ListCMDList.insert(tk.END, str(i)) - - print('页面刷新函数加载完成!') - - def changePackName(event): - a = tkinter.simpledialog.askstring(title=READABLETEXT[50], prompt=READABLETEXT[139], initialvalue='Ryoun') - if a is None: - return - dataset[0]['mainset']['PackName'] = a - del a - RefreshMain() - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeMusicTitle(event): - a = tkinter.simpledialog.askstring(title=READABLETEXT[50], prompt=READABLETEXT[140], initialvalue='Noname') - if a is None: - return - dataset[0]['mainset']['MusicTitle'] = a - RefreshMain() - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeIsRepeat(event): - dataset[0]['mainset']['IsRepeat'] = not dataset[0]['mainset']['IsRepeat'] - RefreshMain() - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changePlayerSelect(event): - dataset[0]['mainset']['PlayerSelect'] = tkinter.simpledialog.askstring(title=READABLETEXT[50], - prompt=READABLETEXT[141], - initialvalue='') - if dataset[0]['mainset']['PlayerSelect'] is None: - dataset[0]['mainset']['PlayerSelect'] = '' - RefreshMain() - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeEntityName(event): - global NowMusic - a = tkinter.simpledialog.askstring(title=READABLETEXT[51], prompt=READABLETEXT[142], - initialvalue='musicSupport') - if a is None: - return - dataset[0]['musics'][NowMusic]['set']['EntityName'] = a - RefreshMusic(NowMusic) - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeScoreboardName(event): - global NowMusic - a = tkinter.simpledialog.askstring(title=READABLETEXT[51], prompt=READABLETEXT[143], - initialvalue='musicSupport') - if a is None: - return - dataset[0]['musics'][NowMusic]['set']['ScoreboardName'] = a - RefreshMusic(NowMusic) - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeInstrument(event): - from nmcsup.const import Instuments as inst - global NowMusic - while True: # 改正:(True) - instemp = tkinter.simpledialog.askstring(title=READABLETEXT[51], prompt=READABLETEXT[144], - initialvalue='note.harp') - if instemp not in inst.keys(): # 改正:not instemp in inst.keys() ,not in 为固定写法 - if tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[145]): - dataset[0]['musics'][NowMusic]['set']['Instrument'] = instemp - del instemp - break - else: - smsg = READABLETEXT[52] - for i, j in inst.items(): - smsg += i + ' : ' + j + '\n' - tkinter.messagebox.showinfo(title=READABLETEXT[1], message=smsg) - del smsg - else: - dataset[0]['musics'][NowMusic]['set']['Instrument'] = instemp - del instemp - break - RefreshMusic(NowMusic) - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - - def changeFileName(event): - global NowMusic - a = tkinter.simpledialog.askstring(title=READABLETEXT[51], prompt=READABLETEXT[146], initialvalue='Music') - if a is None: - return - dataset[0]['musics'][NowMusic]['set']['FileName'] = a - RefreshMusic(NowMusic) - print(event) # 保证变量使用(虽然我不清楚金羿这为啥不调用要写个event) - # 滚滚滚,这个函数不能无参! ——金羿 - - print('标签点击命令加载完成!') - - def ResetSetting(): - global dataset - dataset[0]['mainset'] = {'PackName': 'Ryoun', 'MusicTitle': 'Noname', 'IsRepeat': False, 'PlayerSelect': ''} - RefreshMain() - - def DelNowMusic(): - global NowMusic - del dataset[0]['musics'][NowMusic] - NowMusic -= 1 - RefreshMain() - RefreshMusic(NowMusic) - - from nmcsup.vers import resetver - - print('按钮点击命令加载完成!') - print('完成!') - print('加载菜单与页面...') - - # 创建一个菜单 - main_menu_bar = tk.Menu(root) - - # 创建文件菜单 - filemenu = tk.Menu(main_menu_bar, tearoff=0) - - filemenu.add_command(label=READABLETEXT[53], command=openProject) - filemenu.add_command(label=READABLETEXT[54], command=openOldProject) - filemenu.add_command(label=READABLETEXT[55], command=SaveProject) - filemenu.add_command(label=READABLETEXT[56], command=SaveAsProject) - - filemenu.add_separator() # 分隔符 - - filemenu.add_command(label=READABLETEXT[57], command=exitapp) - - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[58], menu=filemenu) - - # 创建编辑菜单 - editmenu = tk.Menu(main_menu_bar, tearoff=0) - editmenu.add_command(label=READABLETEXT[59], command=FromMP3) - editmenu.add_command(label=READABLETEXT[60], command=FromListMidi) - editmenu.add_command(label=READABLETEXT[61], command=FromForm) - editmenu.add_command(label=READABLETEXT[62], command=FromText) - editmenu.add_separator() - editmenu.add_command(label=READABLETEXT[160], command=FromClassMidi) - editmenu.add_command(label=READABLETEXT[148], command=FromNewMidi) - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[63], menu=editmenu) - - # 创建函数菜单 - funcmenu = tk.Menu(main_menu_bar, tearoff=0) - funcmenu.add_command(label=READABLETEXT[64], command=MakeCMD) - funcmenu.add_command(label=READABLETEXT[65], command=MakeCMDdir) - funcmenu.add_command(label=READABLETEXT[66], command=MakePackFile) - funcmenu.add_separator() - funcmenu.add_command(label=READABLETEXT[147], command=MakeNewCMD) - funcmenu.add_command(label=READABLETEXT[153], command=MakeNewCMDdir) - funcmenu.add_command(label=READABLETEXT[154], command=MakeNewFunctionPackFile) - funcmenu.add_command(label=READABLETEXT[155], command=MakeNewFunctionPack_ResourcesPacks_File) - funcmenu.add_separator() - funcmenu.add_command(label=READABLETEXT[164], command=MakeClassCMD) - funcmenu.add_command(label=READABLETEXT[165], command=MakeClassCMDdir) - funcmenu.add_command(label=READABLETEXT[166], command=MakeClassFunctionPackFile) - - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[67], menu=funcmenu) - - # 创建世界菜单 - worldmenu = tk.Menu(main_menu_bar, tearoff=0) - worldmenu.add_command(label=READABLETEXT[68], command=ToBlockWorldEpt) - worldmenu.add_command(label=READABLETEXT[69], command=ToBlockWorld) - worldmenu.add_separator() - worldmenu.add_command(label=READABLETEXT[70], command=ToCmdWorldEpt) - worldmenu.add_command(label=READABLETEXT[71], command=ToCmdWorld) - worldmenu.add_separator() - worldmenu.add_command(label=READABLETEXT[72], command=toRSworldEPT) - worldmenu.add_command(label=READABLETEXT[73], command=toRSworld) - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[74], menu=worldmenu) - - # 创建结构功能菜单 - structureMenu = tk.Menu(main_menu_bar, tearoff=0) - structureMenu.add_command(label=READABLETEXT[92], command=toBDXfile) - structureMenu.add_command(label=READABLETEXT[76], command=toScbBDXfile) - structureMenu.add_command(label=READABLETEXT[77], command=world2BDX) - structureMenu.add_separator() - structureMenu.add_command(label=READABLETEXT[78], command=world2RyStruct) - - main_menu_bar.add_cascade(label=READABLETEXT[95], menu=structureMenu) - - # 创建辅助功能菜单 - otherMenu = tk.Menu(main_menu_bar, tearoff=0) - otherMenu.add_command(label=READABLETEXT[75], command=MakeFuncPlayer) - otherMenu.add_separator() - otherMenu.add_command(label=READABLETEXT[79], command=func2World) - otherMenu.add_command(label=READABLETEXT[80], command=bigFunc2World) - - main_menu_bar.add_cascade(label=READABLETEXT[81], menu=otherMenu) - - # 创建实验功能菜单 - trymenu = tk.Menu(main_menu_bar, tearoff=0) - trymenu.add_command(label=READABLETEXT[82], command=ShowCMD) - trymenu.add_command(label=READABLETEXT[83], command=wsPlay) - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[84], menu=trymenu) - - # 创建帮助菜单 - helpmenu = tk.Menu(main_menu_bar, tearoff=0) - helpmenu.add_command(label=READABLETEXT[85], command=ClearLog) - helpmenu.add_command(label=READABLETEXT[86], command=resetver) - helpmenu.add_command(label=READABLETEXT[152], command=end) - helpmenu.add_command(label=READABLETEXT[156], command=changeResourcesPath) - - helpmenu.add_separator() # 分隔符 - - helpmenu.add_command(label=READABLETEXT[87], command=apphelp) - helpmenu.add_command(label=READABLETEXT[88], command=appabout) - helpmenu.add_command(label=READABLETEXT[89], command=sendBugReport) - # 将子菜单加入到菜单条中 - main_menu_bar.add_cascade(label=READABLETEXT[90], menu=helpmenu) - - # 窗口内容 - - # 上半部分框 - UpFrame = tk.Frame(root) - - # 左边的框(音乐总设置) - UpLeftFrame = tk.Frame(UpFrame, bg='white') - # 大标题 - tk.Label(UpLeftFrame, text=READABLETEXT[91], font=('', 20)).pack() - # 按钮式文本 - LabelPackName = tk.Label(UpLeftFrame, bg='white', - text=READABLETEXT[46].format(str(dataset[0]['mainset']['PackName'])), font=('', 15)) - LabelMusicTitle = tk.Label(UpLeftFrame, bg='white', - text=READABLETEXT[47].format(str(dataset[0]['mainset']['MusicTitle'])), font=('', 15)) - LabelIsRepeat = tk.Label(UpLeftFrame, bg='white', - text=READABLETEXT[48].format(str(dataset[0]['mainset']['IsRepeat'])), font=('', 15)) - LabelPlayerSelect = tk.Label(UpLeftFrame, bg='white', - text=READABLETEXT[49].format(str(dataset[0]['mainset']['PlayerSelect'])), - font=('', 15)) - # 绑定按钮 - LabelPackName.bind('', changePackName) - LabelMusicTitle.bind('', changeMusicTitle) - LabelIsRepeat.bind('', changeIsRepeat) - LabelPlayerSelect.bind('', changePlayerSelect) - # 装入容器 - LabelPackName.pack() - LabelMusicTitle.pack() - LabelIsRepeat.pack() - LabelPlayerSelect.pack() - # 按钮:重置项目设置 - tk.Button(UpLeftFrame, text=READABLETEXT[96], command=ResetSetting).pack() - # 装入窗口 - UpLeftFrame.pack(side='left') - - # 中间的框容器 - UpMidleFrame = tk.Frame(UpFrame, bg='blue') - # 列表 - MusicList_var = tk.StringVar() - ListMusicList = tk.Listbox(UpMidleFrame, listvariable=MusicList_var) - ListMusicList.bind('', MusicList_selected) # 设置选中响应函数 - ListMusicList.pack(side='left') - # 滑块 - tk.Scrollbar(UpMidleFrame, command=ListMusicList.yview).pack(side='left', fill='y') - # 装入窗口 - UpMidleFrame.pack(side='left') - - # 右边的框容器 - UpRightFrame = tk.Frame(UpFrame, bg='white') - # 大标题 - tk.Label(UpRightFrame, text=READABLETEXT[97], font=('', 20)).pack() - # 按钮式文本 - LabelEntityName = tk.Label(UpRightFrame, bg='white', - text=READABLETEXT[42].format(dataset[0]['musics'][NowMusic]['set']['EntityName']), - font=('', 15)) - LabelScoreboardName = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[43].format( - dataset[0]['musics'][NowMusic]['set']['ScoreboardName']), font=('', 15)) - LabelInstrument = tk.Label(UpRightFrame, bg='white', - text=READABLETEXT[44].format(dataset[0]['musics'][NowMusic]['set']['Instrument']), - font=('', 15)) - LabelFileName = tk.Label(UpRightFrame, bg='white', - text=READABLETEXT[45].format(dataset[0]['musics'][NowMusic]['set']['FileName']), - font=('', 15)) - # 绑定按钮 - LabelEntityName.bind('', changeEntityName) - LabelScoreboardName.bind('', changeScoreboardName) - LabelInstrument.bind('', changeInstrument) - LabelFileName.bind('', changeFileName) - # 装入框容器 - LabelEntityName.pack() - LabelScoreboardName.pack() - LabelInstrument.pack() - LabelFileName.pack() - # 按钮:删除选中音轨 - tk.Button(UpRightFrame, text=READABLETEXT[102], command=DelNowMusic).pack() - # 装入窗口 - UpRightFrame.pack(side='left') - - # 上半部分框容器装入窗口 - UpFrame.pack() - - # 下半部分框容器 - DownFrame = tk.Frame(root, bg='blue') - - # 经典名言语录 - import datetime - - if datetime.date.today().month == 4 and datetime.date.today().day == 3: - tk.Label(DownFrame, text='金羿生日快乐!!',fg='yellow', bg='red', font=('DengXian', 20, 'bold')).pack(fill='x') - else: - import random - texts = open('./resources/myWords.txt', 'r', encoding='utf-8').readlines() - tk.Label(DownFrame, text=texts[random.randint(0, len(texts) - 1)].replace('\n', '').replace('\\n', '\n'), - fg='white', bg='black', font=('DengXian Light', 20)).pack(fill='x') - del texts - - # 音符列表菜单 - NoteList_var = tk.StringVar() - ListNoteList = tk.Listbox(DownFrame, listvariable=NoteList_var, width=40, height=30) - ListNoteList.bind('', NoteList_selected) # 设置选中响应函数 - ListNoteList.pack(side='left') - # 音符列表滑块 - tk.Scrollbar(DownFrame, command=ListNoteList.yview).pack(side='left', fill='y') - - # 指令列表菜单 - ListCMDList = tk.Text(DownFrame, height=37, width=40) - ListCMDList.pack(side='left') - # 指令列表滑块 - tk.Scrollbar(DownFrame, command=ListCMDList.yview).pack(fill='y', side='left') - - # 下半部分容器载入窗口 - DownFrame.pack() - - RefreshMain() - - # 将菜单添加到主窗口中 - root.config(menu=main_menu_bar) - - print('完成!') - - log('启动root.mainloop(窗口)') - - if len(sys.argv) != 1: - log('初始化打开音·创项目' + sys.argv[1]) - global is_save - is_save = True - error = True - try: - with open(sys.argv[1], 'r', encoding='UTF-8') as c: - dataset[0] = json.load(c) - error = False - except OSError: - print(READABLETEXT[8].format(sys.argv[1])) - log('无法打开' + sys.argv[1]) - return - finally: - if error is True: - print(READABLETEXT[8].format(sys.argv[1])) - log('无法打开' + sys.argv[1]) - return - global is_new_file - global ProjectName - is_new_file = False - ProjectName = sys.argv[1] - RefreshMain() - RefreshMusic(NowMusic) - - # 进入窗口消息循环 - root.mainloop() - log('退出') - del filemenu, editmenu, helpmenu, otherMenu - - exitapp() - - -if __name__ == '__main__': - __main__() - -################## - - # def openNewProject(): - # global is_save - # if is_save is not True: - # result = tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]) - # if result: - # SaveProject() - # fn = tkinter.filedialog.askopenfilename(title=READABLETEXT[7], initialdir=r'./', - # filetypes=[(READABLETEXT[108], '.msct'), (READABLETEXT[112], '*')], - # multiple=True) - # if fn is None or fn == '': - # return - # else: - # # print(fn) - # fn = fn[0] - # # print(fn) - # log("尝试打开:" + fn) - # try: - # try: - # with open(fn, 'rb') as C: - # global dataset - # # print(pickle.load(C)) - # read = pickle.load(C) # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # print(read) - # dataset = read[0] - # pkl1 = read[1] - # log("读取新文件成功") - # with open("1.pkl", 'wb') as w: - # pickle.dump(pkl1, w) - # except KeyError: - # with open(fn, 'rb') as C: - # dataset[0] = pickle.load(C) - # log("读取新文件成功") - # except pickle.UnpicklingError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # # pickle.UnpicklingError - # print(READABLETEXT[8].format(fn)) - # log('无法打开{}'.format(fn)) - # return - # global is_new_file - # global ProjectName - # is_new_file = False - # ProjectName = fn - # del fn - # global NowMusic - # RefreshMain() - # RefreshMusic(NowMusic) - - # def openClassProject(): - # global is_save - # if is_save is not True: - # result = tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]) - # if result: - # SaveProject() - # fn = tkinter.filedialog.askopenfilename(title=READABLETEXT[7], initialdir=r'./', - # filetypes=[(READABLETEXT[108], '.msct'), (READABLETEXT[112], '*')], - # multiple=True) - # if fn is None or fn == '': - # return - # else: - # # print(fn) - # fn = fn[0] - # # print(fn) - # log("尝试打开:" + fn) - # try: - # try: - # with open(fn, 'rb') as C: - # global dataset - # # print(pickle.load(C)) - # read = pickle.load(C) # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # 重要的事情说三遍!!!pickle.load只能load一次,所以多load几次就有bug,要一次读完! - # # print(read) - # dataset = read - # log("读取新文件成功") - # except KeyError: - # with open(fn, 'rb') as C: - # dataset[0] = pickle.load(C) - # log("读取新文件成功") - # except pickle.UnpicklingError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # # pickle.UnpicklingError - # print(READABLETEXT[8].format(fn)) - # log('无法打开{}'.format(fn)) - # return - # global is_new_file - # global ProjectName - # is_new_file = False - # ProjectName = fn - # del fn - # global NowMusic - # RefreshMain() - # RefreshMusic(NowMusic) - - -# ------------------ - # filemenu.add_separator() - # - # filemenu.add_command(label=READABLETEXT[149], command=openNewProject) - # filemenu.add_command(label=READABLETEXT[150], command=SaveNewProject) - # filemenu.add_command(label=READABLETEXT[151], command=SaveAsNewProject) - - # filemenu.add_separator() - # - # filemenu.add_command(label=READABLETEXT[161], command=openClassProject) - # filemenu.add_command(label=READABLETEXT[162], command=SaveClassProject) - # filemenu.add_command(label=READABLETEXT[163], command=SaveAsClassProject) diff --git a/fcwslib/__init__.py b/fcwslib/__init__.py deleted file mode 100644 index 19a8fdf..0000000 --- a/fcwslib/__init__.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:2个---未解决;警告(二级)错误:2个;语法(一级)错误:17个 - - -__version__ = '0.0.1' -__all__ = [] -__author__ = 'Fuckcraft ' - -''' -Fuckcraft Websocket Library (FCWSLIB) -A library to develop minecraft websocket server easily. - - Copyright (C) 2021 Fuckcraft - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. -''' - -from main import * - -# import os -import json -import uuid -# import logging -import asyncio -import time -import websockets - - -# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。 -# 现在只有上帝知道。 -# ---- -# 没毛病,我讨厌两种人:一种是要我写注释的人,一种是给我代码看但没有写注释的人。 - -# 此函数用于向 Minecraft 订阅请求 -async def subscribe(websocket, event_name): - """ - 参数: - : websocket : websocket 对象 : - : event_name : 需要订阅的请求 : - - 返回: - None - """ - - response = { - 'body': { - 'eventName': str(event_name) # 示例:PlayerMessage - }, - 'header': { - 'requestId': str(uuid.uuid4()), - 'messagePurpose': 'subscribe', - 'version': 1, - 'messageType': 'commandRequest' - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - - -# 此函数用于向 Minecraft 消除订阅请求 -async def unsubscribe(webscket): - """ - 参数: - : websocket : websocket 对象 : - : event_name : 需要消除订阅的请求 : - - 返回: - None - """ - print(webscket) - - response = { - "body": { - "eventName": str(event_name) # PlayerMessage - }, - "header": { - "requestId": str(uuid.uuid4()), - "messagePurpose": "unsubscribe", - "version": 1, - "messageType": "commandRequest" - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - - -# 此函数用于向 Minecraft 执行命令 -async def send_command(websocket, command): - """ - 参数: - : websocket : websocket 对象 : - : command : 执行的命令 : - - 返回: - None - """ - - response = { - 'body': { - 'origin': { - 'type': 'player' - }, - 'commandLine': str(command), - 'version': 1 - }, - 'header': { - 'requestId': str(uuid.uuid4()), - 'messagePurpose': 'commandRequest', - 'version': 1, - 'messageType': 'commandRequest' - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - - -# 此函数用于向 Minecraft 发送消息 -async def tellraw(websocket, message): - """ - 参数: - : websocket : websocket 对象 : - : message : 发送的消息 : - - 返回: - None - """ - - command = { - 'rawtext': [ - { - 'text': '[{}] {}'.format(time.asctime(), message) - } - ] - } - - # 增加 json 可读性 - # command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - command = json.dumps(command) - command = 'tellraw @a {}'.format(command) - - await send_command(websocket, command) - - -def run_server(function): - # 修改 ip 地址和端口 - start_server = websockets.serve(function, 'localhost', 8080) - asyncio.get_event_loop().run_until_complete(start_server) - asyncio.get_event_loop().run_forever() diff --git a/fcwslib/main.py b/fcwslib/main.py deleted file mode 100644 index a0f8b76..0000000 --- a/fcwslib/main.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -__version__ = '0.0.1' -__all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw'] -__author__ = 'Fuckcraft ' - -''' -Fuckcraft Websocket Library (FCWSLIB) -A library to develop minecraft websocket server easily. - - Copyright (C) 2021 Fuckcraft - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. -''' - -import os -import json -import uuid -import logging -import asyncio -import time -import websockets - -# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。 -# 现在只有上帝知道。 - -# 此函数用于向 Minecraft 订阅请求 -async def subscribe(websocket, event_name): - ''' - 输入: - : websocket : websocket 对象 : - : event_name : 需要订阅的请求 : - - 输出: - None - ''' - - response = { - 'body': { - 'eventName': str(event_name) # 示例:PlayerMessage - }, - 'header': { - 'requestId': str(uuid.uuid4()), - 'messagePurpose': 'subscribe', - 'version': 1, - 'messageType': 'commandRequest' - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - -# 此函数用于向 Minecraft 消除订阅请求 -async def unsubscribe(webscket): - ''' - 输入: - : websocket : websocket 对象 : - : event_name : 需要消除订阅的请求 : - - 输出: - None - ''' - - response = { - "body": { - "eventName": str(event_name) # 示例:PlayerMessage - }, - "header": { - "requestId": str(uuid.uuid4()), - "messagePurpose": "unsubscribe", - "version": 1, - "messageType": "commandRequest" - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - -# 我个人不负责这块的质量,因为他们逼迫我违心的写了这段代码 - -# 此函数用于向 Minecraft 执行命令 -async def send_command(websocket, command): - ''' - 输入: - : websocket : websocket 对象 : - : command : 执行的命令 : - - 输出: - None - ''' - - response = { - 'body': { - 'origin': { - 'type': 'player' - }, - 'commandLine': str(command), - 'version': 1 - }, - 'header': { - 'requestId': str(uuid.uuid4()), - 'messagePurpose': 'commandRequest', - 'version': 1, - 'messageType': 'commandRequest' - } - } - - # 增加 json 的可读性 - # response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - response = json.dumps(response) - - await websocket.send(response) - -# 此函数用于向 Minecraft 发送消息 -async def tellraw(websocket, message): - ''' - 输入: - : websocket : websocket 对象 : - : message : 发送的消息 : - - 输出: - None - ''' - - command = { - 'rawtext':[ - { - 'text':'[{}] {}'.format(time.asctime(), message) - } - ] - } - - # 增加 json 可读性 - # command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) - command = json.dumps(command) - command = 'tellraw @a {}'.format(command) - - await send_command(websocket, command) - -def run_server(function): - # 修改 ip 地址和端口 - start_server = websockets.serve(function, 'localhost', 8080) - asyncio.get_event_loop().run_until_complete(start_server) - asyncio.get_event_loop().run_forever() - diff --git a/fcwslib/版权声明.png b/fcwslib/版权声明.png deleted file mode 100644 index 05ebcf592e10e8b83b3fcf63f2dc33f72acd9663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68955 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 diff --git a/msctspt/__pycache__/__init__.cpython-38.pyc b/msctspt/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 5a4a934a00fa678e3aee29120720984291571a4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmWIL<>g`kf&kC2i6Hthh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o71z$aS-d3D=GE zj0q^pPcKT$&CSe9k9j$N^V5#mG0Gv?nRz9tMKQU>$tA@FB{A{wnR%Hd@$q^EmA5!- Ra`RJ4b5iXg`k0_kI>Ng(<$h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o1Ty$n~*`F$m8u z%1QApEzV4KE=o--NiEX#b@L5Y$V)9(NKMHs$;{7-dD-6kY+lQY{q4_oEPUSC@odhT zm@)%BLjyg77_df&zL?zN4T%)HE!_;|g7%3B;Zx%nxjIjMFa+dl&_0|4_; BHhlm9 diff --git a/msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc b/msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc deleted file mode 100644 index ab550424751af84cd116203519b1a6197d19915b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6194 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 diff --git a/msctspt/__pycache__/bugReporter.cpython-38.pyc b/msctspt/__pycache__/bugReporter.cpython-38.pyc deleted file mode 100644 index cb5547d374e01c6edde3ebcd10d8e1a346a27f0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4430 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 bwfunKD7`TW8PA~zCS8)?Y{cw>rl0*6`JRh< diff --git a/msctspt/__pycache__/funcOpera.cpython-38.pyc b/msctspt/__pycache__/funcOpera.cpython-38.pyc deleted file mode 100644 index c131e41abfd48ace311bfddef0091b59042160a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10610 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 diff --git a/msctspt/__pycache__/funcOpera.cpython-39.pyc b/msctspt/__pycache__/funcOpera.cpython-39.pyc deleted file mode 100644 index 6ac59d773e09c2bc341208760ef55b42453721cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11157 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 P?(G4qJ6KSrugm@bPo(^U diff --git a/msctspt/__pycache__/threadOpera.cpython-38.pyc b/msctspt/__pycache__/threadOpera.cpython-38.pyc deleted file mode 100644 index 61df0447fc4b290af60adff7f78ecf975d77249a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1003 zcmZWn%}>-&5TCd0c3Wgo;qFB*dys=iV${S$;{}aijGIkfn!d8`+U>%7ZH#0OBw#R+ z00-bgR5*~Z9)yHMQ6T$&^y+q5PM$n?bEf+N(P`dvUOOMZ`OQ4bW(NRe^6npdRRj1* zmy4p~JddAj?)^DumS(G8xu zD)fTZ#`o62dVBd>ys{C${n~D<#hV}Fx#K!GNJ(GF?j3alF98Is2J@+{)HX1vq0O~g z3bif(by~m#)Y*8>h|(&YcBM>VP-Jpm@=F2dkvk z^Ga2O9@&GO&xE$u{gdHbR2>`|5iY4$If5$6cE{zs-n}5V!&2H0^C-1(u`DoF%%x~Z9zR%x#g;Z*QfL!@`>)EP8 z$S=H{7Zon|;K-{0oN#KB9C<)^j4M^b6_b?cqLPboI!V&%DcFz+1M$3I3>0}2z$7`! z33}udo~)56$`!6wlR1^gxmG2)I8SgL-dc^QB$t4=1AcPCoO|+Im<8??Ax5~d9~}N@ z9W1mCKDL{iC%bRM4?FGVYP-G^)Q-dT{ohAjrTg*oQnZ8uXi z-N&Z%Y&YEa9)4MGFMkVGHiB1Q+s(CLb1PUlY7he`=?m(;Bd@{5B`&Ry#n^VNPAI8> z&Xh_FP~`+L&dDTc(22C>$E7!83K0V*UuVp6ESE7~o$?&RR|}#jeN9BAq!nM4radJR zU@CNg2KAGS8FoQR#sud7!vP-N&S#&Nh0Vu3X&GZcjcbbQ->+t=j{EKYnMmCepM~)r8{IoP&IpgNth~r04Yaui9QfQDU2}fcf zgbq;+p84VaFfzSX42lL_K^;3CgCmClDx`#mE+Z>3WJTagq?NNS1*U0Gfy)>**?|;X zeMNZAMNlLLC3HS@mLLB7ml`SRr*O6n(9;TE1E;TTWDo z7=j@G){*Ql3^paBt)_!?e&np4zD1fw-f11j?G&a>8212U(`D}2s1GtW>lN(op9EvP zY`}PtaDlyw5dc5c9lT-Mc6a!lqAs8bk`t{I?n*QwovL(5)0OBe(0d6jF89pN^@AKm R{=R;vQ`22+Ct_Gv{sM0q6V?C# diff --git a/msctspt/__pycache__/transfer.cpython-38.pyc b/msctspt/__pycache__/transfer.cpython-38.pyc deleted file mode 100644 index 75c69803251c48d42c2943f6fb4b321b4e0e59fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17537 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 diff --git a/msctspt/__pycache__/transfer.cpython-39.pyc b/msctspt/__pycache__/transfer.cpython-39.pyc deleted file mode 100644 index fabe34b25f4d89823876e82589d3b9cecf1e257b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16319 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 新-旧={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"\x24" - 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) diff --git a/msctspt/bugReporter.py b/msctspt/bugReporter.py deleted file mode 100644 index a1a62cf..0000000 --- a/msctspt/bugReporter.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: UTF-8 -*- -"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能""" - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:1个;语法(一级)错误:72个 -import os - - -def makeZip(sourceDir, outFilename, compression=8, exceptFile=None): - import zipfile - """使用compression指定的算法打包目录为zip文件\n - 默认算法为DEFLATED(8),可用算法如下:\n - STORED = 0\n - DEFLATED = 8\n - BZIP2 = 12\n - LZMA = 14\n - """ - zipf = zipfile.ZipFile(outFilename, 'w', compression) - pre_len = len(os.path.dirname(sourceDir)) - for parent, dirnames, filenames in os.walk(sourceDir): - for filename in filenames: - if filename == exceptFile: - continue - print(filename) - pathfile = os.path.join(parent, filename) - arcname = pathfile[pre_len:].strip(os.path.sep) # 相对路径 - zipf.write(pathfile, arcname) - - zipf.close() - del zipf, pre_len - - -# 以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942 - - -class report: - """发送报告以及相应的任务处理""" - - def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''): - """:param senderName 发送者名称 - :param senderContact 发送者联系方式 - :param describetion 问题描述""" - self.senderName = senderName - self.senderContact = senderContact - self.describetion = describetion - if not self.senderName: - self.senderName = 'Unknown' - if not self.senderContact: - self.senderContact = 'None' - - def emailReport(self): - """使用E-mail方法发送当前的日志和临时文件等""" - import smtplib - from email.mime.text import MIMEText - from email.mime.multipart import MIMEMultipart - from email.header import Header - from nmcsup.log import log - log("发送错误报告") - import os - log("添加标题与正文") - msg = MIMEMultipart() - # 发送者与接收者显示名称 - msg["From"] = Header(self.senderName, 'utf-8') - msg["To"] = Header("W-YI (QQ2647547478)", 'utf-8') - # 标题 - msg["Subject"] = '音·创 - 来自 ' + self.senderName + ' 的错误报告' - # 正文 - msg.attach( - MIMEText("来自" + self.senderName + "( " + self.senderContact + " )的错误描述:\n" + self.describetion, - 'utf-8')) - log("添加完毕,正在生成压缩包...") - makeZip("./", "Temps&Logs.zip", exceptFile="Temps&Logs.zip") - attafile = MIMEText(str(open("Temps&Logs.zip", 'rb').read()), "base64", 'gb2312') - attafile["Content-Type"] = 'application/octet-stream' - attafile["Content-Disposition"] = 'attachmentfilename="BugReport_from_' + self.senderName + '.zip"' - msg.attach(attafile) - log("完毕,准备发送") - try: - smtp = smtplib.SMTP() - smtp.connect("smtp.163.com") - # smtp.login("RyounDevTeam@163.com","RyounDaiYi99") - # SIQQKQQYCZRVIDFJ是授权密码 - smtp.login("RyounDevTeam@163.com", "SIQQKQQYCZRVIDFJ") - smtp.sendmail("RyounDevTeam@163.com", ["RyounDevTeam@163.com", ], msg.as_string()) - log("错误汇报邮件已发送") - except smtplib.SMTPException as e: - log("错误汇报邮件发送失败:\n" + str(e)) - log("清空内存和临时文件") - del msg, attafile - os.remove("./Temps&Logs.zip") - - -from msctLib.buildIN import version \ No newline at end of file diff --git a/msctspt/funcOpera.py b/msctspt/funcOpera.py deleted file mode 100644 index ef71f6b..0000000 --- a/msctspt/funcOpera.py +++ /dev/null @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -"""音·创 的函数操作和一些其他功能""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:91个 - - -from nmcsup.log import log - - -def delPart(Data, starter, ender, includeStart: bool = True, includend: bool = True): - """删除序列从starter物件到ender物件之间的部分\n - includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n - starter与ender若为None则默认从首或尾开始""" - try: - if starter is None: - includeStart = True - starter = Data[0] - if ender is None: - includend = True - ender = Data[len(Data) - 1] - if includend: - if includeStart: - return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender)] - else: - return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender)] - else: - if includeStart: - return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender) - 1] - else: - return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender) - 1] - except: - return 0 - - -def keepart(Data, starter, ender, includeStart: bool = True, includend: bool = True): - """保留序列从starter物件到ender物件之间的部分\n - includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n - starter与ender若为None则默认从首或尾开始""" - try: - if starter is None: - includeStart = True - starter = Data[0] - if ender is None: - includend = True - ender = Data[len(Data) - 1] - if includend: - if includeStart: - return Data[Data.index(starter):Data.index(ender) + 1] - else: - return Data[Data.index(starter) + 1:Data.index(ender) + 1] - else: - if includeStart: - return Data[Data.index(starter):Data.index(ender)] - else: - return Data[Data.index(starter) + 1:Data.index(ender)] - except: - return 0 - - -def lenFunction(fun) -> int: - """取得函数指令部分长度,即忽略#开头的注释""" - try: - f = 0 - for i in fun: - if i.replace(" ", '')[0] == '#': - f += 1 - return len(fun) - f - except: - return -1 - - -def funSplit(bigFile, maxCmdLen: int = 10000): - """分割bigFile大的函数文件,bigFile需要读入文件流\n - 返回的部分,每行指令皆带有行尾换行符\\n\n - 返回-1为大小低于maxCmdLen最长函数指令长度""" - bigFile = bigFile.readlines() - if lenFunction(bigFile) < maxCmdLen: - return -1 - part = [] - parts = [] - h = 0 - for i in bigFile: - if i.replace(" ", '')[0] == '#': - part.append(i + '\n') - else: - part.append(i + '\n') - h += 1 - if h >= 10000: - parts.append(part) - part = [] - h = 0 - return parts - - -def makeFuncFiles(musicset, path='./'): - """在指定目录下生成函数文件""" - from nmcsup.trans import Note2Cmd - commands = [] - starts = [] - log("=========================正在在此处生成文件:" + path) - maxlen = -1 - for i in range(len(musicset['musics'])): - log('写入第' + str(i) + '个数据') - commands.append("scoreboard players add @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\"] " + - musicset['musics'][i]['set']['ScoreboardName'] + " 1\n") - commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'][ - 'PlayerSelect'] + " title " + musicset['mainset']['MusicTitle'] + "\n") - commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'][ - 'PlayerSelect'] + " subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\n") - if len(musicset['musics'][i]['notes']) > maxlen: - maxlen = len(musicset['musics'][i]['notes']) - starts.append("scoreboard objectives add " + musicset['musics'][i]['set']['ScoreboardName'] + " dummy\n") - starts.append("summon armor_stand " + musicset['musics'][i]['set']['EntityName'] + '\n') - with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w', - encoding='UTF-8') as f: - f.writelines(Note2Cmd(musicset['musics'][i]['notes'], musicset['musics'][i]['set']['ScoreboardName'], - musicset['musics'][i]['set']['Instrument'], musicset['mainset']['PlayerSelect'], - True)) - if musicset['mainset']['IsRepeat']: - log("增加重复语句") - for i in range(len(musicset['musics'])): - commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - musicset['musics'][i]['set']['ScoreboardName'] + "=" + str( - (maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][ - 'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n") - log("增加版权语句") - commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - log("写入支持文件") - with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(commands) - log("写入开始文件") - with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(starts) - del commands, starts, maxlen - log("完成============================") - - - - - - - - - - - - - - - - -def makeFunDir(musicset, path='./'): - """在指定目录下生成函数包文件夹""" - import os - import uuid - log("=============================生成函数包文件夹") - # note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support', - # MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp' - try: - os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - except FileExistsError: - log("目录已有无需创建") - pass - # 判断文件皆存在 - if not (os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/manifest.json")): - log("创建manifest.json以及world_behavior_packs.json") - behaviorUuid = uuid.uuid4() - with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f: - f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]") - p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \ - "/manifest.json" - with open(p, "w") as f: - f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" + - musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str( - behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":" - " [ 0, 0, 1 ],\n \"uuid\": \"" + str( - uuid.uuid4()) + "\"\n }\n ]\n}") - makeFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions/") - log("完成============================") - - - - - - - - - -def makeNewFuncFiles(musicset, path='./', isProsess:bool = False): - """在指定目录下生成函数文件""" - from msctspt.transfer import newList_conversion_SinglePlayer - commands = [] - starts = [] - starts.__len__() - starts.append("scoreboard objectives add " + musicset['musics'][0]['set']['ScoreboardName'] + " dummy\n") - # starts.append("summon armor_stand " + musicset['musics'][0]['set']['EntityName'] + '\n') - # starts.append("scoreboard objectives setdisplay sidebar " + musicset['musics'][0]['set']['ScoreboardName'] + '\n') - # starts.append("scoreboard players set @e[type=armor_stand, name=\"" + musicset['musics'][0]['set']['EntityName'] +"\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 0" + '\n') - - log("=========================正在在此处生成文件:" + path) - - # commands.append("scoreboard players add @e[name=\"" + musicset['musics'][0]['set']['EntityName'] + "\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 1\n") - maxlen = -1 - for i in range(len(musicset['musics'])): - log('写入第' + str(i) + '个数据') - - if len(musicset['musics'][i]['notes']) > maxlen: - maxlen = len(musicset['musics'][i]['notes']) - with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w', - encoding='UTF-8') as f: - f.writelines(newList_conversion_SinglePlayer(musicset['musics'][i]['notes'], - musicset['musics'][i]['set']['ScoreboardName'], - musicset['musics'][i]['set']['Instrument'])) - if musicset['mainset']['IsRepeat']: - log("增加重复语句") - for i in range(len(musicset['musics'])): - commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - musicset['musics'][i]['set']['ScoreboardName'] + "=" + str( - (maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][ - 'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n") - log("增加版权语句") - commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n") - starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n") - log("写入支持文件") - with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(commands) - log("写入开始文件") - with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(starts) - del commands, starts, maxlen - log("完成============================") - - - - - - - - - - - - - - - -def makeNewFunDir(musicset, path='./'): - """在指定目录下生成函数包文件夹""" - import os - import uuid - log("=============================生成函数包文件夹") - # note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support', - # MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp' - try: - os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - except FileExistsError: - log("目录已有无需创建") - pass - # 判断文件皆存在 - if not (os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/manifest.json")): - log("创建manifest.json以及world_behavior_packs.json") - behaviorUuid = uuid.uuid4() - with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f: - f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]") - p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \ - "/manifest.json" - with open(p, "w") as f: - f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" + - musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str( - behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":" - " [ 0, 0, 1 ],\n \"uuid\": \"" + str( - uuid.uuid4()) + "\"\n }\n ]\n}") - makeNewFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions/") - log("完成============================") - - -def makeClassFuncFiles(musicset, path='./'): - """在指定目录下生成函数文件""" - from msctspt.transfer import classList_conversion_SinglePlayer - commands = [] - starts = [] - starts.__len__() - starts.append("scoreboard objectives add " + musicset['musics'][0]['set']['ScoreboardName'] + " dummy\n") - starts.append("summon armor_stand " + musicset['musics'][0]['set']['EntityName'] + '\n') - starts.append("scoreboard objectives setdisplay sidebar " + musicset['musics'][0]['set']['ScoreboardName'] + '\n') - starts.append("scoreboard players set @e[type=armor_stand, name=\"" + musicset['musics'][0]['set']['EntityName'] + - "\"] " + musicset['musics'][0]['set']['ScoreboardName'] + " 0" + '\n') - log("=========================正在在此处生成文件:" + path) - commands.append("scoreboard players add @e[name=\"" + musicset['musics'][0]['set']['EntityName'] + "\"] " + - musicset['musics'][0]['set']['ScoreboardName'] + " 1\n") - maxlen = -1 - for i in range(len(musicset['musics'])): - log('写入第' + str(i) + '个数据') - # commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - # musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'] - # [ - # 'PlayerSelect'] + " title " + musicset['mainset']['MusicTitle'] + "\n") - # commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - # musicset['musics'][i]['set']['ScoreboardName'] + "=1..10}] ~~~ title @a" + musicset['mainset'] - # [ - # 'PlayerSelect'] + " subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\n") - if len(musicset['musics'][i]['notes']) > maxlen: - maxlen = len(musicset['musics'][i]['notes']) - with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w', - encoding='UTF-8') as f: - f.writelines(classList_conversion_SinglePlayer(musicset['musics'][i]['notes'], - musicset['musics'][i]['set']['ScoreboardName'], - musicset['mainset']['PlayerSelect'], - True)) - if musicset['mainset']['IsRepeat']: - log("增加重复语句") - for i in range(len(musicset['musics'])): - commands.append("execute @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\",scores={" + - musicset['musics'][i]['set']['ScoreboardName'] + "=" + str( - (maxlen + 2) * 10) + "}] ~~~ scoreboard players set @e[name=\"" + musicset['musics'][i]['set'][ - 'EntityName'] + "\"] " + musicset['musics'][i]['set']['ScoreboardName'] + " -1\n") - log("增加版权语句") - commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n") - starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿),bgArray(诸葛亮与八卦阵)\n") - log("写入支持文件") - with open(path + musicset['mainset']['MusicTitle'] + '_Support.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(commands) - log("写入开始文件") - with open(path + 'Start_' + musicset['mainset']['MusicTitle'] + '.mcfunction', 'w', encoding='UTF-8') as f: - f.writelines(starts) - del commands, starts, maxlen - log("完成============================") - - -def makeClassFunDir(musicset, path='./'): - """在指定目录下生成函数包文件夹""" - import os - import uuid - log("=============================生成函数包文件夹") - # note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support', - # MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp' - try: - os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions") - except FileExistsError: - log("目录已有无需创建") - pass - # 判断文件皆存在 - if not (os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists( - path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/manifest.json")): - log("创建manifest.json以及world_behavior_packs.json") - behaviorUuid = uuid.uuid4() - with open(path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json", "w") as f: - f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) + "\",\n \"version\": [ 0, 0, 1 ]}\n]") - p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \ - "/manifest.json" - with open(p, "w") as f: - f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \"" + - musicset['mainset']['PackName'] + "Pack\",\n \"uuid\": \"" + str( - behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \"" + musicset['mainset'][ - 'PackName'] + " Pack : behavior pack\",\n \"type\": \"data\",\n \"version\":" - " [ 0, 0, 1 ],\n \"uuid\": \"" + str( - uuid.uuid4()) + "\"\n }\n ]\n}") - makeClassFuncFiles(musicset, path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ - 'PackName'] + "/functions/") - log("完成============================") - - -""" -这里是往事,用于记载一些用不到的功能 - -#存在于 Musicreater.py 播放(试听)音乐 -def PlayNote(Notes, t=480): # Notes是音符列表,t是一拍占有的毫秒数 - tkinter.messagebox.showinfo(title='提示!', message="播放发音不一定标准\n说不定还会坏音响/(ㄒoㄒ)/~~qwq\n请注意。") - import winsound - import time - from nmcsup.trans import mcnote2freq - Notes = mcnote2freq(Notes) - for frequency, duration in Notes: - log("播放:"+str([int(frequency), int(duration*t)])) - if int(frequency) != 0: - winsound.Beep(int(frequency), int(duration*t)) - elif int(frequency) == 0: - time.sleep(duration*t/1000) - -#同上,执行播放命令 -def PlayOne(): - log("试听") - tkinter.messagebox.showwarning(title="警告⚠", message="试听音质可能引起您的不适,更可能引起您的扬声器的不适,请酌情播放。") - global NowMusic - PlayNote(dataset[0]['musics'][NowMusic]['notes']) - - - -#同上,是早期 MinecraftMusicFunctionMaker.py (函数音创)的代码转移至音·创时的注解 -n2c(dataset[0]['musics'][i]['notes'],EntityName=dataset[0]['musics'][i]['set']['EntityName'],ScoreboardName=dataset[0][' -musics'][i]['set']['ScoreboardName'],PlayerSelect=dataset[0]['mainset']['PlayerSelect'],Instrument=dataset[0]['musics'] -i]['set']["Instrument"]) - - -""" diff --git a/msctspt/threadOpera.py b/msctspt/threadOpera.py deleted file mode 100644 index f18f14c..0000000 --- a/msctspt/threadOpera.py +++ /dev/null @@ -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 - self.result = None - - def run(self): - self.result = self.func(*self.args) - - def getResult(self): - threading.Thread.join(self) # 等待线程执行完毕 - return self.result - -# -# ———————————————— -# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 -# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014 -# ———————————————— -# \ No newline at end of file diff --git a/msctspt/transfer.py b/msctspt/transfer.py deleted file mode 100644 index aa32ad1..0000000 --- a/msctspt/transfer.py +++ /dev/null @@ -1,577 +0,0 @@ -"""音·创 的转换工具库""" - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:4个--未解决1个;语法(一级)错误:302个 - - -# 可序列化对象,即可迭代对象 -from typing import Iterable - -import amulet - -from amulet.api.block import Block -from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc -from amulet_nbt import TAG_String as ts -from msctLib.log import log - - -def hans2pinyin(hans, style=3): - """将汉字字符串转化为拼音字符串""" - from pypinyin import lazy_pinyin - result = lazy_pinyin(hans=hans, style=style) - final = '' - for i in result: - final += i - return final - - -def classList_conversion_SinglePlayer(List: list, ScoreboardName: str, playerSelection: str = '', - isProsess: bool = False) -> list: - from bgArrayLib.compute import round_up - from bgArrayLib.pitchStrConstant import pitch - from bgArrayLib.instrumentConstant import instrument_list - commands = [] - length = len(List) - j = 1 - for k in range(len(List)): - i = List[k][0] - try: - commands.append( - f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}=" - f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~{127 - i.velocity} " - f"~ playsound note.{instrument_list.get(str(i.instrument))} @s ~ ~ ~ " - f"1000 {pitch.get(str(i.pitch))} 1000\n") - if isProsess: - commands.append( - f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}=" - f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~ ~ " - f"title @s actionbar §e▶ 播放中: §a{j}/{length} || {int(j / length * 1000) / 10}\n") - j += 1 - except Exception: - pass - # a += List[i][1] - # commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - return commands - - -def newList_conversion_SinglePlayer(List: list, ScoreboardName: str, playerSelection: str = '', - isProsess: bool = False) -> list: - from bgArrayLib.compute import round_up - commands = [] - length = len(List) - j = 1 - print(List) - for k in range(len(List)): - i = List[k][0] - print(i) - print(type(i)) - try: - if i.instrument > 119: - pass - else: - commands.append( - f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}=" - f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~{127 - i.velocity} " - f"~ playsound {i.instrument}{i.CD}.{i.pitch} @s ~ ~ ~ 1000 1.0 1000\n") - if isProsess: - commands.append( - f"execute @a{playerSelection} ~ ~ ~ execute @s[scores={{{ScoreboardName}=" - f"{str(round_up(i.time_position)).replace('.0', '')}}}] ~ ~ ~ " - f"title @s actionbar §e▶ 播放中: §a{j}/{length} || {int(j / length * 1000) / 10}\n") - j += 1 - except: - pass - # a += List[i][1] - # commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - print(commands) - return commands - - -def classList_conversion(List: list, ScoreboardName: str, isProsess: bool = False) -> list: - from bgArrayLib.compute import round_up - commands = [] - length = len(List) - j = 1 - print(List) - for k in range(len(List)): - i = List[k][0] - print(i) - print(type(i)) - try: - if i.instrument > 119: - pass - else: - commands.append("execute @e[scores={" + - ScoreboardName + "=" + str(round_up(i.time_position)).replace(".0", "") + "}] ~ ~" + - str(127 - i.velocity) + - " ~ playsound " + - str(i.instrument) + - str(i.CD) + "." + - str(i.pitch) - + " @a ~ ~ ~ 1000 1.0 1000\n") - if isProsess: - commands.append("execute @a"" ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + - str(round_up(i.time_position)).replace(".0", "") + - "}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a" + - str(j) + "/" + str(length) + " || " + str(int(j / length * 1000) / 10) + "\n") - j += 1 - except AttributeError: - pass - # a += List[i][1] - # commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - print(commands) - return commands - - -def formCmdBlock(direction: Iterable, command: str, particularValue: int, impluse: int = 0, condition: bool = False, - needRedstone: bool = True, tickDelay: int = 0, customName: str = '', lastOutput: str = '', - executeOnFirstTick: bool = False, trackOutput: bool = True): - """ - 使用指定项目返回指定的指令方块格式字典 - :param direction: `list[x: int, y: int, z: int]` - 方块位置 - :param command: `str` - 指令 - :param particularValue: - 方块特殊值,即朝向 - :0 下 无条件 - :1 上 无条件 - :2 z轴负方向 无条件 - :3 z轴正方向 无条件 - :4 x轴负方向 无条件 - :5 x轴正方向 无条件 - :6 下 无条件 - :7 下 无条件 - - :8 下 有条件 - :9 上 有条件 - :10 z轴负方向 有条件 - :11 z轴正方向 有条件 - :12 x轴负方向 有条件 - :13 x轴正方向 有条件 - :14 下 有条件 - :14 下 有条件 - 注意!此处特殊值中的条件会被下面condition参数覆写 - :param impluse: `int 0|1|2` - 方块类型 - 0脉冲 1循环 2连锁 - :param condition: `bool` - 是否有条件 - :param needRedstone: `bool` - 是否需要红石 - :param tickDelay: `int` - 执行延时 - :param customName: `str` - 悬浮字 - :param lastOutput: `str` - 上次输出字符串,注意此处需要留空 - :param executeOnFirstTick: `bool` - 执行第一个已选项(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) - :param trackOutput: `bool` - 是否输出 - - :return: 指令方块字典结构,如下 - """ - ''' - :param block: { - "direction": [x: int, y: int, z: int] #方块位置 - "block_name": str, #方块名称(无需指定,默认为command_block) - "particular_value": int, #方块特殊值 - "impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32 - "command": str, #指令 - "customName": str, #悬浮字 - "lastOutput": str, #上次输出 - "tickdelay": int, #方块延时 int32 - "executeOnFirstTick": int, #执行第一个选项 1 bytes - "trackOutput": int, #是否输出 1 bytes - "conditional": int, #是否有条件 1 bytes - "needRedstone": int #是否需要红石 1 bytes - } - ''' - # for particularValue, is like this - # :0 下 无条件 - # :1 上 无条件 - # :2 z轴负方向 无条件 - # :3 z轴正方向 无条件 - # :4 x轴负方向 无条件 - # :5 x轴正方向 无条件 - print(f"==[DEBUG]=={direction}: {command} {'下' if particularValue == 0 else '上' if particularValue ==1 else 'z-' if particularValue ==2 else 'z+' if particularValue==3 else 'x-' if particularValue==4 else 'x+'} {'脉冲' if impluse==0 else '循环' if impluse ==1 else '连锁'} {'有条件' if condition else '无条件'} {'需要红石' if needRedstone else '不需要红石'}") - return {"direction": direction, - "block_name": "command_block", - "particular_value": particularValue, - "impluse": impluse, - "command": command, - "customName": customName, - "lastOutput": lastOutput, - "tickdelay": tickDelay, - "executeOnFirstTick": executeOnFirstTick, - "trackOutput": trackOutput, - "conditional": condition, - "needRedstone": needRedstone - } - - -def note2bdx(filePath: str, dire: list, Notes: list, ScoreboardName: str, Instrument: str, - PlayerSelect: str = '', isProsess: bool = False, height: int = 200): - """使用方法同Note2Cmd - :param 参数说明: - filePath: 生成.bdx文件的位置 - dire: 指令方块在地图中生成的起始位置(相对位置) - Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 - 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) - ScoreboardName: 用于执行的计分板名称 - Instrument: 播放的乐器 - PlayerSelect: 执行的玩家选择器 - isProsess: 是否显示进度条(会很卡) - height: 生成结构的最高高度 - :return 返回一个BdxConverter类,同时在指定位置生成.bdx文件""" - - from nmcsup.trans import Note2Cmd - from msctspt.bdxOpera_CP import BdxConverter - cmd = Note2Cmd(Notes, ScoreboardName, Instrument, PlayerSelect, isProsess) - cdl = [] - - for i in cmd: - if '#' in i: - if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''): - cdl.append(i[:i.index('#')]) - else: - cdl.append(i) - i = 0 - down = False - blocks = [formCmdBlock(dire, cdl.pop(0), 1, 1)] - dire[1] += 1 - for j in cdl: - if dire[1] + i > height: - dire[0] += 1 - i = 0 - down = not down - if dire[1] + i == height: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 5, 2, False, False)) - else: - if down: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 0, 2, False, False)) - else: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 1, 2, False, False)) - i += 1 - del i, cdl, down, cmd - return BdxConverter(filePath, 'Build by RyounMusicreater', blocks) - - - -def music2cmdBlocks(direction: Iterable, music: dict, isProsess: bool = False, height: int = 200, - isSquare: bool = False): - """使用方法同Note2Cmd - :param 参数说明: - filePath: 生成.bdx文件的位置 - dire: 指令方块在地图中生成的起始位置(相对位置) - music: 详见 Musicreater.py - dataset[0] - isProsess: 是否显示进度条(会很卡) - height: 生成结构的最高高度 - isSquare: 生成的结构是否需要遵循生成正方形原则 - :return 返回一个列表,其中包含了音乐生成的所有的指令方块数据""" - from msctspt.threadOpera import NewThread - - - allblocks = [] - '''需要放置的方块''' - baseDire = direction - - direction = list(direction) - - def trackDealing(direction,track): - # print('=========DEBUG=========音轨起方块:', direction) - blocks = [] - cmdList = classList_conversion_SinglePlayer(track['notes'], track['set']['ScoreboardName'], - music['mainset']['PlayerSelect'], isProsess) - if len(cmdList) == 0: - return [] - elif cmdList is []: - return [] - dire = direction.copy() - down = False - '''当前是否为向下的阶段?''' - # 开头的指令方块 - blocks.append(formCmdBlock(dire, - f"scoreboard players add @a{music['mainset']['PlayerSelect']} " - f"{track['set']['ScoreboardName']} 1", - 1, 1)) - dire[1] += 1 - blocks.append(formCmdBlock(dire, cmdList.pop(0), 2, needRedstone=False)) - dire[1] += 1 - # :0 下 无条件 - # :1 上 无条件 - # :2 z轴负方向 无条件 - # :3 z轴正方向 无条件 - # :4 x轴负方向 无条件 - # :5 x轴正方向 无条件 - for cmd in cmdList: - # print('=========DEBUG=========方块:', dire) - blocks.append(formCmdBlock(dire, cmd, 5 if (down is False and dire[1] == height + direction[1]) or ( - down and dire[1] == direction[1] + 1) else 0 if down else 1, 2, needRedstone=False)) - if down: - if dire[1] > direction[1] + 1: - dire[1] -= 1 - else: - if dire[1] < height + direction[1]: - dire[1] += 1 - - if (down is False and dire[1] == height + direction[1]) or (down and dire[1] == direction[1] + 1): - down = not down - dire[0] += 1 - return blocks - - threads = [] - for track in music['musics']: - threads.append(NewThread(trackDealing,(direction.copy(),track))) - threads[-1].start() - direction[2] += 2 - - for th in threads: - allblocks += th.getResult() - - print(allblocks) - return allblocks - - - - - - - - - - - -def music2BDX(filePath: str, direction: Iterable, music: dict, isProsess: bool = False, height: int = 200, - isSquare: bool = False): - """使用方法同Note2Cmd - :param 参数说明: - filePath: 生成.bdx文件的位置 - dire: 指令方块在地图中生成的起始位置(相对位置) - music: 详见 Musicreater.py - dataset[0] - isProsess: 是否显示进度条(会很卡) - height: 生成结构的最高高度 - isSquare: 生成的结构是否需要遵循生成正方形原则 - :return 返回一个BdxConverter类,同时在指定位置生成.bdx文件""" - from msctspt.bdxOpera_CP import BdxConverter - return BdxConverter(filePath, 'Build by Ryoun Musicreater', music2cmdBlocks(direction,music,isProsess,height,isSquare) -) - - -def note2webs(Notes: list, Instrument: str, speed: float = 5.0, PlayerSelect: str = '', isProsess: bool = False): - """传入音符,在oaclhost:8080上建立websocket服务器以供我的世界connect/wssever指令连接 - :param 参数说明: - Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 - 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) - Instrument: 播放的乐器 - speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍 - PlayerSelect: 执行的玩家选择器 - isProsess: 是否显示进度条 - :return None""" - - import time - import fcwslib - # import asyncio - from nmcsup.log import log - from nmcsup.vers import VER - - async def run_server(websocket): # , path - log('服务器连接创建') - await fcwslib.tellraw(websocket, '已连接服务器——音·创' + VER[1] + VER[0] + ' 作者:金羿(W-YI)') - length = len(Notes) - j = 1 - for i in range(len(Notes)): - await fcwslib.send_command(websocket, - f'execute @a{PlayerSelect} ~ ~ ~ playsound {Instrument} @s ~ ~ ~ 1000 ' - f'{Notes[i][0]} 1000') - if isProsess: - await fcwslib.send_command(websocket, - 'execute @a' + PlayerSelect + ' ~ ~ ~ title @s actionbar §e▶ 播放中: §a' + - str( - j) + '/' + str(length) + ' || ' + str(int(j / length * 1000) / 10)) - j += 1 - time.sleep(Notes[i][1] / speed) - - fcwslib.run_server(run_server) - - -def note2RSworld(world: str, startpos: list, notes: list, instrument: str, speed: float = 2.5, - posadder: Iterable = (1, 0, 0), baseblock: str = 'stone'): # -> bool - """传入音符,生成以音符盒存储的红石音乐 - :param 参数说明: - world: 地图文件的路径 - startpos: list[int,int,int] 开始生成的坐标 - notes: list[list[float,float]] 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] - 格式存储的音符列表 例如Musicreater.py的dataset[0]['musics'][NowMusic]['notes'] - instrument: 播放的乐器 - speed: 一拍占多少个中继器延迟(红石刻/rt) - posadder: list[int,int,int] 坐标增加规律,即红石的延长时按照此增加规律增加坐标 - baseblock: 在中继器下垫着啥方块呢~ - :return 是否生成成功 - """ - - from msctspt.values import height2note, instuments - - def formNoteBlock(note: int, instrument1: str = 'note.harp', powered: bool = False): - """生成音符盒方块 - :param powered: - :param instrument1: - :param note: 0~24 - :return Block()""" - if powered: - powered = 'true' - else: - powered = 'false' - return Block('universal_minecraft', 'notebooks', - {"instrument": ts(instrument1.replace("note.", '')), 'note': ts(str(note)), - 'powered': ts(powered)}) - - def formRepeater(delay: int, facing: str, locked: bool = False, powered: bool = False): - """生成中继器方块 - :param powered: - :param locked: - :param facing: - :param delay: 1~4 - :return Block()""" - if powered: - powered = 'true' - else: - powered = 'false' - if locked: - locked = 'true' - else: - locked = 'false' - return Block('universal_minecraft', 'repeater', - {"delay": ts(str(delay)), 'facing': ts(facing), 'locked': ts(locked), 'powered': ts(powered)}) - - level = amulet.load_level(world) - - def setblock(block: Block, pos: list): - """pos : list[int,int,int]""" - cx, cz = bc2cc(pos[0], pos[2]) - chunk = level.get_chunk(cx, cz, "minecraft:overworld") - offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz - chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(block) - chunk.changed = True - - # 1拍 x 2.5 rt - def placeNoteBlock(): - for i in notes: - error = True - try: - setblock(formNoteBlock(height2note[i[0]], instrument), [startpos[0], startpos[1] + 1, startpos[2]]) - setblock(Block("universal_minecraft", instuments[i[0]][1]), startpos) - error = False - except ValueError: - log("无法放置音符:" + str(i) + '于' + str(startpos)) - setblock(Block("universal_minecraft", baseblock), startpos) - setblock(Block("universal_minecraft", baseblock), [startpos[0], startpos[1] + 1, startpos[2]]) - finally: - if error is True: - log("无法放置音符:" + str(i) + '于' + str(startpos)) - setblock(Block("universal_minecraft", baseblock), startpos) - setblock(Block("universal_minecraft", baseblock), [startpos[0], startpos[1] + 1, startpos[2]]) - delay = int(i[1] * speed + 0.5) - if delay <= 4: - startpos[0] += 1 - setblock(formRepeater(delay, 'west'), [startpos[0], startpos[1] + 1, startpos[2]]) - setblock(Block("universal_minecraft", baseblock), startpos) - else: - for j in range(int(delay / 4)): - startpos[0] += 1 - setblock(formRepeater(4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]]) - setblock(Block("universal_minecraft", baseblock), startpos) - if delay % 4 != 0: - startpos[0] += 1 - setblock(formRepeater(delay % 4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]]) - setblock(Block("universal_minecraft", baseblock), startpos) - startpos[0] += posadder[0] - startpos[1] += posadder[1] - startpos[2] += posadder[2] - - # e = True - try: - placeNoteBlock() - # e = False - except: # ValueError - log("无法放置方块了,可能是因为区块未加载叭") - # finally: - # if e: - # log("无法放置方块了,可能是因为区块未加载叭") - level.save() - level.close() - - -class ryStruct: - - def __init__(self, world: str) -> None: - - self.RyStruct = dict() - self._world = world - self._level = amulet.load_level(world) - - def reloadLevel(self): - # e = True - try: - self._level = amulet.load_level(self.world) - # e = False - except: # ValueError - log("无法重载地图") - # finally: - # if e: - # log("无法重载地图") - - def closeLevel(self): - # e = True - try: - self._level.close() - # e = False - except: # ValueError - log("无法关闭地图") - # finally: - # if e: - # log("无法重载地图") - - def world2Rys(self, startp: list, endp: list, includeAir: bool = False): - """将世界转换为RyStruct字典,注意,此函数运行成功后将关闭地图,若要打开需要运行 reloadLevel - :param startp: [x,y,z] 转化的起始坐标 - :param endp : [x,y,z] 转换的终止坐标,注意,终止坐标需要大于起始坐标,且最终结果包含终止坐标 - :param includeAir : bool = False 是否包含空气,即空气是否在生成之时覆盖地图内容 - :return dict RyStruct """ - - level = self._level - - for x in range(startp[0], endp[0] + 1): - for y in range(startp[1], endp[1] + 1): - for z in range(startp[2], endp[2] + 1): - - RyStructBlock = dict() - - cx, cz = bc2cc(x, z) - chunk = level.get_chunk(cx, cz, "minecraft:overworld") - universal_block = chunk.block_palette[chunk.blocks[x - 16 * cx, y, z - 16 * cz]] - if universal_block == Block("universal_minecraft", "air") and includeAir: - continue - universal_block_entity = chunk.block_entities.get((x, y, z), None) - - RyStructBlock["block"] = str(universal_block) - RyStructBlock["blockEntity"] = str(universal_block_entity) - - log("载入方块数据" + str(RyStructBlock)) - - self.RyStruct[(x, y, z)] = RyStructBlock - - level.close() - - return self.RyStruct - - -""" -RyStruct = { - (0,0,0) = { - "block": str 完整的方块结构 - "blockEntity": str | 'None' - } -} -""" diff --git a/msctspt/values.py b/msctspt/values.py deleted file mode 100644 index 8a7bfc5..0000000 --- a/msctspt/values.py +++ /dev/null @@ -1,56 +0,0 @@ -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:40个 - -instuments = { - 'note.banjo': ['班卓琴', 'hay_block'], - 'note.bass': ['贝斯', 'planks'], - 'note.bassattack': ['低音鼓/贝斯', 'log'], - 'note.bd': ['底鼓', 'stone'], # 即basedrum - 'note.bell': ['铃铛/钟琴', 'gold_block'], - 'note.bit': ['比特/“芯片”(方波)', 'emerald_block'], - 'note.chime': ['管钟', 'packed_ice'], - 'note.cow_bell': ['牛铃', 'soul_sand'], - 'note.didgeridoo': ['迪吉里杜管', 'pumpkin'], - 'note.flute': ['长笛', 'clay'], - 'note.guitar': ['吉他', 'wool'], - 'note.harp': ['竖琴/钢琴', 'concrete'], # 任意其他类型的方块皆可 - 'note.hat': ['击鼓沿/架子鼓', 'glass'], - 'note.iron_xylophone': ['“铁木琴”(颤音琴)', 'iron_block'], - 'note.pling': ['“扣弦”(电钢琴)', 'glowstone'], - 'note.snare': ['小军鼓', 'sand'], - 'note.xylophone': ['木琴', 'bone_block'] -} -'''乐器对照表\n -乐器英文:[中文, 对应音符盒下方块名称] -注:方块仅取一个''' - -height2note = { - 0.5: 0, - 0.53: 1, - 0.56: 2, - 0.6: 3, - 0.63: 4, - 0.67: 5, - 0.7: 6, - 0.75: 7, - 0.8: 8, - 0.84: 9, - 0.9: 10, - 0.94: 11, - 1.0: 12, - - 1.05: 13, - 1.12: 14, - 1.2: 15, - 1.25: 16, - 1.33: 17, - 1.4: 18, - 1.5: 19, - 1.6: 20, - 1.7: 21, - 1.8: 22, - 1.9: 23, - 2.0: 24, -} -'''音高对照表\n -MC音高:音符盒音调''' diff --git a/nmcsup/EptWorld.zip b/nmcsup/EptWorld.zip deleted file mode 100644 index 4a075aa0b3f315ffaf82e96238d36116fdc28560..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19085 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

cp_(kZKKc2!G~Um z9za|lnvTNl8uB==wbAwXG?_PB5mpNOle@tA{4k?-f*c+~!oFjv23Su&+%?3^IY6zc z!3Re7G<2r@y*OgwoX`CIb+YK2PJjQ011IarN#?KbL+#UU^G-Xd`e~0Z#|l~O)QBui zroddn(`rbE4ruw#+6my&&9xahF)_}ni!zEWy`nXALK_Ay_FIv2TnouxB0?YXKM z`F^mH{R@R|;h5nMQicUos5P-Vc=Yk378l`4z3zRY#MxqrB)L7*a59hHy z`3fTeeuFonx1;XAe>ZT@f&flTMVn34GWJ6AuXzN@w+dGZbWsnZOO#w-v6_31--rn;<}4k`nGk;f-<9*Ili5x!Ig z8v2UfJ#SAs{M4=-92G>$@K&a6!~QNY3GS>J!xB}F4C*faHds=8q-W?u# ztb(G0S$%L6_YRIEe@S{ec**FN^GgWWt#YN|sAGo)8e<^3nifi#Lrt1ymD{q_?`CvJ zbBGXV!nme&kp}vVj>3*OHTPe_34Woe7a99GWpk40o|0lUwSQsG;Kw?^nVa|0Tg%vp zSq&yw!9*Avx-8w{u-}ynG5M&sE8ZdB%pGj%>|1NR^H(|h*cM_O_a0Hs(7H*_=T<#p zLeeo#!ghA-_Q76|d2sv-tt*o(HnvPy)fXlf25;dsXS=*Bw17SJ6AL&SAA+dy#nKXl zdXPTwLk1^32NY?Rjn}fq%@)*R0wTBUnAct~%&Cwgpln%KTsWw_`{g+^HtAx7n}#~% z0aSQY76mD0y`C|^86#WOE-ZlCtKF8o`pW8r7a@5aJ&UW$iCu4_4h1y6v8j-81*uqV z|0mkg!9N8?ojFPq5{5*_oa$LQHRYioVQwiU?M`jCVFXUkgUDErtM(|PDKl+$ zNx%Xx>xJh*NhLj21~#i4i%Ry1d!htgVw-!uGrOMh0nH47eKwi*kPkR|^%gr&XT3rg;C_&Um z%OGAMihHlmF$%8to``(XhRr=%EshWw2j@yQ`a?NSNj9Zg zlk7qAhEh*c%}GJj2x}G@;P-Bzt=$cgv(Dlt#fIj>I{c5#>z4BFmHd{U_^kuK?HT0|X3MAJzTY;pa z>6g|1WW54@eJ2#?Hm&hL`l0|{-xme&3;=(3NddP0;~>BeS^o5JpshCmzZc(i#X&NF KTN8i=5a?ga=@F3t diff --git a/nmcsup/MMFM Cpp E Develop Log.txt b/nmcsup/MMFM Cpp E Develop Log.txt deleted file mode 100644 index 0ec7376..0000000 --- a/nmcsup/MMFM Cpp E Develop Log.txt +++ /dev/null @@ -1,62 +0,0 @@ -ҵ硷 -C++汾־ - -ڱ˼ƻѧҵԭ򣬱ӳټƻʼд롣 - - Beta V0.1 - 20200920 -0.help -1.make -2.form -3.exit -4.ܹCDEFGABת.mcfunction -5.н - - Beta V0.2 - 20200921 -0.޸makeΪwrite -1.ôʵ -2.üƷְ -3.趨 -4.ѭģʽ趨 -5.""һֱ,޸ijΪ"ҵ纯" - - Beta V0.3 - 20200922 -0.޸writeΪmake -1.ʵ趨 -2.Ʒְ趨 -3.趨 - - Beta V0.4 - 20200923 -0.ļ趨 -1.bug:ָдļ(DE001) -2.verʾ汾Ϣ - - Beta V0.5 - 20200925 -0.޸makeΪwrite -1.趨ļ· -2.֧ɼ1234567ʾ -3.ֹ֧0 - - Beta V0.6 - 20200926 -0.޸writeΪmake -1.޸bug:ָдļ(DE001) -2.buld -3.comd -4.help򿪵İ˵һҳΪҳ -5.дڴСԶ - - Beta V0.7 - 20200927 -0.mdir,ֱ -1.ldir,Բ鿴ǰĿ¼Ϣ -3.ָlook,ʾָıļ -4.ɾ˳ʱĵȴʾ -5.bug:ʹlook鿴ļмʿ޷ʾʾ">>>"(DE002DE003) -6.bug:mdir޷ʹ(DE004) - -TO-DO Beta V0.8_ - 20200929 -0.ʵ,ڹڼԵõһйַ -1.ʵ,ڼԵõһַ -˰汾ֱ - - Beta V0.9 - 20201224 -0.޸bug:mdir޷ʹ(DE004) -1.bug:mdirһֹͣ(DE005) \ No newline at end of file diff --git a/nmcsup/MMFM Py E Development Log.txt b/nmcsup/MMFM Py E Development Log.txt deleted file mode 100644 index 00eaba5..0000000 --- a/nmcsup/MMFM Py E Development Log.txt +++ /dev/null @@ -1,126 +0,0 @@ -这是MMFM(我的世界函数音乐生成器)的Python版本日志 -我从2021年5月移植,中间停更了一段时间。 - - Beta V 0.0.0 -2021 5 ?15 - 2021 5 23 -1.将C++版本全部有用的功能移植至Python版本 -2.新增了可更改的音乐乐器 -3.新增了可更改的语言包Chinese -4.附带应用"jsonread - lang"可用于新增语言文本 -5.支持全部音阶,但不支持附点、X分音符等 - - Beta V 0.0.1 -2021 6 5 -1.可读取不同的语言文件,通过lang指令完成 -2.新增English语言包 -3.在输入非内部指令时以命令行运行 - - Beta V 0.0.2 -2021 6 13 -1.支持设置项保存 -2.语言设置移至设置项中 -3.新增RESET命令以重置所有设置项至默认 -4.支持休止符(“0”) -5.设置项更加人性化 - - Beta V 0.0.3 -2021 6 14 -1.支持全平台(能运行Python的平台) -2.安卓系统下不需要从源地址运行 -3.设置中给出乐器列表并需要使用在列表内的乐器 - - Beta V 0.0.4 -2021 6 14 -1.新增win指令支持窗口化输入 -2.语言包English停止支持 -3.停止支持的语言包部分将使用Chinese语言包 -4.输出结果更加人性化 -5.停止支持输入非内部命令以系统指令运行 - - Formal V 0.0.1 -2021 6 21 - 2021 6 22 -1*.支持附点、延音等时间延长谱号 -2*.支持X分音符等时间缩短谱号 -3.删除win指令支持的窗口化输入,即禁止窗口运行 -4.新增日志系统,程序运行将载入日志以便检查 -*实际上输入的时候是不支持的,只是支持了修改音符延长时间而已 - - - Formal V 0.0.2 -2121 6 22 -1.解决了字符串解析为列表时出现的问题 -2.停止调整命令行窗口大小 -3.解决了输入的音符被除重的问题 -4.buld指令建立的附加包中新增startXXX函数用于初始设定 - - - Formal V 0.0.3 -2021 6 29 -1.新增save、load指令支持工程文件存取 -2.新增default指令存储默认设置 -3.输入exit指令退出时不会保存为默认设置 -4.新增delog指令在Windows系统下删除日志文件 - - - Formal V 0.0.4 ~ 0.0.4.2 -2021 6 30 -1.支持midi解析,能够通过midi文件解析音符,且仅支持打击乐器,即音长为0的声音,不能解析音的长度,解析仅包含note_on消息而不包含note_off消息,且暂时不能解析音乐附带的其他信息 -2.新增彩蛋指令TAFTCPC(the Anniversary of the Founding of The Communist Party of China) -(0.0.4.1) -3.修复读取文件时读取内容不正确的问题 -(0.0.4.2) - - - Formal V0.0.4.3 -2021 7 1 -1.内部代码优化,更加模块化,便于以后窗口化调用 - - - Formal V0.0.5 ~ 0.0.5.2 -2021 7 3 ~ 2021 7 4 -1.支持同时编辑、生成多个音乐函数 -2.支持一个项目中保存多个文件 -3.支持同一函数中出现不同的乐器 -(0.0.5.1) -4.读取midi文件时支持音长的自动解析读取,并支持选择音轨 -(0.0.5.2) -5.修复了编辑不同乐器时出现闪退的问题 -(0.0.5.2) - - - Formal V0.0.5.3 -2021 7 5 -1.修复了存储工程文件时的崩溃问题 -2.读取midi时支持通过音轨自动生成不同的函数文件 -3.修复了生成函数文件中计分板为浮点数的问题 -4.修复文件路径不正确的问题 -5.新增应用bat脚本(仅Windows):可以快速启动、可以清除日志 -6.新增开发bat脚本(仅Windows):可以快速编译文件并启动测试、可以快速编译文件、可以快速启动测试 - - - Formal V0.0.6 -2021 7 8 - 2021 7 9 -1.停止对非Windows系统环境的支持 -2.支持预听生成的函数,即音乐试听 -3.乐曲修改设置:单个乐曲可包含多个文件序列(多个乐器),歌曲可以有自己单独的曲名、执行实体、执行计分板等独立设置;同时,每个歌曲可包含不同的乐器序列等等 -4.读取的音频格式更新:音符、我的世界音调、频率(Hz),仍是字典:'str' : [ float , float ] -5.单个项目内不包含多首歌曲,但是做了预制功能:可以编辑多个项目(现在暂时不行) -6.不可单独编辑单个音符的乐器 -7.放弃对语言文件的读取的支持 -8.停止支持对已读取的音轨的编辑(即删除edit指令) -9.停止支持全局设置的修改,以及其相关支持(即删除当前的set、reset、default指令) -10.预制支持对于单个音轨设置的修改以及音乐主设置的修改(现在暂时不行) -11.存储的项目结构变为json文件结构,则无需zipfile库 -12.生成的文件包含:支持函数(1个、循环执行)、音乐函数(多个、循环执行)、启动函数(1个、执行一次) -13.发现并修改错误:遇到休止符0时,播放会报错并停止 -14.新增彩蛋指令:RYOUN,生成团队队歌文件及项目 -15.项目更名为“我的世界函数音乐构建” - - - - - - - TO-DO -1.支持从midi文件的元信息中收取音符信息并自动生成 -2.Windows平台下支持窗口化 -3.支持使用WebSocket接口自动播放已编辑的音乐 -4.可以编辑多个项目 -5.能够自动将一个长串的音乐分成多个函数文件 -6.对于单个音轨设置的修改以及音乐主设置的修改 -7.支持汇报崩溃记录(通过邮件附件的方式) \ No newline at end of file diff --git a/nmcsup/NFC Dev Log.txt b/nmcsup/NFC Dev Log.txt deleted file mode 100644 index 87a6740..0000000 --- a/nmcsup/NFC Dev Log.txt +++ /dev/null @@ -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.可编辑音符 \ No newline at end of file diff --git a/nmcsup/NMC Dev Log.txt b/nmcsup/NMC Dev Log.txt deleted file mode 100644 index 1c8a675..0000000 --- a/nmcsup/NMC Dev Log.txt +++ /dev/null @@ -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 diff --git a/nmcsup/__init__.py b/nmcsup/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/nmcsup/__pycache__/__init__.cpython-37.pyc b/nmcsup/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 2871e42259b062ead2cc6f4d901d8c1ac28c30dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmZ?b<>g`k0_!TrBoO@=M8E(ekl_Ht#VkM~g&~+hlhJP_LlHg`kf&kC2i6Hthh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o71j$aS-d3D=GE zj0q^pPcKT$&CSe9k9j$N^V5#mG0Gv?nRz9tMKO7~$;G7wG4b)4d6^~g@p=W7w>WHa Q^HWN5Qtd!Segg`kf*{YYi6Hthh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o71!$n~*`F$m8u z%1QApEzV4KE=o--NiEX#b@L5Y$V)9(NKMHs$;{7-dD=DqMf2X6G6OwxJ=2)H+~nfY hf|&UD%)HE!_;|g7%3B;Zx%nxjIjMFaJ3a$30{~9|DE$Bc diff --git a/nmcsup/__pycache__/const.cpython-38.pyc b/nmcsup/__pycache__/const.cpython-38.pyc deleted file mode 100644 index 54f49db9bd8ccbc0959d80e90a2ce55c59aa69bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6179 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 Nul;}cZ)MF_{|iicBp3hy diff --git a/nmcsup/__pycache__/log.cpython-37.pyc b/nmcsup/__pycache__/log.cpython-37.pyc deleted file mode 100644 index 41528fa6539782dd618b33a3e484099c549de6bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1695 zcmbtV&2Jk;6rb4-@2+E~`D(sOQ&Xu@eW)!V4k#eRrv*|7&;%9j#oBl#$)@XFYi3Q_ z$Q)1;HK3LTRggd{u|5FhK!a2XrD;h1kGUb@q(0?{$R)hl#3AC)3$vOxzj^cC=*@e- znSCRjP9kV8&%HkJhl$Xia?)xE0IxykgBT%#Y(y|oJZ$55RBR<4Ra>PRRcF*lucI3{ zN)VN3b%iKIUr+{+ZBWBDNy4_MMa@2BCn=8FXsV9wG)>R6Q#^Bu7`HJ-RGI0BI!U6A z`8BFUT@ry7N8L0@z!N-r=;=dzL$35hvGmYZONM)&csz(x1(gM)*)L@w_IQ~4|wx<@~u-kgzx z`4nYyFJ8Fl@KWfOX_jX$WiDLwonsiAo|u;@=gt%u3N&8GYC?1U$v_w`zrx&*3d`jm zFxL+$5uGj{iT59ICoa=cz(`4xK|#}@ThQNx&hLW=(F~5D!cdLg5Jjp)7}YQ%p+<11 z_aUM{hguW;wt6S`saDgXL}-NOj2T&y2_!)b$pBfq8UkBO))1pBh$KHmm(j)~|ZHy*C+eDfH}By;cjQ@aa4HP+UiZr*L&T;JRH z{AknvB(Al2W9in;@^6j%52Q0?jrF_RYri~w_-o_$ua6w#DzwaJWl8>LEG^p1S-CQB zL{dgzXHNfUym09y;F3xGQb6D!%{E9z2I4u(Nn#)5j%(8Qp z5|@EKs8C;|#zHn0IxHLq_6a?XSg1T?!X!>eB`1aI2eU$t6DtyjCuj1t$m;RH48RPY z6T~E^1fKjEv9o~obNT6@O!L(BJj(NLQGPWHD*5-S+$}K*yR*DsF7awb-iuu2x=>-v zgCp+(f!b0yi8b7hUjTU?Iy(p2l3Z#v6+q14egME*3_MmO>m-Nk2*W!D{K2DePYfA2 zq{%jj%bf|23hmv|!uz(#r>h|eX8kzi6JiLq6e{(}+W>fcb8rf?^DxV5Ox~dJ!g%(a zFp5PIl!`@`0Tt_zLPo>-q!<7p3`Q%SQ=;s&oM|$rwpDgqzbH#%o0WjOp&R(NHATab zm|4Os7UiXfZO?!cL>FYw22__;sV4OIFTn=X%;8Te5D+asz+ai o9|+<(5SnIU_>>{6DVky`N!+eLRTJ$vB}bf8Oh7Q|LwaxTKUTT@*Z=?k diff --git a/nmcsup/__pycache__/log.cpython-38.pyc b/nmcsup/__pycache__/log.cpython-38.pyc deleted file mode 100644 index 779deb31c10d03544fc2481aff49f08fa9161314..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1710 zcmbtV&2Jk;6rb4-@2)@6=7W5-q^4D+`VdDTkWhpW62hWV6iVw7SXr_*o=LKG zNE?|0YN7_z(x3_wXe8E16gbczRYGYRlK*3Fh-}iFasosy;myVg5r~sW?chjnq7+}!_tKGD#xz^J_W-skMW|s<1 z(T-?WXuXm4%3vk?0^v(-ot|&7wy0I_xJZ=*@22XK9Ip&tgtyw>P!xa29=%LUE+ZvHB-Lyxj0W^Kp?gapd{o8(pbUs~`Y4cvhEW|e z;wuFEY8N6BbikXacjUX-kCeI+#C*-y%X(l4Hjo(61PcUybp*DCz!9Sn^a^?xT}JPt zy2L*9 zCMvMIHn;g?cIT`4om-!8uWvx9ch_#$Zuk?f6Fywr`tmVACF*ZGj*YAb5 zR(IDvX$JjI@eYHB^S8GaehHU;5YCi^tM@inetP=w=kV7rnvM|?hvriPmj9Ux6Sz$q z*(#7kaE4=RTD_Xj^}h;a(y3E&37ldl0aiQhAoj4qaeO$F;*#rerDpjPJVvkEp6_wJ zYF(qmX0YzosKb+2e0IgRn4bswaWzVp%bw4;PAs1aQgYdGr??tbmB$W_%{2I(j2aCL zo)g3bmza2BI3D{Eu|ClLco9TyurSj9!NtNQ=8iL~T7^st2REj0E`Lo>l@*+7$(yVd zAau5NgUc`ufT!060wt0-juqUEUjlg+I!nW9No*Z&GE5>WcY^}-#Xx6CkWWy#fiOI2 zKqEX1S4I;@fHX{v*q$|7p57 zvwhojOk+oNKyetSs(J_2dA66tq(xo_VkpS6P3r>m=$0Z#!7}Y+tv-2Oj1psyc diff --git a/nmcsup/__pycache__/log.cpython-39.pyc b/nmcsup/__pycache__/log.cpython-39.pyc deleted file mode 100644 index bab33501763228c19c70371fa645bb2f8d71462a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747 zcmbtV-A^1<6u);qc4n4c%9nh#(zT{Z_kjfyjSVrz*tpSzq7e)_A=wOjFEH!w%;wHe zD8UBo*;t-^Ju)i^1eI=w2sAh#(UYOr#<%iKq)w2QoFPnL3G?1~sVOhRis{K^;w0u$iRELOsQWQ$)LgF``nTA!sDA z3ihU{6f_A9tT!={JlXjl)O9rQD zOSCGq&PaP|_M{0;cSbxUc~>Fzjk#K+S7>oY z%fNh`vY8jpU$DHqZM zr{M+UIlTx+&j%o9CH9RUe_9-Y|E$b@_UnSgY!s2i0g1ZFzaZ^+3YsWFUutW!QvG=4 zz;INCzEt)0O1SiWSyW|reR1pYLhY-i+O^NOH#VXCyX)7>SN#ds3Gd&oe)$OC6PVb} z`1ZmN;p*zn#;x$$+V1)%he7{S(4*kt()H@{ui@Pv#b(OFwOd=OzwF$95I*_haASnd zk^7W@>VM|K1eP;KrUb+hJmT1zQQsTNc3%X7>D0-)1Wr+_1Fu>$h&^m@93Mz0x#W6W zDO>&okI`w{^F6MYtPd%%8Q9%2b$DXXXM?`Q{2`zuSEF>f?D>rA#PX>iDwiF1imOpo zdFP_VQrL zp;IZy#kXB&B>eQ=&fJrcE4`VQGcS!erMx#;9)Wjd%2&AzV-JM#nn0ks1dd|`x8p3x zbI@4|ta-6?vdJ)s_}&f*a2x~YCBaa^_X=>4Am9}qfbU8ZXMzfv8nHcVv`D$~)VIvk;QY)FE$x;zeH?PGI&t%+d-Ix9d=LD1DY|xg2rxxf~PM2x}Cg zLkN))>jc3yM$1JjPg$#&DWcq_QL=0&Cr~r>vg<|lF^zHR_eYH5dM+m}2?%=zHbIuK zA}$$rPJ|UTVuA&%MXc6k?IL~Ca!8RfQ=2$Y*lDq3WL;LWe1O9=#*Wnlg!^|P3G|>= z={P{%bv(C7&A3I#p^+=2u3L;ih$?WRPJ#q1Dwh6A$t9CT`YQZzke30WC_08m>cWbo bNV*iq^%5W(tH%j3;<%)P2BX@gwzmEQPihDs diff --git a/nmcsup/__pycache__/nmcreader.cpython-38.pyc b/nmcsup/__pycache__/nmcreader.cpython-38.pyc deleted file mode 100644 index 3d6a0a74db8564ed1edb42d09f8c1350a1496e62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2836 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 YxH}wyO}`gqs-oVDZRmNvXE5IPpVyXMBme*a diff --git a/nmcsup/__pycache__/vers.cpython-37.pyc b/nmcsup/__pycache__/vers.cpython-37.pyc deleted file mode 100644 index d65d352845113a9116a1d53ef5ab77577ef2e792..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2077 zcmZuy?{5@E7@nE^aeLPv;)zs{m`l~fGjPY9N=(JZVkIHL2B{IV!PMhs=q-4wFXHK`T{n|SJ zN9*gek=?#{Zt4ED*8KhUH;bz<8>Mj&n_^rzRd=LFln08jR^NqQ+=fP?8fxGsrg#C@ z35;-Oq)i`}q(&MTTCIU65Fe0QO1U|pAbjnwq5kPR#?vL*tgvR#+mfFI}m=kC-rt}5K`n<9$ac&{cdM2yDJ-|2ykZgUnr{>HqTWv zk~RWONFEr%D?2jK%FGQ6UU0`*pgFEg8@8@?6SjHVC_6&tqAnj`=NH7gA}|>Ok{_dn2=R3`@S!nB4-83c-E~Hh3{n*B{JSj5Gz(I9t@s_uf;ZKP^=gCk_>(h z6R0||$R?~~sD$@Iv_l~s2C9Y>+6zWVbW{QQU^Km}rs(iWT>}cBi5O2xLc#6>T3}Qo z6sXaMs1c1PlZO#C;WA_X^N^^0<5KI!oz|ZhmmVy%KflqsbE|dz%*qdQ;0d7uMw?2=Av)+v7WTfvFGEzA1 zc*!qh81*wnH!GZqS7sw=Eg)6FpMvax;c*4O9%yd$gl!zyzjrhjXxw)>NIyb7gr4`P z*p*D2APzNz@J(QWM8|Ox)YsIM4k_tF3s{_$ zIt6`Uh&GK*Ojj}RnH>+zrbdIDf4vTBZN_Q<=~hHz(Y)zx;e{mOLR3t9=%4)bFaq$c z56~g>F_PA}Qa)Uu`}2m(amd^oW{xkQy1wq4M6^;(SL-!M-KZJVoX{>{o|hJQ6V#d` zTi5b#$g1|c`-%JA9`1MZ#{FKvlbhD>_%nlAK%B1VWjuLh<-t7Ye(CP5h(wWc|Iec! zHgxdd@X&`tv;9ZbiQ`B`6lG?pD4i)bT#yBkQI3#h?aPZDqRsX^_ECUOguD!JVkE$v ztH(9n#Wz70=w3mV0+UUHTt#4xGs)bkP;7x!DNHcxa1rQLPl^2mcR-+uAwe9(O3RMR zL@2tnX=|WSTQ38x0(>l_UVx`;QuHG7DIr7*G>fGPn7aoY;w5Mh*#gwtjJMzgFz<(XMKxI!^&F`)gtSb75h=S4zlbLM1c00xkaLZI>M>3meiEjw&YxSp ze|X+G|!bqqa*7a^|X{KfxR=*YR?fVbV_Cx6a diff --git a/nmcsup/__pycache__/vers.cpython-38.pyc b/nmcsup/__pycache__/vers.cpython-38.pyc deleted file mode 100644 index 465dd05441fcd0f4e3bcda9528ff5380d7fe00ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2081 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 diff --git a/nmcsup/const.py b/nmcsup/const.py deleted file mode 100644 index 817047e..0000000 --- a/nmcsup/const.py +++ /dev/null @@ -1,312 +0,0 @@ -"""音创系列的音符对照表 以及一系列常数""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:109个 - - -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''' diff --git a/nmcsup/log.py b/nmcsup/log.py deleted file mode 100644 index a509a44..0000000 --- a/nmcsup/log.py +++ /dev/null @@ -1,71 +0,0 @@ -"""提供对于音创系列的日志""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个 - -import logging -import os -import datetime - -StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7] -time = StrStartTime - -main_path = './log/' - -position = main_path + time - -logger = logging.getLogger(__name__) -logger.setLevel(level=logging.INFO) - -if not os.path.exists('./log/'): - os.makedirs('./log/') - -# try: -# handler = logging.FileHandler(position + ".logger") -# except FileNotFoundError: -# os.makedirs('./log/') -handler = logging.FileHandler(position + ".logger") -print(position + ".logger") - -handler.setLevel(logging.INFO) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') -handler.setFormatter(formatter) - -console = logging.StreamHandler() -console.setLevel(logging.INFO) - -logger.addHandler(handler) -logger.addHandler(console) - -# import logger - -# 载入日志功能 -StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7] -# logger.setting(StrStartTime) -"""字符串型的程序开始时间""" - - -def log(info: str = '', isWrite: bool = True, isPrinted: bool = False, isLoggerLibRecord: bool = True): - """ - info: 信息 - isPrinted: 是否print(仅限金羿log,python官方的logging照常输出) - isLoggerLibRecord: 是否同时在logger库中记录 - isWrite: 是否write(仅限金羿log,python官方的logging照常输出) - """ - """将信息连同当前时间载入日志""" - # 致后来的开发者:请让金羿的log存在吧,不然他自己都看不懂你们写了什么了 - # 我指的是程序内部 - # ——金羿 - if not os.path.exists('./log/'): - os.makedirs('./log/') - if isWrite: - 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) - if isLoggerLibRecord: - logger.info(info) - - -def end(): - logging.disable(logging.INFO) - logging.shutdown() diff --git a/nmcsup/nmcreader.py b/nmcsup/nmcreader.py deleted file mode 100644 index ffefe49..0000000 --- a/nmcsup/nmcreader.py +++ /dev/null @@ -1,128 +0,0 @@ -"""音创系列的文件读取功能""" - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:3个;语法(一级)错误:22个 - - -from nmcsup.log import log -from nmcsup.const import notes - - - -# 从格式文本文件读入一个音轨并存入一个列表 -def ReadFile(fn: str): # -> list - from nmcsup.trans import note2list - log('打开' + fn + "并读取音符") - try: - nat = open(fn, 'r', encoding='UTF-8').read().split(" ") - del fn - except FileNotFoundError: - 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 msctspt.threadOpera import NewThread - Notes = [] - try: - mid = mido.MidiFile(midfile) - except FileNotFoundError: - log("找不到文件或无法读取文件" + midfile) - return False - # 解析 - ks = list(notes.values()) - - def loadMidi(track1): - datas = [] - for i in track1: - 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 nmcsup.trans import note2list - log("读取文件:" + fn) - try: - with open(fn, 'r', encoding='UTF-8') as c: - dataset = json.load(c) - except FileNotFoundError: - print('找不到文件:' + fn + ",请查看您是否输入正确") - log("丢失" + fn) - return False - for i in range(len(dataset['musics'])): - dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes']) - # 返回 音轨列表 选择器 - return dataset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -if __name__ == '__main__': - # a = midi_conversion("L:\\0WorldMusicCreater-MFMS new edition\\框架\\v0.3.2\\Musicreater\\测试用\\同道殊途标准.mid") - # midi_conversion("L:\\0WorldMusicCreater-MFMS new edition\\框架\\v0.3.2\\Musicreater\\测试用\\" - # "Illusionary_Daytime_--------幻昼.mid") - # a = midi_conversion(r"C:\Users\lc\Documents\MuseScore3\乐谱\架子鼓.mid") - from bgArrayLib.reader import midi_conversion - a = midi_conversion(r"C:\Users\lc\Documents\MuseScore3\乐谱\stay2.mid") - # print(a) diff --git a/nmcsup/trans.py b/nmcsup/trans.py deleted file mode 100644 index adc532c..0000000 --- a/nmcsup/trans.py +++ /dev/null @@ -1,246 +0,0 @@ -"""音创系列的转换功能""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:2个;语法(一级)错误:192个 - - -from nmcsup.log import log - -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 - - -# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float -def note2list(Notes: list) -> list: - from 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 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 - 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 - - -# def newDataStructureCounterChange(): - - -# 简单载入方块 -# 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: - # e = True - try: - if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''): - cdl.append(i[:i.index('#')]) - # e = False - except: - cdl.append(i) - # finally: - # if e is True: - # 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 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 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]) diff --git a/nmcsup/vers.py b/nmcsup/vers.py deleted file mode 100644 index f89ce58..0000000 --- a/nmcsup/vers.py +++ /dev/null @@ -1,86 +0,0 @@ -"""音创系列版本号和版本操作函数""" -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:24个 - - -from msctspt.bugReporter import version -import os - -# 以下下两个值请在 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 -# ———————————————— -# - - -def InstallLibs(now, LIBS1): - """比对库信息并安装库""" - from os import system as run - for i in LIBS1: - if i not 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\\') diff --git a/查看代码数.py b/《作者的自我激励》.py similarity index 96% rename from 查看代码数.py rename to 《作者的自我激励》.py index 4887557..c8e156e 100644 --- a/查看代码数.py +++ b/《作者的自我激励》.py @@ -1,24 +1,24 @@ -# -*- conding: utf8 -*- - -import os -from msctspt.funcOpera import keepart - -m = 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', '') - - if code.startswith('#'): - continue - if code: - print("\t" + code) - m += 1 - else: - pass - -input("\n最终代码行数为:" + str(m)) +# -*- conding: utf8 -*- + +import os +from msctspt.funcOpera import keepart + +m = 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', '') + + if code.startswith('#'): + continue + if code: + print("\t" + code) + m += 1 + else: + pass + +input("\n最终代码行数为:" + str(m))