This commit is contained in:
EillesWan 2022-01-23 22:02:36 +08:00
commit f0dedabe1a
16 changed files with 1189 additions and 956 deletions

View File

@ -232,6 +232,7 @@ def __main__():
if clearLog: if clearLog:
print(READABLETEXT[2]) print(READABLETEXT[2])
err = True
try: try:
if os.path.exists('./log/'): if os.path.exists('./log/'):
shutil.rmtree('./log/') shutil.rmtree('./log/')
@ -239,8 +240,12 @@ def __main__():
shutil.rmtree('./logs/') shutil.rmtree('./logs/')
if os.path.exists('./cache/'): if os.path.exists('./cache/'):
shutil.rmtree('./cache/') shutil.rmtree('./cache/')
err = False
except ZeroDivisionError: # 程序规范修改根据新的语法标准except后面不能没有错误类型所以既然是pass就随便填一个错误 except ZeroDivisionError: # 程序规范修改根据新的语法标准except后面不能没有错误类型所以既然是pass就随便填一个错误
print(READABLETEXT[3]) print(READABLETEXT[3])
finally:
if err is True:
print(READABLETEXT[3])
exit() exit()
@ -660,6 +665,7 @@ def __main__():
except ValueError: # 测试完为ValueError故修改语法 except ValueError: # 测试完为ValueError故修改语法
tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117]) tkinter.messagebox.showerror(title=READABLETEXT[0], message=READABLETEXT[117])
continue continue
break
Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./') Outdire = tkinter.filedialog.askdirectory(title=READABLETEXT[29], initialdir=r'./')
if Outdire is None or Outdire == '': if Outdire is None or Outdire == '':
return return

View File

@ -1,5 +1,8 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误2个---未解决警告二级错误2个语法一级错误17个
__version__ = '0.0.1' __version__ = '0.0.1'
__all__ = [] __all__ = []
@ -24,3 +27,144 @@ A library to develop minecraft websocket server easily.
from main import * 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()

View File

@ -9,7 +9,7 @@
# 若需转载或借鉴 请附作者 # 若需转载或借鉴 请附作者
''' """
Copyright 2022 Eilles Wan (金羿) Copyright 2022 Eilles Wan (金羿)
Licensed under the Apache License, Version 2.0 (the 'License') 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. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
''' """
# 代码写的并非十分的漂亮还请大佬多多包涵本软件源代码依照Apache软件协议公开 # 代码写的并非十分的漂亮还请大佬多多包涵本软件源代码依照Apache软件协议公开
''' # -----------------------------分割线-----------------------------
将程序中用双引号""括起来的字符串 # 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
转为字符串列表 list[str, str, ...] # 统计致命三级错误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 import sys
startWith = 0
def __main__(): def __main__():
@ -46,23 +58,25 @@ def __main__():
print('读取文件: {}'.format(fileName)) print('读取文件: {}'.format(fileName))
fileText = [] fileText = []
for line in open(fileName, 'r', encoding='utf-8'): 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: if line[
thisText = textList.index(line[line.index('"'):2+line[line.index('"')+1:].index('"')+len(line[:line.index('"')])]) 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: else:
thisText = len(textList) 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.replace(
line[line.index('"'):2+line[line.index('"') + 1:].index('"')+len(line[:line.index('"')])], line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])],
'READABLETEXT[{}]'.format(thisText+startWith) 'READABLETEXT[{}]'.format(thisText + startWith)
) )
fileText.append(line) fileText.append(line)
open(fileName+'_C','w',encoding='utf-8').writelines(fileText) open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText)
outFile = open('lang__.py', 'w', encoding='utf-8')
outFile = open('lang__.py','w',encoding='utf-8')
outFile.write('''# -*- coding:utf-8 -*- outFile.write('''# -*- coding:utf-8 -*-
# 由金羿翻译工具生成字符串列表 # 由金羿翻译工具生成字符串列表
@ -73,7 +87,7 @@ def __main__():
READABLETEXT = { READABLETEXT = {
''') ''')
for i in range(len(textList)): 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.write('}')
outFile.close() outFile.close()

View File

@ -4,160 +4,159 @@
# 请在所需翻译的文件前from 此文件 import READABLETEXT # 请在所需翻译的文件前from 此文件 import READABLETEXT
READABLETEXT = { READABLETEXT = {
'Translator':(("Eilles Wan (金羿)",True),), 'Translator': (("Eilles Wan (金羿)", True),),
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 # 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
0:"ERROR❌", 0: "ERROR❌",
1:"TIPS❗", 1: "TIPS❗",
2:"Clearing log(this wont be in the file)", 2: "Clearing log(this wont be in the file)",
3:"Could not clear the temporary files or logs", 3: "Could not clear the temporary files or logs",
4:"saved", 4: "saved",
5:"New Musicreater Project", 5: "New Musicreater Project",
6:"Select old-type project", 6: "Select old-type project",
7:"Select Musicreater Project", 7: "Select Musicreater Project",
8:"Cant open:{}, please check if youve entered the right name", 8: "Cant open:{}, please check if youve entered the right name",
9:"Musicreat - About", 9: "Musicreat - About",
10:"Musicreater", 10: "Musicreater",
11:"Ver. {}", 11: "Ver. {}",
12:"""Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""", 12: """Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""",
13:"OK", 13: "OK",
14:"Inpute Notes", 14: "Inpute Notes",
15:(("- Developers -",False), 15: (("- Developers -", False),
("Eilles Wan (金羿)",True),("EillesWan@outlook.com",False),("QQ 2647547478",False), ("Eilles Wan (金羿)", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
("bgArray “诸葛亮与八卦阵”",True),("QQ 474037765",False)), ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False)),
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
16:"- Translators -", 16: "- Translators -",
# 17:"", # 17:"",
18:"QQ Group: 861684859", 18: "QQ Group: 861684859",
19:"Musicreater - Help", 19: "Musicreater - Help",
20:"Select sound file", 20: "Select sound file",
21:"Select MIDI file", 21: "Select MIDI file",
22:"Select NoteText file", 22: "Select NoteText file",
23:"Get Note info", 23: "Get Note info",
24:"Write in Note info: {}", 24: "Write in Note info: {}",
25:"Select generating file", 25: "Select generating file",
26:"Select generating folder", 26: "Select generating folder",
27:"Select generating .mcpack file", 27: "Select generating .mcpack file",
28:"Input position info", 28: "Input position info",
29:"Select generating world folder", 29: "Select generating world folder",
30:"Select generating Function Pack", 30: "Select generating Function Pack",
31:"Select .mcfunction file ", 31: "Select .mcfunction file ",
32:"Select .bdx file ", 32: "Select .bdx file ",
33:"DONE✔", 33: "DONE✔",
34:"Input playing rate", 34: "Input playing rate",
35:"Generating", 35: "Generating",
36:"Select a world folder", 36: "Select a world folder",
37:"Make sure", 37: "Make sure",
38:"Generate .RyStruct file", 38: "Generate .RyStruct file",
39:"FAILED❌", 39: "FAILED❌",
40:"Report message inpution", 40: "Report message inpution",
41:"Musicreater - Eilles - {}", 41: "Musicreater - Eilles - {}",
42:"ExecutingEntityName: {}", 42: "ExecutingEntityName: {}",
43:"ScoreboardName: {}", 43: "ScoreboardName: {}",
44:"Instrument: {}", 44: "Instrument: {}",
45:"TrackName: {}", 45: "TrackName: {}",
46:"PackName: {}", 46: "PackName: {}",
47:"MusicTitle: {}", 47: "MusicTitle: {}",
48:"IsRepeat?: {}", 48: "IsRepeat?: {}",
49:"Player'sTargetSelector: {}", 49: "Player'sTargetSelector: {}",
50:"Modify Main Option", 50: "Modify Main Option",
51:"Modify Track Option", 51: "Modify Track Option",
52:"Default Instrument: Enter English\n", 52: "Default Instrument: Enter English\n",
53:"Open...", 53: "Open...",
54:"Open Old Project...", 54: "Open Old Project...",
55:"Save", 55: "Save",
56:"Save as...", 56: "Save as...",
57:"Exit", 57: "Exit",
58:"File", 58: "File",
59:"Load tracks from sound", 59: "Load tracks from sound",
60:"Load tracks from Midi", 60: "Load tracks from Midi",
61:"Load tracks from Text", 61: "Load tracks from Text",
62:"Input notes to track", 62: "Input notes to track",
63:"Edit", 63: "Edit",
64:"Generate file...", 64: "Generate file...",
65:"Generate function pack...", 65: "Generate function pack...",
66:"Generate .mcpack file...", 66: "Generate .mcpack file...",
67:"Functions(Pack)", 67: "Functions(Pack)",
68:"Save music as blocks into a map", 68: "Save music as blocks into a map",
69:"Save music as blocks into a exist map...", 69: "Save music as blocks into a exist map...",
70:"Save music as commands into a map", 70: "Save music as commands into a map",
71:"Save music as commands into a exist map...", 71: "Save music as commands into a exist map...",
72:"Save music as notebox into a map", 72: "Save music as notebox into a map",
73:"Save music as notebox into a exist map...", 73: "Save music as notebox into a exist map...",
74:"World", 74: "World",
75:"Generate a function that fits current music...", 75: "Generate a function that fits current music...",
76:"Save selected track as commands in .bdx file...", 76: "Save selected track as commands in .bdx file...",
77:"Export .bdx file from map...", 77: "Export .bdx file from map...",
78:"Export .RyStruct file from map...", 78: "Export .RyStruct file from map...",
79:"Load functions into a world...", 79: "Load functions into a world...",
80:"Separate long .mcfunction file into small ones and set them into a world as a chain...", 80: "Separate long .mcfunction file into small ones and set them into a world as a chain...",
81:"Additional Functions", 81: "Additional Functions",
82:"Show generating result", 82: "Show generating result",
83:"Set a websocket server on localhost:8080 and play the selected track", 83: "Set a websocket server on localhost:8080 and play the selected track",
84:"Experimental Functions", 84: "Experimental Functions",
85:"Clear log file", 85: "Clear log file",
86:"Clear save file(obsolete)", 86: "Clear save file(obsolete)",
87:"Help", 87: "Help",
88:"About", 88: "About",
89:"Send a bug report", 89: "Send a bug report",
90:"Q&A", 90: "Q&A",
91:"Main Options", 91: "Main Options",
# 92:"", # 92:"",
# 93:"", # 93:"",
# 94:"", # 94:"",
# 95:"", # 95:"",
96:"Reset Main Options", 96: "Reset Main Options",
97:"Track Options", 97: "Track Options",
# 98:"", # 98:"",
# 99:"", # 99:"",
# 100:"", # 100:"",
# 101:"", # 101:"",
102:"Delete Selected Track", 102: "Delete Selected Track",
# 103:"", # 103:"",
# 104:"", # 104:"",
105:"找不到或无法读取文件😢:{}", 105: "找不到或无法读取文件😢:{}",
106:"您当前的项目已修改但未存储,是否先保存当前项目?", 106: "您当前的项目已修改但未存储,是否先保存当前项目?",
107:"项目已经存储至:{}", 107: "项目已经存储至:{}",
108:"音·创工程文件", 108: "音·创工程文件",
109:"任意类型", 109: "任意类型",
110:"函数音创工程文件", 110: "函数音创工程文件",
111:"MMFM0.0.6版本工程文件", 111: "MMFM0.0.6版本工程文件",
112:"全部类型", 112: "全部类型",
113:"钢琴声音的音频文件", 113: "钢琴声音的音频文件",
114:"Midi文件", 114: "Midi文件",
115:"文本文件", 115: "文本文件",
116:"请输入坐标:", 116: "请输入坐标:",
117:"您输入的格式有误,请重新输入!", 117: "您输入的格式有误,请重新输入!",
118:"我的世界指令函数文件", 118: "我的世界指令函数文件",
119:"请输入执行链生成坐标:", 119: "请输入执行链生成坐标:",
120:"您输入的格式有误,请重新输入。", 120: "您输入的格式有误,请重新输入。",
121:"您的函数文件不大于一万条指令,无需进行分割操作。", 121: "您的函数文件不大于一万条指令,无需进行分割操作。",
122:"请输入执行链生成相对坐标:", 122: "请输入执行链生成相对坐标:",
123:"FastBuilder结构文件", 123: "FastBuilder结构文件",
124:"转换结束!\n{}", 124: "转换结束!\n{}",
125:"一秒,音乐走几拍?", 125: "一秒,音乐走几拍?",
126:"按下确认后在游戏中使用connect指令连接localhost:8080即可播放", 126: "按下确认后在游戏中使用connect指令连接localhost:8080即可播放",
127:"请输入区域选择的开始坐标:", 127: "请输入区域选择的开始坐标:",
128:"请输入区域选择的结束坐标:", 128: "请输入区域选择的结束坐标:",
129:"所选区块导出时是否需要保留空气方块?", 129: "所选区块导出时是否需要保留空气方块?",
130:"音·创结构文件", 130: "音·创结构文件",
131:"文件已生成\n{}", 131: "文件已生成\n{}",
132:"文件无法生成\n{}\n{}", 132: "文件无法生成\n{}\n{}",
133:"本功能尚未开发。", 133: "本功能尚未开发。",
134:"您的称呼", 134: "您的称呼",
135:"您的联系方式", 135: "您的联系方式",
136:"您对问题的描述", 136: "您对问题的描述",
137:"在程序结束后将清除日志及临时文件信息。", 137: "在程序结束后将清除日志及临时文件信息。",
138:"在程序结束后将不会清除日志及临时文件信息。", 138: "在程序结束后将不会清除日志及临时文件信息。",
139:"修改包名", 139: "修改包名",
140:"修改音乐标题", 140: "修改音乐标题",
141:"修改玩家选择器\n注意!要加上中括号“[]”", 141: "修改玩家选择器\n注意!要加上中括号“[]”",
142:"修改本音轨的执行实体名", 142: "修改本音轨的执行实体名",
143:"修改本音轨所用的积分板", 143: "修改本音轨所用的积分板",
144:"修改本音轨所用乐器", 144: "修改本音轨所用乐器",
145:"您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?", 145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?",
146:"修改本音轨生成的文件名", 146: "修改本音轨生成的文件名",
} }

View File

@ -23,9 +23,9 @@ READABLETEXT = {
13: "确定", 13: "确定",
14: "请输入音符", 14: "请输入音符",
15: (("- 开发者 -", False), 15: (("- 开发者 -", False),
("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False), ("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
("bgArray “诸葛亮与八卦阵”",True),("QQ 474037765",False), ("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False),
), ),
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字 # 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
16: "- 翻译者 -", 16: "- 翻译者 -",
# 17:"", # 17:"",

View File

@ -4,6 +4,10 @@ import brotli
'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码''' '''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码'''
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误7个
class BdxConverter: class BdxConverter:
__header = "BD@" __header = "BD@"
__bin_header = b"BDX" __bin_header = b"BDX"
@ -42,8 +46,8 @@ class BdxConverter:
:return: list 给出的所有方块种类名称 :return: list 给出的所有方块种类名称
""" """
block_type = set() block_type = set()
for block in self.blocks: for block_ in self.blocks:
block_type.add(block["block_name"]) block_type.add(block_["block_name"])
block_type = list(block_type) block_type = list(block_type)
return block_type return block_type
@ -74,6 +78,7 @@ class BdxConverter:
f.write(brotli.compress(_bytes)) f.write(brotli.compress(_bytes))
f.close() f.close()
return return
def upload_blocks(self): def upload_blocks(self):
""" """
计算差值 计算差值
@ -83,17 +88,17 @@ class BdxConverter:
:return: :return:
""" """
_types = b"" _types = b""
for block in self.blocks: for block_ in self.blocks:
# print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]") # 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 _types += diff
if block["block_name"] in ["command_block", if block_["block_name"] in ["command_block",
"chain_command_block", "chain_command_block",
"repeating_command_block"]: "repeating_command_block"]:
_types += self.obtain_command_block(block) _types += self.obtain_command_block(block_)
else: else:
_types += self.obtain_universal_block(block) _types += self.obtain_universal_block(block_)
self.direction = block["direction"] self.direction = block_["direction"]
return _types return _types
def move_pointer(self, direction: list, new_direction): def move_pointer(self, direction: list, new_direction):
@ -148,21 +153,21 @@ class BdxConverter:
return pointer_type + num_byte return pointer_type + num_byte
return pointer_type return pointer_type
def obtain_universal_block(self, block): def obtain_universal_block(self, block1):
""" """
给定一个方块 返回此方块在这个bdx中的id和方块data 给定一个方块 返回此方块在这个bdx中的id和方块data
:param block: {block_name: str,particular_value: int} :param block1: {block_name: str,particular_value: int}
:return: bytes :return: bytes
""" """
block_id = b"\x07" + self.block_type.index(block["block_name"]).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 = block["particular_value"].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 block_header = block_id + particular_value
return block_header 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] "direction": [x: int, y: int, z: int]
"block_name": str, "block_name": str,
"particular_value": int, "particular_value": int,
@ -179,23 +184,24 @@ class BdxConverter:
:return: bytes of command_block :return: bytes of command_block
""" """
block_id = b"\x1b" + self.block_type.index(block["block_name"]).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 = block["particular_value"].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 block_header = block_id + particular_value
for i in [ for i in [
block["impluse"].to_bytes(4, byteorder="big", signed=False), block1["impluse"].to_bytes(4, byteorder="big", signed=False),
bytes(block["command"], encoding="utf-8") + b"\x00", bytes(block1["command"], encoding="utf-8") + b"\x00",
bytes(block["customName"], encoding="utf-8") + b"\x00", bytes(block1["customName"], encoding="utf-8") + b"\x00",
bytes(block["lastOutput"], encoding="utf-8") + b"\x00", bytes(block1["lastOutput"], encoding="utf-8") + b"\x00",
block["tickdelay"].to_bytes(4, byteorder="big", signed=True), block1["tickdelay"].to_bytes(4, byteorder="big", signed=True),
block["executeOnFirstTick"].to_bytes(1, byteorder="big"), block1["executeOnFirstTick"].to_bytes(1, byteorder="big"),
block["trackOutput"].to_bytes(1, byteorder="big"), block1["trackOutput"].to_bytes(1, byteorder="big"),
block["conditional"].to_bytes(1, byteorder="big"), block1["conditional"].to_bytes(1, byteorder="big"),
block["needRedstone"].to_bytes(1, byteorder="big") block1["needRedstone"].to_bytes(1, byteorder="big")
]: ]:
block_header += i block_header += i
return block_header return block_header
if __name__ == '__main__': if __name__ == '__main__':
block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5}, block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5},
{"direction": [1, 5, 1], "block_name": "stained_glass", "particular_value": 7}, {"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": [3, 4, 1], "block_name": "concrete", "particular_value": 6},
{"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}] {"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}]
bdx = BdxConverter("./test02.bdx", "Charlie_Ping",block) bdx = BdxConverter("./test02.bdx", "Charlie_Ping", block)

View File

@ -1,22 +1,21 @@
# -*- coding: UTF-8 -*- # -*- 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 默认算法为DEFLATED(8),可用算法如下\n
STORED = 0\n STORED = 0\n
DEFLATED = 8\n DEFLATED = 8\n
BZIP2 = 12\n BZIP2 = 12\n
LZMA = 14\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)) pre_len = len(os.path.dirname(sourceDir))
for parent, dirnames, filenames in os.walk(sourceDir): for parent, dirnames, filenames in os.walk(sourceDir):
for filename in filenames: for filename in filenames:
@ -24,37 +23,33 @@ def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None):
continue continue
print(filename) print(filename)
pathfile = os.path.join(parent, 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.write(pathfile, arcname)
zipf.close() zipf.close()
del zipf,pre_len del zipf, pre_len
#以上函数节选并修改自 正在攀登的小蜗牛 的博客https://blog.csdn.net/qq_21127151/article/details/107503942
# 以上函数节选并修改自 正在攀登的小蜗牛 的博客https://blog.csdn.net/qq_21127151/article/details/107503942
class report:
"""发送报告以及相应的任务处理"""
def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''):
""":param senderName 发送者名称
class report():
'''发送报告以及相应的任务处理'''
def __init__(self,senderName:str = 'Unknown',senderContact:str = 'None',describetion:str = ''):
''':param senderName 发送者名称
:param senderContact 发送者联系方式 :param senderContact 发送者联系方式
:param describetion 问题描述''' :param describetion 问题描述"""
self.senderName = senderName self.senderName = senderName
self.senderContact = senderContact self.senderContact = senderContact
self.describetion = describetion self.describetion = describetion
if not self.senderName : if not self.senderName:
self.senderName = 'Unknown' self.senderName = 'Unknown'
if not self.senderContact : if not self.senderContact:
self.senderContact = 'None' self.senderContact = 'None'
def emailReport(self): def emailReport(self):
'''使用E-mail方法发送当前的日志和临时文件等''' """使用E-mail方法发送当前的日志和临时文件等"""
import smtplib import smtplib
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
@ -64,73 +59,72 @@ class report():
import os import os
log("添加标题与正文") log("添加标题与正文")
msg = MIMEMultipart() msg = MIMEMultipart()
#发送者与接收者显示名称 # 发送者与接收者显示名称
msg["From"] = Header(self.senderName,'utf-8') msg["From"] = Header(self.senderName, 'utf-8')
msg["To"] = Header("W-YI (QQ2647547478)",'utf-8') msg["To"] = Header("W-YI (QQ2647547478)", 'utf-8')
#标题 # 标题
msg["Subject"] = '音·创 - 来自 '+self.senderName+' 的错误报告' msg["Subject"] = '音·创 - 来自 ' + self.senderName + ' 的错误报告'
#正文 # 正文
msg.attach(MIMEText("来自"+self.senderName+"( "+self.senderContact+" )的错误描述:\n"+self.describetion,'plain','utf-8')) msg.attach(
MIMEText("来自" + self.senderName + "( " + self.senderContact + " )的错误描述:\n" + self.describetion,
'utf-8'))
log("添加完毕,正在生成压缩包...") log("添加完毕,正在生成压缩包...")
makeZip("./","Temps&Logs.zip",exceptFile="Temps&Logs.zip") makeZip("./", "Temps&Logs.zip", exceptFile="Temps&Logs.zip")
attafile=MIMEText(open("Temps&Logs.zip",'rb').read(),"base64",'gb2312') attafile = MIMEText(str(open("Temps&Logs.zip", 'rb').read()), "base64", 'gb2312')
attafile["Content-Type"] = 'application/octet-stream' 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) msg.attach(attafile)
log("完毕,准备发送") log("完毕,准备发送")
try: try:
smtp = smtplib.SMTP() smtp = smtplib.SMTP()
smtp.connect("smtp.163.com") smtp.connect("smtp.163.com")
#smtp.login("RyounDevTeam@163.com","RyounDaiYi99") # smtp.login("RyounDevTeam@163.com","RyounDaiYi99")
#SIQQKQQYCZRVIDFJ是授权密码 # SIQQKQQYCZRVIDFJ是授权密码
smtp.login("RyounDevTeam@163.com","SIQQKQQYCZRVIDFJ") smtp.login("RyounDevTeam@163.com", "SIQQKQQYCZRVIDFJ")
smtp.sendmail("RyounDevTeam@163.com",["RyounDevTeam@163.com",],msg.as_string()) smtp.sendmail("RyounDevTeam@163.com", ["RyounDevTeam@163.com", ], msg.as_string())
log("错误汇报邮件已发送") log("错误汇报邮件已发送")
except smtplib.SMTPException as e: except smtplib.SMTPException as e:
log("错误汇报邮件发送失败:\n"+str(e)) log("错误汇报邮件发送失败:\n" + str(e))
log("清空内存和临时文件") log("清空内存和临时文件")
del msg,attafile del msg, attafile
os.remove("./Temps&Logs.zip") os.remove("./Temps&Logs.zip")
class version: 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: def __init__(self) -> None:
self.libraries = version.libraries self.libraries = version.libraries
'''当前所需库,有一些是开发用的,用户不需要安装''' """当前所需库,有一些是开发用的,用户不需要安装"""
self.version = version.version self.version = version.version
'''当前版本''' """当前版本"""
def installLibraries(self): def installLibraries(self):
'''安装全部开发用库''' """安装全部开发用库"""
from sys import platform from sys import platform
import os import os
if platform == 'win32': if platform == 'win32':
import shutil import shutil
try: try:
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\') shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')
except: except FloatingPointError:
pass pass
for i in self.libraries: for i in self.libraries:
print("安装库:"+i) print("安装库:" + i)
os.system("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple") os.system("python -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple")
elif platform == 'linux': elif platform == 'linux':
os.system("sudo apt-get install python3-pip") os.system("sudo apt-get install python3-pip")
os.system("sudo apt-get install python3-tk") os.system("sudo apt-get install python3-tk")
os.system("sudo apt-get install python3-tkinter") os.system("sudo apt-get install python3-tkinter")
for i in self.libraries: for i in self.libraries:
print("安装库:"+i) print("安装库:" + i)
os.system("sudo python3 -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple") os.system("sudo python3 -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple")

View File

@ -1,186 +1,204 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""音·创 的函数操作和一些其他功能""" """音·创 的函数操作和一些其他功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误91个
from nmcsup.log import log from nmcsup.log import log
def delPart(Data, starter, ender, includeStart: bool = True, includend: bool = True):
def delPart(Data,starter,ender,includeStart :bool= True,includend :bool= True): """删除序列从starter物件到ender物件之间的部分\n
'''删除序列从starter物件到ender物件之间的部分\n
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分默认为真\n includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分默认为真\n
starter与ender若为None则默认从首或尾开始''' starter与ender若为None则默认从首或尾开始"""
e = True
try: try:
if starter == None: if starter is None:
includeStart = True includeStart = True
starter = Data[0] starter = Data[0]
if ender == None: if ender is None:
includend = True includend = True
ender = Data[len(Data)-1] ender = Data[len(Data) - 1]
if includend: if includend:
if includeStart: 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: 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: else:
if includeStart: 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: else:
return Data[Data.index(starter)+1:len(Data)-Data[len(Data)::-1].index(ender)-1] e = False
except: return Data[Data.index(starter) + 1:len(Data) - Data[len(Data)::-1].index(ender) - 1]
except ValueError:
return 0 return 0
finally:
if e is True:
return 0
def keepart(Data,starter,ender,includeStart :bool= True,includend :bool= True): def keepart(Data, starter, ender, includeStart: bool = True, includend: bool = True):
'''保留序列从starter物件到ender物件之间的部分\n """保留序列从starter物件到ender物件之间的部分\n
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分默认为真\n includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分默认为真\n
starter与ender若为None则默认从首或尾开始''' starter与ender若为None则默认从首或尾开始"""
e = True
try: try:
if starter == None: if starter is None:
includeStart = True includeStart = True
starter = Data[0] starter = Data[0]
if ender == None: if ender is None:
includend = True includend = True
ender = Data[len(Data)-1] ender = Data[len(Data) - 1]
if includend: if includend:
if includeStart: if includeStart:
return Data[Data.index(starter):Data.index(ender)+1] e = False
return Data[Data.index(starter):Data.index(ender) + 1]
else: else:
return Data[Data.index(starter)+1:Data.index(ender)+1] e = False
return Data[Data.index(starter) + 1:Data.index(ender) + 1]
else: else:
if includeStart: if includeStart:
e = False
return Data[Data.index(starter):Data.index(ender)] return Data[Data.index(starter):Data.index(ender)]
else: else:
return Data[Data.index(starter)+1:Data.index(ender)] e = False
except: return Data[Data.index(starter) + 1:Data.index(ender)]
except ValueError:
return 0 return 0
finally:
if e is True:
return 0
def lenFunction(fun) -> int: def lenFunction(fun) -> int:
'''取得函数指令部分长度,即忽略#开头的注释''' """取得函数指令部分长度,即忽略#开头的注释"""
e = True
try: try:
l = 0 f = 0
for i in fun: for i in fun:
if i.replace(" ",'')[0] == '#': if i.replace(" ", '')[0] == '#':
l += 1 f += 1
return len(fun)-l e = False
except: return len(fun) - f
except IndexError:
return -1 return -1
finally:
if e is True:
return -1
def funSplit(bigFile, maxCmdLen: int = 10000):
def funSplit(bigFile,maxCmdLen : int = 10000 ): """分割bigFile大的函数文件bigFile需要读入文件流\n
'''分割bigFile大的函数文件bigFile需要读入文件流\n
返回的部分每行指令皆带有行尾换行符\\n\n 返回的部分每行指令皆带有行尾换行符\\n\n
返回-1为大小低于maxCmdLen最长函数指令长度''' 返回-1为大小低于maxCmdLen最长函数指令长度"""
bigFile = bigFile.readlines() bigFile = bigFile.readlines()
if lenFunction(bigFile) < maxCmdLen: if lenFunction(bigFile) < maxCmdLen:
return -1 return -1
part = [] part = []
parts = [] parts = []
l = 0 h = 0
for i in bigFile: for i in bigFile:
if i.replace(" ",'')[0] == '#': if i.replace(" ", '')[0] == '#':
part.append(i+'\n') part.append(i + '\n')
else: else:
part.append(i+'\n') part.append(i + '\n')
l += 1 h += 1
if l >= 10000: if h >= 10000:
parts.append(part) parts.append(part)
part = [] part = []
l = 0 h = 0
return parts return parts
def makeFuncFiles(musicset, path='./'): def makeFuncFiles(musicset, path='./'):
'''在指定目录下生成函数文件''' """在指定目录下生成函数文件"""
from nmcsup.trans import Note2Cmd from nmcsup.trans import Note2Cmd
commands = [] commands = []
starts = [] starts = []
log("=========================正在在此处生成文件:"+path) log("=========================正在在此处生成文件:" + path)
maxlen = -1 maxlen = -1
for i in range(len(musicset['musics'])): for i in range(len(musicset['musics'])):
log('写入第'+str(i)+'个数据') log('写入第' + str(i) + '个数据')
commands.append("scoreboard players add @e[name=\""+musicset['musics'][i]['set']['EntityName']+"\"] "+musicset['musics'][i]['set']['ScoreboardName']+" 1\n") commands.append("scoreboard players add @e[name=\"" + musicset['musics'][i]['set']['EntityName'] + "\"] " +
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") 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']+" subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\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: if len(musicset['musics'][i]['notes']) > maxlen:
maxlen = len(musicset['musics'][i]['notes']) maxlen = len(musicset['musics'][i]['notes'])
starts.append("scoreboard objectives add " +musicset['musics'][i]['set']['ScoreboardName']+" dummy\n") starts.append("scoreboard objectives add " + musicset['musics'][i]['set']['ScoreboardName'] + " dummy\n")
starts.append("summon armor_stand " +musicset['musics'][i]['set']['EntityName']+'\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: with open(path + musicset['mainset']['MusicTitle'] + '_Part' + str(i) + '.mcfunction', 'w',
f.writelines(Note2Cmd(musicset['musics'][i]['notes'],musicset['musics'][i]['set']['ScoreboardName'],musicset['musics'][i]['set']['Instrument'],musicset['mainset']['PlayerSelect'],True)) 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']: if musicset['mainset']['IsRepeat']:
log("增加重复语句") log("增加重复语句")
for i in range(len(musicset['musics'])): 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("增加版权语句") log("增加版权语句")
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n") commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n")
starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n") starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n")
log("写入支持文件") 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) f.writelines(commands)
log("写入开始文件") 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) f.writelines(starts)
del commands, starts, maxlen del commands, starts, maxlen
log("完成============================") log("完成============================")
def makeFunDir(musicset, path='./'): def makeFunDir(musicset, path='./'):
'''在指定目录下生成函数包文件夹''' """在指定目录下生成函数包文件夹"""
import os import os
import uuid import uuid
log("=============================生成函数包文件夹") 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: try:
os.makedirs(path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions") os.makedirs(path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
log("已创建目录"+path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions") 'PackName'] + "/functions")
except: log("已创建目录" + path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset'][
'PackName'] + "/functions")
except FileExistsError:
log("目录已有无需创建") log("目录已有无需创建")
pass 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") log("创建manifest.json以及world_behavior_packs.json")
behaviorUuid = uuid.uuid4() behaviorUuid = uuid.uuid4()
with open(path+musicset['mainset']['PackName']+"Pack/world_behavior_packs.json", "w") as f: 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]") 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: p = path + musicset['mainset']['PackName'] + "Pack/behavior_packs/" + musicset['mainset']['PackName'] + \
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}") "/manifest.json"
makeFuncFiles(musicset, path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions/") 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("完成============================") log("完成============================")
"""
'''
这里是往事用于记载一些用不到的功能 这里是往事用于记载一些用不到的功能
#存在于 Musicreater.py 播放(试听)音乐 #存在于 Musicreater.py 播放(试听)音乐
@ -207,8 +225,9 @@ def PlayOne():
#同上,是早期 MinecraftMusicFunctionMaker.py (函数音创)的代码转移至音·创时的注解 #同上,是早期 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"])
''' """

View File

@ -1,22 +1,26 @@
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误9个--未解决1个
import threading import threading
class NewThread(threading.Thread): class NewThread(threading.Thread):
'''新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值''' """新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值"""
def __init__(self, func, args=()): def __init__(self, func, args=()):
super(NewThread, self).__init__() super(NewThread, self).__init__()
self.func = func self.func = func
self.args = args self.args = args
def run(self): def run(self):
self.result = self.func(*self.args) self.result = self.func(*self.args)
def getResult(self): def getResult(self):
threading.Thread.join(self) # 等待线程执行完毕 threading.Thread.join(self) # 等待线程执行完毕
try: try:
return self.result return self.result
except Exception: except ValueError:
return None return None
# #

View File

@ -1,27 +1,47 @@
"""音·创 的转换工具库""" """音·创 的转换工具库"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---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 from pypinyin import lazy_pinyin
result = lazy_pinyin(hans=hans,style=style) result = lazy_pinyin(hans=hans, style=style)
final = '' final = ''
for i in result: for i in result:
final += i final += i
return final 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 = '',
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): 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: { :param block: {
"direction": [x: int, y: int, z: int] #方块位置 "direction": [x: int, y: int, z: int] #方块位置
"block_name": str, #方块名称无需指定默认为command_block "block_name": str, #方块名称无需指定默认为command_block
@ -36,7 +56,6 @@ def formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,cond
"conditional": int, #是否有条件 1 bytes "conditional": int, #是否有条件 1 bytes
"needRedstone": int #是否需要红石 1 bytes "needRedstone": int #是否需要红石 1 bytes
} }
:return: 指令方块字典结构
""" """
return {"direction": direction, return {"direction": direction,
"block_name": "command_block", "block_name": "command_block",
@ -50,68 +69,71 @@ def formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,cond
"trackOutput": trackOutput, "trackOutput": trackOutput,
"conditional": condition, "conditional": condition,
"needRedstone": needRedstone "needRedstone": needRedstone
} }
def note2bdx(filePath: str, dire: list, Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '',
isProsess: bool = False, height: int = 200):
def note2bdx(filePath:str,dire:list,Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False,height:int = 200) : """使用方法同Note2Cmd
'''使用方法同Note2Cmd
:param 参数说明 :param 参数说明
filePath: 生成.bdx文件的位置 filePath: 生成.bdx文件的位置
dire: 指令方块在地图中生成的起始位置相对位置 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: 用于执行的计分板名称 ScoreboardName: 用于执行的计分板名称
Instrument: 播放的乐器 Instrument: 播放的乐器
PlayerSelect: 执行的玩家选择器 PlayerSelect: 执行的玩家选择器
isProsess: 是否显示进度条会很卡 isProsess: 是否显示进度条会很卡
height: 生成结构的最高高度 height: 生成结构的最高高度
:return 返回一个BdxConverter类实际上没研究过同时在指定位置生成.bdx文件''' :return 返回一个BdxConverter类实际上没研究过同时在指定位置生成.bdx文件"""
from msctspt.transfer import formCmdBlock from msctspt.transfer import formCmdBlock
from nmcsup.trans import Note2Cmd from nmcsup.trans import Note2Cmd
from msctspt.bdxOpera_CP import BdxConverter from msctspt.bdxOpera_CP import BdxConverter
cmd = Note2Cmd(Notes,ScoreboardName,Instrument, PlayerSelect,isProsess) cmd = Note2Cmd(Notes, ScoreboardName, Instrument, PlayerSelect, isProsess)
cdl = [] cdl = []
for i in cmd: for i in cmd:
e = True
try: 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('#')]) cdl.append(i[:i.index('#')])
except: e = False
except ValueError:
cdl.append(i) cdl.append(i)
finally:
if e is True:
cdl.append(i)
i = 0 i = 0
down = False down = False
blocks = [formCmdBlock(dire,cdl.pop(0),1,1)] blocks = [formCmdBlock(dire, cdl.pop(0), 1, 1)]
dire[1]+=1 dire[1] += 1
for j in cdl: for j in cdl:
if dire[1]+i > height: if dire[1] + i > height:
dire[0]+=1 dire[0] += 1
i=0 i = 0
down = not down down = not down
if dire[1]+i == height : if dire[1] + i == height:
blocks.append(formCmdBlock([dire[0],dire[1]+i,dire[2]],j,5,2,False,False)) blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 5, 2, False, False))
else: else:
if down: 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: else:
blocks.append(formCmdBlock([dire[0],dire[1]+i,dire[2]],j,1,2,False,False)) blocks.append(formCmdBlock([dire[0], dire[1] + i, dire[2]], j, 1, 2, False, False))
i+=1 i += 1
del i, cdl, down, cmd 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 参数说明 :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: 播放的乐器 Instrument: 播放的乐器
speed: 用于控制播放速度数值越大播放速度越快相当于把一秒变为几拍 speed: 用于控制播放速度数值越大播放速度越快相当于把一秒变为几拍
PlayerSelect: 执行的玩家选择器 PlayerSelect: 执行的玩家选择器
isProsess: 是否显示进度条 isProsess: 是否显示进度条
:return None''' :return None"""
import time import time
import fcwslib import fcwslib
@ -119,77 +141,82 @@ def note2webs(Notes : list,Instrument:str, speed:float = 5.0, PlayerSelect:str='
from nmcsup.log import log from nmcsup.log import log
from nmcsup.vers import VER from nmcsup.vers import VER
async def run_server(websocket, path): async def run_server(websocket): # , path
log('服务器连接创建') 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: if isProsess:
length = len(Notes) length = len(Notes)
j = 1 j = 1
for i in range(len(Notes)): 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: if isProsess:
fcwslib.send_command(websocket,'execute @a'+PlayerSelect+' ~ ~ ~ title @s actionbar §e▶ 播放中: §a'+str(j)+'/'+str(length)+' || '+str(int(j/length*1000)/10)) fcwslib.send_command(websocket,
j+=1 'execute @a' + PlayerSelect + ' ~ ~ ~ title @s actionbar §e▶ 播放中: §a' + str(
time.sleep(Notes[i][1]/speed) j) + '/' + str(length) + ' || ' + str(int(j / length * 1000) / 10))
j += 1
time.sleep(Notes[i][1] / speed)
fcwslib.run_server(run_server) 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
"""传入音符,生成以音符盒存储的红石音乐
import amulet
from amulet.api.block import Block
from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc
from amulet_nbt import TAG_String as ts
from nmcsup.log import log
def note2RSworld(world:str,startpos:list,notes:list,instrument:str,speed:float = 2.5,posadder:list = [1,0,0],baseblock:str = 'stone') -> bool:
'''传入音符,生成以音符盒存储的红石音乐
:param 参数说明 :param 参数说明
world: 地图文件的路径 world: 地图文件的路径
startpos: list[int,int,int] 开始生成的坐标 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: 播放的乐器 instrument: 播放的乐器
speed: 一拍占多少个中继器延迟(红石刻/rt) speed: 一拍占多少个中继器延迟(红石刻/rt)
posadder: list[int,int,int] 坐标增加规律即红石的延长时按照此增加规律增加坐标 posadder: list[int,int,int] 坐标增加规律即红石的延长时按照此增加规律增加坐标
baseblock: 在中继器下垫着啥方块呢~ baseblock: 在中继器下垫着啥方块呢~
:return 是否生成成功 :return 是否生成成功
''' """
from msctspt.values import height2note, instuments
from msctspt.values import height2note,instuments def formNoteBlock(note: int, instrument1: str = 'note.harp', powered: bool = False):
"""生成音符盒方块
:param powered:
def formNoteBlock(note:int,instrument:str='note.harp',powered:bool = False): :param instrument1:
'''生成音符盒方块
:param note: 0~24 :param note: 0~24
:return Block()''' :return Block()"""
if powered: if powered:
powered = 'true' powered = 'true'
else: else:
powered = 'false' powered = 'false'
return Block('universal_minecraft','noteblock',{"instrument":ts(instrument.replace("note.",'')),'note':ts(str(note)),'powered':ts(powered)}) 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): def formRepeater(delay: int, facing: str, locked: bool = False, powered: bool = False):
'''生成中继器方块 """生成中继器方块
:param powered:
:param locked:
:param facing:
:param delay: 1~4 :param delay: 1~4
:return Block()''' :return Block()"""
if powered:powered = 'true' if powered:
else:powered = 'false' powered = 'true'
if locked:locked = 'true' else:
else:locked = 'false' powered = 'false'
return Block('universal_minecraft','repeater',{"delay":ts(str(delay)),'facing':ts(facing),'locked':ts(locked),'powered':ts(powered)}) 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) level = amulet.load_level(world)
def setblock(block:Block,pos:list): def setblock(block: Block, pos: list):
'''pos : list[int,int,int]''' """pos : list[int,int,int]"""
cx, cz = bc2cc(pos[0], pos[2]) cx, cz = bc2cc(pos[0], pos[2])
chunk = level.get_chunk(cx, cz, "minecraft:overworld") chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz 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 # 1拍 x 2.5 rt
def placeNoteBlock(): def placeNoteBlock():
for i in notes: for i in notes:
try : error = True
setblock(formNoteBlock(height2note[i[0]],instrument),[startpos[0],startpos[1]+1,startpos[2]]) try:
setblock(Block("universal_minecraft",instuments[i[0]][1]),startpos) setblock(formNoteBlock(height2note[i[0]], instrument), [startpos[0], startpos[1] + 1, startpos[2]])
except : setblock(Block("universal_minecraft", instuments[i[0]][1]), startpos)
log("无法放置音符:"+str(i)+''+str(startpos)) error = False
setblock(Block("universal_minecraft",baseblock),startpos) except ValueError:
setblock(Block("universal_minecraft",baseblock),[startpos[0],startpos[1]+1,startpos[2]]) log("无法放置音符:" + str(i) + '' + str(startpos))
delay = int(i[1]*speed+0.5) 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: if delay <= 4:
startpos[0]+=1 startpos[0] += 1
setblock(formRepeater(delay,'west'),[startpos[0],startpos[1]+1,startpos[2]]) setblock(formRepeater(delay, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
setblock(Block("universal_minecraft",baseblock),startpos) setblock(Block("universal_minecraft", baseblock), startpos)
else: else:
for i in range(int(delay/4)): for j in range(int(delay / 4)):
startpos[0]+=1 startpos[0] += 1
setblock(formRepeater(4,'west'),[startpos[0],startpos[1]+1,startpos[2]]) setblock(formRepeater(4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
setblock(Block("universal_minecraft",baseblock),startpos) setblock(Block("universal_minecraft", baseblock), startpos)
if delay % 4 != 0: if delay % 4 != 0:
startpos[0]+=1 startpos[0] += 1
setblock(formRepeater(delay%4,'west'),[startpos[0],startpos[1]+1,startpos[2]]) setblock(formRepeater(delay % 4, 'west'), [startpos[0], startpos[1] + 1, startpos[2]])
setblock(Block("universal_minecraft",baseblock),startpos) setblock(Block("universal_minecraft", baseblock), startpos)
startpos[0]+=posadder[0] startpos[0] += posadder[0]
startpos[1]+=posadder[1] startpos[1] += posadder[1]
startpos[2]+=posadder[2] startpos[2] += posadder[2]
e = True
try: try:
placeNoteBlock() placeNoteBlock()
except: e = False
except ValueError:
log("无法放置方块了,可能是因为区块未加载叭") log("无法放置方块了,可能是因为区块未加载叭")
finally:
if e:
log("无法放置方块了,可能是因为区块未加载叭")
level.save() level.save()
level.close() level.close()
class ryStruct: class ryStruct:
def __init__(self,world:str) -> None: def __init__(self, world: str) -> None:
self.RyStruct = dict() self.RyStruct = dict()
self._world = world self._world = world
self._level = amulet.load_level(world) self._level = amulet.load_level(world)
def reloadLevel(self): def reloadLevel(self):
e = True
try: try:
self._level = amulet.load_level(self.world) self._level = amulet.load_level(self.world)
except: e = False
except ValueError:
log("无法重载地图") log("无法重载地图")
finally:
if e:
log("无法重载地图")
def closeLevel(self): def closeLevel(self):
e = True
try: try:
self._level.close() self._level.close()
except: e = False
except ValueError:
log("无法关闭地图") log("无法关闭地图")
finally:
if e:
log("无法重载地图")
def world2Rys(self, startp: list, endp: list, includeAir: bool = False):
def world2Rys(self,startp:list,endp:list,includeAir:bool=False): """将世界转换为RyStruct字典注意此函数运行成功后将关闭地图若要打开需要运行 reloadLevel
'''将世界转换为RyStruct字典注意此函数运行成功后将关闭地图若要打开需要运行 reloadLevel
:param startp: [x,y,z] 转化的起始坐标 :param startp: [x,y,z] 转化的起始坐标
:param endp : [x,y,z] 转换的终止坐标注意终止坐标需要大于起始坐标且最终结果包含终止坐标 :param endp : [x,y,z] 转换的终止坐标注意终止坐标需要大于起始坐标且最终结果包含终止坐标
:param includeAir : bool = False 是否包含空气即空气是否在生成之时覆盖地图内容 :param includeAir : bool = False 是否包含空气即空气是否在生成之时覆盖地图内容
:return dict RyStruct ''' :return dict RyStruct """
level = self._level level = self._level
for x in range(startp[0], endp[0] + 1):
for x in range(startp[0],endp[0]+1): for y in range(startp[1], endp[1] + 1):
for y in range(startp[1],endp[1]+1): for z in range(startp[2], endp[2] + 1):
for z in range(startp[2],endp[2]+1):
RyStructBlock = dict() RyStructBlock = dict()
cx, cz = bc2cc(x, z) cx, cz = bc2cc(x, z)
chunk = level.get_chunk(cx, cz, "minecraft:overworld") chunk = level.get_chunk(cx, cz, "minecraft:overworld")
universal_block = chunk.block_palette[chunk.blocks[x - 16 * cx, y, z - 16 * cz]] 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 continue
universal_block_entity = chunk.block_entities.get((x, y, z), None) universal_block_entity = chunk.block_entities.get((x, y, z), None)
RyStructBlock["block"] = str(universal_block) RyStructBlock["block"] = str(universal_block)
RyStructBlock["blockEntity"] = str(universal_block_entity) 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() level.close()
return self.RyStruct return self.RyStruct
"""
'''
RyStruct = { RyStruct = {
(0,0,0) = { (0,0,0) = {
"block": str 完整的方块结构 "block": str 完整的方块结构
"blockEntity": str | 'None' "blockEntity": str | 'None'
} }
} }
''' """

View File

@ -1,30 +1,29 @@
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误40个
instuments = { instuments = {
'note.banjo' : ['班卓琴','hay_block'], 'note.banjo': ['班卓琴', 'hay_block'],
'note.bass' : ['贝斯','planks'], 'note.bass': ['贝斯', 'planks'],
'note.bassattack' : ['低音鼓/贝斯','log'], 'note.bassattack': ['低音鼓/贝斯', 'log'],
'note.bd' : ['底鼓','stone'], #即basedrum 'note.bd': ['底鼓', 'stone'], # 即basedrum
'note.bell' : ['铃铛/钟琴','gold_block'], 'note.bell': ['铃铛/钟琴', 'gold_block'],
'note.bit' : ['比特/“芯片”(方波)','emerald_block'], 'note.bit': ['比特/“芯片”(方波)', 'emerald_block'],
'note.chime' : ['管钟','packed_ice'], 'note.chime': ['管钟', 'packed_ice'],
'note.cow_bell' : ['牛铃','soul_sand'], 'note.cow_bell': ['牛铃', 'soul_sand'],
'note.didgeridoo' : ['迪吉里杜管','pumpkin'], 'note.didgeridoo': ['迪吉里杜管', 'pumpkin'],
'note.flute' : ['长笛','clay'], 'note.flute': ['长笛', 'clay'],
'note.guitar' : ['吉他','wool'], 'note.guitar': ['吉他', 'wool'],
'note.harp' : ['竖琴/钢琴','concrete'], #任意其他类型的方块皆可 'note.harp': ['竖琴/钢琴', 'concrete'], # 任意其他类型的方块皆可
'note.hat' : ['击鼓沿/架子鼓','glass'], 'note.hat': ['击鼓沿/架子鼓', 'glass'],
'note.iron_xylophone' : ['“铁木琴”(颤音琴)','iron_block'], 'note.iron_xylophone': ['“铁木琴”(颤音琴)', 'iron_block'],
'note.pling' : ['“扣弦”(电钢琴)','glowstone'], 'note.pling': ['“扣弦”(电钢琴)', 'glowstone'],
'note.snare' : ['小军鼓','sand'], 'note.snare': ['小军鼓', 'sand'],
'note.xylophone' : ['木琴','bone_block'] 'note.xylophone': ['木琴', 'bone_block']
} }
'''乐器对照表\n '''乐器对照表\n
乐器英文:[中文, 对应音符盒下方块名称] 乐器英文:[中文, 对应音符盒下方块名称]
方块仅取一个''' 方块仅取一个'''
height2note = { height2note = {
0.5: 0, 0.5: 0,
0.53: 1, 0.53: 1,
@ -55,5 +54,3 @@ height2note = {
} }
'''音高对照表\n '''音高对照表\n
MC音高:音符盒音调''' MC音高:音符盒音调'''

View File

@ -1,105 +1,103 @@
"""音创系列的音符对照表 以及一系列常数""" """音创系列的音符对照表 以及一系列常数"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误109个
notes = { notes = {
'....A' : [0.074, 27.5, 'wood', 8], '....A': [0.074, 27.5, 'wood', 8],
'....A#' : [0.0787, 29.135, 'wood', 9], '....A#': [0.0787, 29.135, 'wood', 9],
'....B' : [0.083, 30.868, 'wood', 10], '....B': [0.083, 30.868, 'wood', 10],
'...C' : [0.088, 32.703, 'wood', 11], '...C': [0.088, 32.703, 'wood', 11],
'...C#' : [0.094, 34.648, 'wood', 12], '...C#': [0.094, 34.648, 'wood', 12],
'...D' : [0.1, 36.708, 'wood', 13], '...D': [0.1, 36.708, 'wood', 13],
'...D#' : [0.105, 38.891, 'log', 0], '...D#': [0.105, 38.891, 'log', 0],
'...E' : [0.11, 41.203, 'log', 1], '...E': [0.11, 41.203, 'log', 1],
'...F' : [0.12, 43.654, 'log', 2], '...F': [0.12, 43.654, 'log', 2],
'...F#' : [0.125, 46.249, 'wood', 0], '...F#': [0.125, 46.249, 'wood', 0],
'...G' : [0.13, 48.999, 'wood', 1], '...G': [0.13, 48.999, 'wood', 1],
'...G#' : [0.14, 51.913, 'wood', 2], '...G#': [0.14, 51.913, 'wood', 2],
'...A' : [0.15, 55.0, 'wood', 3], '...A': [0.15, 55.0, 'wood', 3],
'...A#' : [0.16, 58.27, 'wood', 4], '...A#': [0.16, 58.27, 'wood', 4],
'...B' : [0.17, 61.735, 'wood', 5], '...B': [0.17, 61.735, 'wood', 5],
'..C' : [0.18, 65.406, 'wool', 0], '..C': [0.18, 65.406, 'wool', 0],
'..C#' : [0.19, 69.296, 'wool', 1], '..C#': [0.19, 69.296, 'wool', 1],
'..D' : [0.2, 73.416, 'wool', 2], '..D': [0.2, 73.416, 'wool', 2],
'..D#' : [0.21, 77.782, 'wool', 3], '..D#': [0.21, 77.782, 'wool', 3],
'..E' : [0.22, 82.407, 'wool', 4], '..E': [0.22, 82.407, 'wool', 4],
'..F' : [0.235, 87.307, 'wool', 5], '..F': [0.235, 87.307, 'wool', 5],
'..F#' : [0.25, 92.499, 'concretepowder', 0], '..F#': [0.25, 92.499, 'concretepowder', 0],
'..G' : [0.26, 97.999, 'concretepowder', 1], '..G': [0.26, 97.999, 'concretepowder', 1],
'..G#' : [0.28, 103.826, 'concretepowder', 2], '..G#': [0.28, 103.826, 'concretepowder', 2],
'..A' : [0.3, 110.0, 'concretepowder', 3], '..A': [0.3, 110.0, 'concretepowder', 3],
'..A#' : [0.31, 116.541, 'concretepowder', 4], '..A#': [0.31, 116.541, 'concretepowder', 4],
'..B' : [0.33, 123.471, 'concretepowder', 5], '..B': [0.33, 123.471, 'concretepowder', 5],
'.C' : [0.35, 130.813, 'concretepowder', 6], '.C': [0.35, 130.813, 'concretepowder', 6],
'.C#' : [0.37, 138.591, 'concretepowder', 7], '.C#': [0.37, 138.591, 'concretepowder', 7],
'.D' : [0.4, 146.832, 'concretepowder', 8], '.D': [0.4, 146.832, 'concretepowder', 8],
'.D#' : [0.42, 155.563, 'concretepowder', 9], '.D#': [0.42, 155.563, 'concretepowder', 9],
'.E' : [0.44, 164.814, 'concretepowder', 10], '.E': [0.44, 164.814, 'concretepowder', 10],
'.F' : [0.47, 174.614, 'concretepowder', 11], '.F': [0.47, 174.614, 'concretepowder', 11],
'.F#' : [0.5, 184.997, 'concretepowder', 12], '.F#': [0.5, 184.997, 'concretepowder', 12],
'.G' : [0.53, 195.998, 'concretepowder', 13], '.G': [0.53, 195.998, 'concretepowder', 13],
'.G#' : [0.56, 207.652, 'concretepowder', 14], '.G#': [0.56, 207.652, 'concretepowder', 14],
'.A' : [0.6, 220.0, 'concretepowder', 15], '.A': [0.6, 220.0, 'concretepowder', 15],
'.A#' : [0.63, 233.082, 'concrete', 0], '.A#': [0.63, 233.082, 'concrete', 0],
'.B' : [0.67, 246.942, 'concrete', 1], '.B': [0.67, 246.942, 'concrete', 1],
'C' : [0.7, 261.626, 'concrete', 2], 'C': [0.7, 261.626, 'concrete', 2],
'C#' : [0.75, 277.183, 'concrete', 3], 'C#': [0.75, 277.183, 'concrete', 3],
'D' : [0.8, 293.665, 'concrete', 4], 'D': [0.8, 293.665, 'concrete', 4],
'D#' : [0.84, 311.127, 'concrete', 5], 'D#': [0.84, 311.127, 'concrete', 5],
'E' : [0.9, 329.628, 'concrete', 6], 'E': [0.9, 329.628, 'concrete', 6],
'F' : [0.94, 349.228, 'concrete', 7], 'F': [0.94, 349.228, 'concrete', 7],
'F#' : [1.0, 369.994, 'concrete', 8], 'F#': [1.0, 369.994, 'concrete', 8],
'G' : [1.05, 391.995, 'concrete', 9], 'G': [1.05, 391.995, 'concrete', 9],
'G#' : [1.12, 415.305, 'concrete', 10], 'G#': [1.12, 415.305, 'concrete', 10],
'A' : [1.2, 440.0, 'concrete', 11], 'A': [1.2, 440.0, 'concrete', 11],
'A#' : [1.25, 466.164, 'concrete', 12], 'A#': [1.25, 466.164, 'concrete', 12],
'B' : [1.33, 493.883, 'concrete', 13], 'B': [1.33, 493.883, 'concrete', 13],
'`C' : [1.4, 523.251, 'concrete', 14], '`C': [1.4, 523.251, 'concrete', 14],
'`C#' : [1.5, 554.365, 'concrete', 15], '`C#': [1.5, 554.365, 'concrete', 15],
'`D' : [1.6, 587.33, 'stained_hardened_clay', 0], '`D': [1.6, 587.33, 'stained_hardened_clay', 0],
'`D#' : [1.7, 622.254, 'stained_hardened_clay', 1], '`D#': [1.7, 622.254, 'stained_hardened_clay', 1],
'`E' : [1.8, 659.255, 'stained_hardened_clay', 2], '`E': [1.8, 659.255, 'stained_hardened_clay', 2],
'`F' : [1.9, 698.456, 'stained_hardened_clay', 3], '`F': [1.9, 698.456, 'stained_hardened_clay', 3],
'`F#' : [2.0, 739.989, 'stained_hardened_clay', 4], '`F#': [2.0, 739.989, 'stained_hardened_clay', 4],
'`G' : [2.1, 783.991, 'stained_hardened_clay', 5], '`G': [2.1, 783.991, 'stained_hardened_clay', 5],
'`G#' : [2.24, 830.609, 'stained_hardened_clay', 6], '`G#': [2.24, 830.609, 'stained_hardened_clay', 6],
'`A' : [2.4, 880.0, 'stained_hardened_clay', 7], '`A': [2.4, 880.0, 'stained_hardened_clay', 7],
'`A#' : [2.5, 932.328, 'stained_hardened_clay', 8], '`A#': [2.5, 932.328, 'stained_hardened_clay', 8],
'`B' : [2.67, 987.767, 'stained_hardened_clay', 9], '`B': [2.67, 987.767, 'stained_hardened_clay', 9],
'``C' : [2.83, 1046.502, 'stained_hardened_clay', 10], '``C': [2.83, 1046.502, 'stained_hardened_clay', 10],
'``C#' : [3.0, 1108.731, 'stained_hardened_clay', 11], '``C#': [3.0, 1108.731, 'stained_hardened_clay', 11],
'``D' : [3.17, 1174.659, 'stained_hardened_clay', 12], '``D': [3.17, 1174.659, 'stained_hardened_clay', 12],
'``D#' : [3.36, 1244.508, 'stained_hardened_clay', 13], '``D#': [3.36, 1244.508, 'stained_hardened_clay', 13],
'``E' : [3.56, 1318.51, 'stained_hardened_clay', 14], '``E': [3.56, 1318.51, 'stained_hardened_clay', 14],
'``F' : [3.78, 1396.913, 'stained_hardened_clay', 15], '``F': [3.78, 1396.913, 'stained_hardened_clay', 15],
'``F#' : [4.0, 1479.978, 'white_glazed_terracotta', 0], '``F#': [4.0, 1479.978, 'white_glazed_terracotta', 0],
'``G' : [4.24, 1567.982, 'orange_glazed_terracotta', 0], '``G': [4.24, 1567.982, 'orange_glazed_terracotta', 0],
'``G#' : [4.5, 1661.219, 'magenta_glazed_terracotta', 0], '``G#': [4.5, 1661.219, 'magenta_glazed_terracotta', 0],
'``A' : [4.76, 1760.0, 'light_blue_glazed_terracotta', 0], '``A': [4.76, 1760.0, 'light_blue_glazed_terracotta', 0],
'``A#' : [5.04, 1864.655, 'yellow_glazed_terracotta', 0], '``A#': [5.04, 1864.655, 'yellow_glazed_terracotta', 0],
'``B' : [5.34, 1975.533, 'lime_glazed_terracotta', 0], '``B': [5.34, 1975.533, 'lime_glazed_terracotta', 0],
'```C' : [5.66, 2093.005, 'pink_glazed_terracotta', 0], '```C': [5.66, 2093.005, 'pink_glazed_terracotta', 0],
'```C#' : [6.0, 2217.461, 'gray_glazed_terracotta', 0], '```C#': [6.0, 2217.461, 'gray_glazed_terracotta', 0],
'```D' : [6.35, 2349.318, 'silver_glazed_terracotta', 0], '```D': [6.35, 2349.318, 'silver_glazed_terracotta', 0],
'```D#' : [6.73, 2489.016, 'cyan_glazed_terracotta', 0], '```D#': [6.73, 2489.016, 'cyan_glazed_terracotta', 0],
'```E' : [7.13, 2637.02, 'purple_glazed_terracotta', 0], '```E': [7.13, 2637.02, 'purple_glazed_terracotta', 0],
'```F' : [7.55, 2793.826, 'blue_glazed_terracotta', 0], '```F': [7.55, 2793.826, 'blue_glazed_terracotta', 0],
'```F#' : [8.0, 2959.955, 'brown_glazed_terracotta', 0], '```F#': [8.0, 2959.955, 'brown_glazed_terracotta', 0],
'```G' : [8.47, 3135.963, 'green_glazed_terracotta', 0], '```G': [8.47, 3135.963, 'green_glazed_terracotta', 0],
'```G#' : [8.98, 3322.438, 'red_glazed_terracotta', 0], '```G#': [8.98, 3322.438, 'red_glazed_terracotta', 0],
'```A' : [9.51, 3520.0, 'black_glazed_terracotta', 0], '```A': [9.51, 3520.0, 'black_glazed_terracotta', 0],
'```A#' : [10.08, 3729.31, 'stained_glass', 0], '```A#': [10.08, 3729.31, 'stained_glass', 0],
'```B' : [10.68, 3951.066, 'stained_glass', 1], '```B': [10.68, 3951.066, 'stained_glass', 1],
'````C' : [11.31, 4186.009, 'stained_glass', 2], '````C': [11.31, 4186.009, 'stained_glass', 2],
'0' : [0.0, 0.0, 'glass', 0] '0': [0.0, 0.0, 'glass', 0]
} }
'''音符对照表\n '''音符对照表\n
音符:[MC音调, 声音频率, 方块名称, 数据值]''' 音符:[MC音调, 声音频率, 方块名称, 数据值]'''
# 方块
#方块
''' '''
blocks = { blocks = {
0.074 : ['stained_glass', 3], 0.074 : ['stained_glass', 3],
@ -195,7 +193,6 @@ blocks = {
#向查理平致敬!!!!! #向查理平致敬!!!!!
''' '''
Blocks = { Blocks = {
0.074: 'barrel', 0.074: 'barrel',
0.0787: 'beacon', 0.0787: 'beacon',
@ -290,31 +287,26 @@ Blocks = {
'''频率对照表\n '''频率对照表\n
MC音调:方块名称''' MC音调:方块名称'''
# 乐器 # 乐器
Instuments = { Instuments = {
'note.banjo' : '班卓', 'note.banjo': '班卓',
'note.bass' : '低音', 'note.bass': '低音',
'note.bassattack' : '贝斯', 'note.bassattack': '贝斯',
'note.bd' : '鼓声', 'note.bd': '鼓声',
'note.bell' : '铃声', 'note.bell': '铃声',
'note.bit' : '比特', 'note.bit': '比特',
'note.cow_bell' : '牛铃', 'note.cow_bell': '牛铃',
'note.didgeridoo' : '迪吉', 'note.didgeridoo': '迪吉',
'note.flute' : '长笛', 'note.flute': '长笛',
'note.guitar' : '吉他', 'note.guitar': '吉他',
'note.harp' : '竖琴', 'note.harp': '竖琴',
'note.hat' : '架鼓', 'note.hat': '架鼓',
'note.chime' : '钟声', 'note.chime': '钟声',
'note.iron_xylophone' : '铁琴', 'note.iron_xylophone': '铁琴',
'note.pling' : '叮叮', 'note.pling': '叮叮',
'note.snare' : '响弦', 'note.snare': '响弦',
'note.xylophone' : '木琴' 'note.xylophone': '木琴'
} }
'''乐器对照表\n '''乐器对照表\n
乐器英文:中文 乐器英文:中文
翻译雪莹工坊Fun-Fer''' 翻译雪莹工坊Fun-Fer'''

View File

@ -1,17 +1,53 @@
"""提供对于音创系列的日志""" """提供对于音创系列的日志"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误9个
import datetime,os import logging
import os
import datetime
import sys
#载入日志功能
StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7] 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)
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): def log(info: str = '', isPrinted: bool = False, isLoggerLibRecord: bool = True):
'''将信息连同当前时间载入日志''' # isLoggerLibRecord: 是否同时在logger库中记录
"""将信息连同当前时间载入日志"""
if not os.path.exists('./log/'): if not os.path.exists('./log/'):
os.makedirs('./log/') os.makedirs('./log/')
with open('./log/'+StrStartTime+'.msct.log', 'a',encoding='UTF-8') as f: with open('./log/' + StrStartTime + '.msct.log', 'a', encoding='UTF-8') as f:
f.write(str(datetime.datetime.now())[11:19]+' '+info+'\n') f.write(str(datetime.datetime.now())[11:19] + ' ' + info + '\n')
if isPrinted: if isPrinted:
print(str(datetime.datetime.now())[11:19]+' '+info) print(str(datetime.datetime.now())[11:19] + ' ' + info)
if isLoggerLibRecord:
logger.info(info)

View File

@ -1,87 +1,84 @@
"""音创系列的文件读取功能""" """音创系列的文件读取功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误3个语法一级错误22个
from nmcsup.log import log from nmcsup.log import log
from nmcsup.const import notes from nmcsup.const import notes
# 从格式文本文件读入一个音轨并存入一个列表
#从格式文本文件读入一个音轨并存入一个列表 def ReadFile(fn: str): # -> list
def ReadFile(fn : str) -> list:
from nmcsup.trans import note2list from nmcsup.trans import note2list
log('打开'+fn+"并读取音符") log('打开' + fn + "并读取音符")
try: try:
nat = open(fn, 'r', encoding='UTF-8').read().split(" ") nat = open(fn, 'r', encoding='UTF-8').read().split(" ")
del fn del fn
except: except FileNotFoundError:
log("找不到读取目标文件") log("找不到读取目标文件")
return False return False
Notes = [] Notes = []
log(str(nat)+"已读取") log(str(nat) + "已读取")
for i in range(int(len(nat)/2)): for i in range(int(len(nat) / 2)):
Notes.append([nat[i*2], float(nat[i*2+1])]) Notes.append([nat[i * 2], float(nat[i * 2 + 1])])
Notes = note2list(Notes) Notes = note2list(Notes)
log('音符数据更新'+str(Notes)) log('音符数据更新' + str(Notes))
return [Notes,] return [Notes, ]
#从midi读入多个音轨返回多个音轨列表 # 从midi读入多个音轨返回多个音轨列表
def ReadMidi(midfile : str ) -> list: def ReadMidi(midfile: str): # -> list
import mido import mido
from msctspt.threadOpera import NewThread from msctspt.threadOpera import NewThread
Notes = [] Notes = []
try: try:
mid = mido.MidiFile(midfile) mid = mido.MidiFile(midfile)
except: except FileNotFoundError:
log("找不到文件或无法读取文件"+midfile) log("找不到文件或无法读取文件" + midfile)
return False return False
# 解析 # 解析
ks = list(notes.values()) ks = list(notes.values())
def loadMidi(track):
def loadMidi(track1):
datas = [] datas = []
for i in track: for i in track1:
if i.is_meta: if i.is_meta:
log('元信息'+str(i)) log('元信息' + str(i))
pass # 不处理元信息 pass # 不处理元信息
elif 'note_on' in str(i): elif 'note_on' in str(i):
msg = str(i).replace("note=", '').replace("time=", '').split(" ") msg = str(i).replace("note=", '').replace("time=", '').split(" ")
log('音符on消息处理后'+str(msg)) log('音符on消息处理后' + str(msg))
if msg[4] == '0': if msg[4] == '0':
datas.append([ks[int(msg[2])-20][0], 1.0]) datas.append([ks[int(msg[2]) - 20][0], 1.0])
log('延续时间0tick--:添加音符'+str([ks[int(msg[2])-20][0], 1.0])) log('延续时间0tick--:添加音符' + str([ks[int(msg[2]) - 20][0], 1.0]))
else: else:
datas.append([ks[int(msg[2])-20][0], float(msg[4])/480]) 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])) log('延续时间' + msg[4] + 'tick--:添加音符' + str([ks[int(msg[2]) - 20][0], float(msg[4]) / 480]))
del msg del msg
log('音符增加'+str(datas)) log('音符增加' + str(datas))
return datas return datas
for j, track in enumerate(mid.tracks): for j, track in enumerate(mid.tracks):
th = NewThread(loadMidi,(track,)) th = NewThread(loadMidi, (track,))
th.start() th.start()
Notes.append(th.getResult()) Notes.append(th.getResult())
del ks del ks
return Notes return Notes
def ReadOldProject(fn: str): # -> list
def ReadOldProject(fn:str) -> list:
import json import json
from nmcsup.trans import note2list from nmcsup.trans import note2list
log("读取文件:"+fn) log("读取文件:" + fn)
try: try:
with open(fn, 'r', encoding='UTF-8') as c: with open(fn, 'r', encoding='UTF-8') as c:
dataset = json.load(c) dataset = json.load(c)
except: except FileNotFoundError:
print('找不到文件:'+fn+",请查看您是否输入正确") print('找不到文件:' + fn + ",请查看您是否输入正确")
log("丢失"+fn) log("丢失" + fn)
return False return False
for i in range(len(dataset['musics'])): for i in range(len(dataset['musics'])):
dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes']) dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes'])
#返回 音轨列表 选择器 # 返回 音轨列表 选择器
return dataset return dataset

View File

@ -1,37 +1,41 @@
"""音创系列的转换功能""" """音创系列的转换功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误2个语法一级错误192个
from nmcsup.log import log 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 # 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
def note2list(Notes : list) -> list: def note2list(Notes: list) -> list:
from nmcsup.const import notes from nmcsup.const import notes
def change(base): def change(base):
enwo = { enwo = {
'a': 'A', 'a': 'A',
'b': 'B', 'b': 'B',
'c': 'C', 'c': 'C',
'd': "D", 'd': "D",
"e": "E", "e": "E",
'f': 'F', 'f': 'F',
'g': "G" 'g': "G"
} }
nuwo = { nuwo = {
'6': 'A', '6': 'A',
'7': 'B', '7': 'B',
'1': 'C', '1': 'C',
'2': "D", '2': "D",
"3": "E", "3": "E",
'4': 'F', '4': 'F',
'5': "G" '5': "G"
} }
for k, v in enwo.items(): for k, v in enwo.items():
if k in base: if k in base:
@ -40,193 +44,184 @@ def note2list(Notes : list) -> list:
if k in base: if k in base:
base = base.replace(k, v) base = base.replace(k, v)
return base return base
res = [] res = []
log(" === 音符列表=>音调列表") log(" === 音符列表=>音调列表")
for i in Notes: for i in Notes:
s2 = change(i[0]) s2 = change(i[0])
log(' === 正在操作音符'+i[0]+'->'+s2) log(' === 正在操作音符' + i[0] + '->' + s2)
if s2 in notes.keys(): if s2 in notes.keys():
log(" === 找到此音符,加入:"+str(notes[s2][0])) log(" === 找到此音符,加入:" + str(notes[s2][0]))
res.append([notes[s2][0], float(i[1])]) res.append([notes[s2][0], float(i[1])])
else: else:
log(' === '+s2+'不在音符表内,此处自动替换为 休止符0 ') log(' === ' + s2 + '不在音符表内,此处自动替换为 休止符0 ')
res.append(['0', float(i[1])]) res.append(['0', float(i[1])])
log(' === 最终反回'+str(res)) log(' === 最终反回' + str(res))
return res return res
def mcnote2freq(Notes): def mcnote2freq(Notes):
from nmcsup.const import notes from nmcsup.const import notes
mcnback = {} mcnback = {}
for i,j in notes.items(): for i, j in notes.items():
mcnback[j[0]] = i mcnback[j[0]] = i
res = [] res = []
log(" === 我的世界音调表=>频率列表") log(" === 我的世界音调表=>频率列表")
for i in Notes: for i in Notes:
log(' === 正在操作音符'+i[0]+'->'+mcnback[i[0]]) log(' === 正在操作音符' + i[0] + '->' + mcnback[i[0]])
res.append([notes[mcnback[i[0]]][1], float(i[1])]) res.append([notes[mcnback[i[0]]][1], float(i[1])])
log(' === 最终反回'+str(res)) log(' === 最终反回' + str(res))
return res return res
# MP3文件转midi文件
#MP3文件转midi文件
def Mp32Mid(mp3File, midFile): def Mp32Mid(mp3File, midFile):
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
# 加载 # 加载
(audio, _) = load_audio(mp3File, sr=sample_rate, mono=True) (audio, _) = load_audio(mp3File, sr=sample_rate) # , mono=True
# 实例化并转换 # 实例化并转换
PianoTranscription(device="cpu").transcribe(audio, midFile) PianoTranscription(device="cpu").transcribe(audio, midFile)
# 传入一个音符列表转为指令列表
def Note2Cmd(Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '',
isProsess: bool = False) -> list:
#传入一个音符列表转为指令列表
def Note2Cmd(Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False) -> list:
commands = [] commands = []
a = 0.0 a = 0.0
if isProsess: if isProsess:
length = len(Notes) length = len(Notes)
j = 1 j = 1
for i in range(len(Notes)): 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") commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str(
a += Notes[i][1] int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ playsound " + Instrument + " @s ~ ~ ~ 1000 " + str(
if isProsess: Notes[i][0]) + " 1000\n")
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") a += Notes[i][1]
j+=1 if isProsess:
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n") 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 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
import amulet
import amulet_nbt
from amulet.api.block import Block
from amulet.api.block_entity import BlockEntity
from amulet.utils.world_utils import block_coords_to_chunk_coords
from amulet_nbt import TAG_String,TAG_Compound,TAG_Byte
#简单载入方块
#level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
#转入指令列表与位置信息转至世界
def Cmd2World(cmd:list,world:str,dire:list):
'''将指令以命令链的形式载入世界\n
cmd指令列表位为一个序列中包含指令字符串\n cmd指令列表位为一个序列中包含指令字符串\n
world为地图所在位置需要指向文件夹dire为指令方块生成之位置''' world为地图所在位置需要指向文件夹dire为指令方块生成之位置"""
level = amulet.load_level(world) level = amulet.load_level(world)
cdl = [] cdl = []
for i in cmd: for i in cmd:
e = True
try: 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('#')]) cdl.append(i[:i.index('#')])
except: e = False
except ValueError:
cdl.append(i) cdl.append(i)
finally:
if e is True:
cdl.append(i)
i = 0 i = 0
#第一个是特殊 # 第一个是特殊
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("repeating")}) 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]) cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
chunk = level.get_chunk(cx, cz, "minecraft:overworld") chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz 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))}) }))) 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.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.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
chunk.changed = True chunk.changed = True
#集体上移 # 集体上移
dire[1]+=1 dire[1] += 1
#真正开始 # 真正开始
down = False down = False
for j in cdl: for j in cdl:
if dire[1]+i >= 255: if dire[1] + i >= 255:
dire[0]+=1 dire[0] += 1
i=0 i = 0
down = not down down = not down
#定义此方块 # 定义此方块
if dire[1]+i == 254 : if dire[1] + i == 254:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('east'),'mode':TAG_String("chain")}) universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('east'),
'mode': TAG_String("chain")})
else: else:
if down: if down:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('down'),'mode':TAG_String("chain")}) universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('down'),
'mode': TAG_String("chain")})
else: else:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("chain")}) 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]) cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
#获取区块 # 获取区块
chunk = level.get_chunk(cx, cz, "minecraft:overworld") chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
if down: 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)}) }))) 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.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 chunk.block_entities[(dire[0], 254 - i, dire[2])] = universal_block_entity
else: 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)}) }))) 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.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.block_entities[(dire[0], dire[1] + i, dire[2])] = universal_block_entity
#设置为已更新区块 # 设置为已更新区块
chunk.changed = True chunk.changed = True
i+=1 i += 1
del i, cdl del i, cdl
#保存世界并退出 # 保存世界并退出
level.save() level.save()
level.close() level.close()
# 音符转成方块再加载到世界里头
def Blocks2World(world: str, dire: list, Datas: list):
#音符转成方块再加载到世界里头
def Blocks2World(world:str,dire:list,Datas:list):
from nmcsup.const import Blocks from nmcsup.const import Blocks
level = amulet.load_level(world) level = amulet.load_level(world)
i = 0 i = 0
def setblock(block:str,pos:list):
'''pos : list[int,int,int]''' def setblock(block: str, pos: list):
"""pos : list[int,int,int]"""
cx, cz = block_coords_to_chunk_coords(pos[0], pos[2]) cx, cz = block_coords_to_chunk_coords(pos[0], pos[2])
chunk = level.get_chunk(cx, cz, "minecraft:overworld") chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz 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.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(Block("minecraft", block))
chunk.changed = True chunk.changed = True
for j in Datas: for j in Datas:
if dire[1]+1 >= 255: if dire[1] + 1 >= 255:
i = 0 i = 0
dire[0]+=1 dire[0] += 1
setblock(Blocks[j[0]],[dire[0],dire[1]+i,dire[2]]) setblock(Blocks[j[0]], [dire[0], dire[1] + i, dire[2]])
i = int(i+j[1]+0.5) #四舍五入 i = int(i + j[1] + 0.5) # 四舍五入
level.save() level.save()
level.close() level.close()
# 传入音符列表制作播放器指令
def Notes2Player(Note, dire: list, CmdData: dict):
"""传入音符列表、坐标、指令数据,生成播放器指令"""
#传入音符列表制作播放器指令
def Notes2Player(Note,dire:list,CmdData:dict):
'''传入音符列表、坐标、指令数据,生成播放器指令'''
Notes = {} Notes = {}
for i in Note: for i in Note:
Notes[i[0]] = '' Notes[i[0]] = ''
@ -234,21 +229,17 @@ def Notes2Player(Note,dire:list,CmdData:dict):
from nmcsup.const import Blocks from nmcsup.const import Blocks
Cmds = [] Cmds = []
for j in Notes: 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.append('execute @e[x=' + str(dire[0]) + ',y=' + str(dire[1]) + ',z=' + str(dire[2]) + ',dy=' + str(
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'] 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 return Cmds
# 传入音符列表生成方块至世界
def Datas2BlkWorld(NoteData, world: str, dire: list):
#传入音符列表生成方块至世界
def Datas2BlkWorld(NoteData,world:str,dire:list):
for i in range(len(NoteData)): for i in range(len(NoteData)):
Blocks2World(world,[dire[0],dire[1],dire[2]+i],NoteData[i]) Blocks2World(world, [dire[0], dire[1], dire[2] + i], NoteData[i])

View File

@ -1,20 +1,19 @@
"""音创系列版本号和版本操作函数""" """音创系列版本号和版本操作函数"""
# 统计致命三级错误0个警告二级错误0个语法一级错误24个
from msctspt.bugReporter import version from msctspt.bugReporter import version
import os
# 以下下两个值请在 msctspt/bugReporter 的version类中修改
#以下下两个值请在 msctspt/bugReporter 的version类中修改
VER = version.version VER = version.version
'''当前版本''' """当前版本"""
LIBS = version.libraries LIBS = version.libraries
'''当前所需库''' """当前所需库"""
# 判断版本、临时文件与补全库
#判断版本、临时文件与补全库
def compver(ver1, ver2): def compver(ver1, ver2):
""" """
传入不带英文的版本号,特殊情况"10.12.2.6.5">"10.12.2.6" 传入不带英文的版本号,特殊情况"10.12.2.6.5">"10.12.2.6"
@ -39,6 +38,8 @@ def compver(ver1, ver2):
return -1 return -1
else: else:
return 1 return 1
# #
# ———————————————— # ————————————————
# 版权声明上面的函数compver为CSDN博主「基友死得早」的原创文章中的函数遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。 # 版权声明上面的函数compver为CSDN博主「基友死得早」的原创文章中的函数遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。
@ -46,44 +47,40 @@ def compver(ver1, ver2):
# ———————————————— # ————————————————
# #
import os
def InstallLibs(now,LIBS): def InstallLibs(now, LIBS1):
'''比对库信息并安装库''' """比对库信息并安装库"""
from os import system as run from os import system as run
for i in LIBS: for i in LIBS1:
if not i in now: if i not in now:
print("安装库:"+i) print("安装库:" + i)
run("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple") run("python -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple")
def chkver(ver = VER,libs = LIBS): def chkver(ver=VER, libs=LIBS):
'''通过文件比对版本信息并安装库''' """通过文件比对版本信息并安装库"""
if not os.path.exists(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct'): if not os.path.exists(os.getenv('APPDATA') + '\\Musicreater\\msct.ActiveDatas.msct'):
print("新安装库") print("新安装库")
os.makedirs(os.getenv('APPDATA')+'\\Musicreater\\') os.makedirs(os.getenv('APPDATA') + '\\Musicreater\\')
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f: with open(os.getenv('APPDATA') + '\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
f.write(ver[0]+'\n') f.write(ver[0] + '\n')
for i in libs: for i in libs:
f.write(i+'\n') f.write(i + '\n')
InstallLibs([],libs) InstallLibs([], libs)
else: else:
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'r') as f: with open(os.getenv('APPDATA') + '\\Musicreater\\msct.ActiveDatas.msct', 'r') as f:
v = f.readlines() v = f.readlines()
cp = compver(ver[0], v[0]) cp = compver(ver[0], v[0])
if cp != 0: if cp != 0:
InstallLibs(v[1:],libs) InstallLibs(v[1:], libs)
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f: with open(os.getenv('APPDATA') + '\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
f.write(ver[0]+'\n') f.write(ver[0] + '\n')
for i in libs: for i in libs:
f.write(i+'\n') f.write(i + '\n')
del cp del cp
def resetver(): def resetver():
'''重置版本信息''' """重置版本信息"""
import shutil import shutil
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\') shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')