diff --git a/1.pkl b/1.pkl new file mode 100644 index 0000000..bb555bb Binary files /dev/null and b/1.pkl differ diff --git a/Musicreater.py b/Musicreater.py index 1ffe08f..8bbcce6 100644 --- a/Musicreater.py +++ b/Musicreater.py @@ -1,1375 +1,1584 @@ -# -*- coding: utf-8 -*- -# ! python3 - - -# W-YI 金羿 -# QQ 2647547478 -# 音·创 开发交流群 861684859 -# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com -# 版权所有 Team-Ryoun 金羿 -# 若需转载或借鉴 请附作者 - - -""" - Copyright 2022 Eilles Wan (金羿) - - Licensed under the Apache License, Version 2.0 (the 'License') - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 - -# -----------------------------分割线----------------------------- -# 诸葛亮与八卦阵帮忙修改语法 日期:---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 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__ = 'W-YI (金羿)' -dire = "" -begp = "" -endp = "" - - - -print('建立变量,存入内存,载入字典常量函数') - -# 主体部分 - -# 支持多文件同时操作 - -# dataset[{ 'mainset':{ 'x':'y' }, 'musics': [ { 'set' :{ 'A':'B' } , 'note' : [ [ 'a' , b ], ] }, ] }, ] - -# 编辑: -# 修改主设置: dataset[第几个项目]['mainset']['什么设置'] = '设置啥' -# 修改音乐: dataset[第几个项目]['musics'][第几个音轨]['notes'][第几个音符][音符还是时间(0,1)] = 改成啥 -# 修改音轨设置: dataset[第几个项目]['musics'][第几个音轨]['set']['什么设置'] = '设置啥' -# -# 新增音轨: dataset[第几个项目]['musics'].append(datasetmodelpart) -# -''' -dataset=[ - { - 'mainset':{ - 'PackName':'Ryoun', - 'MusicTitle':'Noname', - 'IsRepeat':False, - 'PlayerSelect':'' - }, - 'musics':[ - { - 'set':{ - 'EntityName':'music_support', - 'ScoreboardName':'music_support', - 'Instrument':'harp', - 'FileName':'Music' - }, - 'notes':[ - [0.0,1.0], - ] - }, - ], - }, - ] -''' - -dataset = [ - { - 'mainset': { - 'PackName': 'Ryoun', - 'MusicTitle': 'Noname', - 'IsRepeat': False, - 'PlayerSelect': '' - }, - 'musics': [ - { - 'set': { - 'EntityName': 'MusicSupport', - 'ScoreboardName': 'MusicSupport', - 'Instrument': 'note.harp', - 'FileName': 'Music' - }, - 'notes': [ - [0.0, 1.0], - ] - }, - ], - }, -] - -is_new_file = True -is_save = True -ProjectName = '' -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 - 若需转载或借鉴 请附作者\n - """ - - print('音·创 正在启动……') - - print('载入日志功能...') - from nmcsup.log import log - 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 FileNotFoundError: - 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 - - 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('程序正常退出') - - try: - global dataset - del dataset - global root - root.destroy() - del root - except FileNotFoundError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,所以既然是pass就随便填一个错误 - pass - - if clearLog: - print(READABLETEXT[2]) - err = True - try: - if os.path.exists('./log/'): - shutil.rmtree('./log/') - if os.path.exists('./logs/'): - shutil.rmtree('./logs/') - if os.path.exists('./cache/'): - shutil.rmtree('./cache/') - err = False - except ZeroDivisionError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,所以既然是pass就随便填一个错误 - print(READABLETEXT[3]) - finally: - if err is True: - print(READABLETEXT[3]) - - exit() - - print('退出命令加载完成!') - - def SaveProject(): - if is_new_file: - # 新的项目相等于另存为 - SaveAsProject() - return - else: - # 旧项目旧存着吧 - 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)) - global is_save - is_save = True - - print('保存项目命令加载完成!') - - def SaveAsProject(): - # 另存为项目 - fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', - filetypes=[(READABLETEXT[108], '.msct'), (READABLETEXT[109], '*')], - defaultextension='Noname.msct') - if fn is None or fn == '': - return - 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)) - global is_save - 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 - 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: - fn = fn[0] - try: - with open(fn, 'r', encoding='UTF-8') as C: - dataset[0] = json.load(C) - - except json.decoder.JSONDecodeError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: - # json.decoder.JSONDecodeError - 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) - - 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(): - ahpw = tk.Tk() - ahpw.title(READABLETEXT[19]) - ahpw.geometry('400x600') # 像素 - - 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 FromMidi(): - 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_): - 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('读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('写入命令加载完成!') - - 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/') - - # 转为空方块世界 - 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[120]) - 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(): - 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[120]) - 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 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 FileNotFoundError: - 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 - - root.title(READABLETEXT[41].format(VER[1] + VER[0])) - root.geometry('900x900') # 像素 - - 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'])) - 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=FromMidi) - editmenu.add_command(label=READABLETEXT[61], command=FromForm) - editmenu.add_command(label=READABLETEXT[62], command=FromText) - # 将子菜单加入到菜单条中 - 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) - # 将子菜单加入到菜单条中 - 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) - - # 创建其他功能菜单 - otherMenu = tk.Menu(main_menu_bar, tearoff=0) - otherMenu.add_command(label=READABLETEXT[75], command=MakeFuncPlayer) - otherMenu.add_separator() - otherMenu.add_command(label=READABLETEXT[76], command=toScbBDXfile) - otherMenu.add_command(label=READABLETEXT[77], command=world2BDX) - otherMenu.add_command(label=READABLETEXT[78], command=world2RyStruct) - 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_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], font=('', 15)) - LabelMusicTitle = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[47], font=('', 15)) - LabelIsRepeat = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[48], font=('', 15)) - LabelPlayerSelect = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[49], 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], font=('', 15)) - LabelScoreboardName = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[43], font=('', 15)) - LabelInstrument = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[44], font=('', 15)) - LabelFileName = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[45], 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 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 - global dataset - 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] - global NowMusic - RefreshMain() - RefreshMusic(NowMusic) - - # 进入窗口消息循环 - root.mainloop() - log('退出') - del filemenu, editmenu, helpmenu, otherMenu - - exitapp() - - -if __name__ == '__main__': - __main__() +# -*- coding: utf-8 -*- +# ! python3 + + +# W-YI 金羿 +# QQ 2647547478 +# 音·创 开发交流群 861684859 +# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com +# 版权所有 Team-Ryoun 金羿 +# 若需转载或借鉴 请附作者 + + +""" + Copyright 2022 Eilles Wan (金羿) + + Licensed under the Apache License, Version 2.0 (the 'License') + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 + +# -----------------------------分割线----------------------------- +# 诸葛亮与八卦阵帮忙修改语法 日期:---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__ = 'W-YI (金羿)' +dire = "" +begp = "" +endp = "" + +print('建立变量,存入内存,载入字典常量函数') + +# 主体部分 + +# 支持多文件同时操作 + +# dataset[{ 'mainset':{ 'x':'y' }, 'musics': [ { 'set' :{ 'A':'B' } , 'note' : [ [ 'a' , b ], ] }, ] }, ] + +# 编辑: +# 修改主设置: dataset[第几个项目]['mainset']['什么设置'] = '设置啥' +# 修改音乐: dataset[第几个项目]['musics'][第几个音轨]['notes'][第几个音符][音符还是时间(0,1)] = 改成啥 +# 修改音轨设置: dataset[第几个项目]['musics'][第几个音轨]['set']['什么设置'] = '设置啥' +# +# 新增音轨: dataset[第几个项目]['musics'].append(datasetmodelpart) +# +''' +dataset=[ + { + 'mainset':{ + 'PackName':'Ryoun', + 'MusicTitle':'Noname', + 'IsRepeat':False, + 'PlayerSelect':'' + }, + 'musics':[ + { + 'set':{ + 'EntityName':'music_support', + 'ScoreboardName':'music_support', + 'Instrument':'harp', + 'FileName':'Music' + }, + 'notes':[ + [0.0,1.0], + ] + }, + ], + }, + ] +''' + +dataset = [ + { + 'mainset': { + 'ReadMethod': 'old', + 'PackName': 'Ryoun', + 'MusicTitle': 'Noname', + 'IsRepeat': False, + 'PlayerSelect': '' + }, + 'musics': [ + { + 'set': { + 'EntityName': 'MusicSupport', + 'ScoreboardName': 'MusicSupport', + 'Instrument': 'note.harp', + 'FileName': 'Music' + }, + 'notes': [ + [0.0, 1.0], + ] + }, + ], + }, +] + +is_new_file = True +is_save = True +ProjectName = '' +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 + 若需转载或借鉴 请附作者\n + """ + + print('音·创 正在启动……') + + print('载入日志功能...') + from nmcsup.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 FileNotFoundError: + 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 nmcsup.nmcreader import midi_conversion + k = midi_conversion(midfile) + if k is False: + tk.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[105].format(midfile)) + return + else: + return k + + print('完成!') + + # 菜单命令 + print('加载菜单命令...') + + def exitapp(): + if os.path.isfile("1.pkl"): + # os.remove("1.pkl") + pass + global is_save + if is_save is not True: + if tkinter.messagebox.askyesno(title=READABLETEXT[1], message=READABLETEXT[106]): + SaveProject() + log('程序正常退出') + + 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(): + if is_new_file: + # 新的项目相等于另存为 + SaveAsProject() + return + else: + try: + # 旧项目旧存着吧 + 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)) + global is_save + is_save = True + except TypeError: + SaveNewProject() + return + + def SaveNewProject(): + if is_new_file: + # 新的项目相等于另存为 + SaveAsNewProject() + return + else: + with open(ProjectName, 'wb') as f: + pickle.dump(dataset, f) + tkinter.messagebox.showinfo(title=READABLETEXT[4], message=READABLETEXT[107].format(ProjectName)) + global is_save + is_save = True + + print('保存项目命令加载完成!') + + def SaveAsProject(): + # 另存为项目 + fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', + filetypes=[(READABLETEXT[108], '.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)) + global is_save + 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 + + def SaveAsNewProject(): + fn = tkinter.filedialog.asksaveasfilename(title=READABLETEXT[5], initialdir=r'./', + filetypes=[(READABLETEXT[108], '.msct'), (READABLETEXT[109], '*')], + defaultextension='Noname.msct') + if fn is None or fn == '': + return + 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)) + global is_save + 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 + 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: + fn = fn[0] + try: + with open(fn, 'r', encoding='UTF-8') as C: + dataset[0] = json.load(C) + + except json.decoder.JSONDecodeError: # 程序规范修改:根据新的语法标准:except后面不能没有错误类型,测试后改为: + # json.decoder.JSONDecodeError + 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 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: + fn = fn[0] + try: + try: + with open(fn, 'rb') as C: + dataset[0] = pickle.load(C) + except IndexError: + with open(fn, 'rb') as C: + dataset[0] = pickle.load(C)[0] + + 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) + + 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(): + ahpw = tk.Tk() + ahpw.title(READABLETEXT[19]) + ahpw.geometry('400x600') # 像素 + + 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 FromMidi(): + 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_): + 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 + + def MidiClass(): + 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_): + 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'] = "new" + + 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('写入命令加载完成!') + + 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 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 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 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 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/') + + 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 scatteredPack + scatteredPack(file) + 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 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[120]) + 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(): + 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[120]) + 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 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 + + root.title(READABLETEXT[41].format(VER[1] + VER[0])) + root.geometry('900x900') # 像素 + + 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[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[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=FromMidi) + editmenu.add_command(label=READABLETEXT[61], command=FromForm) + editmenu.add_command(label=READABLETEXT[62], command=FromText) + editmenu.add_separator() + editmenu.add_command(label=READABLETEXT[148], command=MidiClass) + # 将子菜单加入到菜单条中 + 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) + + # 将子菜单加入到菜单条中 + 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) + + # 创建其他功能菜单 + otherMenu = tk.Menu(main_menu_bar, tearoff=0) + otherMenu.add_command(label=READABLETEXT[75], command=MakeFuncPlayer) + otherMenu.add_separator() + otherMenu.add_command(label=READABLETEXT[76], command=toScbBDXfile) + otherMenu.add_command(label=READABLETEXT[77], command=world2BDX) + otherMenu.add_command(label=READABLETEXT[78], command=world2RyStruct) + 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_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], font=('', 15)) + LabelMusicTitle = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[47], font=('', 15)) + LabelIsRepeat = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[48], font=('', 15)) + LabelPlayerSelect = tk.Label(UpLeftFrame, bg='white', text=READABLETEXT[49], 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], font=('', 15)) + LabelScoreboardName = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[43], font=('', 15)) + LabelInstrument = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[44], font=('', 15)) + LabelFileName = tk.Label(UpRightFrame, bg='white', text=READABLETEXT[45], 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 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 + global dataset + 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] + global NowMusic + RefreshMain() + RefreshMusic(NowMusic) + + # 进入窗口消息循环 + root.mainloop() + log('退出') + del filemenu, editmenu, helpmenu, otherMenu + + exitapp() + + +if __name__ == '__main__': + __main__() diff --git a/README_en.md b/README_en.md index d59401f..1a8686b 100644 --- a/README_en.md +++ b/README_en.md @@ -1,76 +1,76 @@ -# Musicreater - -### Introduction -Musicreater(音·创) is an Eilles(*W-YI*)'s app that is used for creating musics in **Minecraft: Bedrock Edition**. - -Welcome to join our QQ group: 861684859 - -### Framework - -Using *Python* to develop, using Tkinter as a graphics library. - -Support Windows7+ && Linux (that supports Python3.8) - -***ATTENTION TO DEVELOPERS!!! TO SUPPORT DIFFERENT LANGUAGES, PLEASE USE CONSTANT `READABLETEXT` TO OUTPUT!!! IF YOU NEED TO SUPPLEMENT, PLEASE ADD THEM IN SIMPLEFIED CHINESE\'S LANGUAGE FILE(zhCN.py), WHEATHER WHAT LANGUAGE YOU USE!!!*** - - -### Installation - -Comming soon... - -### Run with Source Code - -#### Windows - -0. First, download the source code pack of Musicreater. - [Download from Gitee (Need to Login)](https://gitee.com/EillesWan/Musicreater/repository/archive/master.zip) - [Download from Github](https://github.com/EillesWan/Musicreater/archive/refs/heads/master.zip) -1. Install Python 3.8.10 - [Download the 64-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe) - [Download the 32-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe) -2. After completing installation, we need to install the libraries : - - Open "Start Menu" and find `cmd` - - Run `cmd` as Administrator - - Drag "补全库.py" into the opened window and press Enter -3. After completing installation,double click Musicreater.py to run - -#### Linux - -0. If you 're not sure whether your environment is good enough, please run these commands on Terminal -```bash -sudo apt-get update -sudo apt-get upgrade -sudo apt-get install python3 -sudo apt-get install python3-pip -sudo apt-get install git -``` -1. Now if you are confident enough about your runtime environment, open Terminal on the place which you want to download Musicreater, and run these -```bash -sudo git clone https://gitee.com/EillesWan/Musicreater.git -cd Musicreater -python3 补全库.py -python3 Musicreater.py -``` - - -### Instructions - -1. Just make u understand the Chinese -2. If u dont understand, u can come to the QQ group or email me to ask questions -3. The English Edition is comming soon. - -### Thanks - -1. Thank [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”and so on for the function of Creating the Websocket Server for Minecraft: Bedrock Edition. -2. Thank 昀梦\ for finding and correcting the bugs in the commands that *Musicreater* Created. -3. Thank Charlie_Ping “查理平” for bdx convert funtion. -4. Thank CMA_2401PT for BDXWorkShop as the .bdx structure's operation guide. -5. Thanks for a lot of groupmates who support me and help me to test the program. -6. If u have give me some help but u haven't been in the list, please contact me. - - -### Contact *Eilles(W-YI)*(金羿) - -1. QQ 2647547478 -2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com +# Musicreater + +### Introduction +Musicreater(音·创) is an Eilles(*W-YI*)'s app that is used for creating musics in **Minecraft: Bedrock Edition**. + +Welcome to join our QQ group: 861684859 + +### Framework + +Using *Python* to develop, using Tkinter as a graphics library. + +Support Windows7+ && Linux (that supports Python3.8) + +***ATTENTION TO DEVELOPERS!!! TO SUPPORT DIFFERENT LANGUAGES, PLEASE USE CONSTANT `READABLETEXT` TO OUTPUT!!! IF YOU NEED TO SUPPLEMENT, PLEASE ADD THEM IN SIMPLEFIED CHINESE\'S LANGUAGE FILE(zhCN.py), WHEATHER WHAT LANGUAGE YOU USE!!!*** + + +### Installation + +Comming soon... + +### Run with Source Code + +#### Windows + +0. First, download the source code pack of Musicreater. + [Download from Gitee (Need to Login)](https://gitee.com/EillesWan/Musicreater/repository/archive/master.zip) + [Download from Github](https://github.com/EillesWan/Musicreater/archive/refs/heads/master.zip) +1. Install Python 3.8.10 + [Download the 64-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe) + [Download the 32-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe) +2. After completing installation, we need to install the libraries : + - Open "Start Menu" and find `cmd` + - Run `cmd` as Administrator + - Drag "补全库.py" into the opened window and press Enter +3. After completing installation,double click Musicreater.py to run + +#### Linux + +0. If you 're not sure whether your environment is good enough, please run these commands on Terminal +```bash +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install python3 +sudo apt-get install python3-pip +sudo apt-get install git +``` +1. Now if you are confident enough about your runtime environment, open Terminal on the place which you want to download Musicreater, and run these +```bash +sudo git clone https://gitee.com/EillesWan/Musicreater.git +cd Musicreater +python3 补全库.py +python3 Musicreater.py +``` + + +### Instructions + +1. Just make u understand the Chinese +2. If u dont understand, u can come to the QQ group or email me to ask questions +3. The English Edition is comming soon. + +### Thanks + +1. Thank [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”and so on for the function of Creating the Websocket Server for Minecraft: Bedrock Edition. +2. Thank 昀梦\ for finding and correcting the bugs in the commands that *Musicreater* Created. +3. Thank Charlie_Ping “查理平” for bdx convert funtion. +4. Thank CMA_2401PT for BDXWorkShop as the .bdx structure's operation guide. +5. Thanks for a lot of groupmates who support me and help me to test the program. +6. If u have give me some help but u haven't been in the list, please contact me. + + +### Contact *Eilles(W-YI)*(金羿) + +1. QQ 2647547478 +2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com 3. WeChat WYI_DoctorYI \ No newline at end of file diff --git a/bgArrayLib/__init__.py b/bgArrayLib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bgArrayLib/__pycache__/__init__.cpython-39.pyc b/bgArrayLib/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..727712a Binary files /dev/null and b/bgArrayLib/__pycache__/__init__.cpython-39.pyc differ diff --git a/bgArrayLib/__pycache__/bpm.cpython-39.pyc b/bgArrayLib/__pycache__/bpm.cpython-39.pyc new file mode 100644 index 0000000..7b635ed Binary files /dev/null and b/bgArrayLib/__pycache__/bpm.cpython-39.pyc differ diff --git a/bgArrayLib/__pycache__/compute.cpython-39.pyc b/bgArrayLib/__pycache__/compute.cpython-39.pyc new file mode 100644 index 0000000..511aa40 Binary files /dev/null and b/bgArrayLib/__pycache__/compute.cpython-39.pyc differ diff --git a/bgArrayLib/__pycache__/namesConstant.cpython-39.pyc b/bgArrayLib/__pycache__/namesConstant.cpython-39.pyc new file mode 100644 index 0000000..2d96be4 Binary files /dev/null and b/bgArrayLib/__pycache__/namesConstant.cpython-39.pyc differ diff --git a/bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc b/bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc new file mode 100644 index 0000000..6cf2a36 Binary files /dev/null and b/bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc differ diff --git a/bgArrayLib/bpm.py b/bgArrayLib/bpm.py new file mode 100644 index 0000000..a48aa7a --- /dev/null +++ b/bgArrayLib/bpm.py @@ -0,0 +1,57 @@ +import mido +import numpy + + +def mt2gt(mt, tpb_a, bpm_a): + return round(mt / tpb_a / bpm_a * 60) + + +def get(mf): + mid = mido.MidiFile(mf) + long = mid.length + tpb = mid.ticks_per_beat + bpm = 20 + gotV = 0 + + for track in mid.tracks: + global_time = 0 + for msg in track: + global_time += msg.time + if msg.type == "note_on" and msg.velocity > 0: + gotV = mt2gt(global_time, tpb, bpm) + errorV = numpy.fabs(gotV - long) + last_dic = {bpm: errorV} + if last_dic.get(bpm) > errorV: + last_dic = {bpm: errorV} + bpm += 2 + + while True: + for track in mid.tracks: + global_time = 0 + for msg in track: + global_time += msg.time + if msg.type == "note_on" and msg.velocity > 0: + gotV = mt2gt(global_time, tpb, bpm) + errorV = numpy.fabs(gotV - long) + try: + if last_dic.get(bpm - 2) > errorV: + last_dic = {bpm: errorV} + except TypeError: + pass + bpm += 2 + if bpm >= 252: + break + print(list(last_dic.keys())[0]) + return list(last_dic.keys())[0] + + +def compute(mf): + mid = mido.MidiFile(mf) + answer = 60000000/mid.ticks_per_beat + print(answer) + return answer + + +if __name__ == '__main__': + get(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\Bad style - Time back.mid") + compute(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\Bad style - Time back.mid") diff --git a/bgArrayLib/compute.py b/bgArrayLib/compute.py new file mode 100644 index 0000000..47a0296 --- /dev/null +++ b/bgArrayLib/compute.py @@ -0,0 +1,40 @@ +def round_up(num, power=0): + """ + 实现精确四舍五入,包含正、负小数多种场景 + :param num: 需要四舍五入的小数 + :param power: 四舍五入位数,支持0-∞ + :return: 返回四舍五入后的结果 + """ + try: + print(1 / 0) + except ZeroDivisionError: + digit = 10 ** power + num2 = float(int(num * digit)) + # 处理正数,power不为0的情况 + if num >= 0 and power != 0: + tag = num * digit - num2 + 1 / (digit * 10) + if tag >= 0.5: + return (num2 + 1) / digit + else: + return num2 / digit + # 处理正数,power为0取整的情况 + elif num >= 0 and power == 0: + tag = num * digit - int(num) + if tag >= 0.5: + return (num2 + 1) / digit + else: + return num2 / digit + # 处理负数,power为0取整的情况 + elif power == 0 and num < 0: + tag = num * digit - int(num) + if tag <= -0.5: + return (num2 - 1) / digit + else: + return num2 / digit + # 处理负数,power不为0的情况 + else: + tag = num * digit - num2 - 1 / (digit * 10) + if tag <= -0.5: + return (num2 - 1) / digit + else: + return num2 / digit diff --git a/bgArrayLib/namesConstant.py b/bgArrayLib/namesConstant.py new file mode 100644 index 0000000..32fd831 --- /dev/null +++ b/bgArrayLib/namesConstant.py @@ -0,0 +1,92 @@ +zip_name = {-1: '-1.Acoustic_Kit_打击乐.zip', 0: '0.Acoustic_Grand_Piano_大钢琴.zip', 1: '1.Bright_Acoustic_Piano_亮音大钢琴.zip', + 10: '10.Music_Box_八音盒.zip', 100: '100.FX_brightness_合成特效-亮音.zip', 101: '101.FX_goblins_合成特效-小妖.zip', + 102: '102.FX_echoes_合成特效-回声.zip', 103: '103.FX_sci-fi_合成特效-科幻.zip', 104: '104.Sitar_锡塔尔.zip', + 105: '105.Banjo_班卓.zip', 106: '106.Shamisen_三味线.zip', 107: '107.Koto_筝.zip', 108: '108.Kalimba_卡林巴.zip', + 109: '109.Bagpipe_风笛.zip', 11: '11.Vibraphone_电颤琴.zip', 110: '110.Fiddle_古提琴.zip', 111: '111.Shanai_唢呐.zip', + 112: '112.Tinkle_Bell_铃铛.zip', 113: '113.Agogo_拉丁打铃.zip', 114: '114.Steel_Drums_钢鼓.zip', + 115: '115.Woodblock_木块.zip', 116: '116.Taiko_Drum_太鼓.zip', 117: '117.Melodic_Tom_嗵鼓.zip', + 118: '118.Synth_Drum_合成鼓.zip', 119: '119.Reverse_Cymbal_镲波形反转.zip', 12: '12.Marimba_马林巴.zip', + 13: '13.Xylophone_木琴.zip', 14: '14.Tubular_Bells_管钟.zip', 15: '15.Dulcimer_扬琴.zip', + 16: '16.Drawbar_Organ_击杆风琴.zip', 17: '17.Percussive_Organ_打击型风琴.zip', 18: '18.Rock_Organ_摇滚风琴.zip', + 19: '19.Church_Organ_管风琴.zip', 2: '2.Electric_Grand_Piano_电子大钢琴.zip', 20: '20.Reed_Organ_簧风琴.zip', + 21: '21.Accordion_手风琴.zip', 22: '22.Harmonica_口琴.zip', 23: '23.Tango_Accordian_探戈手风琴.zip', + 24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.zip', 25: '25.Acoustic_Guitar(steel)_钢弦吉他.zip', + 26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.zip', 27: '27.Electric_Guitar_(clean)_清音电吉他.zip', + 28: '28.Electric_Guitar_(muted)_弱音电吉他.zip', 29: '29.Overdriven_Guitar_驱动音效吉他.zip', + 3: '3.Honky-Tonk_Piano_酒吧钢琴.zip', 30: '30.Distortion_Guitar_失真音效吉他.zip', 31: '31.Guitar_Harmonics_吉他泛音.zip', + 32: '32.Acoustic_Bass_原声贝司.zip', 33: '33.Electric_Bass(finger)_指拨电贝司.zip', + 34: '34.Electric_Bass(pick)_拨片拨电贝司.zip', 35: '35.Fretless_Bass_无品贝司.zip', 36: '36.Slap_Bass_A_击弦贝司A.zip', + 37: '37.Slap_Bass_B_击弦贝司B.zip', 38: '38.Synth_Bass_A_合成贝司A.zip', 39: '39.Synth_Bass_B_合成贝司B.zip', + 4: '4.Electric_Piano_1_电钢琴A.zip', 40: '40.Violin_小提琴.zip', 41: '41.Viola_中提琴.zip', 42: '42.Cello_大提琴.zip', + 43: '43.Contrabass_低音提琴.zip', 44: '44.Tremolo_Strings_弦乐震音.zip', 45: '45.Pizzicato_Strings_弦乐拨奏.zip', + 46: '46.Orchestral_Harp_竖琴.zip', 47: '47.Timpani_定音鼓.zip', 48: '48.String_Ensemble_A_弦乐合奏A.zip', + 49: '49.String_Ensemble_B_弦乐合奏B.zip', 5: '5.Electric_Piano_2_电钢琴B.zip', 50: '50.SynthStrings_A_合成弦乐A.zip', + 51: '51.SynthStrings_B_合成弦乐B.zip', 52: '52.Choir_Aahs_合唱“啊”音.zip', 53: '53.Voice_Oohs_人声“哦”音.zip', + 54: '54.Synth_Voice_合成人声.zip', 55: '55.Orchestra_Hit_乐队打击乐.zip', 56: '56.Trumpet_小号.zip', + 57: '57.Trombone_长号.zip', 58: '58.Tuba_大号.zip', 59: '59.Muted_Trumpet_弱音小号.zip', + 6: '6.Harpsichord_拨弦古钢琴.zip', 60: '60.French_Horn_圆号.zip', 61: '61.Brass_Section_铜管组.zip', + 62: '62.Synth_Brass_A_合成铜管A.zip', 63: '63.Synth_Brass_A_合成铜管B.zip', 64: '64.Soprano_Sax_高音萨克斯.zip', + 65: '65.Alto_Sax_中音萨克斯.zip', 66: '66.Tenor_Sax_次中音萨克斯.zip', 67: '67.Baritone_Sax_上低音萨克斯.zip', + 68: '68.Oboe_双簧管.zip', 69: '69.English_Horn_英国管.zip', 7: '7.Clavinet_击弦古钢琴.zip', 70: '70.Bassoon_大管.zip', + 71: '71.Clarinet_单簧管.zip', 72: '72.Piccolo_短笛.zip', 73: '73.Flute_长笛.zip', 74: '74.Recorder_竖笛.zip', + 75: '75.Pan_Flute_排笛.zip', 76: '76.Bottle_Blow_吹瓶口.zip', 77: '77.Skakuhachi_尺八.zip', 78: '78.Whistle_哨.zip', + 79: '79.Ocarina_洋埙.zip', 8: '8.Celesta_钢片琴.zip', 80: '80.Lead_square_合成主音-方波.zip', + 81: '81.Lead_sawtooth_合成主音-锯齿波.zip', 82: '82.Lead_calliope_lead_合成主音-汽笛风琴.zip', + 83: '83.Lead_chiff_lead_合成主音-吹管.zip', 84: '84.Lead_charang_合成主音5-吉他.zip', 85: '85.Lead_voice_合成主音-人声.zip', + 86: '86.Lead_fifths_合成主音-五度.zip', 87: '87.Lead_bass+lead_合成主音-低音加主音.zip', 88: '88.Pad_new_age_合成柔音-新时代.zip', + 89: '89.Pad_warm_合成柔音-暖音.zip', 9: '9.Glockenspiel_钟琴.zip', 90: '90.Pad_polysynth_合成柔音-复合成.zip', + 91: '91.Pad_choir_合成柔音-合唱.zip', 92: '92.Pad_bowed_合成柔音-弓弦.zip', 93: '93.Pad_metallic_合成柔音-金属.zip', + 94: '94.Pad_halo_合成柔音-光环.zip', 95: '95.Pad_sweep_合成柔音-扫弦.zip', 96: '96.FX_rain_合成特效-雨.zip', + 97: '97.FX_soundtrack_合成特效-音轨.zip', 98: '98.FX_crystal_合成特效-水晶.zip', 99: '99.FX_atmosphere_合成特效-大气.zip'} + +mcpack_name = {-1: '-1.Acoustic_Kit_打击乐.mcpack', 0: '0.Acoustic_Grand_Piano_大钢琴.mcpack', + 1: '1.Bright_Acoustic_Piano_亮音大钢琴.mcpack', 10: '10.Music_Box_八音盒.mcpack', + 100: '100.FX_brightness_合成特效-亮音.mcpack', 101: '101.FX_goblins_合成特效-小妖.mcpack', + 102: '102.FX_echoes_合成特效-回声.mcpack', 103: '103.FX_sci-fi_合成特效-科幻.mcpack', 104: '104.Sitar_锡塔尔.mcpack', + 105: '105.Banjo_班卓.mcpack', 106: '106.Shamisen_三味线.mcpack', 107: '107.Koto_筝.mcpack', + 108: '108.Kalimba_卡林巴.mcpack', 109: '109.Bagpipe_风笛.mcpack', 11: '11.Vibraphone_电颤琴.mcpack', + 110: '110.Fiddle_古提琴.mcpack', 111: '111.Shanai_唢呐.mcpack', 112: '112.Tinkle_Bell_铃铛.mcpack', + 113: '113.Agogo_拉丁打铃.mcpack', 114: '114.Steel_Drums_钢鼓.mcpack', 115: '115.Woodblock_木块.mcpack', + 116: '116.Taiko_Drum_太鼓.mcpack', 117: '117.Melodic_Tom_嗵鼓.mcpack', 118: '118.Synth_Drum_合成鼓.mcpack', + 119: '119.Reverse_Cymbal_镲波形反转.mcpack', 12: '12.Marimba_马林巴.mcpack', 13: '13.Xylophone_木琴.mcpack', + 14: '14.Tubular_Bells_管钟.mcpack', 15: '15.Dulcimer_扬琴.mcpack', 16: '16.Drawbar_Organ_击杆风琴.mcpack', + 17: '17.Percussive_Organ_打击型风琴.mcpack', 18: '18.Rock_Organ_摇滚风琴.mcpack', + 19: '19.Church_Organ_管风琴.mcpack', 2: '2.Electric_Grand_Piano_电子大钢琴.mcpack', + 20: '20.Reed_Organ_簧风琴.mcpack', 21: '21.Accordion_手风琴.mcpack', 22: '22.Harmonica_口琴.mcpack', + 23: '23.Tango_Accordian_探戈手风琴.mcpack', 24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.mcpack', + 25: '25.Acoustic_Guitar(steel)_钢弦吉他.mcpack', 26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.mcpack', + 27: '27.Electric_Guitar_(clean)_清音电吉他.mcpack', 28: '28.Electric_Guitar_(muted)_弱音电吉他.mcpack', + 29: '29.Overdriven_Guitar_驱动音效吉他.mcpack', 3: '3.Honky-Tonk_Piano_酒吧钢琴.mcpack', + 30: '30.Distortion_Guitar_失真音效吉他.mcpack', 31: '31.Guitar_Harmonics_吉他泛音.mcpack', + 32: '32.Acoustic_Bass_原声贝司.mcpack', 33: '33.Electric_Bass(finger)_指拨电贝司.mcpack', + 34: '34.Electric_Bass(pick)_拨片拨电贝司.mcpack', 35: '35.Fretless_Bass_无品贝司.mcpack', + 36: '36.Slap_Bass_A_击弦贝司A.mcpack', 37: '37.Slap_Bass_B_击弦贝司B.mcpack', 38: '38.Synth_Bass_A_合成贝司A.mcpack', + 39: '39.Synth_Bass_B_合成贝司B.mcpack', 4: '4.Electric_Piano_1_电钢琴A.mcpack', 40: '40.Violin_小提琴.mcpack', + 41: '41.Viola_中提琴.mcpack', 42: '42.Cello_大提琴.mcpack', 43: '43.Contrabass_低音提琴.mcpack', + 44: '44.Tremolo_Strings_弦乐震音.mcpack', 45: '45.Pizzicato_Strings_弦乐拨奏.mcpack', + 46: '46.Orchestral_Harp_竖琴.mcpack', 47: '47.Timpani_定音鼓.mcpack', 48: '48.String_Ensemble_A_弦乐合奏A.mcpack', + 49: '49.String_Ensemble_B_弦乐合奏B.mcpack', 5: '5.Electric_Piano_2_电钢琴B.mcpack', + 50: '50.SynthStrings_A_合成弦乐A.mcpack', 51: '51.SynthStrings_B_合成弦乐B.mcpack', + 52: '52.Choir_Aahs_合唱“啊”音.mcpack', 53: '53.Voice_Oohs_人声“哦”音.mcpack', 54: '54.Synth_Voice_合成人声.mcpack', + 55: '55.Orchestra_Hit_乐队打击乐.mcpack', 56: '56.Trumpet_小号.mcpack', 57: '57.Trombone_长号.mcpack', + 58: '58.Tuba_大号.mcpack', 59: '59.Muted_Trumpet_弱音小号.mcpack', 6: '6.Harpsichord_拨弦古钢琴.mcpack', + 60: '60.French_Horn_圆号.mcpack', 61: '61.Brass_Section_铜管组.mcpack', 62: '62.Synth_Brass_A_合成铜管A.mcpack', + 63: '63.Synth_Brass_A_合成铜管B.mcpack', 64: '64.Soprano_Sax_高音萨克斯.mcpack', 65: '65.Alto_Sax_中音萨克斯.mcpack', + 66: '66.Tenor_Sax_次中音萨克斯.mcpack', 67: '67.Baritone_Sax_上低音萨克斯.mcpack', 68: '68.Oboe_双簧管.mcpack', + 69: '69.English_Horn_英国管.mcpack', 7: '7.Clavinet_击弦古钢琴.mcpack', 70: '70.Bassoon_大管.mcpack', + 71: '71.Clarinet_单簧管.mcpack', 72: '72.Piccolo_短笛.mcpack', 73: '73.Flute_长笛.mcpack', + 74: '74.Recorder_竖笛.mcpack', 75: '75.Pan_Flute_排笛.mcpack', 76: '76.Bottle_Blow_吹瓶口.mcpack', + 77: '77.Skakuhachi_尺八.mcpack', 78: '78.Whistle_哨.mcpack', 79: '79.Ocarina_洋埙.mcpack', + 8: '8.Celesta_钢片琴.mcpack', 80: '80.Lead_square_合成主音-方波.mcpack', 81: '81.Lead_sawtooth_合成主音-锯齿波.mcpack', + 82: '82.Lead_calliope_lead_合成主音-汽笛风琴.mcpack', 83: '83.Lead_chiff_lead_合成主音-吹管.mcpack', + 84: '84.Lead_charang_合成主音5-吉他.mcpack', 85: '85.Lead_voice_合成主音-人声.mcpack', + 86: '86.Lead_fifths_合成主音-五度.mcpack', 87: '87.Lead_bass+lead_合成主音-低音加主音.mcpack', + 88: '88.Pad_new_age_合成柔音-新时代.mcpack', 89: '89.Pad_warm_合成柔音-暖音.mcpack', 9: '9.Glockenspiel_钟琴.mcpack', + 90: '90.Pad_polysynth_合成柔音-复合成.mcpack', 91: '91.Pad_choir_合成柔音-合唱.mcpack', + 92: '92.Pad_bowed_合成柔音-弓弦.mcpack', 93: '93.Pad_metallic_合成柔音-金属.mcpack', + 94: '94.Pad_halo_合成柔音-光环.mcpack', 95: '95.Pad_sweep_合成柔音-扫弦.mcpack', 96: '96.FX_rain_合成特效-雨.mcpack', + 97: '97.FX_soundtrack_合成特效-音轨.mcpack', 98: '98.FX_crystal_合成特效-水晶.mcpack', + 99: '99.FX_atmosphere_合成特效-大气.mcpack'} + +if __name__ == '__main__': + print(zip_name[0]) diff --git a/bgArrayLib/sy_resourcesPacker.py b/bgArrayLib/sy_resourcesPacker.py new file mode 100644 index 0000000..634f1ba --- /dev/null +++ b/bgArrayLib/sy_resourcesPacker.py @@ -0,0 +1,130 @@ +import os +import pickle +# import tkinter.filedialog +# from namesConstant import zip_name +# from namesConstant import mcpack_name +import bgArrayLib.namesConstant +import shutil +zipN = bgArrayLib.namesConstant.zip_name +mpN = bgArrayLib.namesConstant.mcpack_name + +manifest = { + "format_version": 1, + "header": { + "name": "羽音缭绕-midiout_25.5--音创使用", + "description": "羽音缭绕-midiout_25.0--音创使用", + "uuid": "c1adbda4-3b3e-4e5b-a57e-cde8ac80ee19", + "version": [25, 5, 0] + }, + "modules": [ + { + "description": "羽音缭绕-midiout_25.0--音创使用", + "type": "resources", + "uuid": "c13455d5-b9f3-47f2-9706-c05ad86b3180 ", + "version": [25, 5, 0] + } + ] +} + + +def resources_pathSetting(newPath: str = ""): + if not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath == "": + return [False, 1] # 1:没有路径文件 + elif not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath != "": + path = newPath + with open("./bgArrayLib/resourcesPath.rpposi", 'w') as w: + path = w.write(path) + if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path): + return [True, path, 1] # 1:都有 + elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path): + return [True, path, 2] # 2:有pack + elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path): + return [True, path, 3] # 3:有zip + else: + return [False, 2] # 2:路径文件指示错误 + if os.path.isfile("./bgArrayLib/resourcesPath.rpposi"): + with open("./bgArrayLib/resourcesPath.rpposi", 'r') as f: + path = f.read() + if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path): + return [True, path, 1] # 1:都有 + elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path): + return [True, path, 2] # 2:有pack + elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path): + return [True, path, 3] # 3:有zip + else: + return [False, 2] # 2:路径文件指示错误 + + +def choose_resources(): + global zipN + global mpN + back_list = [] + try: + with open(r"L:\0WorldMusicCreater-MFMS new edition\框架\v0.3.2\Musicreater\1.pkl", 'rb') as rb: + instrument = list(pickle.load(rb)) + print(instrument) + except FileNotFoundError: + try: + with open(r"L:\0WorldMusicCreater-MFMS new edition\框架\v0.3.2\Musicreater\nmcsup\1.pkl", 'rb') as rb: + instrument = list(pickle.load(rb)) + print(instrument) + except FileNotFoundError: + return False + path = resources_pathSetting() + if path.__len__() == 2: + return path + else: + dataT = path[2] + pathT = path[1] + if dataT == 1: + if instrument[1] is True: + index = zipN.get(-1) + percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index + # print(percussion_instrument) + back_list.append(percussion_instrument) + for i in instrument[0]: + ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i)) + # print(ins_p) + back_list.append(ins_p) + print(back_list) + return back_list + elif dataT == 2: + if instrument[1] is True: + index = mpN.get(-1) + percussion_instrument = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + index + # print(percussion_instrument) + back_list.append(percussion_instrument) + for i in instrument[0]: + ins_p = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + str(mpN.get(i)) + # print(ins_p) + back_list.append(ins_p) + print(back_list) + return back_list + elif dataT == 3: + if instrument[1] is True: + index = zipN.get(-1) + percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index + # print(percussion_instrument) + back_list.append(percussion_instrument) + for i in instrument[0]: + ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i)) + # print(ins_p) + back_list.append(ins_p) + print(back_list) + return back_list + + +def scatteredPack(path): + pack_list = choose_resources() + print(pack_list) + print(path) + # os.close("L:/0WorldMusicCreater-MFMS new edition") + # shutil.copy("L:\\shenyu\\音源的资源包\\羽音缭绕-midiout_25.0\\mcpack(国际版推荐)格式_25.0\\0.Acoustic_Grand_Piano_大钢琴.mcpack", + # "L:/0WorldMusicCreater-MFMS new edition") + for i in pack_list: + shutil.copy(i, path) + + +if __name__ == '__main__': + # print(resources_pathSetting(r"L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0")) + choose_resources() diff --git a/fcwslib/__init__.py b/fcwslib/__init__.py index 15b1ac3..19a8fdf 100644 --- a/fcwslib/__init__.py +++ b/fcwslib/__init__.py @@ -1,170 +1,170 @@ -#!/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() +#!/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 index 02e37b7..a0f8b76 100644 --- a/fcwslib/main.py +++ b/fcwslib/main.py @@ -1,160 +1,160 @@ -#!/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() - +#!/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/languages/const2string.py b/languages/const2string.py index 6807a11..06b7c30 100644 --- a/languages/const2string.py +++ b/languages/const2string.py @@ -1,96 +1,96 @@ -# -*- coding:utf-8 -*- - - -# W-YI 金羿 -# QQ 2647547478 -# 音·创 开发交流群 861684859 -# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com -# 版权所有 Team-Ryoun 金羿 -# 若需转载或借鉴 请附作者 - - -""" - Copyright 2022 Eilles Wan (金羿) - - Licensed under the Apache License, Version 2.0 (the 'License') - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 - -# -----------------------------分割线----------------------------- -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:12个 -# 目前我的Pycharm并没有显示任何错误,有错误可以向: -# bgArray 诸葛亮与八卦阵 -# QQ 474037765 或最好加入:音·创 开发交流群 861684859 -# ------------------------- split line----------------------------- -# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022 -# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597 -# At present, my Pycham does not display any errors. If there are errors, you can report them to me -# Bgarray Zhuge Liang and Bagua array -# QQ 474037765 or better join: Musicreater development exchange group 861684859 -# ------------------------- split line----------------------------- - -# 下面为正文 - - -# 将程序中用双引号""括起来的字符串 -# 转为字符串列表 list[str, str, ...] -# 方便进行语言翻译支持。 - -import sys -startWith = 0 - - -def __main__(): - textList = [] - for fileName in sys.argv[1:]: - print('读取文件: {}'.format(fileName)) - fileText = [] - for line in open(fileName, 'r', encoding='utf-8'): - while line.count('"') >= 2: - # 只有上帝看得懂我在写什么。 - if line[ - line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])] in textList: - thisText = textList.index( - line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])]) - else: - thisText = len(textList) - textList.append( - line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])]) - line = line.replace( - line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])], - 'READABLETEXT[{}]'.format(thisText + startWith) - ) - fileText.append(line) - - open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText) - - outFile = open('lang__.py', 'w', encoding='utf-8') - outFile.write('''# -*- coding:utf-8 -*- - -# 由金羿翻译工具生成字符串列表 -# 请在所需翻译文件前from 此文件 import READABLETEXT - - - -READABLETEXT = { -''') - for i in range(len(textList)): - outFile.write(" {}:{},\n".format(i + startWith, textList[i])) - outFile.write('}') - outFile.close() - - -if __name__ == '__main__': - __main__() +# -*- coding:utf-8 -*- + + +# W-YI 金羿 +# QQ 2647547478 +# 音·创 开发交流群 861684859 +# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com +# 版权所有 Team-Ryoun 金羿 +# 若需转载或借鉴 请附作者 + + +""" + Copyright 2022 Eilles Wan (金羿) + + Licensed under the Apache License, Version 2.0 (the 'License') + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开 + +# -----------------------------分割线----------------------------- +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:12个 +# 目前我的Pycharm并没有显示任何错误,有错误可以向: +# bgArray 诸葛亮与八卦阵 +# QQ 474037765 或最好加入:音·创 开发交流群 861684859 +# ------------------------- split line----------------------------- +# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022 +# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597 +# At present, my Pycham does not display any errors. If there are errors, you can report them to me +# Bgarray Zhuge Liang and Bagua array +# QQ 474037765 or better join: Musicreater development exchange group 861684859 +# ------------------------- split line----------------------------- + +# 下面为正文 + + +# 将程序中用双引号""括起来的字符串 +# 转为字符串列表 list[str, str, ...] +# 方便进行语言翻译支持。 + +import sys +startWith = 0 + + +def __main__(): + textList = [] + for fileName in sys.argv[1:]: + print('读取文件: {}'.format(fileName)) + fileText = [] + for line in open(fileName, 'r', encoding='utf-8'): + while line.count('"') >= 2: + # 只有上帝看得懂我在写什么。 + if line[ + line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])] in textList: + thisText = textList.index( + line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])]) + else: + thisText = len(textList) + textList.append( + line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])]) + line = line.replace( + line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])], + 'READABLETEXT[{}]'.format(thisText + startWith) + ) + fileText.append(line) + + open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText) + + outFile = open('lang__.py', 'w', encoding='utf-8') + outFile.write('''# -*- coding:utf-8 -*- + +# 由金羿翻译工具生成字符串列表 +# 请在所需翻译文件前from 此文件 import READABLETEXT + + + +READABLETEXT = { +''') + for i in range(len(textList)): + outFile.write(" {}:{},\n".format(i + startWith, textList[i])) + outFile.write('}') + outFile.close() + + +if __name__ == '__main__': + __main__() diff --git a/languages/enGB.py b/languages/enGB.py index 1705d23..5a444ca 100644 --- a/languages/enGB.py +++ b/languages/enGB.py @@ -1,162 +1,162 @@ -# -*- coding:utf-8 -*- - -# 由金羿翻译工具生成字符串列表 -# 请在所需翻译的文件前from 此文件 import READABLETEXT - - -READABLETEXT = { - 'Translator': (("Eilles Wan (金羿)", True),), - # 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 - 0: "ERROR❌", - 1: "TIPS❗", - 2: "Clearing log(this wont be in the file)", - 3: "Could not clear the temporary files or logs", - 4: "saved", - 5: "New Musicreater Project", - 6: "Select old-type project", - 7: "Select Musicreater Project", - 8: "Cant open:{}, please check if youve entered the right name", - 9: "Musicreat - About", - 10: "Musicreater", - 11: "Ver. {}", - 12: """Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""", - 13: "OK", - 14: "Inpute Notes", - 15: (("- Developers -", False), - ("Eilles Wan (金羿)", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), - ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False)), - # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 - 16: "- Translators -", - # 17:"", - 18: "QQ Group: 861684859", - 19: "Musicreater - Help", - 20: "Select sound file", - 21: "Select MIDI file", - 22: "Select NoteText file", - 23: "Get Note info", - 24: "Write in Note info: {}", - 25: "Select generating file", - 26: "Select generating folder", - 27: "Select generating .mcpack file", - 28: "Input position info", - 29: "Select generating world folder", - 30: "Select generating Function Pack", - 31: "Select .mcfunction file ", - 32: "Select .bdx file ", - 33: "DONE✔", - 34: "Input playing rate", - 35: "Generating", - 36: "Select a world folder", - 37: "Make sure", - 38: "Generate .RyStruct file", - 39: "FAILED❌", - 40: "Report message inpution", - 41: "Musicreater - Eilles - {}", - 42: "ExecutingEntityName: {}", - 43: "ScoreboardName: {}", - 44: "Instrument: {}", - 45: "TrackName: {}", - 46: "PackName: {}", - 47: "MusicTitle: {}", - 48: "IsRepeat?: {}", - 49: "Player'sTargetSelector: {}", - 50: "Modify Main Option", - 51: "Modify Track Option", - 52: "Default Instrument: Enter English\n", - 53: "Open...", - 54: "Open Old Project...", - 55: "Save", - 56: "Save as...", - 57: "Exit", - 58: "File", - 59: "Load tracks from sound", - 60: "Load tracks from Midi", - 61: "Load tracks from Text", - 62: "Input notes to track", - 63: "Edit", - 64: "Generate file...", - 65: "Generate function pack...", - 66: "Generate .mcpack file...", - 67: "Functions(Pack)", - 68: "Save music as blocks into a map", - 69: "Save music as blocks into a exist map...", - 70: "Save music as commands into a map", - 71: "Save music as commands into a exist map...", - 72: "Save music as notebox into a map", - 73: "Save music as notebox into a exist map...", - 74: "World", - 75: "Generate a function that fits current music...", - 76: "Save selected track as commands in .bdx file...", - 77: "Export .bdx file from map...", - 78: "Export .RyStruct file from map...", - 79: "Load functions into a world...", - 80: "Separate long .mcfunction file into small ones and set them into a world as a chain...", - 81: "Additional Functions", - 82: "Show generating result", - 83: "Set a websocket server on localhost:8080 and play the selected track", - 84: "Experimental Functions", - 85: "Clear log file", - 86: "Clear save file(obsolete)", - 87: "Help", - 88: "About", - 89: "Send a bug report", - 90: "Q&A", - 91: "Main Options", - # 92:"", - # 93:"", - # 94:"", - # 95:"", - 96: "Reset Main Options", - 97: "Track Options", - # 98:"", - # 99:"", - # 100:"", - # 101:"", - 102: "Delete Selected Track", - # 103:"", - # 104:"", - - 105: "找不到或无法读取文件😢:{}", - 106: "您当前的项目已修改但未存储,是否先保存当前项目?", - 107: "项目已经存储至:{}", - 108: "音·创工程文件", - 109: "任意类型", - 110: "函数音创工程文件", - 111: "MMFM0.0.6版本工程文件", - 112: "全部类型", - 113: "钢琴声音的音频文件", - 114: "Midi文件", - 115: "文本文件", - 116: "请输入坐标:", - 117: "您输入的格式有误,请重新输入!", - 118: "我的世界指令函数文件", - 119: "请输入执行链生成坐标:", - 120: "您输入的格式有误,请重新输入。", - 121: "您的函数文件不大于一万条指令,无需进行分割操作。", - 122: "请输入执行链生成相对坐标:", - 123: "FastBuilder结构文件", - 124: "转换结束!\n{}", - 125: "一秒,音乐走几拍?", - 126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放", - 127: "请输入区域选择的开始坐标:", - 128: "请输入区域选择的结束坐标:", - 129: "所选区块导出时是否需要保留空气方块?", - 130: "音·创结构文件", - 131: "文件已生成\n{}", - 132: "文件无法生成\n{}\n{}", - 133: "本功能尚未开发。", - 134: "您的称呼", - 135: "您的联系方式", - 136: "您对问题的描述", - 137: "在程序结束后将清除日志及临时文件信息。", - 138: "在程序结束后将不会清除日志及临时文件信息。", - 139: "修改包名", - 140: "修改音乐标题", - 141: "修改玩家选择器\n注意!要加上中括号“[]”", - 142: "修改本音轨的执行实体名", - 143: "修改本音轨所用的积分板", - 144: "修改本音轨所用乐器", - 145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?", - 146: "修改本音轨生成的文件名", - -} +# -*- coding:utf-8 -*- + +# 由金羿翻译工具生成字符串列表 +# 请在所需翻译的文件前from 此文件 import READABLETEXT + + +READABLETEXT = { + 'Translator': (("Eilles Wan (金羿)", True),), + # 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 + 0: "ERROR❌", + 1: "TIPS❗", + 2: "Clearing log(this wont be in the file)", + 3: "Could not clear the temporary files or logs", + 4: "saved", + 5: "New Musicreater Project", + 6: "Select old-type project", + 7: "Select Musicreater Project", + 8: "Cant open:{}, please check if youve entered the right name", + 9: "Musicreat - About", + 10: "Musicreater", + 11: "Ver. {}", + 12: """Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""", + 13: "OK", + 14: "Inpute Notes", + 15: (("- Developers -", False), + ("Eilles Wan (金羿)", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), + ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False)), + # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 + 16: "- Translators -", + # 17:"", + 18: "QQ Group: 861684859", + 19: "Musicreater - Help", + 20: "Select sound file", + 21: "Select MIDI file", + 22: "Select NoteText file", + 23: "Get Note info", + 24: "Write in Note info: {}", + 25: "Select generating file", + 26: "Select generating folder", + 27: "Select generating .mcpack file", + 28: "Input position info", + 29: "Select generating world folder", + 30: "Select generating Function Pack", + 31: "Select .mcfunction file ", + 32: "Select .bdx file ", + 33: "DONE✔", + 34: "Input playing rate", + 35: "Generating", + 36: "Select a world folder", + 37: "Make sure", + 38: "Generate .RyStruct file", + 39: "FAILED❌", + 40: "Report message inpution", + 41: "Musicreater - Eilles - {}", + 42: "ExecutingEntityName: {}", + 43: "ScoreboardName: {}", + 44: "Instrument: {}", + 45: "TrackName: {}", + 46: "PackName: {}", + 47: "MusicTitle: {}", + 48: "IsRepeat?: {}", + 49: "Player'sTargetSelector: {}", + 50: "Modify Main Option", + 51: "Modify Track Option", + 52: "Default Instrument: Enter English\n", + 53: "Open...", + 54: "Open Old Project...", + 55: "Save", + 56: "Save as...", + 57: "Exit", + 58: "File", + 59: "Load tracks from sound", + 60: "Load tracks from Midi", + 61: "Load tracks from Text", + 62: "Input notes to track", + 63: "Edit", + 64: "Generate file...", + 65: "Generate function pack...", + 66: "Generate .mcpack file...", + 67: "Functions(Pack)", + 68: "Save music as blocks into a map", + 69: "Save music as blocks into a exist map...", + 70: "Save music as commands into a map", + 71: "Save music as commands into a exist map...", + 72: "Save music as notebox into a map", + 73: "Save music as notebox into a exist map...", + 74: "World", + 75: "Generate a function that fits current music...", + 76: "Save selected track as commands in .bdx file...", + 77: "Export .bdx file from map...", + 78: "Export .RyStruct file from map...", + 79: "Load functions into a world...", + 80: "Separate long .mcfunction file into small ones and set them into a world as a chain...", + 81: "Additional Functions", + 82: "Show generating result", + 83: "Set a websocket server on localhost:8080 and play the selected track", + 84: "Experimental Functions", + 85: "Clear log file", + 86: "Clear save file(obsolete)", + 87: "Help", + 88: "About", + 89: "Send a bug report", + 90: "Q&A", + 91: "Main Options", + # 92:"", + # 93:"", + # 94:"", + # 95:"", + 96: "Reset Main Options", + 97: "Track Options", + # 98:"", + # 99:"", + # 100:"", + # 101:"", + 102: "Delete Selected Track", + # 103:"", + # 104:"", + + 105: "找不到或无法读取文件😢:{}", + 106: "您当前的项目已修改但未存储,是否先保存当前项目?", + 107: "项目已经存储至:{}", + 108: "音·创工程文件", + 109: "任意类型", + 110: "函数音创工程文件", + 111: "MMFM0.0.6版本工程文件", + 112: "全部类型", + 113: "钢琴声音的音频文件", + 114: "Midi文件", + 115: "文本文件", + 116: "请输入坐标:", + 117: "您输入的格式有误,请重新输入!", + 118: "我的世界指令函数文件", + 119: "请输入执行链生成坐标:", + 120: "您输入的格式有误,请重新输入。", + 121: "您的函数文件不大于一万条指令,无需进行分割操作。", + 122: "请输入执行链生成相对坐标:", + 123: "FastBuilder结构文件", + 124: "转换结束!\n{}", + 125: "一秒,音乐走几拍?", + 126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放", + 127: "请输入区域选择的开始坐标:", + 128: "请输入区域选择的结束坐标:", + 129: "所选区块导出时是否需要保留空气方块?", + 130: "音·创结构文件", + 131: "文件已生成\n{}", + 132: "文件无法生成\n{}\n{}", + 133: "本功能尚未开发。", + 134: "您的称呼", + 135: "您的联系方式", + 136: "您对问题的描述", + 137: "在程序结束后将清除日志及临时文件信息。", + 138: "在程序结束后将不会清除日志及临时文件信息。", + 139: "修改包名", + 140: "修改音乐标题", + 141: "修改玩家选择器\n注意!要加上中括号“[]”", + 142: "修改本音轨的执行实体名", + 143: "修改本音轨所用的积分板", + 144: "修改本音轨所用乐器", + 145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?", + 146: "修改本音轨生成的文件名", + +} diff --git a/languages/lang.py b/languages/lang.py index af3b636..8f92190 100644 --- a/languages/lang.py +++ b/languages/lang.py @@ -1,20 +1,20 @@ -# -*- coding:utf-8 -*- - - -DEFAULTLANGUAGE = 'zh-CN' - -LANGUAGELIST = { - 'zh-CN': ( - "简体中文 中国大陆", - "Simplified Chinese, China Mainland", - ), - 'en-GB': ( - "英式英语 大不列颠", - "British English, Great Britain", - ), -} - -if DEFAULTLANGUAGE == 'zh-CN': - from languages.zhCN import READABLETEXT -elif DEFAULTLANGUAGE == 'en-GB': - from languages.enGB import READABLETEXT +# -*- coding:utf-8 -*- + + +DEFAULTLANGUAGE = 'zh-CN' + +LANGUAGELIST = { + 'zh-CN': ( + "简体中文 中国大陆", + "Simplified Chinese, China Mainland", + ), + 'en-GB': ( + "英式英语 大不列颠", + "British English, Great Britain", + ), +} + +if DEFAULTLANGUAGE == 'zh-CN': + from languages.zhCN import READABLETEXT +elif DEFAULTLANGUAGE == 'en-GB': + from languages.enGB import READABLETEXT diff --git a/languages/zhCN.py b/languages/zhCN.py index 6cdcaaa..6c2ecd0 100644 --- a/languages/zhCN.py +++ b/languages/zhCN.py @@ -1,162 +1,172 @@ -# -*- coding:utf-8 -*- - -# 由金羿翻译工具生成字符串列表 -# 请在所需翻译文件前from 此文件 import READABLETEXT - - -READABLETEXT = { - 'Translator': (("金羿 Eilles 原稿", True),), - # 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 - 0: "错误❌", - 1: "提示❗", - 2: "清除log(此句不载入日志)", - 3: "无法清除日志及临时文件", - 4: "已存储", - 5: "新建 音·创 项目", - 6: "请选择旧类型的项目", - 7: "请选择 音·创 项目", - 8: "无法打开文件:{},请查看您是否输入正确", - 9: "音·创 - 关于", - 10: "音·创 Musicreater", - 11: "当前版本:{}", - 12: """凌云我的世界开发团队\n×\n凌云计算机应用软件开发团队""", - 13: "确定", - 14: "请输入音符", - 15: (("- 开发者 -", False), - ("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), - ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False), - ), - # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 - 16: "- 翻译者 -", - # 17:"", - 18: "讨论群: 861684859", - 19: "音·创 - 帮助", - 20: "请选择钢琴声音的音乐文件", - 21: "请选择 MIDI 文件", - 22: "请选择 音符文本 文件", - 23: "获取音符信息", - 24: "音符数据写入{}", - 25: "请选择文件生成的位置", - 26: "请选择文件夹生成的位置", - 27: "请选择.mcpack文件生成的位置", - 28: "坐标信息输入", - 29: "请选择世界文件夹生成的位置", - 30: "请选择函数包生成的位置", - 31: "请选择 .mcfunction 文件", - 32: "请选择需要生成的.bdx文件", - 33: "完成✔", - 34: "输入播放速度", - 35: "创建中", - 36: "请选择世界文件夹所在的位置", - 37: "请确认", - 38: "生成.RyStruct文件", - 39: "失败❌", - 40: "邮件反馈信息输入", - 41: "音·创 - 金羿 - {}", - 42: "执行实体名:{}", - 43: "使用计分板:{}", - 44: "所用的乐器:{}", - 45: "当前音轨名:{}", - 46: "包名:{}", - 47: "音乐标题:{}", - 48: "是否重复:{}", - 49: "玩家选择器:{}", - 50: "修改主设置", - 51: "修改节设置", - 52: "游戏内置乐器如下:请输入英文\n", - 53: "打开音·创项目...", - 54: "打开旧项目...", - 55: "保存项目", - 56: "另存为...", - 57: "退出", - 58: "文件", - 59: "从钢琴MP3导入音轨", - 60: "从midi导入音轨", - 61: "从文本文件导入音轨", - 62: "输入音符至音轨", - 63: "编辑", - 64: "生成文件至...", - 65: "生成函数包至...", - 66: "生成附加包文件至...", - 67: "函数(包)", - 68: "将音乐以方块存储生成地图", - 69: "将音乐以方块存储载入地图…", - 70: "将音乐以指令存储生成地图", - 71: "将音乐以指令存储载入地图…", - 72: "将音乐以音符盒存储生成地图", - 73: "将音乐以音符盒存储载入地图…", - 74: "世界", - 75: "生成符合当前音乐的函数播放器…", - 76: "将选中音轨以指令存储生成.bdx文件…", - 77: "由地图导出至.bdx文件…", - 78: "由地图导出至.RyStruct文件…", - 79: "将函数载入世界…", - 80: "将大函数分割并建立执行链…", - 81: "辅助功能", - 82: "展示生成结果", - 83: "建立位于localhost:8080上的websocket服务器播放选中音轨", - 84: "实验性功能", - 85: "清除日志文件", - 86: "清除早期版本的存储文件", - 87: "帮助", - 88: "关于", - 89: "发送错误日志反馈", - 90: "帮助与疑问", - 91: "音乐总设置(项目设置)", - # 92:"", - # 93:"", - # 94:"", - # 95:"", - 96: "重置项目设置", - 97: "当前音轨设置(段落设置)", - # 98:"", - # 99:"", - # 100:"", - # 101:"", - 102: "删除选中音轨", - # 103:"", - # 104:"", - 105: "找不到或无法读取文件😢:{}", - 106: "您当前的项目已修改但未存储,是否先保存当前项目?", - 107: "项目已经存储至:{}", - 108: "音·创工程文件", - 109: "任意类型", - 110: "函数音创工程文件", - 111: "MMFM0.0.6版本工程文件", - 112: "全部类型", - 113: "钢琴声音的音频文件", - 114: "Midi文件", - 115: "文本文件", - 116: "请输入坐标:", - 117: "您输入的格式有误,请重新输入!", - 118: "我的世界指令函数文件", - 119: "请输入执行链生成坐标:", - 120: "您输入的格式有误,请重新输入。", - 121: "您的函数文件不大于一万条指令,无需进行分割操作。", - 122: "请输入执行链生成相对坐标:", - 123: "FastBuilder结构文件", - 124: "转换结束!\n{}", - 125: "一秒,音乐走几拍?", - 126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放", - 127: "请输入区域选择的开始坐标:", - 128: "请输入区域选择的结束坐标:", - 129: "所选区块导出时是否需要保留空气方块?", - 130: "音·创结构文件", - 131: "文件已生成\n{}", - 132: "文件无法生成\n{}\n{}", - 133: "本功能尚未开发。", - 134: "您的称呼", - 135: "您的联系方式", - 136: "您对问题的描述", - 137: "在程序结束后将清除日志及临时文件信息。", - 138: "在程序结束后将不会清除日志及临时文件信息。", - 139: "修改包名", - 140: "修改音乐标题", - 141: "修改玩家选择器\n注意!要加上中括号“[]”", - 142: "修改本音轨的执行实体名", - 143: "修改本音轨所用的积分板", - 144: "修改本音轨所用乐器", - 145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?", - 146: "修改本音轨生成的文件名", - -} +# -*- coding:utf-8 -*- + +# 由金羿翻译工具生成字符串列表 +# 请在所需翻译文件前from 此文件 import READABLETEXT + + +READABLETEXT = { + 'Translator': (("金羿 Eilles 原稿", True),), + # 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 + 0: "错误❌", + 1: "提示❗", + 2: "清除log(此句不载入日志)", + 3: "无法清除日志及临时文件", + 4: "已存储", + 5: "新建 音·创 项目", + 6: "请选择旧类型的项目", + 7: "请选择 音·创 项目", + 8: "无法打开文件:{},请查看您是否输入正确", + 9: "音·创 - 关于", + 10: "音·创 Musicreater", + 11: "当前版本:{}", + 12: """凌云我的世界开发团队\n×\n凌云计算机应用软件开发团队""", + 13: "确定", + 14: "请输入音符", + 15: (("- 开发者 -", False), + ("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), + ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False), + ), + # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 + 16: "- 翻译者 -", + # 17:"", + 18: "讨论群: 861684859", + 19: "音·创 - 帮助", + 20: "请选择钢琴声音的音乐文件", + 21: "请选择 MIDI 文件", + 22: "请选择 音符文本 文件", + 23: "获取音符信息", + 24: "音符数据写入{}", + 25: "请选择文件生成的位置", + 26: "请选择文件夹生成的位置", + 27: "请选择.mcpack文件生成的位置", + 28: "坐标信息输入", + 29: "请选择世界文件夹生成的位置", + 30: "请选择函数包生成的位置", + 31: "请选择 .mcfunction 文件", + 32: "请选择需要生成的.bdx文件", + 33: "完成✔", + 34: "输入播放速度", + 35: "创建中", + 36: "请选择世界文件夹所在的位置", + 37: "请确认", + 38: "生成.RyStruct文件", + 39: "失败❌", + 40: "邮件反馈信息输入", + 41: "音·创 - 金羿 - {}", + 42: "执行实体名:{}", + 43: "使用计分板:{}", + 44: "所用的乐器:{}", + 45: "当前音轨名:{}", + 46: "包名:{}", + 47: "音乐标题:{}", + 48: "是否重复:{}", + 49: "玩家选择器:{}", + 50: "修改主设置", + 51: "修改节设置", + 52: "游戏内置乐器如下:请输入英文\n", + 53: "打开音·创项目...", + 54: "打开旧项目...", + 55: "保存项目", + 56: "另存为...", + 57: "退出", + 58: "文件", + 59: "从钢琴MP3导入音轨", + 60: "从midi导入音轨", + 61: "从文本文件导入音轨", + 62: "输入音符至音轨", + 63: "编辑", + 64: "生成文件至...", + 65: "生成函数包至...", + 66: "生成附加包文件至...", + 67: "函数(包)", + 68: "将音乐以方块存储生成地图", + 69: "将音乐以方块存储载入地图…", + 70: "将音乐以指令存储生成地图", + 71: "将音乐以指令存储载入地图…", + 72: "将音乐以音符盒存储生成地图", + 73: "将音乐以音符盒存储载入地图…", + 74: "世界", + 75: "生成符合当前音乐的函数播放器…", + 76: "将选中音轨以指令存储生成.bdx文件…", + 77: "由地图导出至.bdx文件…", + 78: "由地图导出至.RyStruct文件…", + 79: "将函数载入世界…", + 80: "将大函数分割并建立执行链…", + 81: "辅助功能", + 82: "展示生成结果", + 83: "建立位于localhost:8080上的websocket服务器播放选中音轨", + 84: "实验性功能", + 85: "清除日志文件", + 86: "清除早期版本的存储文件", + 87: "帮助", + 88: "关于", + 89: "发送错误日志反馈", + 90: "帮助与疑问", + 91: "音乐总设置(项目设置)", + # 92:"", + # 93:"", + # 94:"", + # 95:"", + 96: "重置项目设置", + 97: "当前音轨设置(段落设置)", + # 98:"", + # 99:"", + # 100:"", + # 101:"", + 102: "删除选中音轨", + # 103:"", + # 104:"", + 105: "找不到或无法读取文件😢:{}", + 106: "您当前的项目已修改但未存储,是否先保存当前项目?", + 107: "项目已经存储至:{}", + 108: "音·创工程文件", + 109: "任意类型", + 110: "函数音创工程文件", + 111: "MMFM0.0.6版本工程文件", + 112: "全部类型", + 113: "钢琴声音的音频文件", + 114: "Midi文件", + 115: "文本文件", + 116: "请输入坐标:", + 117: "您输入的格式有误,请重新输入!", + 118: "我的世界指令函数文件", + 119: "请输入执行链生成坐标:", + 120: "您输入的格式有误,请重新输入。", + 121: "您的函数文件不大于一万条指令,无需进行分割操作。", + 122: "请输入执行链生成相对坐标:", + 123: "FastBuilder结构文件", + 124: "转换结束!\n{}", + 125: "一秒,音乐走几拍?", + 126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放", + 127: "请输入区域选择的开始坐标:", + 128: "请输入区域选择的结束坐标:", + 129: "所选区块导出时是否需要保留空气方块?", + 130: "音·创结构文件", + 131: "文件已生成\n{}", + 132: "文件无法生成\n{}\n{}", + 133: "本功能尚未开发。", + 134: "您的称呼", + 135: "您的联系方式", + 136: "您对问题的描述", + 137: "在程序结束后将清除日志及临时文件信息。", + 138: "在程序结束后将不会清除日志及临时文件信息。", + 139: "修改包名", + 140: "修改音乐标题", + 141: "修改玩家选择器\n注意!要加上中括号“[]”", + 142: "修改本音轨的执行实体名", + 143: "修改本音轨所用的积分板", + 144: "修改本音轨所用乐器", + 145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?", + 146: "修改本音轨生成的文件名", + # -----2022.1.25更新 + 147: "生成新文件至...", + 148: "从midi导入音轨且用新方法解析", + 149: "打开 新: 音·创项目...", + 150: "保存为新项目", + 151: "另存为新项...", + 152: "(开发调试)关闭本次日志记录", + 153: "生成新函数包至...", + 154: "生成新函数附加包文件至...", + 155: "生成新函数附加包文件,并将神羽资源包以散包形式放置至...", + +} diff --git a/msctspt/__init__.pyc b/msctspt/__init__.pyc new file mode 100644 index 0000000..d6538b0 Binary files /dev/null and b/msctspt/__init__.pyc differ diff --git a/msctspt/bdxOpera_CP.py b/msctspt/bdxOpera_CP.py index 5c569b0..ba32a30 100644 --- a/msctspt/bdxOpera_CP.py +++ b/msctspt/bdxOpera_CP.py @@ -1,221 +1,221 @@ -import os -import brotli - -'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码''' - - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:7个 - - -class BdxConverter: - __header = "BD@" - __bin_header = b"BDX" - __generator_author = b"&Charlie_Ping" - - keys = { - # x--, x++, addSmallX(-128~127), addX(-32768~32767), addBigX(-2147483648~2147483647) - "x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"], - "y": [b"\x11", b"\x10", b"\x1d", b"\x16", b"\x17"], - "z": [b"\x13", b"\x12", b"\x1e", b"\x18", b"\x19"], - "end": b"\x58", - "isSigned": b"\x5a", - "placeCommandBlockWithData": b"\x1b", - "placeBlock": b"\x07" - } - - def __init__(self, file_path: str, author: str, blocks): - self.author = author - self.blocks = blocks - self.file_path = file_path - self.direction = [0, 0, 0] - self.block_type = self.get_block_type - self.__file = self.create_and_upload_file - - @property - def get_block_type(self): - """ - blocks - [ - { - "direction": [x: int, y: int, z: int], - block_name: str, - particular_value: int, - } - ] - :return: list 给出的所有方块种类名称 - """ - block_type = set() - for block_ in self.blocks: - block_type.add(block_["block_name"]) - block_type = list(block_type) - return block_type - - @property - def create_and_upload_file(self): - """ - (瞎用property? 害怕 - 创建一个bdx文件 - 要close! - :return: 一个文件对象 - """ - _dir = os.path.dirname(self.file_path) - if not os.path.isdir(_dir): - os.makedirs(_dir) - _bytes = self.__bin_header - _bytes += b"\x00" - _bytes += self.author.encode("utf-8") + self.__generator_author - for i in self.block_type: - _bytes += b"\x00\x01" - _bytes += bytes(i, encoding="utf-8") - _bytes += b"\x00" - _bytes += self.upload_blocks() - _bytes += b"X" - with open(self.file_path, "w+") as f: - f.write("BD@") - f.close() - with open(self.file_path, "ab+") as f: - f.write(brotli.compress(_bytes)) - f.close() - return - - def upload_blocks(self): - """ - 计算差值 - 写入移动过程 - 写入方块 - 更新差值 - :return: - """ - _types = b"" - for block_ in self.blocks: - # print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]") - diff = self.move_pointer(self.direction, block_["direction"]) - _types += diff - if block_["block_name"] in ["command_block", - "chain_command_block", - "repeating_command_block"]: - _types += self.obtain_command_block(block_) - else: - _types += self.obtain_universal_block(block_) - self.direction = block_["direction"] - return _types - - def move_pointer(self, direction: list, new_direction): - """ - 给出 两个[x, y, z]坐标,返回pointer的移动过程 - :param direction: 坐标 1 - :param new_direction: 坐标 2 - :return: bytes - """ - _bytes = b"" - for i, sign in enumerate(["x", "y", "z"]): - # print(f"<{sign}> 新-旧={new_direction[i]-direction[i]}") - distance = new_direction[i] - direction[i] - if distance == 0: - # print("距离是0?跳过了") - continue - _bytes += self.obtain_pointer_type(distance, sign) - # print(f"向 {sign} 运动了 {distance} 格子") - return _bytes - - @classmethod - def obtain_pointer_type(cls, num: int, coordinate: str): - """ - - 用于确定辅助玩家以某一数据类型走指定长度 - - -1 -> 0 - 1 -> 1 - [128, 127] -> 2 - [-32768, 32767] -> 3 - [-2147483648, 2147483647] -> 4 - :param num: - :param coordinate: 坐标轴种类,x y 或 z - :return: - """ - if num == 0: - return - pointer = 0 - condition = (num != -1, # byte=0, pointer=1 - num < -1 or num > 1, # byte=1, pointer=2 - num < -128 or num > 127, # byte=2, pointer=3 - num < -32768 or num > 32767, # byte=4, pointer=4 - ) - for i in condition: - if i: - pointer += 1 - pointer_type = cls.keys[coordinate][pointer] - - byte_len = 2 ** (pointer - 2) - if byte_len >= 1: - num_byte = num.to_bytes(byte_len, byteorder="big", signed=True) - return pointer_type + num_byte - return pointer_type - - def obtain_universal_block(self, block1): - """ - 给定一个方块, 返回此方块在这个bdx中的id和方块data - :param block1: {block_name: str,particular_value: int} - :return: bytes - """ - block_id = b"\x07" + self.block_type.index(block1["block_name"]).to_bytes(2, byteorder="big", signed=False) - particular_value = block1["particular_value"].to_bytes(2, byteorder="big", signed=False) - block_header = block_id + particular_value - return block_header - - def obtain_command_block(self, block1): - """ - 给定一个命令方块,返回命令方块各种数据 - :param block1: { - "direction": [x: int, y: int, z: int] - "block_name": str, - "particular_value": int, - "impluse": int, # unsigned_int32 - "command": str, - "customName": str, - "lastOutput": str, # 没特殊要求写个\x00就得了 - "tickdelay": int, # int32 - "executeOnFirstTick": int, # 1 bytes - "trackOutput": int, # 1 bytes - "conditional": int, # 1 bytes - "needRedstone": int # 1 bytes - } - :return: bytes of command_block - """ - - block_id = b"\x1b" + self.block_type.index(block1["block_name"]).to_bytes(2, byteorder="big", signed=False) - particular_value = block1["particular_value"].to_bytes(2, byteorder="big", signed=False) - block_header = block_id + particular_value - for i in [ - block1["impluse"].to_bytes(4, byteorder="big", signed=False), - bytes(block1["command"], encoding="utf-8") + b"\x00", - bytes(block1["customName"], encoding="utf-8") + b"\x00", - bytes(block1["lastOutput"], encoding="utf-8") + b"\x00", - block1["tickdelay"].to_bytes(4, byteorder="big", signed=True), - block1["executeOnFirstTick"].to_bytes(1, byteorder="big"), - block1["trackOutput"].to_bytes(1, byteorder="big"), - block1["conditional"].to_bytes(1, byteorder="big"), - block1["needRedstone"].to_bytes(1, byteorder="big") - ]: - block_header += i - return block_header - - -if __name__ == '__main__': - block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5}, - {"direction": [1, 5, 1], "block_name": "stained_glass", "particular_value": 7}, - {"direction": [2, 4, 1], "block_name": "command_block", "particular_value": 3, - "impluse": 0, - "command": "say A generator test", - "customName": "test", - "lastOutput": "", - "tickdelay": 24, - "executeOnFirstTick": 0, - "trackOutput": 0, - "conditional": 0, - "needRedstone": 1 - }, - {"direction": [3, 4, 1], "block_name": "concrete", "particular_value": 6}, - {"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}] - bdx = BdxConverter("./test02.bdx", "Charlie_Ping", block) +import os +import brotli + +'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码''' + + +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:7个 + + +class BdxConverter: + __header = "BD@" + __bin_header = b"BDX" + __generator_author = b"&Charlie_Ping" + + keys = { + # x--, x++, addSmallX(-128~127), addX(-32768~32767), addBigX(-2147483648~2147483647) + "x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"], + "y": [b"\x11", b"\x10", b"\x1d", b"\x16", b"\x17"], + "z": [b"\x13", b"\x12", b"\x1e", b"\x18", b"\x19"], + "end": b"\x58", + "isSigned": b"\x5a", + "placeCommandBlockWithData": b"\x1b", + "placeBlock": b"\x07" + } + + def __init__(self, file_path: str, author: str, blocks): + self.author = author + self.blocks = blocks + self.file_path = file_path + self.direction = [0, 0, 0] + self.block_type = self.get_block_type + self.__file = self.create_and_upload_file + + @property + def get_block_type(self): + """ + blocks + [ + { + "direction": [x: int, y: int, z: int], + block_name: str, + particular_value: int, + } + ] + :return: list 给出的所有方块种类名称 + """ + block_type = set() + for block_ in self.blocks: + block_type.add(block_["block_name"]) + block_type = list(block_type) + return block_type + + @property + def create_and_upload_file(self): + """ + (瞎用property? 害怕 + 创建一个bdx文件 + 要close! + :return: 一个文件对象 + """ + _dir = os.path.dirname(self.file_path) + if not os.path.isdir(_dir): + os.makedirs(_dir) + _bytes = self.__bin_header + _bytes += b"\x00" + _bytes += self.author.encode("utf-8") + self.__generator_author + for i in self.block_type: + _bytes += b"\x00\x01" + _bytes += bytes(i, encoding="utf-8") + _bytes += b"\x00" + _bytes += self.upload_blocks() + _bytes += b"X" + with open(self.file_path, "w+") as f: + f.write("BD@") + f.close() + with open(self.file_path, "ab+") as f: + f.write(brotli.compress(_bytes)) + f.close() + return + + def upload_blocks(self): + """ + 计算差值 + 写入移动过程 + 写入方块 + 更新差值 + :return: + """ + _types = b"" + for block_ in self.blocks: + # print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]") + diff = self.move_pointer(self.direction, block_["direction"]) + _types += diff + if block_["block_name"] in ["command_block", + "chain_command_block", + "repeating_command_block"]: + _types += self.obtain_command_block(block_) + else: + _types += self.obtain_universal_block(block_) + self.direction = block_["direction"] + return _types + + def move_pointer(self, direction: list, new_direction): + """ + 给出 两个[x, y, z]坐标,返回pointer的移动过程 + :param direction: 坐标 1 + :param new_direction: 坐标 2 + :return: bytes + """ + _bytes = b"" + for i, sign in enumerate(["x", "y", "z"]): + # print(f"<{sign}> 新-旧={new_direction[i]-direction[i]}") + distance = new_direction[i] - direction[i] + if distance == 0: + # print("距离是0?跳过了") + continue + _bytes += self.obtain_pointer_type(distance, sign) + # print(f"向 {sign} 运动了 {distance} 格子") + return _bytes + + @classmethod + def obtain_pointer_type(cls, num: int, coordinate: str): + """ + + 用于确定辅助玩家以某一数据类型走指定长度 + + -1 -> 0 + 1 -> 1 + [128, 127] -> 2 + [-32768, 32767] -> 3 + [-2147483648, 2147483647] -> 4 + :param num: + :param coordinate: 坐标轴种类,x y 或 z + :return: + """ + if num == 0: + return + pointer = 0 + condition = (num != -1, # byte=0, pointer=1 + num < -1 or num > 1, # byte=1, pointer=2 + num < -128 or num > 127, # byte=2, pointer=3 + num < -32768 or num > 32767, # byte=4, pointer=4 + ) + for i in condition: + if i: + pointer += 1 + pointer_type = cls.keys[coordinate][pointer] + + byte_len = 2 ** (pointer - 2) + if byte_len >= 1: + num_byte = num.to_bytes(byte_len, byteorder="big", signed=True) + return pointer_type + num_byte + return pointer_type + + def obtain_universal_block(self, block1): + """ + 给定一个方块, 返回此方块在这个bdx中的id和方块data + :param block1: {block_name: str,particular_value: int} + :return: bytes + """ + block_id = b"\x07" + self.block_type.index(block1["block_name"]).to_bytes(2, byteorder="big", signed=False) + particular_value = block1["particular_value"].to_bytes(2, byteorder="big", signed=False) + block_header = block_id + particular_value + return block_header + + def obtain_command_block(self, block1): + """ + 给定一个命令方块,返回命令方块各种数据 + :param block1: { + "direction": [x: int, y: int, z: int] + "block_name": str, + "particular_value": int, + "impluse": int, # unsigned_int32 + "command": str, + "customName": str, + "lastOutput": str, # 没特殊要求写个\x00就得了 + "tickdelay": int, # int32 + "executeOnFirstTick": int, # 1 bytes + "trackOutput": int, # 1 bytes + "conditional": int, # 1 bytes + "needRedstone": int # 1 bytes + } + :return: bytes of command_block + """ + + block_id = b"\x1b" + self.block_type.index(block1["block_name"]).to_bytes(2, byteorder="big", signed=False) + particular_value = block1["particular_value"].to_bytes(2, byteorder="big", signed=False) + block_header = block_id + particular_value + for i in [ + block1["impluse"].to_bytes(4, byteorder="big", signed=False), + bytes(block1["command"], encoding="utf-8") + b"\x00", + bytes(block1["customName"], encoding="utf-8") + b"\x00", + bytes(block1["lastOutput"], encoding="utf-8") + b"\x00", + block1["tickdelay"].to_bytes(4, byteorder="big", signed=True), + block1["executeOnFirstTick"].to_bytes(1, byteorder="big"), + block1["trackOutput"].to_bytes(1, byteorder="big"), + block1["conditional"].to_bytes(1, byteorder="big"), + block1["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 index 9cfe934..71ff912 100644 --- a/msctspt/bugReporter.py +++ b/msctspt/bugReporter.py @@ -1,130 +1,130 @@ -# -*- coding: UTF-8 -*- -"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能""" - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:1个;语法(一级)错误:72个 -import os -import zipfile - - -def makeZip(sourceDir, outFilename, compression=8, exceptFile=None): - """使用compression指定的算法打包目录为zip文件\n - 默认算法为DEFLATED(8),可用算法如下:\n - STORED = 0\n - DEFLATED = 8\n - BZIP2 = 12\n - LZMA = 14\n - """ - zipf = zipfile.ZipFile(outFilename, 'w', compression) - pre_len = len(os.path.dirname(sourceDir)) - for parent, dirnames, filenames in os.walk(sourceDir): - for filename in filenames: - if filename == exceptFile: - continue - print(filename) - pathfile = os.path.join(parent, filename) - arcname = pathfile[pre_len:].strip(os.path.sep) # 相对路径 - zipf.write(pathfile, arcname) - - zipf.close() - del zipf, pre_len - - -# 以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942 - - -class report: - """发送报告以及相应的任务处理""" - - def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''): - """:param senderName 发送者名称 - :param senderContact 发送者联系方式 - :param describetion 问题描述""" - self.senderName = senderName - self.senderContact = senderContact - self.describetion = describetion - if not self.senderName: - self.senderName = 'Unknown' - if not self.senderContact: - self.senderContact = 'None' - - def emailReport(self): - """使用E-mail方法发送当前的日志和临时文件等""" - import smtplib - from email.mime.text import MIMEText - from email.mime.multipart import MIMEMultipart - from email.header import Header - from nmcsup.log import log - log("发送错误报告") - import os - log("添加标题与正文") - msg = MIMEMultipart() - # 发送者与接收者显示名称 - msg["From"] = Header(self.senderName, 'utf-8') - msg["To"] = Header("W-YI (QQ2647547478)", 'utf-8') - # 标题 - msg["Subject"] = '音·创 - 来自 ' + self.senderName + ' 的错误报告' - # 正文 - msg.attach( - MIMEText("来自" + self.senderName + "( " + self.senderContact + " )的错误描述:\n" + self.describetion, - 'utf-8')) - log("添加完毕,正在生成压缩包...") - makeZip("./", "Temps&Logs.zip", exceptFile="Temps&Logs.zip") - attafile = MIMEText(str(open("Temps&Logs.zip", 'rb').read()), "base64", 'gb2312') - attafile["Content-Type"] = 'application/octet-stream' - attafile["Content-Disposition"] = 'attachmentfilename="BugReport_from_' + self.senderName + '.zip"' - msg.attach(attafile) - log("完毕,准备发送") - try: - smtp = smtplib.SMTP() - smtp.connect("smtp.163.com") - # smtp.login("RyounDevTeam@163.com","RyounDaiYi99") - # SIQQKQQYCZRVIDFJ是授权密码 - smtp.login("RyounDevTeam@163.com", "SIQQKQQYCZRVIDFJ") - smtp.sendmail("RyounDevTeam@163.com", ["RyounDevTeam@163.com", ], msg.as_string()) - log("错误汇报邮件已发送") - except smtplib.SMTPException as e: - log("错误汇报邮件发送失败:\n" + str(e)) - log("清空内存和临时文件") - del msg, attafile - os.remove("./Temps&Logs.zip") - - -class version: - libraries = ( - 'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin', - 'pyinstaller','py7zr','websockets', 'torch' - ) - """当前所需库,有一些是开发用的,用户不需要安装""" - - version = ('0.0.1', 'Delta',) - """当前版本""" - - def __init__(self) -> None: - - self.libraries = version.libraries - """当前所需库,有一些是开发用的,用户不需要安装""" - - self.version = version.version - """当前版本""" - - def installLibraries(self): - """安装全部开发用库""" - from sys import platform - import os - if platform == 'win32': - import shutil - try: - shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\') - except FloatingPointError: - pass - for i in self.libraries: - print("安装库:" + i) - os.system("python -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple") - elif platform == 'linux': - os.system("sudo apt-get install python3-pip") - os.system("sudo apt-get install python3-tk") - os.system("sudo apt-get install python3-tkinter") - for i in self.libraries: - print("安装库:" + i) - os.system("sudo python3 -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple") +# -*- coding: UTF-8 -*- +"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能""" + +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:1个;语法(一级)错误:72个 +import os +import zipfile + + +def makeZip(sourceDir, outFilename, compression=8, exceptFile=None): + """使用compression指定的算法打包目录为zip文件\n + 默认算法为DEFLATED(8),可用算法如下:\n + STORED = 0\n + DEFLATED = 8\n + BZIP2 = 12\n + LZMA = 14\n + """ + zipf = zipfile.ZipFile(outFilename, 'w', compression) + pre_len = len(os.path.dirname(sourceDir)) + for parent, dirnames, filenames in os.walk(sourceDir): + for filename in filenames: + if filename == exceptFile: + continue + print(filename) + pathfile = os.path.join(parent, filename) + arcname = pathfile[pre_len:].strip(os.path.sep) # 相对路径 + zipf.write(pathfile, arcname) + + zipf.close() + del zipf, pre_len + + +# 以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942 + + +class report: + """发送报告以及相应的任务处理""" + + def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''): + """:param senderName 发送者名称 + :param senderContact 发送者联系方式 + :param describetion 问题描述""" + self.senderName = senderName + self.senderContact = senderContact + self.describetion = describetion + if not self.senderName: + self.senderName = 'Unknown' + if not self.senderContact: + self.senderContact = 'None' + + def emailReport(self): + """使用E-mail方法发送当前的日志和临时文件等""" + import smtplib + from email.mime.text import MIMEText + from email.mime.multipart import MIMEMultipart + from email.header import Header + from nmcsup.log import log + log("发送错误报告") + import os + log("添加标题与正文") + msg = MIMEMultipart() + # 发送者与接收者显示名称 + msg["From"] = Header(self.senderName, 'utf-8') + msg["To"] = Header("W-YI (QQ2647547478)", 'utf-8') + # 标题 + msg["Subject"] = '音·创 - 来自 ' + self.senderName + ' 的错误报告' + # 正文 + msg.attach( + MIMEText("来自" + self.senderName + "( " + self.senderContact + " )的错误描述:\n" + self.describetion, + 'utf-8')) + log("添加完毕,正在生成压缩包...") + makeZip("./", "Temps&Logs.zip", exceptFile="Temps&Logs.zip") + attafile = MIMEText(str(open("Temps&Logs.zip", 'rb').read()), "base64", 'gb2312') + attafile["Content-Type"] = 'application/octet-stream' + attafile["Content-Disposition"] = 'attachmentfilename="BugReport_from_' + self.senderName + '.zip"' + msg.attach(attafile) + log("完毕,准备发送") + try: + smtp = smtplib.SMTP() + smtp.connect("smtp.163.com") + # smtp.login("RyounDevTeam@163.com","RyounDaiYi99") + # SIQQKQQYCZRVIDFJ是授权密码 + smtp.login("RyounDevTeam@163.com", "SIQQKQQYCZRVIDFJ") + smtp.sendmail("RyounDevTeam@163.com", ["RyounDevTeam@163.com", ], msg.as_string()) + log("错误汇报邮件已发送") + except smtplib.SMTPException as e: + log("错误汇报邮件发送失败:\n" + str(e)) + log("清空内存和临时文件") + del msg, attafile + os.remove("./Temps&Logs.zip") + + +class version: + libraries = ( + 'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin', + 'pyinstaller','py7zr','websockets', 'torch' + ) + """当前所需库,有一些是开发用的,用户不需要安装""" + + version = ('0.0.1', 'Delta',) + """当前版本""" + + def __init__(self) -> None: + + self.libraries = version.libraries + """当前所需库,有一些是开发用的,用户不需要安装""" + + self.version = version.version + """当前版本""" + + def installLibraries(self): + """安装全部开发用库""" + from sys import platform + import os + if platform == 'win32': + import shutil + try: + shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\') + except FloatingPointError: + pass + for i in self.libraries: + print("安装库:" + i) + os.system("python -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple") + elif platform == 'linux': + os.system("sudo apt-get install python3-pip") + os.system("sudo apt-get install python3-tk") + os.system("sudo apt-get install python3-tkinter") + for i in self.libraries: + print("安装库:" + i) + os.system("sudo python3 -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple") diff --git a/msctspt/funcOpera.py b/msctspt/funcOpera.py index 892a848..2709943 100644 --- a/msctspt/funcOpera.py +++ b/msctspt/funcOpera.py @@ -1,233 +1,301 @@ -# -*- 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则默认从首或尾开始""" - e = True - 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: - e = False - return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender)] - else: - e = False - return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender)] - else: - if includeStart: - e = False - return Data[Data.index(starter):len(Data) - Data[len(Data)::-1].index(ender) - 1] - else: - e = False - return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender) - 1] - except ValueError: - return 0 - finally: - if e is True: - return 0 - - -def keepart(Data, starter, ender, includeStart: bool = True, includend: bool = True): - """保留序列从starter物件到ender物件之间的部分\n - includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n - starter与ender若为None则默认从首或尾开始""" - e = True - 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: - e = False - return Data[Data.index(starter):Data.index(ender) + 1] - else: - e = False - return Data[Data.index(starter) + 1:Data.index(ender) + 1] - else: - if includeStart: - e = False - return Data[Data.index(starter):Data.index(ender)] - else: - e = False - return Data[Data.index(starter) + 1:Data.index(ender)] - except ValueError: - return 0 - finally: - if e is True: - return 0 - - -def lenFunction(fun) -> int: - """取得函数指令部分长度,即忽略#开头的注释""" - e = True - try: - f = 0 - for i in fun: - if i.replace(" ", '')[0] == '#': - f += 1 - e = False - return len(fun) - f - except IndexError: - return -1 - finally: - if e is True: - 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("完成============================") - - -""" -这里是往事,用于记载一些用不到的功能 - -#存在于 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"]) - - -""" +# -*- 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 makeNewFuncFiles(musicset, path='./'): + """在指定目录下生成函数文件""" + from nmcsup.trans import classList_conversion + 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(musicset['musics'][i]['notes'], + musicset['musics'][i]['set']['ScoreboardName'])) + 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 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("完成============================") + + +""" +这里是往事,用于记载一些用不到的功能 + +#存在于 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 index cf2d51c..1e1e74e 100644 --- a/msctspt/threadOpera.py +++ b/msctspt/threadOpera.py @@ -1,31 +1,31 @@ -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个--未解决1个 - - -import threading - - -class NewThread(threading.Thread): - """新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值""" - - def __init__(self, func, args=()): - super(NewThread, self).__init__() - self.func = func - self.args = args - - def run(self): - self.result = self.func(*self.args) - - def getResult(self): - threading.Thread.join(self) # 等待线程执行完毕 - try: - return self.result - except ValueError: - return None - -# -# ———————————————— -# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 -# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014 -# ———————————————— -# +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个--未解决1个 + + +import threading + + +class NewThread(threading.Thread): + """新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值""" + + def __init__(self, func, args=()): + super(NewThread, self).__init__() + self.func = func + self.args = args + + def run(self): + self.result = self.func(*self.args) + + def getResult(self): + threading.Thread.join(self) # 等待线程执行完毕 + try: + return self.result + except ValueError: + return None + +# +# ———————————————— +# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 +# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014 +# ———————————————— +# diff --git a/msctspt/transfer.py b/msctspt/transfer.py index 4509bfb..d44bca4 100644 --- a/msctspt/transfer.py +++ b/msctspt/transfer.py @@ -1,343 +1,342 @@ -"""音·创 的转换工具库""" - - -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:4个--未解决1个;语法(一级)错误:302个 - - -import amulet -from amulet.api.block import Block -from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc -from amulet_nbt import TAG_String as ts -from nmcsup.log import log - - -def hans2pinyin(hans, style=3): - """将汉字字符串转化为拼音字符串""" - from pypinyin import lazy_pinyin - result = lazy_pinyin(hans=hans, style=style) - final = '' - for i in result: - final += i - return final - - -def formCmdBlock(direction: list, command: str, particularValue: int, impluse: int, condition: bool = False, - needRedstone: bool = True, tickDelay: int = 0, customName: str = '', lastOutput: str = '', - executeOnFirstTick: bool = False, trackOutput: bool = True): - """ - 使用指定项目返回指定的指令方块格式字典 - :param trackOutput: - :param executeOnFirstTick: - :param lastOutput: - :param customName: - :param tickDelay: - :param needRedstone: - :param condition: - :param impluse: - :param particularValue: - :param command: - :param direction: - - :return: 指令方块字典结构 - """ - """ - :param block: { - "direction": [x: int, y: int, z: int] #方块位置 - "block_name": str, #方块名称(无需指定,默认为command_block) - "particular_value": int, #方块特殊值 - "impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32 - "command": str, #指令 - "customName": str, #悬浮字 - "lastOutput": str, #上次输出 - "tickdelay": int, #方块延时 int32 - "executeOnFirstTick": int, #执行第一个选项 1 bytes - "trackOutput": int, #是否输出 1 bytes - "conditional": int, #是否有条件 1 bytes - "needRedstone": int #是否需要红石 1 bytes - } - """ - return {"direction": direction, - "block_name": "command_block", - "particular_value": particularValue, - "impluse": impluse, - "command": command, - "customName": customName, - "lastOutput": lastOutput, - "tickdelay": tickDelay, - "executeOnFirstTick": executeOnFirstTick, - "trackOutput": trackOutput, - "conditional": condition, - "needRedstone": needRedstone - } - - -def note2bdx(filePath: str, dire: list, Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '', - isProsess: bool = False, height: int = 200): - """使用方法同Note2Cmd - :param 参数说明: - filePath: 生成.bdx文件的位置 - dire: 指令方块在地图中生成的起始位置(相对位置) - Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 - 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) - ScoreboardName: 用于执行的计分板名称 - Instrument: 播放的乐器 - PlayerSelect: 执行的玩家选择器 - isProsess: 是否显示进度条(会很卡) - height: 生成结构的最高高度 - :return 返回一个BdxConverter类(实际上没研究过),同时在指定位置生成.bdx文件""" - - from msctspt.transfer import formCmdBlock - from nmcsup.trans import Note2Cmd - from msctspt.bdxOpera_CP import BdxConverter - cmd = Note2Cmd(Notes, ScoreboardName, Instrument, PlayerSelect, isProsess) - 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 ValueError: - cdl.append(i) - finally: - if e is True: - cdl.append(i) - i = 0 - down = False - blocks = [formCmdBlock(dire, cdl.pop(0), 1, 1)] - dire[1] += 1 - for j in cdl: - if dire[1] + i > height: - dire[0] += 1 - i = 0 - down = not down - if dire[1] + i == height: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 5, 2, False, False)) - else: - if down: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 0, 2, False, False)) - else: - blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 1, 2, False, False)) - i += 1 - del i, cdl, down, cmd - return BdxConverter(filePath, 'Build by RyounMusicreater', blocks) - - -def note2webs(Notes: list, Instrument: str, speed: float = 5.0, PlayerSelect: str = '', isProsess: bool = False): - """传入音符,在oaclhost:8080上建立websocket服务器以供我的世界connect/wssever指令连接 - :param 参数说明: - Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 - 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) - Instrument: 播放的乐器 - speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍 - PlayerSelect: 执行的玩家选择器 - isProsess: 是否显示进度条 - :return None""" - - import time - import fcwslib - import asyncio - from 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 - if isProsess: - length = len(Notes) - j = 1 - for i in range(len(Notes)): - await fcwslib.send_command(websocket, - f'execute @a{PlayerSelect} ~ ~ ~ playsound {Instrument} @s ~ ~ ~ 1000 {Notes[i][0]} 1000') - if isProsess: - fcwslib.send_command(websocket, - 'execute @a' + PlayerSelect + ' ~ ~ ~ title @s actionbar §e▶ 播放中: §a' + str( - j) + '/' + str(length) + ' || ' + str(int(j / length * 1000) / 10)) - j += 1 - time.sleep(Notes[i][1] / speed) - - fcwslib.run_server(run_server) - - -def note2RSworld(world: str, startpos: list, notes: list, instrument: str, speed: float = 2.5, - posadder: list = [1, 0, 0], baseblock: str = 'stone'): # -> bool - """传入音符,生成以音符盒存储的红石音乐 - :param 参数说明: - world: 地图文件的路径 - startpos: list[int,int,int] 开始生成的坐标 - notes: list[list[float,float]] 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] - 格式存储的音符列表 例如Musicreater.py的dataset[0]['musics'][NowMusic]['notes'] - instrument: 播放的乐器 - speed: 一拍占多少个中继器延迟(红石刻/rt) - posadder: list[int,int,int] 坐标增加规律,即红石的延长时按照此增加规律增加坐标 - baseblock: 在中继器下垫着啥方块呢~ - :return 是否生成成功 - """ - - from 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', 'noteblock', - {"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' - } -} -""" +"""音·创 的转换工具库""" + + +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:4个--未解决1个;语法(一级)错误:302个 + + +import amulet +from amulet.api.block import Block +from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc +from amulet_nbt import TAG_String as ts +from nmcsup.log import log + + +def hans2pinyin(hans, style=3): + """将汉字字符串转化为拼音字符串""" + from pypinyin import lazy_pinyin + result = lazy_pinyin(hans=hans, style=style) + final = '' + for i in result: + final += i + return final + + +def formCmdBlock(direction: list, command: str, particularValue: int, impluse: int, condition: bool = False, + needRedstone: bool = True, tickDelay: int = 0, customName: str = '', lastOutput: str = '', + executeOnFirstTick: bool = False, trackOutput: bool = True): + """ + 使用指定项目返回指定的指令方块格式字典 + :param trackOutput: + :param executeOnFirstTick: + :param lastOutput: + :param customName: + :param tickDelay: + :param needRedstone: + :param condition: + :param impluse: + :param particularValue: + :param command: + :param direction: + + :return: 指令方块字典结构 + """ + """ + :param block: { + "direction": [x: int, y: int, z: int] #方块位置 + "block_name": str, #方块名称(无需指定,默认为command_block) + "particular_value": int, #方块特殊值 + "impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32 + "command": str, #指令 + "customName": str, #悬浮字 + "lastOutput": str, #上次输出 + "tickdelay": int, #方块延时 int32 + "executeOnFirstTick": int, #执行第一个选项 1 bytes + "trackOutput": int, #是否输出 1 bytes + "conditional": int, #是否有条件 1 bytes + "needRedstone": int #是否需要红石 1 bytes + } + """ + return {"direction": direction, + "block_name": "command_block", + "particular_value": particularValue, + "impluse": impluse, + "command": command, + "customName": customName, + "lastOutput": lastOutput, + "tickdelay": tickDelay, + "executeOnFirstTick": executeOnFirstTick, + "trackOutput": trackOutput, + "conditional": condition, + "needRedstone": needRedstone + } + + +def note2bdx(filePath: str, dire: list, Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '', + isProsess: bool = False, height: int = 200): + """使用方法同Note2Cmd + :param 参数说明: + filePath: 生成.bdx文件的位置 + dire: 指令方块在地图中生成的起始位置(相对位置) + Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 + 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) + ScoreboardName: 用于执行的计分板名称 + Instrument: 播放的乐器 + PlayerSelect: 执行的玩家选择器 + isProsess: 是否显示进度条(会很卡) + height: 生成结构的最高高度 + :return 返回一个BdxConverter类(实际上没研究过),同时在指定位置生成.bdx文件""" + + # from msctspt.transfer import formCmdBlock + from nmcsup.trans import Note2Cmd + from msctspt.bdxOpera_CP import BdxConverter + cmd = Note2Cmd(Notes, ScoreboardName, Instrument, PlayerSelect, isProsess) + 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: # ValueError + cdl.append(i) + # finally: + # if e is True: + # cdl.append(i) + i = 0 + down = False + blocks = [formCmdBlock(dire, cdl.pop(0), 1, 1)] + dire[1] += 1 + for j in cdl: + if dire[1] + i > height: + dire[0] += 1 + i = 0 + down = not down + if dire[1] + i == height: + blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 5, 2, False, False)) + else: + if down: + blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 0, 2, False, False)) + else: + blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 1, 2, False, False)) + i += 1 + del i, cdl, down, cmd + return BdxConverter(filePath, 'Build by RyounMusicreater', blocks) + + +def note2webs(Notes: list, Instrument: str, speed: float = 5.0, PlayerSelect: str = '', isProsess: bool = False): + """传入音符,在oaclhost:8080上建立websocket服务器以供我的世界connect/wssever指令连接 + :param 参数说明: + Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 + 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) + Instrument: 播放的乐器 + speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍 + PlayerSelect: 执行的玩家选择器 + isProsess: 是否显示进度条 + :return None""" + + import time + import fcwslib + # import asyncio + from 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: list = [1, 0, 0], baseblock: str = 'stone'): # -> bool + """传入音符,生成以音符盒存储的红石音乐 + :param 参数说明: + world: 地图文件的路径 + startpos: list[int,int,int] 开始生成的坐标 + notes: list[list[float,float]] 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] + 格式存储的音符列表 例如Musicreater.py的dataset[0]['musics'][NowMusic]['notes'] + instrument: 播放的乐器 + speed: 一拍占多少个中继器延迟(红石刻/rt) + posadder: list[int,int,int] 坐标增加规律,即红石的延长时按照此增加规律增加坐标 + baseblock: 在中继器下垫着啥方块呢~ + :return 是否生成成功 + """ + + from 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', 'noteblock', + {"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 index 9a49688..8a7bfc5 100644 --- a/msctspt/values.py +++ b/msctspt/values.py @@ -1,56 +1,56 @@ -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:40个 - -instuments = { - 'note.banjo': ['班卓琴', 'hay_block'], - 'note.bass': ['贝斯', 'planks'], - 'note.bassattack': ['低音鼓/贝斯', 'log'], - 'note.bd': ['底鼓', 'stone'], # 即basedrum - 'note.bell': ['铃铛/钟琴', 'gold_block'], - 'note.bit': ['比特/“芯片”(方波)', 'emerald_block'], - 'note.chime': ['管钟', 'packed_ice'], - 'note.cow_bell': ['牛铃', 'soul_sand'], - 'note.didgeridoo': ['迪吉里杜管', 'pumpkin'], - 'note.flute': ['长笛', 'clay'], - 'note.guitar': ['吉他', 'wool'], - 'note.harp': ['竖琴/钢琴', 'concrete'], # 任意其他类型的方块皆可 - 'note.hat': ['击鼓沿/架子鼓', 'glass'], - 'note.iron_xylophone': ['“铁木琴”(颤音琴)', 'iron_block'], - 'note.pling': ['“扣弦”(电钢琴)', 'glowstone'], - 'note.snare': ['小军鼓', 'sand'], - 'note.xylophone': ['木琴', 'bone_block'] -} -'''乐器对照表\n -乐器英文:[中文, 对应音符盒下方块名称] -注:方块仅取一个''' - -height2note = { - 0.5: 0, - 0.53: 1, - 0.56: 2, - 0.6: 3, - 0.63: 4, - 0.67: 5, - 0.7: 6, - 0.75: 7, - 0.8: 8, - 0.84: 9, - 0.9: 10, - 0.94: 11, - 1.0: 12, - - 1.05: 13, - 1.12: 14, - 1.2: 15, - 1.25: 16, - 1.33: 17, - 1.4: 18, - 1.5: 19, - 1.6: 20, - 1.7: 21, - 1.8: 22, - 1.9: 23, - 2.0: 24, -} -'''音高对照表\n -MC音高:音符盒音调''' +# 诸葛亮与八卦阵帮忙修改语法 日期:---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/NFC Dev Log.txt b/nmcsup/NFC Dev Log.txt index da350df..87a6740 100644 --- a/nmcsup/NFC Dev Log.txt +++ b/nmcsup/NFC Dev Log.txt @@ -1,72 +1,72 @@ -从此日志开始,我的世界函数音乐构建更名为 函数音创 NoteFunCreater(谐音NotFun[狗头]),版本号更为0.1.0开始 - -注意,运行此文件需要第三方库: -1. mido 用于对midi文件的解码 -2. py7zr 用于对7z压缩包的压缩与解压等(需pycparser, cffi, texttable, pyzstd, pyppmd, pycryptodomex, multivolumefile, brotli, bcj-cffi支持) -(从0.1.3开始不需要) -3. zipfile 用于自动生成函数包的压缩 -4. pystray 用于支持窗口任务栏 -5. pillow (相当于Python2的PIL)用于绘图 - - - 0.1.0 -2021 7 10 - 2021 7 12 -1.程序窗口化 -2.仅支持基本的菜单操作 -3.程序文件皆储存至其相应目录下 -4.程序./bin/目录下文件将会自动防修改 -5.删除了彩蛋 - - - 0.1.1 -2021 7 14 -1.新增版本辨别的提示 -2.窗口中显示歌曲信息 - - - 0.1.2 -2021 7 14 - 2021 7 15 -1.在没运行过的机器上会自动安装库 -2.从midi导入时不会删除其他音轨 -3.改进UI样式 -4.支持对于单个音轨设置的修改以及音乐主设置的修改 -5.当未保存便退出时,会询问存储 -6.新增加载进度提示 - - - 0.1.3 -2021 7 15 - 2021 7 19 -1.不再从文件中读取音符及乐器信息(所以包更小了) -2.改进UI -3.修复了修改玩家选择器时变更了音乐标题的bug -4.新增删除当前选定音轨按钮 -5.新增重置设置按钮(将音乐总设置设置为开始时的设置) -6.运用多线程加载函数与文件等,程序运行效率更高 -7.修复变量作用域混淆问题 - - - 0.1.3.1 -2021 7 19 -1.修复了菜单中无法退出程序的问题 - - - 0.1.4 -2021 7 22 -1.支持显示指令于列表中 - - - - - - - TO-DO -1.支持从midi文件的元信息中收取音符信息并自动生成 -2.支持生成zip函数包 -3.支持使用WebSocket接口自动播放已编辑的音乐 -4.可以编辑多个项目 -5.能够自动将一个长串的音乐分成多个函数文件 -6.支持用户导入自己的乐器 -7.支持汇报崩溃记录(通过邮件附件的方式) -8.支持播放字幕 -9.支持任务栏角标与通知 -10.将控制台版本的彩蛋移植到此版本,开启了任务栏 +从此日志开始,我的世界函数音乐构建更名为 函数音创 NoteFunCreater(谐音NotFun[狗头]),版本号更为0.1.0开始 + +注意,运行此文件需要第三方库: +1. mido 用于对midi文件的解码 +2. py7zr 用于对7z压缩包的压缩与解压等(需pycparser, cffi, texttable, pyzstd, pyppmd, pycryptodomex, multivolumefile, brotli, bcj-cffi支持) -(从0.1.3开始不需要) +3. zipfile 用于自动生成函数包的压缩 +4. pystray 用于支持窗口任务栏 +5. pillow (相当于Python2的PIL)用于绘图 + + + 0.1.0 +2021 7 10 - 2021 7 12 +1.程序窗口化 +2.仅支持基本的菜单操作 +3.程序文件皆储存至其相应目录下 +4.程序./bin/目录下文件将会自动防修改 +5.删除了彩蛋 + + + 0.1.1 +2021 7 14 +1.新增版本辨别的提示 +2.窗口中显示歌曲信息 + + + 0.1.2 +2021 7 14 - 2021 7 15 +1.在没运行过的机器上会自动安装库 +2.从midi导入时不会删除其他音轨 +3.改进UI样式 +4.支持对于单个音轨设置的修改以及音乐主设置的修改 +5.当未保存便退出时,会询问存储 +6.新增加载进度提示 + + + 0.1.3 +2021 7 15 - 2021 7 19 +1.不再从文件中读取音符及乐器信息(所以包更小了) +2.改进UI +3.修复了修改玩家选择器时变更了音乐标题的bug +4.新增删除当前选定音轨按钮 +5.新增重置设置按钮(将音乐总设置设置为开始时的设置) +6.运用多线程加载函数与文件等,程序运行效率更高 +7.修复变量作用域混淆问题 + + + 0.1.3.1 +2021 7 19 +1.修复了菜单中无法退出程序的问题 + + + 0.1.4 +2021 7 22 +1.支持显示指令于列表中 + + + + + + + TO-DO +1.支持从midi文件的元信息中收取音符信息并自动生成 +2.支持生成zip函数包 +3.支持使用WebSocket接口自动播放已编辑的音乐 +4.可以编辑多个项目 +5.能够自动将一个长串的音乐分成多个函数文件 +6.支持用户导入自己的乐器 +7.支持汇报崩溃记录(通过邮件附件的方式) +8.支持播放字幕 +9.支持任务栏角标与通知 +10.将控制台版本的彩蛋移植到此版本,开启了任务栏 11.可编辑音符 \ No newline at end of file diff --git a/nmcsup/NMC Dev Log.txt b/nmcsup/NMC Dev Log.txt index 9835bbd..1c8a675 100644 --- a/nmcsup/NMC Dev Log.txt +++ b/nmcsup/NMC Dev Log.txt @@ -1,36 +1,36 @@ -世界音创(NoteMapCreater)是金羿开发的一款用于生成我的世界中各类有关音乐的物件的软件 -软件禁止商用,源代码始终公开,如使用未经授权的音乐经过此软件生成的任何物件侵犯了他人权利与本软件及其作者无关 - -Copyright © W-YI 2021 - -开头,特别感谢: -KCINE:提供Cinemusicedit函数包(虽然函数包没怎么用过) -Charlie_Ping:提供MusiCreaterBot(音乐地图生成QQ机器人)源码核心以及时不时的催更(虽然源码没有抄) -金羿(作者本人):提供NoteFunCreater(函数音创)的制作经验以及时不时的摸鱼(虽然不是很支持函数音创) -广大群友:高效的催更作业让我以蜗牛的速度前进 - - Alpha 0.0.0 -2021 8 1 - 2021 8 10 -1.确定了大概的功能 -2.不支持无参数传入 -3.可以查看帮助,但是帮助大多功能没实现 -4.可以从格式文本、midi文件、钢琴声音MP3导入音轨 -5.可以生成一些方块到世界里,但是没有播放器(半支持bw开关) -5.提供了修改文件地址的方法,但是不能修改 - - Alpha 0.0.1 -2021 8 10 -1.可以从函数音创的工程文件读取音轨 -2.可以新建一个空白世界来生成 -3.支持修改输出文件地址 -4.支持修改输出方块起始位置 -5.支持指定播放乐器,执行实体,执行积分板,播放玩家选择器 -6.可以生成指令音乐地图(完全支持-w开关) - - Beta 0.0.0 -2021 8 X? -1.除了-nw 和 -f 开关不支持以外都支持了 - - Beta 0.0.1 -2021 8 19 -1.修复了大量bug +世界音创(NoteMapCreater)是金羿开发的一款用于生成我的世界中各类有关音乐的物件的软件 +软件禁止商用,源代码始终公开,如使用未经授权的音乐经过此软件生成的任何物件侵犯了他人权利与本软件及其作者无关 + +Copyright © W-YI 2021 + +开头,特别感谢: +KCINE:提供Cinemusicedit函数包(虽然函数包没怎么用过) +Charlie_Ping:提供MusiCreaterBot(音乐地图生成QQ机器人)源码核心以及时不时的催更(虽然源码没有抄) +金羿(作者本人):提供NoteFunCreater(函数音创)的制作经验以及时不时的摸鱼(虽然不是很支持函数音创) +广大群友:高效的催更作业让我以蜗牛的速度前进 + + Alpha 0.0.0 +2021 8 1 - 2021 8 10 +1.确定了大概的功能 +2.不支持无参数传入 +3.可以查看帮助,但是帮助大多功能没实现 +4.可以从格式文本、midi文件、钢琴声音MP3导入音轨 +5.可以生成一些方块到世界里,但是没有播放器(半支持bw开关) +5.提供了修改文件地址的方法,但是不能修改 + + Alpha 0.0.1 +2021 8 10 +1.可以从函数音创的工程文件读取音轨 +2.可以新建一个空白世界来生成 +3.支持修改输出文件地址 +4.支持修改输出方块起始位置 +5.支持指定播放乐器,执行实体,执行积分板,播放玩家选择器 +6.可以生成指令音乐地图(完全支持-w开关) + + Beta 0.0.0 +2021 8 X? +1.除了-nw 和 -f 开关不支持以外都支持了 + + Beta 0.0.1 +2021 8 19 +1.修复了大量bug diff --git a/nmcsup/const.py b/nmcsup/const.py index 29ca76c..46b9eba 100644 --- a/nmcsup/const.py +++ b/nmcsup/const.py @@ -1,312 +1,446 @@ -"""音创系列的音符对照表 以及一系列常数""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---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''' +"""音创系列的音符对照表 以及一系列常数""" +# 诸葛亮与八卦阵帮忙修改语法 日期:---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''' +pitch = { + '0': '0.0220970869120796', + '1': '0.0234110480761981', + '2': '0.0248031414370031', + '3': '0.0262780129766786', + '4': '0.0278405849418856', + '5': '0.0294960722713029', + '6': '0.03125', + '7': '0.033108221698728', + '8': '0.0350769390096679', + '9': '0.037162722343835', + '10': '0.0393725328092148', + '11': '0.0417137454428136', + '12': '0.0441941738241592', + '13': '0.0468220961523963', + '14': '0.0496062828740062', + '15': '0.0525560259533572', + '16': '0.0556811698837712', + '17': '0.0589921445426059', + '18': '0.0625', + '19': '0.066216443397456', + '20': '0.0701538780193358', + '21': '0.0743254446876701', + '22': '0.0787450656184296', + '23': '0.0834274908856271', + '24': '0.0883883476483184', + '25': '0.0936441923047926', + '26': '0.0992125657480125', + '27': '0.105112051906714', + '28': '0.111362339767542', + '29': '0.117984289085212', + '30': '0.125', + '31': '0.132432886794912', + '32': '0.140307756038672', + '33': '0.14865088937534', + '34': '0.157490131236859', + '35': '0.166854981771254', + '36': '0.176776695296637', + '37': '0.187288384609585', + '38': '0.198425131496025', + '39': '0.210224103813429', + '40': '0.222724679535085', + '41': '0.235968578170423', + '42': '0.25', + '43': '0.264865773589824', + '44': '0.280615512077343', + '45': '0.29730177875068', + '46': '0.314980262473718', + '47': '0.333709963542509', + '48': '0.353553390593274', + '49': '0.37457676921917', + '50': '0.39685026299205', + '51': '0.420448207626857', + '52': '0.44544935907017', + '53': '0.471937156340847', + '54': '0.5', + '55': '0.529731547179648', + '56': '0.561231024154687', + '57': '0.594603557501361', + '58': '0.629960524947437', + '59': '0.667419927085017', + '60': '0.707106781186548', + '61': '0.749153538438341', + '62': '0.7937005259841', + '63': '0.840896415253715', + '64': '0.890898718140339', + '65': '0.943874312681694', + '66': '1', + '67': '1.0594630943593', + '68': '1.12246204830937', + '69': '1.18920711500272', + '70': '1.25992104989487', + '71': '1.33483985417003', + '72': '1.4142135623731', + '73': '1.49830707687668', + '74': '1.5874010519682', + '75': '1.68179283050743', + '76': '1.78179743628068', + '77': '1.88774862536339', + '78': '2', + '79': '2.11892618871859', + '80': '2.24492409661875', + '81': '2.37841423000544', + '82': '2.51984209978975', + '83': '2.66967970834007', + '84': '2.82842712474619', + '85': '2.99661415375336', + '86': '3.1748021039364', + '87': '3.36358566101486', + '88': '3.56359487256136', + '89': '3.77549725072677', + '90': '4', + '91': '4.23785237743718', + '92': '4.48984819323749', + '93': '4.75682846001088', + '94': '5.03968419957949', + '95': '5.33935941668014', + '96': '5.65685424949238', + '97': '5.99322830750673', + '98': '6.3496042078728', + '99': '6.72717132202972', + '100': '7.12718974512272', + '101': '7.55099450145355', + '102': '8', + '103': '8.47570475487436', + '104': '8.97969638647498', + '105': '9.51365692002177', + '106': '10.079368399159', + '107': '10.6787188333603', + '108': '11.3137084989848', + '109': '11.9864566150135', + '110': '12.6992084157456', + '111': '13.4543426440594', + '112': '14.2543794902454', + '113': '15.1019890029071', + '114': '16', + '115': '16.9514095097487', + '116': '17.95939277295', + '117': '19.0273138400435', + '118': '20.158736798318', + '119': '21.3574376667206', + '120': '22.6274169979695', + '121': '23.9729132300269', + '122': '25.3984168314912', + '123': '26.9086852881189', + '124': '28.5087589804909', + '125': '30.2039780058142', + '126': '32', + '127': '33.9028190194974', + '128': '35.9187855458999', + '129': '38.0546276800871', + '130': '40.3174735966359', + '131': '42.7148753334411' + } diff --git a/nmcsup/log.py b/nmcsup/log.py index a59003e..120a6c2 100644 --- a/nmcsup/log.py +++ b/nmcsup/log.py @@ -1,56 +1,68 @@ -"""提供对于音创系列的日志""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 -# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个 - -import logging -import os -import datetime -import sys - -StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7] -time = StrStartTime - -main_path = './log/' - -position = main_path + time - -if not os.path.exists('./log/'): - os.makedirs('./log/') - -logger = logging.getLogger(__name__) -logger.setLevel(level=logging.INFO) -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) - -print("using Timbre_resources_package_generator_lib \n --made by 诸葛亮与八卦阵") -print(sys.path[0].replace("nmcsup\\logger", "log\\")) - -# import logger - -# 载入日志功能 -StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7] -# logger.setting(StrStartTime) -"""字符串型的程序开始时间""" - - -def log(info: str = '', isPrinted: bool = True, isLoggerLibRecord: bool = True): - # isLoggerLibRecord: 是否同时在logger库中记录 - """将信息连同当前时间载入日志""" - if not os.path.exists('./log/'): - os.makedirs('./log/') - with open('./log/' + StrStartTime + '.msct.log', 'a', encoding='UTF-8') as f: - f.write(str(datetime.datetime.now())[11:19] + ' ' + info + '\n') - if isPrinted: - print(str(datetime.datetime.now())[11:19] + ' ' + info) - if isLoggerLibRecord: - logger.info(info) +"""提供对于音创系列的日志""" +# 诸葛亮与八卦阵帮忙修改语法 日期:---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 = '', isPrinted: bool = False, isLoggerLibRecord: bool = True, isWrite: bool = False): + """ + info: 信息 + isPrinted: 是否print(仅限金羿log,python官方的logging照常输出) + isLoggerLibRecord: 是否同时在logger库中记录 + isWrite: 是否write(仅限金羿log,python官方的logging照常输出) + """ + """将信息连同当前时间载入日志""" + 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 index d7ca5c0..c0f07dc 100644 --- a/nmcsup/nmcreader.py +++ b/nmcsup/nmcreader.py @@ -1,84 +1,201 @@ -"""音创系列的文件读取功能""" - -# 诸葛亮与八卦阵帮忙修改语法 日期:---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 +"""音创系列的文件读取功能""" + +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:3个;语法(一级)错误:22个 + + +from nmcsup.log import log +from nmcsup.const import notes +import pickle + + +# 从格式文本文件读入一个音轨并存入一个列表 +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 + + +class Note: + def __init__(self, channel, pitch, velocity, time, time_position, instrument): + self.channel = channel + self.pitch = pitch + self.velocity = velocity + self.delay = time + self.time_position = time_position + self.instrument = instrument + self.CD = "d" + + def get_CD(self, start, end): + if end - start > 1.00: + self.CD = "c" + else: + self.CD = "d" + + +def midi_conversion(midfile: str): + import mido + # from msctspt.threadOpera import NewThread + from bgArrayLib.bpm import get + + def Time(mt, tpb_a, bpm_a): + return round(mt / tpb_a / bpm_a * 60 * 20) + Notes = [] + tracks = [] + note_list = [] + close = [] + on = [] + off = [] + instruments = [] + isPercussion = False + try: + mid = mido.MidiFile(midfile) + except FileNotFoundError: + log("找不到文件或无法读取文件" + midfile) + return False + tpb = mid.ticks_per_beat + bpm = get(midfile) + # 解析 + # def loadMidi(track1): + for track in mid.tracks: + overallTime = 0.0 + instrument = 0 + for i in track: + overallTime += i.time + try: + if i.channel != 9: + # try: + # log("event_type(事件): " + str(i.type) + " channel(音轨): " + str(i.channel) + " note/pitch(音高): " + + # str(i[2]) + + # " velocity(力度): " + str(i.velocity) + " time(间隔时间): " + str(i.time) + + # " overallTime/globalTime/timePosition: " + str(overallTime) + " \n") + # except AttributeError: + # log("event_type(事件): " + str(i.type) + " thing(内容):" + str(i) + " \n") + if 'program_change' in str(i): + instrument = i.program + if instrument > 119: # 音色不够 + pass + else: + instruments.append(i.program) + if 'note_on' in str(i) and i.velocity > 0: + print(i) + # print(i.note) + # print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)]) + tracks.append([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)]) + note_list.append([i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument]) + on.append([i.note, Time(overallTime, tpb, bpm)]) + # return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))] + if 'note_off' in str(i) or 'note_on' in str(i) and i.velocity == 0: + # print(i) + # print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm))]) + close.append([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)]) + off.append([i.note, Time(overallTime, tpb, bpm)]) + # return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))] + except AttributeError: + pass + if 'note_on' in str(i) and i.channel == 9: + if 'note_on' in str(i) and i.velocity > 0: + print(i) + # print(i.note) + # print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)]) + tracks.append([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)]) + note_list.append([i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1]) + on.append([i.note, Time(overallTime, tpb, bpm)]) + isPercussion = True + # return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))] + Notes.append(tracks) + if instruments is []: + instruments.append(0) + instruments = list(set(instruments)) + with open("1.pkl", 'wb') as b: + pickle.dump([instruments, isPercussion], b) + + # for j, track in enumerate(mid.tracks): + # th = NewThread(loadMidi, (track,)) + # th.start() + # Notes.append(th.getResult()) + + # print(Notes) + print(Notes.__len__()) + # print(note_list) + print(instruments) + return Notes + # return [Notes, note_list] + + +def 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") + a = midi_conversion(r"C:\Users\lc\Documents\MuseScore3\乐谱\stay2.mid") + # print(a) diff --git a/nmcsup/trans.py b/nmcsup/trans.py index 6274c17..b86c886 100644 --- a/nmcsup/trans.py +++ b/nmcsup/trans.py @@ -1,245 +1,289 @@ -"""音创系列的转换功能""" -# 诸葛亮与八卦阵帮忙修改语法 日期:---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 - if isProsess: - length = len(Notes) - j = 1 - for i in range(len(Notes)): - commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str( - int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ playsound " + Instrument + " @s ~ ~ ~ 1000 " + str( - Notes[i][0]) + " 1000\n") - a += Notes[i][1] - if isProsess: - commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str( - int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a" + str( - j) + "/" + str(length) + " || " + str(int(j / length * 1000) / 10) + "\n") - j += 1 - commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n") - return commands - - -# 简单载入方块 -# 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 ValueError: - 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]) +"""音创系列的转换功能""" +# 诸葛亮与八卦阵帮忙修改语法 日期:---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(): + + +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 + + +# 简单载入方块 +# 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]) + + +if __name__ == '__main__': + from nmcreader import midi_conversion + path = "L:\\0WorldMusicCreater-MFMS new edition\\框架\\v0.3.2\\Musicreater\\测试用\\同道殊途标准.mid" + b = midi_conversion(path) + classList_conversion(b, "n") diff --git a/nmcsup/vers.py b/nmcsup/vers.py index b056231..f89ce58 100644 --- a/nmcsup/vers.py +++ b/nmcsup/vers.py @@ -1,86 +1,86 @@ -"""音创系列版本号和版本操作函数""" -# 统计:致命(三级)错误: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\\') +"""音创系列版本号和版本操作函数""" +# 统计:致命(三级)错误: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 index 8a08738..fdf509a 100644 --- a/查看代码数.py +++ b/查看代码数.py @@ -1,27 +1,27 @@ -# -*- conding: utf8 -*- - -import os -from msctspt.funcOpera import keepart - - -l = 0 - -for path,dir_list,file_list in os.walk(r"./") : - for file_name in file_list: - if keepart(file_name,'.',None) == '.py': - file = os.path.join(path, file_name) - print("得到文件名:"+str(file)) - for i in open(file,'r',encoding="utf-8"): - code = i.replace(' ','').replace('\n','') - try: - code -= code[code.index('#'):] - except: - pass - if code: - print("\t"+code) - l+=1 - else: - pass - -input("\n最终代码行数为:"+str(l)) - +# -*- conding: utf8 -*- + +import os +from msctspt.funcOpera import keepart + + +l = 0 + +for path,dir_list,file_list in os.walk(r"./") : + for file_name in file_list: + if keepart(file_name,'.',None) == '.py': + file = os.path.join(path, file_name) + print("得到文件名:"+str(file)) + for i in open(file,'r',encoding="utf-8"): + code = i.replace(' ','').replace('\n','') + try: + code -= code[code.index('#'):] + except: + pass + if code: + print("\t"+code) + l+=1 + else: + pass + +input("\n最终代码行数为:"+str(l)) + diff --git a/测试用/1.msct b/测试用/1.msct new file mode 100644 index 0000000..a469726 --- /dev/null +++ b/测试用/1.msct @@ -0,0 +1 @@ +{"mainset": {"PackName": "1", "MusicTitle": "1", "IsRepeat": false, "PlayerSelect": ""}, "musics": [{"set": {"EntityName": "musicSupport1", "ScoreboardName": "musicSupport1", "Instrument": "note.harp", "FileName": "Music"}, "notes": [[1.0, 1.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [1.0, 3.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [0.67, 1.0], [1.0, 2.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.0, 1.0], [1.2, 3.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.6, 1.0], [0.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [0.67, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.2, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.33, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 1.0], [1.2, 1.0], [1.12, 1.0], [1.2, 0.5], [1.2, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 3.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.2, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.33, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 1.0], [1.5, 1.0], [1.2, 0.5], [1.5, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 3.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [1.0, 3.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [0.67, 1.0], [1.0, 2.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.0, 1.0], [1.2, 3.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.6, 1.0], [0.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [0.75, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.6, 1.0], [0.6, 1.0], [0.67, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 0.5], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [1.0, 1.5], [1.5, 1.0], [1.33, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.2, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.33, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 1.0], [1.2, 1.0], [1.12, 1.0], [1.2, 0.5], [1.2, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 3.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.2, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.33, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 1.0], [1.5, 1.0], [1.2, 0.5], [1.5, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [0.9, 5.0], [0.9, 1.0], [0.9, 1.0], [0.9, 1.0], [1.0, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.6, 1.0], [1.2, 3.5], [1.2, 1.0], [1.0, 1.0], [1.2, 6.5], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [1.6, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.2, 1.0], [1.33, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.33, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.0, 1.0], [1.2, 1.0], [1.2, 1.0], [1.12, 1.0], [1.2, 0.5], [1.2, 1.0], [1.2, 0.5], [1.33, 1.0], [1.5, 1.0], [1.2, 0.5], [1.2, 1.0], [1.0, 1.0], [1.6, 1.0], [1.5, 1.0], [1.2, 1.0], [1.2, 1.0], [1.2, 1.0], [1.33, 1.0], [1.2, 1.0], [1.0, 1.0]]}, {"set": {"EntityName": "MusicSupport", "ScoreboardName": "MusicSupport", "Instrument": "note.harp", "FileName": "Music"}, "notes": [[0.3, 1.0], [0.6, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.3, 1.0], [0.6, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.28, 1.0], [0.56, 1.0], [0.28, 1.0], [0.56, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.3, 1.0], [0.6, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.3, 1.0], [0.6, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.28, 1.0], [0.56, 1.0], [0.28, 1.0], [0.56, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 1.0], [0.37, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.25, 1.0], [0.5, 1.0], [0.22, 1.0], [0.44, 1.0], [0.2, 1.0], [0.4, 1.0], [0.25, 1.0], [0.5, 1.0], [0.22, 1.0], [0.44, 1.0], [0.2, 1.0], [0.4, 1.0], [0.25, 1.0], [0.5, 1.0], [0.22, 1.0], [0.44, 1.0], [0.2, 1.0], [0.4, 1.0], [0.25, 1.0], [0.5, 1.0], [0.22, 1.0], [0.44, 1.0], [0.2, 3.9916666666666667], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.28, 1.0], [0.56, 1.0], [0.28, 1.0], [0.56, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.25, 1.0], [0.5, 1.0], [0.19, 0.008333333333333333], [0.37, 1.0], [0.2, 1.9916666666666667], [0.4, 1.0], [0.2, 1.0], [0.4, 1.0], [0.22, 1.0], [0.44, 1.0], [0.22, 1.0], [0.44, 1.0], [0.25, 1.0], [0.5, 1.0], [0.2, 1.0], [0.4, 1.0]]}]} \ No newline at end of file diff --git a/测试用/2.msct b/测试用/2.msct new file mode 100644 index 0000000..7109af6 --- /dev/null +++ b/测试用/2.msct @@ -0,0 +1 @@ +{"mainset": {"PackName": "2", "MusicTitle": "2", "IsRepeat": false, "PlayerSelect": ""}, "musics": [{"set": {"EntityName": "MusicSupport", "ScoreboardName": "MusicSupport", "Instrument": "note.harp", "FileName": "Music"}, "notes": [[1.2, 0.4], [1.25, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.9, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.9, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [1.05, 1.0], [0.44, 0.1], [1.2, 1.0], [0.9, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [0.44, 1.0], [1.25, 1.0], [0.9, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.9, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [1.8, 1.0], [0.44, 1.0], [1.6, 1.0], [0.9, 1.0], [0.44, 1.0], [1.25, 1.0], [1.25, 1.0], [0.44, 1.0], [1.25, 1.0], [0.9, 1.0], [1.2, 1.0], [0.44, 1.0], [1.05, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [1.33, 1.0], [0.67, 1.0], [1.25, 1.0], [0.67, 1.0], [1.25, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 0.1], [1.2, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.05, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [0.44, 1.0], [0.44, 0.1], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [1.05, 1.0], [1.2, 1.0], [0.44, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [0.9, 1.0], [1.25, 0.1], [0.44, 1.0], [1.33, 1.0], [0.9, 1.0], [0.44, 1.0], [1.25, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.25, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [0.44, 0.1], [0.9, 1.0], [1.2, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.05, 1.0], [0.7, 1.0], [0.7, 1.0], [1.25, 1.0], [1.05, 1.0], [0.53, 1.0], [0.7, 1.0], [1.33, 1.0], [1.05, 1.0], [1.25, 1.0], [1.05, 1.0], [1.05, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [1.05, 1.0], [0.53, 1.0], [0.7, 1.0], [1.33, 1.0], [1.05, 1.0], [1.33, 1.0], [1.05, 1.0], [1.8, 1.0], [1.05, 1.0], [0.67, 1.0], [1.6, 1.0], [0.5, 1.0], [0.67, 1.0], [1.25, 1.0], [1.05, 1.0], [1.25, 1.0], [1.05, 1.0], [0.67, 1.0], [1.05, 1.0], [1.25, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [1.2, 1.0], [1.05, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [1.25, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.67, 1.0], [0.9, 1.0], [1.25, 1.0], [1.33, 1.0], [0.44, 0.1], [1.2, 1.0], [0.9, 1.0], [0.67, 1.0], [1.33, 1.0], [1.05, 1.0], [0.9, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.67, 1.0], [0.67, 1.0], [0.9, 1.0], [0.44, 0.2], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [1.2, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [1.05, 1.0], [1.0, 0.1], [0.8, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 0.1], [0.7, 1.0], [0.67, 0.2], [0.8, 1.0], [0.9, 1.0], [0.67, 1.0], [1.33, 1.0], [0.44, 0.1], [0.9, 1.0], [0.8, 1.0], [0.7, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [1.33, 1.0], [1.05, 0.1], [1.33, 1.0], [0.44, 1.0], [0.9, 1.0], [1.05, 1.0], [1.33, 1.0], [1.05, 1.0], [1.33, 1.0], [0.7, 1.0], [1.05, 1.0], [1.33, 1.0], [0.9, 0.1], [0.7, 1.0], [0.67, 1.0], [0.8, 1.0], [0.67, 1.0], [0.9, 1.0], [0.44, 0.1], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [0.7, 1.0], [0.8, 1.0], [0.9, 1.0], [1.6, 1.0], [0.53, 1.0], [1.6, 1.0], [1.33, 1.0], [0.53, 1.0], [1.6, 1.0], [1.33, 1.0], [1.33, 1.0], [1.8, 1.0], [0.44, 1.0], [0.53, 1.0], [0.7, 1.0], [1.6, 1.0], [1.05, 1.0], [1.0, 0.1], [1.2, 1.0], [0.5, 0.1], [0.6, 1.0], [0.8, 1.0], [1.05, 1.0], [0.9, 1.0], [1.0, 1.0], [1.6, 1.0], [1.7, 0.1], [1.0, 1.0], [0.4, 1.0], [0.6, 1.0], [0.7, 1.0], [1.33, 1.0], [1.2, 1.0], [0.7, 1.0], [0.44, 1.0], [0.67, 1.0], [1.05, 1.0], [0.9, 1.0], [0.8, 0.1], [0.67, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [0.7, 1.0], [0.9, 1.0], [1.33, 1.0], [0.6, 1.0], [0.7, 1.0], [0.44, 1.0], [1.2, 1.0], [1.0, 1.0], [1.05, 0.1], [0.9, 1.0], [0.67, 0.1], [0.4, 1.0], [0.5, 1.0], [0.8, 1.0], [1.0, 1.0], [0.8, 1.0], [0.8, 0.1], [0.67, 1.0], [0.67, 1.0], [0.8, 1.0], [0.67, 1.0], [0.8, 1.0], [0.8, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 0.1], [0.53, 1.0], [0.47, 0.1], [1.2, 1.0], [0.9, 1.0], [0.47, 1.0], [1.8, 1.0], [1.2, 1.0], [0.47, 1.0], [0.6, 1.0], [0.47, 1.0], [1.2, 1.0], [0.9, 1.0], [0.47, 1.0], [1.8, 1.0], [1.2, 1.0], [0.9, 1.0], [0.47, 1.0], [0.47, 1.0], [0.6, 1.0], [1.2, 1.0], [0.47, 1.0], [2.1, 1.0], [1.4, 1.0], [0.53, 1.0], [0.53, 1.0], [2.4, 1.0], [0.53, 1.0], [0.67, 1.0], [1.8, 1.0], [1.05, 1.0], [0.53, 1.0], [2.1, 1.0], [1.05, 1.0], [0.53, 1.0], [1.6, 1.0], [1.05, 1.0], [0.8, 1.0], [0.53, 1.0], [0.53, 1.0], [0.67, 1.0], [1.8, 1.0], [1.05, 1.0], [0.9, 1.0], [0.53, 1.0], [0.44, 1.0], [1.05, 1.0], [0.8, 1.0], [0.44, 1.0], [1.6, 1.0], [1.05, 1.0], [0.44, 1.0], [0.53, 1.0], [0.44, 1.0], [1.05, 1.0], [0.8, 1.0], [0.44, 1.0], [1.6, 1.0], [1.05, 1.0], [0.8, 1.0], [0.44, 1.0], [0.44, 1.0], [0.53, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [1.4, 1.0], [1.05, 1.0], [0.6, 1.0], [0.6, 1.0], [1.6, 1.0], [0.9, 1.0], [0.6, 1.0], [1.8, 1.0], [1.4, 1.0], [0.6, 1.0], [2.4, 1.0], [1.8, 1.0], [1.4, 1.0], [0.6, 1.0], [2.1, 1.0], [1.8, 1.0], [1.05, 1.0], [0.6, 1.0], [1.8, 1.0], [0.9, 1.0], [0.9, 1.0], [0.6, 1.0], [1.6, 1.0], [0.8, 1.0], [0.6, 1.0], [1.05, 1.0], [0.47, 1.0], [1.2, 1.0], [0.9, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.33, 1.0], [1.05, 1.0], [0.67, 1.0], [0.47, 1.0], [0.47, 1.0], [1.4, 1.0], [1.2, 1.0], [0.7, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [2.4, 1.0], [1.9, 1.0], [1.2, 1.0], [0.47, 1.0], [0.44, 1.0], [2.24, 1.0], [1.8, 1.0], [1.12, 1.0], [0.44, 1.0], [0.67, 1.0], [0.44, 1.0], [1.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.44, 1.0], [2.67, 1.0], [2.1, 1.0], [1.6, 1.0], [0.44, 1.0], [0.67, 1.0], [0.44, 1.0], [2.83, 1.0], [2.1, 1.0], [1.4, 1.0], [0.44, 1.0], [0.6, 1.0], [2.67, 1.0], [2.1, 1.0], [1.6, 1.0], [1.33, 1.0], [0.6, 1.0], [0.9, 1.0], [0.6, 1.0], [2.1, 1.0], [1.8, 1.0], [1.05, 1.0], [0.6, 1.0], [0.6, 1.0], [1.8, 1.0], [1.05, 1.0], [0.6, 1.0], [0.9, 1.0], [0.6, 1.0], [1.4, 1.0], [0.6, 1.0], [2.4, 1.0], [1.9, 1.0], [1.2, 1.0], [0.53, 1.0], [0.53, 1.0], [2.1, 1.0], [0.8, 1.0], [0.53, 1.0], [2.4, 1.0], [0.53, 1.0], [1.8, 1.0], [1.4, 1.0], [0.53, 1.0], [0.53, 1.0], [1.6, 1.0], [0.8, 1.0], [0.53, 1.0], [1.4, 1.0], [0.53, 1.0], [0.47, 1.0], [2.4, 1.0], [1.9, 1.0], [1.2, 1.0], [0.47, 1.0], [0.47, 1.0], [0.6, 1.0], [0.47, 1.0], [1.8, 1.0], [1.05, 1.0], [0.47, 1.0], [2.1, 1.0], [1.8, 1.0], [1.05, 1.0], [0.47, 1.0], [2.4, 1.0], [1.2, 1.0], [0.47, 1.0], [0.6, 1.0], [0.47, 1.0], [1.8, 1.0], [0.53, 1.0], [2.1, 1.0], [1.33, 1.0], [0.53, 1.0], [1.8, 1.0], [0.53, 1.0], [0.67, 1.0], [2.83, 1.0], [2.4, 1.0], [1.4, 1.0], [0.53, 1.0], [2.67, 1.0], [1.33, 1.0], [0.53, 1.0], [0.53, 1.0], [2.1, 1.0], [1.4, 1.0], [0.53, 1.0], [0.67, 1.0], [2.83, 1.0], [1.4, 1.0], [0.53, 1.0], [2.67, 1.0], [1.33, 1.0], [0.44, 1.0], [0.44, 1.0], [2.1, 1.0], [1.4, 1.0], [0.44, 1.0], [0.53, 1.0], [2.83, 1.0], [1.4, 1.0], [0.44, 1.0], [2.67, 1.0], [1.33, 1.0], [0.44, 1.0], [0.44, 1.0], [2.1, 1.0], [1.4, 1.0], [0.44, 1.0], [0.53, 1.0], [2.83, 1.0], [1.4, 1.0], [0.44, 1.0], [2.67, 1.0], [2.1, 1.0], [1.33, 1.0], [0.6, 1.0], [0.6, 1.0], [2.1, 1.0], [1.05, 1.0], [0.9, 1.0], [0.6, 1.0], [2.4, 1.0], [1.2, 1.0], [0.6, 1.0], [0.6, 1.0], [2.4, 1.0], [1.4, 1.0], [0.6, 1.0], [2.1, 1.0], [0.9, 1.0], [0.6, 1.0], [1.8, 1.0], [0.6, 1.0], [1.6, 1.0], [0.47, 1.0], [1.4, 1.0], [1.05, 1.0], [0.9, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.2, 1.0], [0.9, 1.0], [0.47, 1.0], [0.47, 1.0], [1.4, 1.0], [1.2, 1.0], [0.7, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [2.4, 1.0], [1.9, 1.0], [1.2, 1.0], [0.47, 1.0], [0.53, 1.0], [1.05, 1.0], [1.8, 1.0], [2.1, 1.0], [0.53, 1.0], [0.8, 1.0], [0.53, 1.0], [1.8, 1.0], [1.05, 1.0], [0.53, 1.0], [0.8, 1.0], [0.53, 1.0], [1.2, 1.0], [0.94, 1.0], [0.7, 1.0], [0.53, 1.0], [0.53, 1.0], [1.4, 1.0], [1.05, 1.0], [0.7, 1.0], [0.6, 0.05], [0.7, 1.0], [0.47, 1.0], [0.6, 1.0], [1.2, 1.0], [0.47, 0.1], [1.05, 1.0], [0.53, 1.0], [0.47, 1.0], [1.2, 1.0], [0.6, 1.0], [0.47, 1.0], [1.8, 1.0], [0.9, 1.0], [0.47, 1.0], [1.2, 0.05], [0.6, 1.0], [0.47, 1.0], [0.47, 1.0], [0.6, 1.0], [1.2, 1.0], [0.53, 1.0], [1.2, 1.0], [0.6, 1.0], [0.53, 1.0], [1.05, 1.0], [0.53, 1.0], [1.2, 1.0], [0.6, 1.0], [0.53, 1.0], [1.8, 1.0], [0.9, 1.0], [0.9, 1.0], [0.53, 1.0], [0.53, 1.0], [1.05, 1.0], [1.2, 0.05], [0.53, 1.0], [1.4, 1.0], [0.44, 1.0], [0.6, 1.0], [1.2, 1.0], [0.44, 0.1], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [1.2, 1.0], [0.6, 1.0], [0.44, 1.0], [1.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.6, 0.05], [1.2, 1.0], [0.44, 1.0], [0.44, 1.0], [1.2, 1.0], [0.6, 1.0], [0.6, 1.0], [0.6, 1.0], [1.2, 1.0], [0.6, 1.0], [1.05, 1.0], [0.53, 1.0], [1.2, 1.0], [0.6, 1.0], [0.6, 1.0], [0.9, 1.0], [1.8, 1.0], [0.6, 1.0], [1.05, 1.0], [2.1, 1.0], [0.6, 1.0], [1.6, 1.0], [1.8, 0.05], [0.6, 1.0], [1.6, 1.0], [0.47, 1.0], [0.7, 1.0], [1.4, 1.0], [1.33, 0.05], [0.67, 1.0], [0.47, 0.05], [0.47, 1.0], [0.53, 1.0], [1.05, 1.0], [0.47, 1.0], [0.44, 1.0], [0.9, 1.0], [0.47, 1.0], [0.47, 1.0], [0.53, 1.0], [1.05, 1.0], [0.47, 1.0], [0.44, 1.0], [0.9, 1.0], [1.05, 1.0], [0.8, 0.05], [1.05, 1.0], [0.44, 0.05], [0.44, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.56, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.67, 1.0], [0.44, 1.0], [1.25, 1.0], [0.44, 1.0], [1.33, 1.0], [0.9, 1.0], [0.44, 1.0], [1.25, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.53, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [1.25, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [0.8, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [1.05, 1.0], [0.53, 1.0], [0.44, 1.0], [1.2, 1.0], [0.44, 1.0], [0.44, 1.0], [1.33, 1.0], [0.7, 1.0], [0.7, 1.0], [1.25, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [0.84, 1.0], [1.33, 1.0], [0.7, 1.0], [1.25, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.33, 1.0], [0.67, 1.0], [1.05, 1.0], [1.33, 1.0], [1.8, 1.0], [0.67, 1.0], [1.6, 1.0], [0.67, 1.0], [0.67, 1.0], [1.25, 1.0], [0.8, 1.0], [0.67, 1.0], [1.25, 1.0], [0.67, 1.0], [1.2, 1.0], [0.67, 1.0], [1.05, 1.0], [0.44, 1.0], [1.0, 1.0], [1.2, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [0.53, 1.0], [1.2, 1.0], [0.9, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [0.44, 1.0], [1.2, 1.0], [1.0, 1.0], [0.44, 1.0], [1.33, 1.0], [0.44, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [0.53, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [1.2, 1.0], [0.6, 1.0], [0.9, 1.0], [1.2, 1.0], [0.6, 1.0], [1.4, 1.0], [0.7, 1.0], [0.6, 1.0], [1.2, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [1.33, 1.0], [1.8, 1.0], [0.67, 0.1], [1.8, 1.0], [1.33, 1.0], [0.67, 1.0], [1.8, 1.0], [1.33, 1.0], [0.67, 1.0], [1.8, 1.0], [1.33, 1.0], [0.8, 1.0], [1.8, 1.0], [1.33, 1.0], [0.67, 1.0], [1.8, 1.0], [1.33, 1.0], [0.9, 1.0], [1.8, 1.0], [1.33, 1.0], [0.9, 1.0], [0.44, 1.0], [1.8, 1.0], [1.33, 1.0], [1.05, 1.0], [0.44, 1.0], [0.44, 1.0], [1.8, 1.0], [1.33, 1.0], [0.44, 1.0], [1.7, 1.0], [1.25, 1.0], [0.53, 1.0], [1.8, 1.0], [1.33, 1.0], [0.44, 1.0], [1.7, 1.0], [1.25, 1.0], [0.44, 1.0], [1.8, 1.0], [1.33, 1.0], [0.44, 1.0], [1.7, 1.0], [1.25, 1.0], [0.44, 1.0], [1.6, 1.0], [1.25, 1.0], [1.05, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [1.33, 1.0], [1.05, 1.0], [0.53, 1.0], [0.44, 1.0], [1.2, 1.0], [0.9, 1.0], [0.44, 1.0], [0.44, 1.0], [1.2, 1.0], [0.5, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.6, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.8, 1.0], [1.33, 1.0], [1.05, 1.0], [0.5, 1.0], [1.6, 1.0], [0.5, 1.0], [0.5, 1.0], [1.33, 1.0], [1.05, 1.0], [0.6, 1.0], [0.5, 1.0], [1.33, 1.0], [0.5, 1.0], [1.2, 1.0], [0.5, 1.0], [1.05, 1.0], [0.7, 1.0], [1.2, 1.0], [1.0, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [0.9, 1.0], [1.2, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [0.7, 1.0], [1.2, 1.0], [1.0, 1.0], [0.7, 1.0], [1.33, 1.0], [0.7, 1.0], [0.7, 1.0], [1.33, 1.0], [1.05, 1.0], [0.9, 1.0], [1.33, 1.0], [1.05, 1.0], [0.7, 1.0], [1.33, 1.0], [1.05, 1.0], [0.7, 1.0], [1.33, 1.0], [1.05, 1.0], [0.7, 1.0], [1.05, 1.0], [0.9, 1.0], [1.2, 1.0], [0.6, 1.0], [0.9, 1.0], [1.2, 1.0], [0.6, 1.0], [1.4, 1.0], [0.7, 1.0], [0.6, 1.0], [1.2, 1.0], [0.6, 1.0], [1.33, 1.0], [0.67, 1.0], [1.0, 1.0], [1.6, 1.0], [1.33, 1.0], [1.0, 1.0], [0.67, 1.0], [1.6, 1.0], [1.0, 1.0], [0.8, 1.0], [1.33, 1.0], [0.67, 1.0], [0.8, 1.0], [1.33, 1.0], [1.6, 1.0], [0.67, 1.0], [1.8, 1.0], [0.9, 1.0], [0.67, 1.0], [0.9, 1.0], [1.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [0.7, 1.0], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [1.05, 1.0], [0.53, 1.0], [1.33, 1.0], [0.67, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [1.4, 0.05], [0.7, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 0.1], [1.33, 1.0], [0.44, 0.1], [1.33, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [0.8, 1.0], [0.44, 1.0], [0.9, 1.0], [1.33, 1.0], [0.67, 1.0], [0.44, 1.0], [1.05, 1.0], [1.33, 1.0], [0.44, 1.0], [1.05, 1.0], [1.33, 1.0], [1.05, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.9, 1.0], [1.6, 1.0], [0.67, 1.0], [0.44, 1.0], [1.33, 1.0], [1.6, 1.0], [0.44, 1.0], [1.6, 1.0], [1.33, 1.0], [1.4, 1.0], [1.8, 1.0], [0.7, 1.0], [1.6, 1.0], [0.9, 1.0], [1.05, 1.0], [1.05, 1.0], [1.05, 1.0], [0.9, 1.0], [0.7, 1.0], [0.53, 1.0], [0.7, 1.0], [1.05, 1.0], [0.9, 1.0], [0.7, 1.0], [1.05, 1.0], [0.9, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [1.05, 1.0], [0.7, 1.0], [1.0, 1.0], [1.2, 1.0], [1.05, 1.0], [1.33, 1.0], [0.53, 1.0], [0.7, 1.0], [1.05, 1.0], [1.33, 1.0], [0.7, 1.0], [1.05, 1.0], [1.33, 1.0], [1.4, 1.0], [1.8, 1.0], [0.67, 1.0], [1.7, 1.0], [0.9, 1.0], [1.33, 1.0], [1.33, 1.0], [1.33, 1.0], [0.67, 1.0], [1.33, 1.0], [0.5, 1.0], [0.67, 1.0], [1.33, 1.0], [1.2, 1.0], [1.2, 1.0], [1.25, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.2, 1.0], [1.25, 1.0], [1.33, 1.0], [0.5, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.4, 1.0], [0.9, 1.0], [0.44, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [0.44, 1.0], [0.67, 1.0], [1.33, 1.0], [0.44, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [0.67, 1.0], [0.9, 1.0], [1.05, 1.0], [0.9, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [0.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.8, 1.0], [0.44, 1.0], [0.9, 1.0], [0.4, 1.0], [0.8, 1.0], [0.44, 1.0], [0.9, 1.0], [1.6, 1.0], [0.8, 1.0], [0.67, 1.0], [0.44, 1.0], [0.44, 1.0], [1.6, 1.0], [0.8, 1.0], [1.6, 1.0], [0.8, 1.0], [0.44, 1.0], [1.8, 1.0], [0.9, 1.0], [0.7, 1.0], [1.6, 1.0], [0.8, 1.0], [1.05, 1.0], [1.33, 1.0], [1.05, 1.0], [1.05, 1.0], [0.7, 1.0], [0.9, 1.0], [0.53, 1.0], [0.7, 1.0], [1.05, 1.0], [0.9, 1.0], [0.7, 1.0], [1.05, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 1.0], [0.67, 1.0], [1.33, 1.0], [0.53, 1.0], [0.7, 1.0], [0.9, 1.0], [1.8, 1.0], [0.7, 1.0], [1.0, 1.0], [1.33, 1.0], [2.0, 1.0], [0.67, 1.0], [1.8, 1.0], [0.9, 1.0], [1.0, 1.0], [2.0, 1.0], [0.67, 1.0], [0.9, 1.0], [1.8, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [2.0, 1.0], [0.9, 1.0], [1.8, 1.0], [1.0, 1.0], [2.0, 1.0], [0.67, 1.0], [1.8, 1.0], [0.9, 1.0], [2.0, 1.0], [1.33, 1.0], [1.0, 1.0], [1.8, 1.0], [0.9, 1.0], [0.67, 1.0], [2.0, 1.0], [1.0, 1.0], [1.8, 1.0], [1.05, 1.0], [0.5, 1.0], [0.67, 1.0], [1.33, 1.0], [1.8, 1.0], [2.67, 1.0], [0.67, 1.0], [1.33, 1.0], [2.67, 1.0], [1.2, 1.0], [2.4, 1.0], [0.67, 1.0], [2.67, 1.0], [1.33, 1.0], [0.53, 1.0], [0.44, 1.0], [2.1, 1.0], [1.8, 1.0], [1.8, 0.05], [1.05, 1.0], [0.9, 0.05], [0.44, 1.0], [1.05, 1.0], [0.53, 1.0], [0.9, 1.0], [0.44, 1.0], [1.05, 1.0], [0.53, 1.0], [1.33, 1.0], [0.67, 1.0], [1.4, 1.0], [0.7, 1.0], [1.4, 0.05], [0.7, 1.0], [1.4, 0.05], [0.7, 1.0], [1.33, 1.0], [0.67, 1.0], [1.4, 1.0], [0.7, 1.0], [1.33, 1.0], [0.67, 1.0], [1.05, 1.0], [0.53, 1.0], [0.9, 1.0], [0.44, 1.0], [0.9, 0.05], [0.44, 1.0], [0.9, 0.05], [0.44, 1.0], [1.05, 1.0], [0.53, 1.0], [0.9, 1.0], [0.44, 1.0], [1.05, 1.0], [0.53, 1.0], [1.33, 1.0], [0.67, 1.0], [1.4, 1.0], [0.7, 1.0], [1.4, 0.05], [0.7, 1.0], [0.7, 0.05], [1.8, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [1.8, 1.0], [2.67, 1.0], [0.7, 1.0], [2.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.2, 1.0], [2.4, 1.0], [0.53, 1.0], [2.67, 1.0], [1.33, 1.0], [1.8, 1.0], [0.53, 1.0], [0.44, 1.0], [2.1, 1.0], [0.44, 0.05], [1.8, 1.0], [1.05, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.7, 0.05], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.7, 1.0], [1.4, 1.0], [0.67, 1.0], [1.33, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.44, 0.05], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.44, 1.0], [0.9, 1.0], [0.53, 1.0], [1.05, 1.0], [0.67, 1.0], [1.33, 1.0], [1.2, 0.4], [1.12, 0.1], [0.4, 0.1], [0.5, 1.0], [0.75, 1.0], [1.0, 1.0], [1.5, 1.0], [1.33, 0.1], [1.5, 1.0], [1.0, 0.1], [1.8, 1.0], [0.44, 1.0], [0.56, 1.0], [0.67, 1.0], [2.0, 0.1], [1.5, 1.0], [1.8, 1.0], [1.33, 1.0], [1.5, 0.1], [1.2, 1.0], [0.37, 0.1], [0.56, 1.0], [0.67, 1.0], [0.9, 1.0], [1.33, 1.0], [0.9, 0.1], [1.33, 1.0], [1.12, 0.1], [1.0, 1.0], [1.2, 1.0], [0.6, 1.0], [0.37, 1.0], [0.5, 1.0], [1.2, 0.1], [1.33, 1.0], [2.0, 1.0], [0.6, 1.0], [0.37, 1.0], [0.44, 1.0], [1.8, 1.0], [1.5, 1.0], [1.33, 1.0], [0.9, 1.0], [0.4, 1.0], [0.6, 1.0], [0.75, 1.0], [1.0, 1.0], [0.9, 0.1], [1.0, 1.0], [2.0, 0.1], [0.37, 0.1], [0.56, 1.0], [0.67, 1.0], [1.9, 1.0], [1.12, 1.0], [1.5, 1.0], [0.47, 0.1], [0.67, 1.0], [0.8, 1.0], [1.5, 1.0], [2.24, 1.0], [2.4, 1.0], [0.6, 0.1], [0.4, 1.0], [0.5, 1.0], [1.8, 1.0], [2.24, 1.0], [1.8, 1.0], [1.5, 0.1], [1.2, 0.1], [2.0, 1.0], [0.44, 1.0], [0.67, 1.0], [0.8, 1.0], [1.8, 0.1], [2.0, 1.0], [1.5, 1.0], [1.2, 1.0], [0.37, 1.0], [0.5, 1.0], [0.6, 1.0], [1.33, 0.1], [1.2, 1.0], [0.4, 0.1], [2.0, 1.0], [1.6, 1.0], [1.0, 1.0], [0.6, 1.0], [0.8, 1.0], [1.5, 0.1], [1.8, 1.0], [0.4, 1.0], [2.0, 1.0], [0.6, 1.0], [0.8, 1.0], [1.5, 1.0], [0.44, 1.0], [1.12, 1.0], [1.8, 1.0], [1.5, 1.0], [0.67, 1.0], [0.9, 1.0], [2.4, 1.0], [2.24, 1.0], [1.8, 0.1], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [1.8, 1.0], [2.4, 1.0], [0.44, 1.0], [2.24, 1.0], [0.47, 1.0], [1.8, 0.1], [0.7, 1.0], [0.94, 1.0], [2.4, 1.0], [1.8, 1.0], [2.24, 1.0], [0.47, 0.1], [1.8, 1.0], [0.7, 1.0], [0.94, 1.0], [2.4, 1.0], [1.8, 1.0], [1.8, 1.0], [2.24, 1.0], [0.5, 1.0], [1.8, 0.1], [0.75, 1.0], [1.0, 1.0], [2.0, 1.0], [1.2, 1.0], [2.0, 1.0], [0.5, 1.0], [1.8, 1.0], [0.75, 1.0], [1.0, 1.0], [1.5, 1.0], [1.33, 1.0], [0.4, 1.0], [1.2, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [0.8, 1.0], [1.0, 1.0], [1.2, 1.0], [0.4, 1.0], [0.6, 0.1], [0.8, 1.0], [1.0, 1.0], [2.0, 1.0], [0.44, 1.0], [0.9, 1.0], [1.2, 1.0], [1.8, 1.0], [0.67, 1.0], [0.9, 1.0], [0.94, 1.0], [1.9, 1.0], [0.94, 0.1], [0.9, 1.0], [0.84, 1.0], [0.8, 1.0], [0.75, 1.0], [0.7, 1.0], [0.67, 1.0], [0.63, 1.0], [0.6, 1.0], [0.56, 1.0], [0.53, 1.0], [0.5, 1.0], [0.47, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [1.9, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [0.63, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [1.9, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.25, 1.0], [0.5, 1.0], [2.24, 1.0], [1.5, 1.0], [0.56, 1.0], [0.56, 1.0], [2.5, 1.0], [0.56, 1.0], [0.7, 1.0], [1.9, 1.0], [1.12, 1.0], [0.56, 1.0], [2.24, 1.0], [1.12, 1.0], [0.56, 1.0], [1.7, 1.0], [1.12, 1.0], [0.84, 1.0], [0.56, 1.0], [0.56, 1.0], [0.7, 1.0], [1.9, 1.0], [1.12, 1.0], [0.94, 1.0], [0.56, 1.0], [0.47, 1.0], [1.12, 1.0], [0.84, 1.0], [0.47, 1.0], [1.7, 1.0], [1.12, 1.0], [0.84, 1.0], [0.47, 1.0], [0.56, 1.0], [0.47, 1.0], [1.12, 1.0], [0.84, 1.0], [0.47, 1.0], [1.7, 1.0], [1.12, 1.0], [0.84, 1.0], [0.47, 1.0], [0.47, 1.0], [0.56, 1.0], [1.4, 1.0], [1.12, 1.0], [0.47, 1.0], [1.5, 1.0], [1.12, 1.0], [0.63, 1.0], [0.63, 1.0], [1.5, 1.0], [0.94, 1.0], [0.63, 1.0], [1.7, 1.0], [1.4, 1.0], [0.63, 1.0], [2.5, 1.0], [1.7, 1.0], [1.4, 1.0], [0.63, 1.0], [2.24, 1.0], [1.9, 1.0], [1.12, 1.0], [0.63, 1.0], [1.9, 1.0], [0.94, 1.0], [0.94, 1.0], [0.63, 1.0], [1.7, 1.0], [0.84, 1.0], [0.63, 1.0], [1.12, 1.0], [0.5, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [1.4, 1.0], [1.12, 1.0], [0.7, 1.0], [0.5, 1.0], [0.5, 1.0], [1.5, 1.0], [1.25, 1.0], [0.75, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [2.5, 1.0], [2.0, 1.0], [1.25, 1.0], [0.5, 1.0], [0.47, 1.0], [2.4, 1.0], [1.8, 1.0], [1.2, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.9, 1.0], [0.94, 1.0], [0.47, 1.0], [0.47, 1.0], [2.83, 1.0], [2.4, 1.0], [1.7, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [3.0, 1.0], [2.4, 1.0], [1.5, 1.0], [0.47, 1.0], [0.63, 1.0], [2.83, 1.0], [2.24, 1.0], [1.7, 1.0], [1.4, 1.0], [0.63, 1.0], [0.94, 1.0], [0.63, 1.0], [2.24, 1.0], [1.12, 1.0], [0.63, 1.0], [0.63, 1.0], [1.9, 1.0], [1.12, 1.0], [0.63, 1.0], [0.94, 1.0], [0.63, 1.0], [1.5, 1.0], [0.63, 1.0], [2.5, 1.0], [2.0, 1.0], [1.25, 1.0], [0.56, 1.0], [0.56, 1.0], [2.24, 1.0], [0.84, 1.0], [0.56, 1.0], [2.5, 1.0], [0.56, 1.0], [1.9, 1.0], [1.5, 1.0], [0.56, 1.0], [0.56, 1.0], [1.7, 1.0], [0.84, 1.0], [0.56, 1.0], [1.5, 1.0], [0.56, 1.0], [0.5, 1.0], [2.5, 1.0], [2.0, 1.0], [1.25, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [0.5, 1.0], [1.9, 1.0], [1.12, 1.0], [0.5, 1.0], [2.24, 1.0], [1.9, 1.0], [1.12, 1.0], [0.5, 1.0], [2.5, 1.0], [1.25, 1.0], [0.5, 1.0], [0.63, 1.0], [0.5, 1.0], [1.9, 1.0], [0.56, 1.0], [2.24, 1.0], [1.4, 1.0], [0.56, 1.0], [1.9, 1.0], [0.56, 1.0], [0.7, 1.0], [3.0, 1.0], [2.5, 1.0], [1.5, 1.0], [0.56, 1.0], [2.83, 1.0], [1.4, 1.0], [0.56, 1.0], [0.56, 1.0], [2.24, 1.0], [1.5, 1.0], [0.56, 1.0], [0.7, 1.0], [3.0, 1.0], [1.5, 1.0], [0.56, 1.0], [2.83, 1.0], [1.4, 1.0], [0.47, 1.0], [0.47, 1.0], [2.24, 1.0], [1.5, 1.0], [0.47, 1.0], [0.56, 1.0], [3.0, 1.0], [1.5, 1.0], [0.47, 1.0], [2.83, 1.0], [1.4, 1.0], [0.47, 1.0], [0.47, 1.0], [2.24, 1.0], [1.5, 1.0], [0.47, 1.0], [0.56, 1.0], [3.0, 1.0], [1.5, 1.0], [0.47, 1.0], [2.83, 1.0], [2.24, 1.0], [1.4, 1.0], [0.63, 1.0], [0.63, 1.0], [2.24, 1.0], [1.12, 1.0], [0.94, 1.0], [0.63, 1.0], [2.5, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [2.5, 1.0], [1.5, 1.0], [0.63, 1.0], [2.24, 1.0], [0.94, 1.0], [0.63, 1.0], [1.9, 1.0], [0.63, 1.0], [1.7, 1.0], [0.5, 1.0], [1.5, 1.0], [1.12, 1.0], [0.94, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.5, 1.0], [1.25, 1.0], [0.75, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [2.5, 1.0], [2.0, 1.0], [1.25, 1.0], [0.5, 1.0], [0.56, 1.0], [2.24, 1.0], [1.9, 1.0], [1.12, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.9, 1.0], [1.12, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.25, 1.0], [1.0, 1.0], [0.75, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.5, 1.0], [0.75, 1.0], [0.56, 1.0], [0.5, 1.0], [1.9, 1.0], [1.5, 1.0], [1.12, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [1.25, 1.0], [1.0, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [0.5, 1.0], [0.56, 1.0], [1.7, 1.0], [0.94, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.9, 1.0], [1.12, 1.0], [0.94, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.5, 1.0], [1.12, 1.0], [0.56, 1.0], [0.84, 1.0], [0.56, 1.0], [1.4, 1.0], [1.12, 1.0], [0.56, 1.0], [0.47, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.12, 1.0], [0.94, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.5, 1.0], [1.12, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.4, 1.0], [1.12, 1.0], [0.47, 1.0], [0.63, 1.0], [0.63, 1.0], [0.47, 1.0], [0.63, 1.0], [1.12, 1.0], [0.94, 1.0], [0.63, 1.0], [0.47, 1.0], [0.63, 1.0], [1.25, 1.0], [0.94, 1.0], [0.63, 1.0], [0.47, 1.0], [0.63, 1.0], [0.75, 1.0], [0.94, 1.0], [0.63, 1.0], [0.5, 1.0], [1.25, 1.0], [1.0, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [1.4, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [1.5, 1.0], [1.25, 1.0], [0.5, 1.0], [0.75, 1.0], [0.5, 1.0], [1.9, 1.0], [1.5, 1.0], [0.5, 1.0], [0.47, 1.0], [1.7, 1.0], [1.4, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.4, 1.0], [1.12, 1.0], [0.47, 1.0], [0.7, 1.0], [0.47, 1.0], [1.5, 1.0], [1.25, 1.0], [0.47, 1.0], [0.63, 1.0], [1.7, 1.0], [1.4, 1.0], [0.63, 1.0], [0.94, 1.0], [0.63, 1.0], [1.25, 1.0], [1.5, 1.0], [0.63, 1.0], [0.94, 1.0], [0.63, 1.0], [1.4, 1.0], [1.7, 1.0], [0.63, 1.0], [0.94, 1.0], [0.63, 1.0], [1.7, 1.0], [2.24, 1.0], [0.63, 1.0], [0.56, 1.0], [1.5, 1.0], [2.0, 1.0], [0.56, 1.0], [0.84, 1.0], [1.12, 1.0], [0.56, 1.0], [0.94, 1.0], [1.9, 1.0], [0.75, 1.0], [0.94, 1.0], [0.37, 1.0], [1.9, 1.0], [0.94, 1.0], [0.75, 1.0], [0.94, 1.0], [2.24, 1.0], [1.9, 1.0], [0.37, 1.0], [1.9, 1.0], [1.12, 1.0], [0.42, 1.0], [2.24, 1.0], [1.12, 1.0], [0.42, 1.0], [2.5, 1.0], [1.25, 1.0], [0.84, 1.0], [1.0, 1.0], [0.42, 1.0], [1.9, 1.0], [1.12, 1.0], [0.84, 1.0], [1.0, 1.0], [2.24, 1.0], [1.12, 1.0], [0.42, 1.0], [2.5, 1.0], [1.25, 1.0], [0.84, 1.0], [1.0, 1.0], [0.42, 1.0], [1.9, 1.0], [0.5, 1.0], [2.24, 1.0], [1.4, 1.0], [0.5, 1.0], [1.9, 1.0], [0.75, 1.0], [1.0, 1.0], [3.0, 1.0], [2.5, 1.0], [1.5, 1.0], [0.5, 1.0], [2.83, 1.0], [1.4, 1.0], [0.75, 1.0], [1.0, 1.0], [0.5, 1.0], [2.24, 1.0], [1.5, 1.0], [0.75, 1.0], [1.0, 1.0], [3.0, 1.0], [1.5, 1.0], [0.5, 1.0], [2.83, 1.0], [1.4, 1.0], [0.47, 1.0], [0.47, 1.0], [2.24, 1.0], [1.5, 1.0], [0.7, 1.0], [0.94, 1.0], [3.0, 1.0], [1.5, 1.0], [0.47, 1.0], [2.83, 1.0], [1.4, 1.0], [0.7, 1.0], [0.94, 1.0], [0.47, 1.0], [2.24, 1.0], [1.5, 1.0], [0.7, 1.0], [0.94, 1.0], [3.0, 1.0], [1.5, 1.0], [0.47, 1.0], [2.83, 1.0], [2.24, 1.0], [1.4, 1.0], [0.63, 1.0], [0.63, 1.0], [2.24, 1.0], [1.12, 1.0], [0.63, 1.0], [0.75, 1.0], [2.5, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [0.75, 1.0], [2.5, 1.0], [1.5, 1.0], [0.63, 1.0], [2.24, 1.0], [0.63, 1.0], [0.75, 1.0], [1.9, 1.0], [0.63, 1.0], [1.7, 1.0], [0.5, 1.0], [1.5, 1.0], [1.12, 1.0], [0.94, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.25, 1.0], [0.94, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.5, 1.0], [1.25, 1.0], [0.75, 1.0], [0.5, 1.0], [0.5, 1.0], [0.63, 1.0], [1.9, 1.0], [1.12, 1.0], [0.94, 1.0], [0.5, 1.0], [0.56, 1.0], [2.24, 1.0], [1.9, 1.0], [1.12, 1.0], [0.56, 1.0], [0.7, 1.0], [0.56, 1.0], [1.9, 1.0], [1.12, 1.0], [0.56, 1.0], [0.47, 1.0], [2.24, 1.0], [1.9, 1.0], [1.12, 1.0], [0.47, 1.0], [0.63, 1.0], [2.5, 1.0], [1.9, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [0.63, 0.05], [1.25, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.94, 1.0], [1.9, 1.0], [0.42, 1.0], [0.84, 1.0], [1.0, 1.0], [2.0, 1.0], [1.0, 0.05], [2.0, 1.0], [0.84, 0.05], [0.42, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [1.25, 1.0], [0.63, 0.05], [1.25, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.94, 1.0], [1.9, 1.0], [0.42, 1.0], [0.84, 1.0], [1.0, 1.0], [2.0, 1.0], [1.0, 0.05], [2.0, 1.0], [0.84, 0.05], [0.42, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [0.6, 1.0], [1.2, 1.0], [0.63, 1.0], [1.25, 1.0], [0.63, 0.05], [1.25, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.63, 1.0], [1.25, 1.0], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [0.63, 1.0], [0.94, 1.0], [1.9, 1.0], [0.42, 1.0], [0.84, 1.0], [1.0, 1.0], [2.0, 1.0], [1.0, 0.05], [2.0, 1.0], [0.84, 0.05], [0.42, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [1.0, 1.0], [2.0, 1.0], [0.94, 1.0], [0.94, 1.0], [1.9, 1.0], [0.47, 1.0], [0.75, 1.0], [1.5, 1.0], [1.25, 1.0], [0.63, 1.0], [0.63, 0.05], [1.25, 1.0], [0.63, 0.05], [1.25, 1.0], [0.75, 1.0], [1.5, 1.0], [1.25, 1.0], [0.63, 1.0], [1.25, 1.0], [1.5, 1.0], [0.75, 1.0], [1.5, 1.0], [1.9, 1.0], [0.94, 1.0], [1.9, 1.0], [1.7, 1.0], [0.84, 1.0], [1.7, 1.0], [0.84, 0.05], [1.7, 1.0], [2.0, 0.05], [1.0, 1.0], [1.8, 1.0], [1.9, 1.0], [0.94, 1.0], [1.9, 1.0], [0.7, 1.0], [1.4, 1.0], [0.56, 1.0], [1.12, 1.0], [0.6, 1.0], [1.2, 1.0], [0.63, 1.0], [1.25, 1.0]]}]} \ No newline at end of file diff --git a/测试用/3.msct b/测试用/3.msct new file mode 100644 index 0000000..fa3c9ad --- /dev/null +++ b/测试用/3.msct @@ -0,0 +1 @@ +{"mainset": {"PackName": "3", "MusicTitle": "3", "IsRepeat": false, "PlayerSelect": ""}, "musics": [{"set": {"EntityName": "musicSupport3", "ScoreboardName": "musicSupport3", "Instrument": "note.harp", "FileName": "Music"}, "notes": [[0.75, 8.933333333333334], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [1.0, 1.0], [1.12, 1.0], [0.84, 1.0], [0.75, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [0.94, 1.0], [1.12, 1.0], [1.12, 1.0], [0.94, 1.0], [0.94, 1.0], [1.12, 1.0], [1.12, 1.0], [0.84, 1.0], [0.75, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [1.12, 1.0], [1.12, 1.0], [0.84, 0.3333333333333333], [0.75, 1.0], [0.84, 1.0], [0.75, 1.0], [1.12, 1.0], [0.75, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.75, 0.3333333333333333], [0.84, 1.0], [0.94, 1.0], [0.94, 1.0], [1.12, 1.0], [1.12, 1.0], [0.75, 1.0], [0.84, 1.0], [0.75, 0.1], [0.7, 1.0], [0.75, 1.0], [0.75, 0.36666666666666664], [0.84, 1.0], [0.94, 1.0], [0.75, 1.0], [1.4, 1.0], [1.4, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.75, 0.36666666666666664], [0.75, 0.1], [0.75, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.84, 1.0], [0.75, 1.8666666666666667], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.25, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [1.5, 1.0], [1.4, 1.0], [1.12, 0.13333333333333333], [1.12, 1.0], [1.12, 1.0], [1.5, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.75, 1.0], [0.7, 1.0], [0.56, 1.0], [0.94, 0.1], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 1.0], [0.75, 0.4], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 0.03333333333333333], [0.94, 1.0], [1.5, 1.0], [1.4, 1.0], [1.12, 0.13333333333333333], [1.12, 1.0], [1.12, 1.0], [1.4, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.56, 0.13333333333333333], [0.94, 1.0], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [1.25, 1.0], [1.12, 1.0], [1.12, 1.0], [1.5, 0.13333333333333333], [1.12, 1.0], [1.0, 1.0], [0.94, 1.0], [1.12, 1.0], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [1.7, 15.666666666666666], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.25, 1.0], [1.7, 1.0], [1.9, 1.0], [1.9, 1.0], [1.7, 0.5333333333333333], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.12, 1.0], [1.7, 1.0], [1.5, 1.0], [1.5, 1.0], [1.4, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.75, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 0.5333333333333333], [0.94, 1.0], [1.12, 1.0], [0.84, 0.26666666666666666], [0.94, 1.0], [1.25, 1.0], [0.84, 0.26666666666666666], [0.94, 1.0], [1.12, 1.0], [0.94, 1.0], [1.12, 1.0], [1.25, 0.26666666666666666], [1.5, 1.0], [1.7, 1.0], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.12, 1.0], [1.7, 1.0], [1.9, 1.0], [1.9, 1.0], [1.7, 0.5333333333333333], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.12, 1.0], [1.7, 1.0], [1.5, 1.0], [1.5, 1.0], [1.4, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.75, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 0.5333333333333333], [0.84, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 0.1], [0.94, 1.0], [1.25, 1.0], [1.12, 1.0], [1.9, 1.0], [1.25, 1.0], [1.12, 1.0], [1.12, 1.0], [0.75, 0.8], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.12, 1.0], [1.25, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 1.0], [0.94, 1.0], [1.5, 1.0], [1.4, 1.0], [1.12, 0.13333333333333333], [1.12, 1.0], [1.12, 1.0], [1.5, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.75, 1.0], [0.7, 1.0], [0.56, 1.0], [0.94, 0.1], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 1.0], [0.75, 0.4], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [1.25, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 0.03333333333333333], [0.94, 1.0], [1.5, 1.0], [1.4, 1.0], [1.12, 0.13333333333333333], [1.12, 1.0], [1.12, 1.0], [1.4, 1.0], [0.94, 1.0], [0.84, 1.0], [0.94, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.7, 1.0], [0.75, 1.0], [0.56, 0.13333333333333333], [0.94, 1.0], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [1.25, 1.0], [1.12, 1.0], [1.12, 1.0], [1.5, 0.13333333333333333], [1.12, 1.0], [1.0, 1.0], [0.94, 1.0], [1.12, 1.0], [0.94, 1.0], [0.84, 1.0], [0.75, 1.0], [1.7, 1.0], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.25, 1.0], [1.7, 1.0], [1.9, 1.0], [1.9, 1.0], [1.7, 0.5333333333333333], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.12, 1.0], [1.7, 1.0], [1.5, 1.0], [1.5, 1.0], [1.4, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.75, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 0.5333333333333333], [0.84, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 1.0], [0.84, 1.0], [0.75, 1.0], [0.84, 1.0], [0.94, 1.0], [0.84, 0.1], [0.94, 1.0], [1.25, 1.0], [1.12, 1.0], [1.9, 1.0], [1.25, 1.0], [1.12, 1.0], [1.12, 1.0], [1.25, 0.36666666666666664], [1.5, 1.0], [1.7, 1.0], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.25, 1.0], [1.7, 1.0], [1.9, 1.0], [1.9, 1.0], [1.7, 0.5333333333333333], [1.9, 1.0], [1.25, 1.0], [1.5, 1.0], [1.7, 1.0], [1.5, 1.0], [1.12, 1.0], [2.24, 1.0], [1.5, 1.0], [1.5, 1.0], [1.4, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.75, 0.26666666666666666], [1.5, 1.0], [1.4, 1.0], [0.94, 1.0], [0.75, 1.0], [0.75, 1.0], [0.84, 0.5333333333333333], [0.94, 1.0], [1.12, 1.0], [0.84, 0.26666666666666666], [0.94, 1.0], [1.25, 1.0], [0.84, 0.26666666666666666], [0.94, 1.0], [1.12, 1.0], [0.94, 1.0], [1.12, 1.0], [0.94, 0.5333333333333333], [1.12, 1.0], [1.25, 1.0], [0.94, 0.26666666666666666], [0.84, 1.0], [0.75, 1.0], [0.94, 0.26666666666666666], [1.12, 1.0], [1.25, 1.0], [0.94, 1.0], [1.5, 1.0], [0.84, 0.5333333333333333], [0.94, 1.0], [1.12, 1.0], [0.94, 1.0], [1.12, 1.0]]}]} \ No newline at end of file diff --git a/测试用/4.msct b/测试用/4.msct new file mode 100644 index 0000000..2202bdb --- /dev/null +++ b/测试用/4.msct @@ -0,0 +1 @@ +{"mainset": {"PackName": "4", "MusicTitle": "4", "IsRepeat": false, "PlayerSelect": ""}, "musics": [{"set": {"EntityName": "musicSupport4", "ScoreboardName": "musicSupport4", "Instrument": "note.harp", "FileName": "Music"}, "notes": [[0.5, 1.0], [0.56, 1.0], [0.44, 1.0], [0.44, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.44, 1.0], [0.6, 1.0], [0.37, 1.0], [0.67, 1.0], [0.37, 1.0], [0.44, 1.0], [0.5, 1.0], [0.56, 1.0], [0.42, 1.0], [0.67, 1.0], [0.5, 1.0], [0.56, 1.0], [0.67, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.37, 1.0], [0.44, 1.0], [0.67, 1.0], [0.56, 1.0], [0.67, 1.0], [0.56, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.44, 1.0], [0.6, 1.0], [0.37, 1.0], [0.67, 1.0], [0.37, 1.0], [0.44, 1.0], [0.5, 1.0], [0.44, 1.0], [0.67, 1.0], [0.56, 1.0], [0.42, 1.0], [0.5, 1.0], [0.56, 1.0], [0.67, 1.0], [0.56, 1.0], [0.5, 1.0], [0.37, 1.0], [0.44, 1.0], [1.0, 1.0], [0.67, 1.0], [0.9, 1.0], [0.56, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.75, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [0.84, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [0.67, 1.0], [0.84, 1.0], [0.37, 1.0], [0.9, 1.0], [1.33, 1.0], [0.5, 1.0], [1.12, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [0.67, 1.0], [0.84, 1.0], [0.56, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.67, 1.0], [0.37, 1.0], [0.9, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [1.0, 0.075], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [0.9, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [1.12, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [1.0, 0.07291666666666667], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [0.9, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [0.9, 1.0], [1.5, 1.0], [1.33, 1.0], [1.8, 1.0], [2.0, 1.0], [2.24, 1.0], [1.12, 1.0], [0.44, 1.0], [0.56, 1.0], [0.56, 1.0], [1.12, 1.0], [0.67, 1.0], [1.0, 1.0], [1.12, 1.0], [0.56, 1.0], [0.56, 1.0], [0.42, 1.0], [1.0, 1.0], [0.9, 1.0], [0.75, 1.0], [0.67, 1.0], [0.44, 1.0], [0.6, 1.0], [1.12, 1.0], [0.37, 1.0], [0.6, 1.0], [0.44, 1.0], [1.33, 1.0], [1.5, 1.0], [1.8, 1.0], [2.0, 1.0], [2.24, 1.0], [0.67, 1.0], [1.12, 1.0], [0.5, 1.0], [1.0, 1.0], [0.67, 1.0], [1.12, 1.0], [0.42, 1.0], [0.5, 1.0], [1.33, 1.0], [0.67, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [0.37, 1.0], [0.84, 1.0], [0.56, 1.0], [0.37, 1.0], [0.9, 1.0], [0.44, 1.0], [1.33, 1.0], [0.75, 1.0], [0.56, 1.0], [1.5, 1.0], [1.33, 1.0], [1.8, 1.0], [2.0, 1.0], [1.8, 1.0], [2.24, 1.0], [1.12, 1.0], [0.44, 1.0], [0.56, 1.0], [0.56, 1.0], [1.12, 1.0], [0.67, 1.0], [1.0, 1.0], [0.56, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.75, 1.0], [0.67, 1.0], [0.44, 1.0], [0.6, 1.0], [1.12, 1.0], [0.37, 1.0], [0.6, 1.0], [1.33, 1.0], [1.5, 1.0], [1.8, 1.0], [2.0, 1.0], [1.12, 1.0], [1.7, 1.0], [2.24, 1.0], [0.5, 1.0], [1.0, 1.0], [0.67, 1.0], [1.12, 1.0], [0.42, 1.0], [1.33, 1.0], [0.67, 1.0], [0.5, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.37, 1.0], [0.56, 1.0], [0.37, 1.0], [0.44, 1.0], [0.56, 1.0], [0.75, 1.0], [0.56, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 1.0], [0.44, 1.0], [0.44, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.6, 1.0], [0.75, 1.0], [0.37, 1.0], [0.44, 1.0], [0.44, 1.0], [0.56, 1.0], [0.67, 1.0], [0.37, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [1.12, 1.0], [0.84, 1.0], [1.0, 1.0], [0.5, 1.0], [1.12, 1.0], [0.42, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [0.37, 1.0], [0.84, 1.0], [0.56, 1.0], [0.9, 1.0], [0.67, 1.0], [0.44, 1.0], [0.75, 1.0], [0.56, 1.0], [1.33, 1.0], [1.12, 1.0], [0.67, 1.0], [0.44, 1.0], [0.9, 1.0], [1.12, 1.0], [0.67, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.75, 1.0], [0.37, 1.0], [0.44, 1.0], [0.44, 1.0], [0.56, 1.0], [0.37, 1.0], [0.67, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [0.84, 1.0], [0.5, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [0.42, 1.0], [1.12, 1.0], [1.0, 1.0], [0.37, 1.0], [0.9, 1.0], [0.56, 1.0], [0.44, 1.0], [0.5, 1.0], [1.33, 1.0], [0.67, 1.0], [0.44, 1.0], [0.56, 1.0], [0.9, 1.0], [1.33, 1.0], [0.44, 1.0], [1.8, 1.0], [0.5, 1.0], [1.33, 1.0], [0.9, 1.0], [0.56, 1.0], [1.33, 1.0], [0.5, 1.0], [0.44, 1.0], [1.8, 1.0], [0.37, 1.0], [0.6, 1.0], [1.5, 1.0], [0.9, 1.0], [1.5, 1.0], [1.5, 1.0], [1.8, 1.0], [0.67, 1.0], [1.5, 1.0], [0.37, 1.0], [1.5, 1.0], [0.37, 1.0], [0.44, 1.0], [0.5, 1.0], [1.8, 1.0], [0.56, 1.0], [0.42, 1.0], [0.37, 1.0], [1.33, 1.0], [1.0, 1.0], [1.33, 1.0], [0.5, 1.0], [0.56, 1.0], [0.67, 1.0], [1.33, 1.0], [0.56, 1.0], [1.33, 1.0], [0.5, 1.0], [1.7, 1.0], [0.37, 1.0], [0.56, 1.0], [1.33, 1.0], [1.12, 1.0], [1.33, 1.0], [1.7, 1.0], [0.44, 1.0], [1.5, 1.0], [1.33, 1.0], [1.12, 1.0], [0.67, 1.0], [0.56, 1.0], [1.33, 1.0], [0.67, 1.0], [0.56, 1.0], [0.9, 1.0], [1.33, 1.0], [0.56, 1.0], [1.8, 1.0], [0.5, 1.0], [1.33, 1.0], [0.9, 1.0], [0.56, 1.0], [1.33, 1.0], [0.5, 1.0], [1.33, 1.0], [0.44, 1.0], [1.8, 1.0], [0.6, 1.0], [0.37, 1.0], [1.5, 1.0], [1.5, 1.0], [1.8, 1.0], [1.5, 1.0], [0.67, 1.0], [1.33, 1.0], [0.9, 1.0], [0.37, 1.0], [0.44, 1.0], [1.5, 1.0], [1.8, 1.0], [0.5, 1.0], [0.42, 1.0], [0.56, 1.0], [1.33, 1.0], [1.0, 1.0], [0.5, 1.0], [1.33, 1.0], [1.33, 1.0], [0.56, 1.0], [1.33, 1.0], [0.67, 1.0], [0.56, 1.0], [1.0, 1.0], [0.5, 1.0], [1.33, 1.0], [1.33, 1.0], [1.7, 1.0], [1.33, 1.0], [0.44, 1.0], [0.37, 1.0], [1.12, 1.0], [1.33, 1.0], [1.7, 1.0], [1.5, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [1.0, 1.0], [0.67, 1.0], [0.44, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.67, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 1.0], [0.6, 1.0], [0.75, 1.0], [0.44, 1.0], [1.0, 1.0], [1.0, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [1.12, 1.0], [0.9, 1.0], [0.5, 1.0], [1.0, 1.0], [0.67, 1.0], [0.6, 1.0], [1.0, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [1.0, 1.0], [0.56, 1.0], [0.9, 1.0], [0.56, 1.0], [1.0, 1.0], [0.37, 1.0], [0.5, 1.0], [0.5, 1.0], [1.12, 1.0], [0.9, 1.0], [0.44, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.56, 1.0], [0.44, 1.0], [0.44, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.67, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 1.0], [0.6, 1.0], [0.75, 1.0], [0.44, 1.0], [1.0, 1.0], [0.75, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [1.12, 1.0], [0.9, 1.0], [0.67, 1.0], [0.6, 1.0], [1.0, 1.0], [0.5, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [0.56, 1.0], [0.9, 1.0], [0.56, 1.0], [1.0, 1.0], [0.5, 1.0], [0.37, 1.0], [1.0, 1.0], [0.5, 1.0], [1.12, 1.0], [0.44, 1.0], [0.9, 1.0], [0.67, 1.0], [0.56, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [0.6, 1.0], [0.37, 1.0], [0.44, 1.0], [1.5, 1.0], [1.5, 1.0], [2.24, 1.0], [2.0, 1.0], [1.8, 1.0], [1.5, 1.0], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [0.5, 1.0], [0.67, 1.0], [0.42, 1.0], [2.24, 1.0], [1.5, 1.0], [2.0, 1.0], [1.8, 1.0], [1.5, 1.0], [1.5, 1.0], [1.33, 1.0], [0.44, 1.0], [0.56, 1.0], [1.5, 1.0], [0.37, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 1.0], [0.44, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [0.37, 1.0], [0.44, 1.0], [0.6, 1.0], [2.24, 1.0], [1.5, 1.0], [2.0, 1.0], [1.8, 1.0], [1.5, 1.0], [1.5, 1.0], [1.33, 1.0], [1.5, 1.0], [0.42, 1.0], [0.5, 1.0], [0.67, 1.0], [1.5, 1.0], [2.24, 1.0], [2.0, 1.0], [1.8, 1.0], [1.5, 1.0], [1.5, 1.0], [1.33, 1.0], [0.56, 1.0], [0.44, 1.0], [1.5, 1.0], [0.37, 1.0], [1.0, 1.0], [0.56, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.56, 1.0], [0.44, 1.0], [0.9, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.44, 1.0], [1.12, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.42, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [1.12, 1.0], [0.44, 1.0], [0.56, 1.0], [0.9, 1.0], [1.0, 1.0], [0.56, 1.0], [0.44, 1.0], [0.42, 1.0], [1.0, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.44, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.44, 1.0], [0.44, 1.0], [1.12, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [0.5, 1.0], [0.42, 1.0], [1.0, 1.0], [0.5, 1.0], [1.0, 1.0], [0.5, 1.0], [0.9, 1.0], [0.5, 1.0], [0.42, 1.0], [1.0, 1.0], [0.37, 1.0], [1.0, 1.0], [0.44, 1.0], [1.12, 1.0], [0.56, 1.0], [0.37, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [0.56, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [1.0, 0.075], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.44, 1.0], [0.9, 1.0], [0.44, 1.0], [0.6, 1.0], [1.0, 1.0], [1.0, 0.035416666666666666], [0.44, 1.0], [1.12, 1.0], [0.6, 1.0], [0.9, 1.0], [0.44, 1.0], [0.6, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [1.0, 1.0], [0.9, 1.0], [0.67, 1.0], [0.5, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.9, 1.0], [0.37, 1.0], [0.37, 1.0], [1.0, 1.0], [0.56, 1.0], [1.0, 1.0], [0.37, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [0.37, 1.0], [0.56, 1.0], [1.0, 1.0], [0.37, 1.0], [1.0, 1.0], [0.37, 1.0], [0.56, 1.0], [0.37, 1.0], [1.12, 1.0], [0.9, 1.0], [0.37, 1.0], [0.56, 1.0], [0.37, 1.0], [1.0, 1.0], [1.0, 1.0], [0.56, 1.0], [0.44, 1.0], [0.56, 1.0], [0.44, 1.0], [1.0, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [0.44, 0.07291666666666667], [1.0, 1.0], [0.56, 1.0], [0.67, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.44, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [0.6, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [0.6, 1.0], [0.44, 1.0], [1.0, 1.0], [1.0, 0.0375], [0.44, 1.0], [0.6, 1.0], [1.12, 1.0], [0.37, 1.0], [0.9, 1.0], [0.6, 1.0], [0.44, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.9, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [0.42, 1.0], [1.0, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [0.56, 1.0], [1.0, 1.0], [0.37, 1.0], [0.37, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.37, 1.0], [1.0, 1.0], [0.37, 1.0], [1.0, 1.0], [0.37, 1.0], [1.12, 1.0], [0.37, 1.0], [0.56, 1.0], [0.9, 1.0], [0.37, 1.0], [0.37, 1.0], [0.37, 1.0], [0.56, 1.0], [1.0, 1.0], [0.67, 1.0], [1.33, 1.0], [0.44, 1.0], [0.67, 1.0], [0.44, 1.0], [1.0, 1.0], [0.56, 1.0], [1.0, 1.0], [0.67, 1.0], [1.33, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [1.0, 1.0], [0.67, 1.0], [0.67, 0.0375], [0.56, 1.0], [0.44, 1.0], [1.0, 1.0], [1.33, 1.0], [1.0, 1.0], [0.67, 1.0], [0.44, 1.0], [1.33, 1.0], [0.9, 1.0], [0.56, 1.0], [0.44, 1.0], [0.56, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.44, 1.0], [0.67, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 1.0], [1.0, 1.0], [0.56, 1.0], [0.9, 1.0], [0.44, 1.0], [0.6, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.44, 1.0], [0.6, 1.0], [0.75, 1.0], [1.12, 1.0], [0.56, 1.0], [0.9, 1.0], [0.44, 1.0], [0.6, 1.0], [1.0, 1.0], [0.67, 1.0], [0.67, 1.0], [0.67, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.56, 1.0], [0.9, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.67, 0.035416666666666666], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.56, 1.0], [0.5, 1.0], [0.67, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [0.67, 1.0], [0.56, 1.0], [1.0, 1.0], [0.37, 1.0], [0.56, 1.0], [0.37, 1.0], [0.67, 1.0], [0.9, 1.0], [1.0, 1.0], [0.67, 1.0], [0.9, 1.0], [0.56, 1.0], [0.56, 1.0], [0.37, 1.0], [0.67, 1.0], [1.0, 1.0], [0.37, 1.0], [0.67, 1.0], [1.0, 1.0], [0.56, 1.0], [0.37, 1.0], [1.12, 1.0], [0.9, 1.0], [0.67, 1.0], [0.56, 1.0], [0.37, 1.0], [0.56, 1.0], [0.37, 1.0], [1.33, 1.0], [2.0, 1.0], [2.0, 1.0], [0.56, 1.0], [0.44, 1.0], [0.67, 1.0], [1.33, 1.0], [1.33, 1.0], [2.0, 1.0], [0.67, 1.0], [0.44, 1.0], [1.8, 1.0], [1.12, 1.0], [0.44, 1.0], [0.67, 1.0], [0.56, 1.0], [1.33, 1.0], [2.0, 1.0], [0.44, 0.07291666666666667], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [0.56, 1.0], [2.0, 1.0], [1.33, 1.0], [0.67, 1.0], [1.12, 1.0], [0.44, 1.0], [1.33, 1.0], [0.67, 1.0], [0.56, 1.0], [0.44, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [2.0, 1.0], [1.33, 1.0], [0.67, 1.0], [0.6, 1.0], [0.44, 1.0], [1.12, 1.0], [1.8, 1.0], [0.67, 1.0], [1.33, 1.0], [2.0, 1.0], [1.8, 1.0], [1.12, 1.0], [0.44, 1.0], [0.6, 1.0], [1.33, 1.0], [2.0, 1.0], [2.0, 0.0375], [1.33, 1.0], [2.24, 1.0], [0.44, 1.0], [1.5, 1.0], [0.6, 1.0], [0.37, 1.0], [1.12, 1.0], [1.8, 1.0], [0.6, 1.0], [0.44, 1.0], [2.0, 1.0], [1.33, 1.0], [0.67, 1.0], [1.33, 1.0], [0.5, 1.0], [0.67, 1.0], [2.0, 1.0], [2.0, 1.0], [1.33, 1.0], [1.12, 1.0], [1.8, 1.0], [0.5, 1.0], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [1.33, 0.035416666666666666], [2.0, 1.0], [0.5, 1.0], [0.67, 1.0], [0.42, 1.0], [2.0, 1.0], [1.33, 1.0], [0.67, 1.0], [0.5, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 1.0], [1.33, 1.0], [0.37, 1.0], [1.33, 1.0], [2.0, 1.0], [1.8, 1.0], [1.12, 1.0], [0.37, 1.0], [2.0, 1.0], [1.33, 1.0], [1.12, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [2.0, 1.0], [1.33, 1.0], [1.5, 1.0], [2.24, 1.0], [1.12, 1.0], [1.8, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [0.44, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.6, 1.0], [1.5, 1.0], [1.5, 1.0], [1.33, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [0.37, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [1.12, 1.0], [1.0, 1.0], [0.9, 1.0], [0.75, 1.0], [0.67, 1.0], [0.56, 1.0], [0.37, 1.0], [1.12, 1.0], [0.37, 1.0], [1.5, 1.0], [0.42, 1.0], [1.33, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [1.33, 1.0], [1.6, 1.0], [1.5, 1.0], [1.5, 1.0], [1.12, 1.0], [0.6, 1.0], [1.6, 1.0], [1.5, 1.0], [1.5, 1.0], [1.12, 1.0], [1.5, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.5, 1.0], [1.12, 1.0], [1.0, 0.0375], [1.5, 1.0], [1.6, 1.0], [1.6, 1.0], [1.5, 1.0], [1.5, 1.0], [0.67, 1.0], [1.33, 1.0], [1.12, 1.0], [1.12, 1.0], [1.33, 1.0], [0.37, 1.0], [1.5, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [0.37, 1.0], [0.9, 1.0], [0.75, 1.0], [0.67, 1.0], [0.56, 1.0], [0.37, 1.0], [0.67, 1.0], [0.75, 1.0], [0.37, 1.0], [0.9, 1.0], [0.37, 1.0], [1.12, 1.0], [1.0, 1.0], [1.33, 1.0], [1.5, 1.0], [0.67, 0.0375], [0.75, 1.0], [0.67, 1.0], [0.56, 1.0], [0.67, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [0.67, 1.0], [1.5, 1.0], [1.0, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [1.12, 1.0], [1.0, 1.0], [1.0, 1.0], [1.12, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [1.0, 1.0], [0.37, 1.0], [0.44, 1.0], [0.9, 1.0], [0.37, 1.0], [0.44, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.67, 1.0], [0.75, 1.0], [0.67, 1.0], [0.75, 1.0], [0.9, 1.0], [1.0, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 1.0], [1.12, 1.0], [1.33, 1.0], [1.0, 1.0], [1.12, 1.0], [0.37, 1.0], [1.33, 1.0], [0.37, 1.0], [1.5, 1.0], [1.12, 1.0], [0.37, 1.0], [1.33, 1.0], [1.5, 1.0], [1.6, 1.0], [1.5, 1.0], [0.37, 1.0], [1.33, 1.0], [1.12, 1.0], [0.37, 1.0], [1.0, 1.0], [0.37, 1.0], [1.12, 1.0], [1.0, 1.0], [0.5, 1.0], [0.56, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.33, 1.0], [1.12, 1.0], [1.33, 1.0], [0.67, 1.0], [0.6, 1.0], [1.12, 1.0], [1.5, 1.0], [1.6, 1.0], [0.6, 1.0], [1.5, 1.0], [1.12, 1.0], [1.5, 1.0], [1.6, 1.0], [1.5, 1.0], [1.12, 1.0], [0.67, 1.0], [1.5, 1.0], [1.6, 1.0], [1.5, 1.0], [1.12, 0.0375], [1.6, 1.0], [1.5, 1.0], [1.5, 1.0], [1.12, 1.0], [0.37, 1.0], [0.37, 1.0], [1.12, 1.0], [1.0, 1.0], [0.75, 1.0], [0.67, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.44, 1.0], [0.5, 1.0], [0.5, 1.0], [0.5, 1.0], [0.44, 1.0], [0.5, 0.0375], [0.67, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [0.44, 1.0], [0.5, 1.0], [0.37, 1.0], [0.5, 1.0], [0.44, 1.0], [0.5, 1.0], [0.37, 1.0], [0.44, 1.0], [0.5, 0.0375], [0.67, 1.0], [0.5, 1.0], [0.56, 1.0], [0.44, 1.0], [0.67, 1.0], [0.5, 0.075], [0.6, 1.0], [0.67, 1.0], [0.5, 1.0], [0.5, 1.0], [0.6, 1.0], [0.44, 1.0], [0.5, 0.0375], [0.56, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [0.56, 1.0], [0.5, 1.0], [0.56, 1.0], [0.44, 1.0], [0.67, 1.0], [0.5, 1.0], [0.5, 1.0], [0.37, 1.0], [0.5, 1.0], [0.44, 1.0], [0.5, 1.0], [0.5, 1.0], [0.44, 1.0], [0.37, 1.0], [0.5, 1.0], [0.44, 1.0], [0.5, 1.0], [0.56, 1.0], [0.37, 1.0], [0.44, 1.0], [0.44, 1.0], [0.37, 1.0], [0.44, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [0.44, 1.0], [0.9, 1.0], [1.0, 0.0375], [0.67, 1.0], [1.0, 1.0], [0.67, 0.07708333333333334], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.37, 1.0], [0.9, 1.0], [1.0, 0.0375], [0.67, 1.0], [1.0, 1.0], [1.12, 1.0], [0.9, 1.0], [0.67, 1.0], [1.0, 0.075], [0.6, 1.0], [1.0, 1.0], [0.6, 1.0], [1.0, 1.0], [0.9, 1.0], [1.0, 0.035416666666666666], [0.56, 1.0], [1.0, 1.0], [0.56, 0.07291666666666667], [1.0, 1.0], [0.9, 1.0], [1.0, 1.0], [0.5, 1.0], [0.37, 1.0], [1.0, 1.0], [0.9, 1.0], [0.5, 1.0], [1.0, 1.0], [0.9, 1.0], [0.37, 1.0], [1.0, 1.0], [0.44, 1.0], [1.0, 1.0], [1.12, 1.0], [0.44, 1.0], [0.9, 1.0], [0.37, 1.0], [0.44, 1.0], [1.0, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.44, 1.0], [0.67, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 0.0375], [1.0, 1.0], [0.67, 1.0], [1.33, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.67, 1.0], [1.0, 1.0], [0.9, 1.0], [0.42, 1.0], [0.56, 1.0], [0.56, 1.0], [0.67, 1.0], [0.37, 1.0], [1.0, 1.0], [1.0, 1.0], [0.67, 1.0], [0.56, 1.0], [0.9, 1.0], [0.56, 1.0], [0.37, 1.0], [0.67, 1.0], [1.0, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 0.03958333333333333], [1.0, 1.0], [0.67, 1.0], [0.67, 1.0], [0.75, 1.0], [1.12, 1.0], [0.67, 1.0], [0.56, 1.0], [0.9, 1.0], [0.67, 0.075], [1.0, 1.0], [0.6, 1.0], [0.67, 1.0], [0.67, 1.0], [1.0, 1.0], [1.0, 1.0], [0.6, 1.0], [0.67, 1.0], [0.56, 1.0], [0.9, 1.0], [1.0, 0.03958333333333333], [0.67, 1.0], [0.56, 1.0], [0.67, 1.0], [1.0, 1.0], [0.67, 1.0], [0.56, 1.0], [1.0, 1.0], [0.67, 1.0], [0.67, 1.0], [0.9, 1.0], [0.56, 1.0], [0.56, 1.0], [0.67, 1.0], [1.0, 1.0], [0.5, 1.0], [0.5, 1.0], [0.67, 1.0], [1.0, 1.0], [0.37, 1.0], [0.9, 1.0], [0.56, 1.0], [0.67, 1.0], [0.5, 1.0], [0.5, 1.0], [1.0, 1.0], [0.56, 1.0], [0.9, 1.0], [0.37, 1.0], [0.67, 1.0], [1.0, 1.0], [0.44, 1.0], [1.33, 1.0], [0.67, 1.0], [1.0, 1.0], [0.75, 1.0], [0.37, 1.0], [1.12, 1.0], [0.44, 1.0], [0.44, 1.0], [0.56, 1.0], [0.9, 1.0], [0.67, 1.0], [0.37, 1.0], [1.33, 1.0], [0.67, 1.0], [0.44, 1.0], [0.44, 1.0], [2.0, 1.0], [2.0, 1.0], [1.33, 1.0], [0.44, 1.0], [1.33, 1.0], [2.0, 1.0], [0.67, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 0.0375], [1.33, 1.0], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [1.33, 1.0], [0.67, 1.0], [2.0, 1.0], [1.12, 1.0], [2.0, 1.0], [1.8, 1.0], [1.33, 1.0], [1.33, 1.0], [2.0, 1.0], [0.37, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 1.0], [1.33, 1.0], [0.37, 1.0], [1.8, 1.0], [1.12, 1.0], [1.33, 0.0375], [2.0, 1.0], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [2.24, 1.0], [1.5, 1.0], [0.67, 1.0], [1.12, 1.0], [1.8, 1.0], [2.0, 0.07083333333333333], [1.33, 1.0], [0.6, 1.0], [1.33, 1.0], [2.0, 1.0], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [0.6, 1.0], [1.8, 1.0], [1.12, 1.0], [0.56, 0.06458333333333334], [1.33, 1.0], [2.0, 1.0], [1.33, 1.0], [0.67, 1.0], [2.0, 1.0], [0.56, 1.0], [1.33, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 1.0], [1.33, 1.0], [0.5, 1.0], [1.33, 1.0], [0.37, 1.0], [2.0, 1.0], [1.12, 1.0], [1.8, 1.0], [0.5, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.12, 1.0], [0.37, 1.0], [1.33, 1.0], [2.0, 1.0], [0.44, 1.0], [1.33, 1.0], [1.5, 1.0], [2.24, 1.0], [0.37, 1.0], [0.44, 1.0], [1.8, 1.0], [0.44, 1.0], [1.12, 1.0], [0.37, 1.0], [2.0, 1.0], [0.9, 1.0], [1.8, 1.0], [0.9, 1.0], [2.0, 1.0], [0.9, 1.0], [1.8, 1.0], [0.9, 1.0], [0.44, 1.0], [0.56, 1.0], [0.67, 1.0], [0.67, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [1.5, 1.0], [1.8, 1.0], [1.33, 1.0], [1.5, 1.0], [2.0, 1.0], [1.5, 1.0], [1.8, 1.0], [1.33, 1.0], [1.5, 1.0], [1.33, 1.0], [0.37, 1.0], [2.0, 1.0], [0.44, 1.0], [0.44, 1.0], [1.5, 1.0], [2.24, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [1.2, 1.0], [1.33, 1.0], [1.8, 1.0], [1.2, 1.0], [2.0, 1.0], [0.67, 1.0], [1.2, 1.0], [1.33, 1.0], [1.8, 1.0], [1.2, 1.0], [2.0, 1.0], [0.42, 1.0], [0.5, 1.0], [1.12, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 1.0], [1.12, 1.0], [1.8, 1.0], [1.12, 1.0], [0.37, 1.0], [2.0, 1.0], [1.0, 1.0], [1.8, 1.0], [1.0, 1.0], [0.37, 1.0], [2.0, 1.0], [1.0, 1.0], [1.8, 1.0], [1.0, 1.0], [0.56, 1.0], [0.44, 1.0], [2.0, 1.0], [0.37, 1.0], [2.24, 1.0], [1.8, 1.0], [2.0, 1.0], [0.9, 1.0], [1.8, 1.0], [0.9, 1.0], [2.0, 1.0], [0.9, 1.0], [1.8, 1.0], [0.9, 1.0], [0.67, 1.0], [2.0, 1.0], [0.44, 1.0], [0.56, 1.0], [0.44, 1.0], [1.33, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [1.33, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [1.5, 1.0], [1.8, 1.0], [1.5, 1.0], [2.0, 1.0], [1.5, 1.0], [1.33, 1.0], [1.8, 1.0], [1.5, 1.0], [1.33, 1.0], [0.44, 1.0], [2.0, 1.0], [0.37, 1.0], [2.24, 1.0], [1.8, 1.0], [2.0, 1.0], [1.2, 1.0], [1.8, 1.0], [1.2, 1.0], [0.67, 1.0], [0.67, 1.0], [2.0, 1.0], [1.2, 1.0], [1.8, 1.0], [1.2, 1.0], [2.0, 1.0], [0.5, 1.0], [0.42, 1.0], [0.67, 1.0], [0.5, 1.0], [1.12, 1.0], [1.8, 1.0], [1.12, 1.0], [2.0, 1.0], [1.12, 1.0], [1.8, 1.0], [1.12, 1.0], [0.37, 1.0], [1.33, 1.0], [2.0, 1.0], [1.8, 1.0], [1.33, 1.0], [2.0, 1.0], [0.5, 1.0], [2.24, 1.0], [1.12, 1.0], [0.37, 1.0], [1.8, 1.0], [0.56, 1.0]]}]} \ No newline at end of file diff --git a/测试用/Illusionary_Daytime_--------幻昼.mid b/测试用/Illusionary_Daytime_--------幻昼.mid new file mode 100644 index 0000000..5256369 Binary files /dev/null and b/测试用/Illusionary_Daytime_--------幻昼.mid differ diff --git a/测试用/RyounTeamSong.ry.nfc b/测试用/RyounTeamSong.ry.nfc index 6f87d52..6b1778a 100644 --- a/测试用/RyounTeamSong.ry.nfc +++ b/测试用/RyounTeamSong.ry.nfc @@ -1,224 +1,224 @@ -{ - "mainset": { - "PackName": "RyounTeamSong", - "MusicTitle": "RyounUp", - "IsRepeat": false, - "PlayerSelect": "" - }, - "musics": [ - { - "set": { - "EntityName": "MusicSupport", - "ScoreboardName": "MusicSupport", - "Instrument": "harp", - "FileName": "RyounUp_RyounTeamSong" - }, - "notes": [ - [ - ".5", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "3", - 1.5 - ], - [ - "3", - 0.5 - ], - [ - "2", - 1.5 - ], - [ - "1", - 0.5 - ], - [ - "2", - 1.0 - ], - [ - "5", - 1.0 - ], - [ - "3", - 1.5 - ], - [ - "2", - 0.5 - ], - [ - ".6", - 1.0 - ], - [ - ".5", - 1.0 - ], - [ - "3", - 1.5 - ], - [ - "2", - 0.5 - ], - [ - "1", - 1.0 - ], - [ - "5", - 1.0 - ], - [ - "5", - 1.0 - ], - [ - "6", - 0.5 - ], - [ - "5", - 0.5 - ], - [ - "3", - 1.0 - ], - [ - "5", - 0.5 - ], - [ - "3", - 0.5 - ], - [ - "2", - 1.0 - ], - [ - "2", - 1.0 - ], - [ - "3", - 0.5 - ], - [ - "2", - 0.5 - ], - [ - "1", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "5", - 1.0 - ], - [ - "0", - 1.0 - ], - [ - ".5", - 0.5 - ], - [ - ".6", - 0.5 - ], - [ - "1", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "6", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "2", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "3", - 1.0 - ], - [ - "2", - 1.0 - ], - [ - "5", - 1.5 - ], - [ - ".5", - 0.5 - ], - [ - "1", - 1.0 - ], - [ - "1", - 1.0 - ], - [ - "0", - 1.0 - ], - [ - "0", - 1.0 - ] - ] - } - ] +{ + "mainset": { + "PackName": "RyounTeamSong", + "MusicTitle": "RyounUp", + "IsRepeat": false, + "PlayerSelect": "" + }, + "musics": [ + { + "set": { + "EntityName": "MusicSupport", + "ScoreboardName": "MusicSupport", + "Instrument": "harp", + "FileName": "RyounUp_RyounTeamSong" + }, + "notes": [ + [ + ".5", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "3", + 1.5 + ], + [ + "3", + 0.5 + ], + [ + "2", + 1.5 + ], + [ + "1", + 0.5 + ], + [ + "2", + 1.0 + ], + [ + "5", + 1.0 + ], + [ + "3", + 1.5 + ], + [ + "2", + 0.5 + ], + [ + ".6", + 1.0 + ], + [ + ".5", + 1.0 + ], + [ + "3", + 1.5 + ], + [ + "2", + 0.5 + ], + [ + "1", + 1.0 + ], + [ + "5", + 1.0 + ], + [ + "5", + 1.0 + ], + [ + "6", + 0.5 + ], + [ + "5", + 0.5 + ], + [ + "3", + 1.0 + ], + [ + "5", + 0.5 + ], + [ + "3", + 0.5 + ], + [ + "2", + 1.0 + ], + [ + "2", + 1.0 + ], + [ + "3", + 0.5 + ], + [ + "2", + 0.5 + ], + [ + "1", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "5", + 1.0 + ], + [ + "0", + 1.0 + ], + [ + ".5", + 0.5 + ], + [ + ".6", + 0.5 + ], + [ + "1", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "6", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "2", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "3", + 1.0 + ], + [ + "2", + 1.0 + ], + [ + "5", + 1.5 + ], + [ + ".5", + 0.5 + ], + [ + "1", + 1.0 + ], + [ + "1", + 1.0 + ], + [ + "0", + 1.0 + ], + [ + "0", + 1.0 + ] + ] + } + ] } \ No newline at end of file diff --git a/测试用/不知名文件.7z b/测试用/不知名文件.7z new file mode 100644 index 0000000..2825519 Binary files /dev/null and b/测试用/不知名文件.7z differ diff --git a/测试用/同道殊途标准.mid b/测试用/同道殊途标准.mid new file mode 100644 index 0000000..9ea9df9 Binary files /dev/null and b/测试用/同道殊途标准.mid differ diff --git a/补全库.py b/补全库.py index 8fccb46..ecad380 100644 --- a/补全库.py +++ b/补全库.py @@ -1,2 +1,2 @@ -from msctspt.bugReporter import version +from msctspt.bugReporter import version version.installLibraries(version) \ No newline at end of file