diff --git a/fcwslib/__init__.py b/fcwslib/__init__.py index b897032..fff0b84 100644 --- a/fcwslib/__init__.py +++ b/fcwslib/__init__.py @@ -1,105 +1,114 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:2个---未解决;警告(二级)错误:2个;语法(一级)错误:17个 + __version__ = '0.0.1' __all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw'] __author__ = 'Fuckcraft ' -import os +# import os import json import uuid -import logging +# 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' - } + '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" - } + "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 + 'body': { + 'origin': { + 'type': 'player' }, - 'header': { - 'requestId': str(uuid.uuid4()), - 'messagePurpose': 'commandRequest', - 'version': 1, - 'messageType': 'commandRequest' - } + '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) @@ -107,24 +116,25 @@ async def send_command(websocket, command): await websocket.send(response) + # 此函数用于向 Minecraft 发送消息 async def tellraw(websocket, message): - ''' + """ 参数: : websocket : websocket 对象 : : message : 发送的消息 : 返回: None - ''' + """ command = { - 'rawtext':[ - { - 'text':'[{}] {}'.format(time.asctime(), message) - } - ] - } + 'rawtext': [ + { + 'text': '[{}] {}'.format(time.asctime(), message) + } + ] + } # 增加 json 可读性 # command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False) @@ -133,9 +143,9 @@ async def tellraw(websocket, message): 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 473bb0f..6807a11 100644 --- a/languages/const2string.py +++ b/languages/const2string.py @@ -9,7 +9,7 @@ # 若需转载或借鉴 请附作者 -''' +""" Copyright 2022 Eilles Wan (金羿) Licensed under the Apache License, Version 2.0 (the 'License') @@ -23,21 +23,33 @@ 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软件协议公开 -''' -将程序中用双引号""括起来的字符串 -转为字符串列表 list[str, str, ...] -方便进行语言翻译支持。 -''' +# -----------------------------分割线----------------------------- +# 诸葛亮与八卦阵帮忙修改语法 日期:---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----------------------------- -startWith = 0 +# 下面为正文 +# 将程序中用双引号""括起来的字符串 +# 转为字符串列表 list[str, str, ...] +# 方便进行语言翻译支持。 + import sys +startWith = 0 def __main__(): @@ -46,23 +58,25 @@ def __main__(): print('读取文件: {}'.format(fileName)) fileText = [] for line in open(fileName, 'r', encoding='utf-8'): - while line.count('"') >=2: + 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('"')])]) + 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('"')])]) + 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) + 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') + + open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText) + + outFile = open('lang__.py', 'w', encoding='utf-8') outFile.write('''# -*- coding:utf-8 -*- # 由金羿翻译工具生成字符串列表 @@ -73,7 +87,7 @@ def __main__(): READABLETEXT = { ''') for i in range(len(textList)): - outFile.write(" {}:{},\n".format(i+startWith,textList[i])) + outFile.write(" {}:{},\n".format(i + startWith, textList[i])) outFile.write('}') outFile.close() diff --git a/languages/enGB.py b/languages/enGB.py index 6f02fdb..1705d23 100644 --- a/languages/enGB.py +++ b/languages/enGB.py @@ -4,160 +4,159 @@ # 请在所需翻译的文件前from 此文件 import READABLETEXT - READABLETEXT = { - 'Translator':(("Eilles Wan (金羿)",True),), + '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)), + 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 -", + 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", + 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", + 96: "Reset Main Options", + 97: "Track Options", # 98:"", # 99:"", # 100:"", # 101:"", - 102:"Delete Selected Track", + 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:"修改本音轨生成的文件名", + 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: "修改本音轨生成的文件名", -} \ No newline at end of file +} diff --git a/languages/zhCN.py b/languages/zhCN.py index 3ade735..6cdcaaa 100644 --- a/languages/zhCN.py +++ b/languages/zhCN.py @@ -23,9 +23,9 @@ READABLETEXT = { 13: "确定", 14: "请输入音符", 15: (("- 开发者 -", False), - ("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), - ("bgArray “诸葛亮与八卦阵”",True),("QQ 474037765",False), - ), + ("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), + ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False), + ), # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 16: "- 翻译者 -", # 17:"", diff --git a/msctspt/bdxOpera_CP.py b/msctspt/bdxOpera_CP.py index 4712935..5c569b0 100644 --- a/msctspt/bdxOpera_CP.py +++ b/msctspt/bdxOpera_CP.py @@ -4,6 +4,10 @@ import brotli '''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码''' +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:7个 + + class BdxConverter: __header = "BD@" __bin_header = b"BDX" @@ -42,8 +46,8 @@ class BdxConverter: :return: list 给出的所有方块种类名称 """ block_type = set() - for block in self.blocks: - block_type.add(block["block_name"]) + for block_ in self.blocks: + block_type.add(block_["block_name"]) block_type = list(block_type) return block_type @@ -74,6 +78,7 @@ class BdxConverter: f.write(brotli.compress(_bytes)) f.close() return + def upload_blocks(self): """ 计算差值 @@ -83,17 +88,17 @@ class BdxConverter: :return: """ _types = b"" - for block in self.blocks: + for block_ in self.blocks: # print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]") - diff = self.move_pointer(self.direction, 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) + 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"] + _types += self.obtain_universal_block(block_) + self.direction = block_["direction"] return _types def move_pointer(self, direction: list, new_direction): @@ -148,21 +153,21 @@ class BdxConverter: return pointer_type + num_byte return pointer_type - def obtain_universal_block(self, block): + def obtain_universal_block(self, block1): """ 给定一个方块, 返回此方块在这个bdx中的id和方块data - :param block: {block_name: str,particular_value: int} + :param block1: {block_name: str,particular_value: int} :return: bytes """ - block_id = b"\x07" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False) - particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False) + block_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, block): + def obtain_command_block(self, block1): """ 给定一个命令方块,返回命令方块各种数据 - :param block: { + :param block1: { "direction": [x: int, y: int, z: int] "block_name": str, "particular_value": int, @@ -179,23 +184,24 @@ class BdxConverter: :return: bytes of command_block """ - block_id = b"\x1b" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False) - particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False) + block_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 [ - block["impluse"].to_bytes(4, byteorder="big", signed=False), - bytes(block["command"], encoding="utf-8") + b"\x00", - bytes(block["customName"], encoding="utf-8") + b"\x00", - bytes(block["lastOutput"], encoding="utf-8") + b"\x00", - block["tickdelay"].to_bytes(4, byteorder="big", signed=True), - block["executeOnFirstTick"].to_bytes(1, byteorder="big"), - block["trackOutput"].to_bytes(1, byteorder="big"), - block["conditional"].to_bytes(1, byteorder="big"), - block["needRedstone"].to_bytes(1, byteorder="big") + 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}, @@ -212,4 +218,4 @@ if __name__ == '__main__': }, {"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) + bdx = BdxConverter("./test02.bdx", "Charlie_Ping", block) diff --git a/msctspt/bugReporter.py b/msctspt/bugReporter.py index 4d25b8f..9ca22b5 100644 --- a/msctspt/bugReporter.py +++ b/msctspt/bugReporter.py @@ -1,22 +1,21 @@ # -*- coding: UTF-8 -*- -'''提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能''' +"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能""" + +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:1个;语法(一级)错误:72个 +import os +import zipfile - - - - - -def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None): - '''使用compression指定的算法打包目录为zip文件\n +def makeZip(sourceDir, outFilename, compression=8, exceptFile=None): + """使用compression指定的算法打包目录为zip文件\n 默认算法为DEFLATED(8),可用算法如下:\n STORED = 0\n DEFLATED = 8\n BZIP2 = 12\n LZMA = 14\n - ''' - import os, zipfile - zipf = zipfile.ZipFile(outFilename, 'w',compression) + """ + 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: @@ -24,113 +23,108 @@ def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None): continue print(filename) pathfile = os.path.join(parent, filename) - arcname = pathfile[pre_len:].strip(os.path.sep) #相对路径 + 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 + del zipf, pre_len +# 以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942 +class report: + """发送报告以及相应的任务处理""" - - -class report(): - '''发送报告以及相应的任务处理''' - def __init__(self,senderName:str = 'Unknown',senderContact:str = 'None',describetion:str = ''): - ''':param senderName 发送者名称 + def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''): + """:param senderName 发送者名称 :param senderContact 发送者联系方式 - :param describetion 问题描述''' + :param describetion 问题描述""" self.senderName = senderName self.senderContact = senderContact self.describetion = describetion - if not self.senderName : + if not self.senderName: self.senderName = 'Unknown' - if not self.senderContact : + if not self.senderContact: self.senderContact = 'None' - - - + def emailReport(self): - '''使用E-mail方法发送当前的日志和临时文件等''' + """使用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 + 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,'plain','utf-8')) + # 发送者与接收者显示名称 + 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(open("Temps&Logs.zip",'rb').read(),"base64",'gb2312') + 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"' + 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()) + # 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("错误汇报邮件发送失败:\n" + str(e)) log("清空内存和临时文件") - del msg,attafile + 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') + """当前所需库,有一些是开发用的,用户不需要安装""" - libraries = ('mido','amulet','amulet-core','amulet-nbt','piano_transcription_inference','pypinyin','pyinstaller','py7zr','websockets','torch') - '''当前所需库,有一些是开发用的,用户不需要安装''' - - version = ('0.0.1','Delta',) - '''当前版本''' + 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: + 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") + 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") - + 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 4d064fc..892a848 100644 --- a/msctspt/funcOpera.py +++ b/msctspt/funcOpera.py @@ -1,186 +1,204 @@ # -*- 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 +def delPart(Data, starter, ender, includeStart: bool = True, includend: bool = True): + """删除序列从starter物件到ender物件之间的部分\n includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n - starter与ender若为None则默认从首或尾开始''' + starter与ender若为None则默认从首或尾开始""" + e = True try: - if starter == None: + if starter is None: includeStart = True starter = Data[0] - if ender == None: + if ender is None: includend = True - ender = Data[len(Data)-1] + ender = Data[len(Data) - 1] if includend: if includeStart: - return Data[Data.index(starter):len(Data)-Data[len(Data)::-1].index(ender)] + e = False + 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)] + e = False + 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] + e = False + 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: + 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 +def keepart(Data, starter, ender, includeStart: bool = True, includend: bool = True): + """保留序列从starter物件到ender物件之间的部分\n includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n - starter与ender若为None则默认从首或尾开始''' + starter与ender若为None则默认从首或尾开始""" + e = True try: - if starter == None: + if starter is None: includeStart = True starter = Data[0] - if ender == None: + if ender is None: includend = True - ender = Data[len(Data)-1] + ender = Data[len(Data) - 1] if includend: if includeStart: - return Data[Data.index(starter):Data.index(ender)+1] + e = False + return Data[Data.index(starter):Data.index(ender) + 1] else: - return Data[Data.index(starter)+1:Data.index(ender)+1] + 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: - return Data[Data.index(starter)+1:Data.index(ender)] - except: + 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: - l = 0 + f = 0 for i in fun: - if i.replace(" ",'')[0] == '#': - l += 1 - return len(fun)-l - except: + 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 +def funSplit(bigFile, maxCmdLen: int = 10000): + """分割bigFile大的函数文件,bigFile需要读入文件流\n 返回的部分,每行指令皆带有行尾换行符\\n\n - 返回-1为大小低于maxCmdLen最长函数指令长度''' + 返回-1为大小低于maxCmdLen最长函数指令长度""" bigFile = bigFile.readlines() if lenFunction(bigFile) < maxCmdLen: return -1 part = [] parts = [] - l = 0 + h = 0 for i in bigFile: - if i.replace(" ",'')[0] == '#': - part.append(i+'\n') + if i.replace(" ", '')[0] == '#': + part.append(i + '\n') else: - part.append(i+'\n') - l += 1 - if l >= 10000: + part.append(i + '\n') + h += 1 + if h >= 10000: parts.append(part) part = [] - l = 0 + h = 0 return parts - - - - - - - def makeFuncFiles(musicset, path='./'): - '''在指定目录下生成函数文件''' + """在指定目录下生成函数文件""" from nmcsup.trans import Note2Cmd commands = [] starts = [] - log("=========================正在在此处生成文件:"+path) + 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") + 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)) + 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") + 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: + 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: + 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' + # 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: + 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")): + if not (os.path.exists( + path + musicset['mainset']['PackName'] + "Pack/world_behavior_packs.json") and os.path.exists( + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][ + 'PackName'] + "/manifest.json")): log("创建manifest.json以及world_behavior_packs.json") behaviorUuid = uuid.uuid4() - with open(path+musicset['mainset']['PackName']+"Pack/world_behavior_packs.json", "w") as f: - f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) +"\",\n \"version\": [ 0, 0, 1 ]}\n]") - with open(path+musicset['mainset']['PackName']+"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/manifest.json", "w") as f: - f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \""+musicset['mainset']['PackName']+" Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \""+musicset['mainset']['PackName']+"Pack\",\n \"uuid\": \"" + str(behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \""+musicset['mainset']['PackName']+" Pack : behavior pack\",\n \"type\": \"data\",\n \"version\": [ 0, 0, 1 ],\n \"uuid\": \"" + str(uuid.uuid4()) + "\"\n }\n ]\n}") - makeFuncFiles(musicset, path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions/") + 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 播放(试听)音乐 @@ -207,8 +225,9 @@ def PlayOne(): #同上,是早期 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"]) +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 420606c..cf2d51c 100644 --- a/msctspt/threadOpera.py +++ b/msctspt/threadOpera.py @@ -1,22 +1,26 @@ - +# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日 +# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个--未解决1个 import threading class NewThread(threading.Thread): - '''新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值''' + """新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值""" + def __init__(self, func, args=()): super(NewThread, self).__init__() self.func = func self.args = args + def run(self): self.result = self.func(*self.args) + def getResult(self): threading.Thread.join(self) # 等待线程执行完毕 try: return self.result - except Exception: + except ValueError: return None # @@ -24,4 +28,4 @@ class NewThread(threading.Thread): # 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 # 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014 # ———————————————— -# \ No newline at end of file +# diff --git a/msctspt/transfer.py b/msctspt/transfer.py index 1c6b029..af928bc 100644 --- a/msctspt/transfer.py +++ b/msctspt/transfer.py @@ -1,32 +1,52 @@ """音·创 的转换工具库""" +# 诸葛亮与八卦阵帮忙修改语法 日期:---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): +def hans2pinyin(hans, style=3): """将汉字字符串转化为拼音字符串""" from pypinyin import lazy_pinyin - result = lazy_pinyin(hans=hans,style=style) + 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): +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 + "impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32 "command": str, #指令 "customName": str, #悬浮字 "lastOutput": str, #上次输出 @@ -36,7 +56,6 @@ def formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,cond "conditional": int, #是否有条件 1 bytes "needRedstone": int #是否需要红石 1 bytes } - :return: 指令方块字典结构 """ return {"direction": direction, "block_name": "command_block", @@ -50,146 +69,154 @@ def formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,cond "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 +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']) + Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 + 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) ScoreboardName: 用于执行的计分板名称 Instrument: 播放的乐器 PlayerSelect: 执行的玩家选择器 isProsess: 是否显示进度条(会很卡) height: 生成结构的最高高度 - :return 返回一个BdxConverter类(实际上没研究过),同时在指定位置生成.bdx文件''' - + :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) + 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(' ','') != ''): + if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''): cdl.append(i[:i.index('#')]) - except: + 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 + 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 + 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)) + 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)) + 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 + 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) + 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指令连接 +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']) + Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 + 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes']) Instrument: 播放的乐器 speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍 PlayerSelect: 执行的玩家选择器 isProsess: 是否显示进度条 - :return None''' - + :return None""" + import time import fcwslib import asyncio from nmcsup.log import log from nmcsup.vers import VER - async def run_server(websocket, path): + async def run_server(websocket): # , path log('服务器连接创建') - await fcwslib.tellraw(websocket, '已连接服务器——音·创'+VER[1]+VER[0]+' 作者:金羿(W-YI)') + 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,'execute @a'+PlayerSelect+' ~ ~ ~ playsound '+Instrument+' @s ~ ~ ~ 1000 '+str(Notes[i][0])+' 1000') + await fcwslib.send_command(websocket, + 'execute @a' + PlayerSelect + ' ~ ~ ~ playsound ' + Instrument + + ' @s ~ ~ ~ 1000 ' + str( + Notes[i][0]) + ' 1000') if isProsess: - fcwslib.send_command(websocket,'execute @a'+PlayerSelect+' ~ ~ ~ title @s actionbar §e▶ 播放中: §a'+str(j)+'/'+str(length)+' || '+str(int(j/length*1000)/10)) - j+=1 - time.sleep(Notes[i][1]/speed) + fcwslib.send_command(websocket, + 'execute @a' + PlayerSelect + ' ~ ~ ~ title @s actionbar §e▶ 播放中: §a' + str( + j) + '/' + str(length) + ' || ' + str(int(j / length * 1000) / 10)) + j += 1 + time.sleep(Notes[i][1] / speed) fcwslib.run_server(run_server) - - - -import amulet -from amulet.api.block import Block -from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc -from amulet_nbt import TAG_String as ts -from nmcsup.log import log - - - - - -def note2RSworld(world:str,startpos:list,notes:list,instrument:str,speed:float = 2.5,posadder:list = [1,0,0],baseblock:str = 'stone') -> bool: - '''传入音符,生成以音符盒存储的红石音乐 +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'] + 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 - from msctspt.values import height2note,instuments - - - def formNoteBlock(note:int,instrument:str='note.harp',powered:bool = False): - '''生成音符盒方块 + def formNoteBlock(note: int, instrument1: str = 'note.harp', powered: bool = False): + """生成音符盒方块 + :param powered: + :param instrument1: :param note: 0~24 - :return Block()''' + :return Block()""" if powered: powered = 'true' else: powered = 'false' - return Block('universal_minecraft','noteblock',{"instrument":ts(instrument.replace("note.",'')),'note':ts(str(note)),'powered':ts(powered)}) - - def formRepeater(delay:int,facing:str,locked:bool=False,powered:bool=False): - '''生成中继器方块 + 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)}) - - + :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]''' + 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 @@ -199,110 +226,120 @@ def note2RSworld(world:str,startpos:list,notes:list,instrument:str,speed:float = # 1拍 x 2.5 rt def placeNoteBlock(): for i in notes: - try : - setblock(formNoteBlock(height2note[i[0]],instrument),[startpos[0],startpos[1]+1,startpos[2]]) - setblock(Block("universal_minecraft",instuments[i[0]][1]),startpos) - except : - log("无法放置音符:"+str(i)+'于'+str(startpos)) - setblock(Block("universal_minecraft",baseblock),startpos) - setblock(Block("universal_minecraft",baseblock),[startpos[0],startpos[1]+1,startpos[2]]) - delay = int(i[1]*speed+0.5) + 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) + startpos[0] += 1 + setblock(formRepeater(delay, 'west'), [startpos[0], startpos[1] + 1, startpos[2]]) + setblock(Block("universal_minecraft", baseblock), startpos) else: - for i in range(int(delay/4)): - startpos[0]+=1 - setblock(formRepeater(4,'west'),[startpos[0],startpos[1]+1,startpos[2]]) - setblock(Block("universal_minecraft",baseblock),startpos) + 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] + 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() - except: + e = False + except ValueError: log("无法放置方块了,可能是因为区块未加载叭") + finally: + if e: + log("无法放置方块了,可能是因为区块未加载叭") level.save() level.close() - - - - - - - class ryStruct: - def __init__(self,world:str) -> None: - + 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) - except: + e = False + except ValueError: log("无法重载地图") + finally: + if e: + log("无法重载地图") def closeLevel(self): + e = True try: self._level.close() - except: + e = False + except ValueError: log("无法关闭地图") + finally: + if e: + log("无法重载地图") - - def world2Rys(self,startp:list,endp:list,includeAir:bool=False): - '''将世界转换为RyStruct字典,注意,此函数运行成功后将关闭地图,若要打开需要运行 reloadLevel + 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 ''' - + :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): + + 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: + 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)) + log("载入方块数据" + str(RyStructBlock)) + + self.RyStruct[(x, y, z)] = 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 5948dc6..9a49688 100644 --- a/msctspt/values.py +++ b/msctspt/values.py @@ -1,59 +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'] + '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, + 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, + 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音高:音符盒音调''' - -