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

View File

@ -1,5 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误2个---未解决警告二级错误2个语法一级错误17个
__version__ = '0.0.1'
__all__ = []
@ -24,3 +27,144 @@ A library to develop minecraft websocket server easily.
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 (金羿)
Licensed under the Apache License, Version 2.0 (the 'License')
@ -23,21 +23,33 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
"""
# 代码写的并非十分的漂亮还请大佬多多包涵本软件源代码依照Apache软件协议公开
'''
将程序中用双引号""括起来的字符串
转为字符串列表 list[str, str, ...]
方便进行语言翻译支持
'''
# -----------------------------分割线-----------------------------
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误12个
# 目前我的Pycharm并没有显示任何错误有错误可以向
# bgArray 诸葛亮与八卦阵
# QQ 474037765 或最好加入:音·创 开发交流群 861684859
# ------------------------- split line-----------------------------
# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022
# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597
# At present, my Pycham does not display any errors. If there are errors, you can report them to me
# Bgarray Zhuge Liang and Bagua array
# QQ 474037765 or better join: Musicreater development exchange group 861684859
# ------------------------- split line-----------------------------
startWith = 0
# 下面为正文
# 将程序中用双引号""括起来的字符串
# 转为字符串列表 list[str, str, ...]
# 方便进行语言翻译支持。
import sys
startWith = 0
def __main__():
@ -48,11 +60,14 @@ def __main__():
for line in open(fileName, 'r', encoding='utf-8'):
while line.count('"') >= 2:
# 只有上帝看得懂我在写什么。
if line[line.index('"'):2+line[line.index('"')+1:].index('"')+len(line[:line.index('"')])] in textList:
thisText = textList.index(line[line.index('"'):2+line[line.index('"')+1:].index('"')+len(line[:line.index('"')])])
if line[
line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])] in textList:
thisText = textList.index(
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
else:
thisText = len(textList)
textList.append(line[line.index('"'):2+line[line.index('"')+1:].index('"')+len(line[:line.index('"')])])
textList.append(
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
line = line.replace(
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])],
'READABLETEXT[{}]'.format(thisText + startWith)
@ -61,7 +76,6 @@ def __main__():
open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText)
outFile = open('lang__.py', 'w', encoding='utf-8')
outFile.write('''# -*- coding:utf-8 -*-

View File

@ -4,7 +4,6 @@
# 请在所需翻译的文件前from 此文件 import READABLETEXT
READABLETEXT = {
'Translator': (("Eilles Wan (金羿)", True),),
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字

View File

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

View File

@ -1,21 +1,20 @@
# -*- coding: UTF-8 -*-
'''提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能'''
"""提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误1个语法一级错误72个
import os
import zipfile
def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
'''使用compression指定的算法打包目录为zip文件\n
"""使用compression指定的算法打包目录为zip文件\n
默认算法为DEFLATED(8),可用算法如下\n
STORED = 0\n
DEFLATED = 8\n
BZIP2 = 12\n
LZMA = 14\n
'''
import os, zipfile
"""
zipf = zipfile.ZipFile(outFilename, 'w', compression)
pre_len = len(os.path.dirname(sourceDir))
for parent, dirnames, filenames in os.walk(sourceDir):
@ -29,20 +28,18 @@ def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None):
zipf.close()
del zipf, pre_len
# 以上函数节选并修改自 正在攀登的小蜗牛 的博客https://blog.csdn.net/qq_21127151/article/details/107503942
class report:
"""发送报告以及相应的任务处理"""
class report():
'''发送报告以及相应的任务处理'''
def __init__(self, senderName: str = 'Unknown', senderContact: str = 'None', describetion: str = ''):
''':param senderName 发送者名称
""":param senderName 发送者名称
:param senderContact 发送者联系方式
:param describetion 问题描述'''
:param describetion 问题描述"""
self.senderName = senderName
self.senderContact = senderContact
self.describetion = describetion
@ -51,10 +48,8 @@ class report():
if not self.senderContact:
self.senderContact = 'None'
def emailReport(self):
'''使用E-mail方法发送当前的日志和临时文件等'''
"""使用E-mail方法发送当前的日志和临时文件等"""
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
@ -70,10 +65,12 @@ class report():
# 标题
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("添加完毕,正在生成压缩包...")
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-Disposition"] = 'attachmentfilename="BugReport_from_' + self.senderName + '.zip"'
msg.attach(attafile)
@ -93,35 +90,33 @@ class report():
os.remove("./Temps&Logs.zip")
class version:
libraries = ('mido','amulet','amulet-core','amulet-nbt','piano_transcription_inference','pypinyin','pyinstaller','py7zr','websockets','torch')
'''当前所需库,有一些是开发用的,用户不需要安装'''
libraries = (
'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin', 'pyinstaller',
'py7zr',
'websockets', 'torch')
"""当前所需库,有一些是开发用的,用户不需要安装"""
version = ('0.0.1', 'Delta',)
'''当前版本'''
"""当前版本"""
def __init__(self) -> None:
self.libraries = version.libraries
'''当前所需库,有一些是开发用的,用户不需要安装'''
"""当前所需库,有一些是开发用的,用户不需要安装"""
self.version = version.version
'''当前版本'''
"""当前版本"""
def installLibraries(self):
'''安装全部开发用库'''
"""安装全部开发用库"""
from sys import platform
import os
if platform == 'win32':
import shutil
try:
shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')
except:
except FloatingPointError:
pass
for i in self.libraries:
print("安装库:" + i)
@ -133,4 +128,3 @@ class version:
for i in self.libraries:
print("安装库:" + i)
os.system("sudo python3 -m pip install " + i + " -i https://pypi.tuna.tsinghua.edu.cn/simple")

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误40个
instuments = {
'note.banjo': ['班卓琴', 'hay_block'],
@ -23,8 +24,6 @@ instuments = {
乐器英文:[中文, 对应音符盒下方块名称]
方块仅取一个'''
height2note = {
0.5: 0,
0.53: 1,
@ -55,5 +54,3 @@ height2note = {
}
'''音高对照表\n
MC音高:音符盒音调'''

View File

@ -1,5 +1,6 @@
"""音创系列的音符对照表 以及一系列常数"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误0个语法一级错误109个
notes = {
@ -96,9 +97,6 @@ notes = {
'''音符对照表\n
音符:[MC音调, 声音频率, 方块名称, 数据值]'''
# 方块
'''
blocks = {
@ -195,7 +193,6 @@ blocks = {
#向查理平致敬!!!!!
'''
Blocks = {
0.074: 'barrel',
0.0787: 'beacon',
@ -290,8 +287,6 @@ Blocks = {
'''频率对照表\n
MC音调:方块名称'''
# 乐器
Instuments = {
'note.banjo': '班卓',
@ -315,6 +310,3 @@ Instuments = {
'''乐器对照表\n
乐器英文:中文
翻译雪莹工坊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]
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/'):
os.makedirs('./log/')
with open('./log/' + StrStartTime + '.msct.log', 'a', encoding='UTF-8') as f:
f.write(str(datetime.datetime.now())[11:19] + ' ' + info + '\n')
if isPrinted:
print(str(datetime.datetime.now())[11:19] + ' ' + info)
if isLoggerLibRecord:
logger.info(info)

View File

@ -1,22 +1,21 @@
"""音创系列的文件读取功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误3个语法一级错误22个
from nmcsup.log import log
from nmcsup.const import notes
# 从格式文本文件读入一个音轨并存入一个列表
def ReadFile(fn : str) -> list:
def ReadFile(fn: str): # -> list
from nmcsup.trans import note2list
log('打开' + fn + "并读取音符")
try:
nat = open(fn, 'r', encoding='UTF-8').read().split(" ")
del fn
except:
except FileNotFoundError:
log("找不到读取目标文件")
return False
Notes = []
@ -29,20 +28,21 @@ def ReadFile(fn : str) -> list:
# 从midi读入多个音轨返回多个音轨列表
def ReadMidi(midfile : str ) -> list:
def ReadMidi(midfile: str): # -> list
import mido
from msctspt.threadOpera import NewThread
Notes = []
try:
mid = mido.MidiFile(midfile)
except:
except FileNotFoundError:
log("找不到文件或无法读取文件" + midfile)
return False
# 解析
ks = list(notes.values())
def loadMidi(track):
def loadMidi(track1):
datas = []
for i in track:
for i in track1:
if i.is_meta:
log('元信息' + str(i))
pass # 不处理元信息
@ -58,6 +58,7 @@ def ReadMidi(midfile : str ) -> list:
del msg
log('音符增加' + str(datas))
return datas
for j, track in enumerate(mid.tracks):
th = NewThread(loadMidi, (track,))
th.start()
@ -66,16 +67,14 @@ def ReadMidi(midfile : str ) -> list:
return Notes
def ReadOldProject(fn:str) -> list:
def ReadOldProject(fn: str): # -> list
import json
from nmcsup.trans import note2list
log("读取文件:" + fn)
try:
with open(fn, 'r', encoding='UTF-8') as c:
dataset = json.load(c)
except:
except FileNotFoundError:
print('找不到文件:' + fn + ",请查看您是否输入正确")
log("丢失" + fn)
return False
@ -83,5 +82,3 @@ def ReadOldProject(fn:str) -> list:
dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes'])
# 返回 音轨列表 选择器
return dataset

View File

@ -1,19 +1,23 @@
"""音创系列的转换功能"""
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
# 统计致命三级错误0个警告二级错误2个语法一级错误192个
from nmcsup.log import log
import amulet
import amulet_nbt
from amulet.api.block import Block
from amulet.api.block_entity import BlockEntity
from amulet.utils.world_utils import block_coords_to_chunk_coords
from amulet_nbt import TAG_String, TAG_Compound, TAG_Byte
# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
def note2list(Notes: list) -> list:
from nmcsup.const import notes
def change(base):
enwo = {
'a': 'A',
@ -40,6 +44,7 @@ def note2list(Notes : list) -> list:
if k in base:
base = base.replace(k, v)
return base
res = []
log(" === 音符列表=>音调列表")
for i in Notes:
@ -55,8 +60,6 @@ def note2list(Notes : list) -> list:
return res
def mcnote2freq(Notes):
from nmcsup.const import notes
mcnback = {}
@ -71,78 +74,70 @@ def mcnote2freq(Notes):
return res
# MP3文件转midi文件
def Mp32Mid(mp3File, midFile):
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
# 加载
(audio, _) = load_audio(mp3File, sr=sample_rate, mono=True)
(audio, _) = load_audio(mp3File, sr=sample_rate) # , mono=True
# 实例化并转换
PianoTranscription(device="cpu").transcribe(audio, midFile)
# 传入一个音符列表转为指令列表
def Note2Cmd(Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False) -> list:
def Note2Cmd(Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '',
isProsess: bool = False) -> list:
commands = []
a = 0.0
if isProsess:
length = len(Notes)
j = 1
for i in range(len(Notes)):
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ playsound "+Instrument+" @s ~ ~ ~ 1000 "+str(Notes[i][0])+" 1000\n")
commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str(
int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ playsound " + Instrument + " @s ~ ~ ~ 1000 " + str(
Notes[i][0]) + " 1000\n")
a += Notes[i][1]
if isProsess:
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a"+str(j)+"/"+str(length)+" || "+str(int(j/length*1000)/10)+"\n")
commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str(
int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a" + str(
j) + "/" + str(length) + " || " + str(int(j / length * 1000) / 10) + "\n")
j += 1
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI金羿\n")
return commands
import amulet
import amulet_nbt
from amulet.api.block import Block
from amulet.api.block_entity import BlockEntity
from amulet.utils.world_utils import block_coords_to_chunk_coords
from amulet_nbt import TAG_String,TAG_Compound,TAG_Byte
# 简单载入方块
# level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
# 转入指令列表与位置信息转至世界
def Cmd2World(cmd: list, world: str, dire: list):
'''将指令以命令链的形式载入世界\n
"""将指令以命令链的形式载入世界\n
cmd指令列表位为一个序列中包含指令字符串\n
world为地图所在位置需要指向文件夹dire为指令方块生成之位置'''
world为地图所在位置需要指向文件夹dire为指令方块生成之位置"""
level = amulet.load_level(world)
cdl = []
for i in cmd:
e = True
try:
if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''):
cdl.append(i[:i.index('#')])
except:
e = False
except ValueError:
cdl.append(i)
finally:
if e is True:
cdl.append(i)
i = 0
# 第一个是特殊
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("repeating")})
universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('up'),
'mode': TAG_String("repeating")})
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1],dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(0),'Command': TAG_String(cdl.pop(0))}) })))
universal_block_entity = BlockEntity('universal_minecraft', 'command_block', dire[0], dire[1], dire[2],
amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound(
{'auto': TAG_Byte(0), 'Command': TAG_String(cdl.pop(0))})})))
chunk.blocks[offset_x, dire[1], offset_z] = level.block_palette.get_add_block(universal_block)
chunk.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
chunk.changed = True
@ -157,26 +152,36 @@ def Cmd2World(cmd:list,world:str,dire:list):
down = not down
# 定义此方块
if dire[1] + i == 254:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('east'),'mode':TAG_String("chain")})
universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('east'),
'mode': TAG_String("chain")})
else:
if down:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('down'),'mode':TAG_String("chain")})
universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('down'),
'mode': TAG_String("chain")})
else:
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("chain")})
universal_block = Block('universal_minecraft', 'command_block',
{'conditional': TAG_String("false"), 'facing': TAG_String('up'),
'mode': TAG_String("chain")})
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
# 获取区块
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
if down:
# 定义方块实体
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],254-i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
universal_block_entity = BlockEntity('universal_minecraft', 'command_block', dire[0], 254 - i, dire[2],
amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound(
{'auto': TAG_Byte(1), 'Command': TAG_String(j)})})))
# 将方块加入世界
chunk.blocks[offset_x, 254 - i, offset_z] = level.block_palette.get_add_block(universal_block)
chunk.block_entities[(dire[0], 254 - i, dire[2])] = universal_block_entity
else:
# 定义方块实体
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1]+i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
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)
@ -190,23 +195,20 @@ def Cmd2World(cmd:list,world:str,dire:list):
level.close()
# 音符转成方块再加载到世界里头
def Blocks2World(world: str, dire: list, Datas: list):
from nmcsup.const import Blocks
level = amulet.load_level(world)
i = 0
def setblock(block: str, pos: list):
'''pos : list[int,int,int]'''
"""pos : list[int,int,int]"""
cx, cz = block_coords_to_chunk_coords(pos[0], pos[2])
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(Block("minecraft", block))
chunk.changed = True
for j in Datas:
if dire[1] + 1 >= 255:
i = 0
@ -217,16 +219,9 @@ def Blocks2World(world:str,dire:list,Datas:list):
level.close()
# 传入音符列表制作播放器指令
def Notes2Player(Note, dire: list, CmdData: dict):
'''传入音符列表、坐标、指令数据,生成播放器指令'''
"""传入音符列表、坐标、指令数据,生成播放器指令"""
Notes = {}
for i in Note:
Notes[i[0]] = ''
@ -234,21 +229,17 @@ def Notes2Player(Note,dire:list,CmdData:dict):
from nmcsup.const import Blocks
Cmds = []
for j in Notes:
Cmds.append('execute @e[x='+str(dire[0])+',y='+str(dire[1])+',z='+str(dire[2])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ detect ~ ~ ~ '+Blocks[j]+' 0 execute @a '+CmdData['Pls']+' ~ ~ ~ playsound '+CmdData['Ins']+' @s ~ ~ ~ 1000 '+str(j)+' 1000\n')
Cmds+=['#本函数由 金羿 音·创 生成\n','execute @e[y='+str(dire[1])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ tp ~ ~1 ~\n','execute @e[y=255,dy=100,name='+CmdData['Ent']+'] ~ ~ ~ tp ~1 '+str(dire[1])+' ~\n','#音·创 开发交流群 861684859']
Cmds.append('execute @e[x=' + str(dire[0]) + ',y=' + str(dire[1]) + ',z=' + str(dire[2]) + ',dy=' + str(
255 - dire[1]) + ',name=' + CmdData['Ent'] + '] ~ ~ ~ detect ~ ~ ~ ' + Blocks[j] + ' 0 execute @a ' +
CmdData['Pls'] + ' ~ ~ ~ playsound ' + CmdData['Ins'] + ' @s ~ ~ ~ 1000 ' + str(j) + ' 1000\n')
Cmds += ['#本函数由 金羿 音·创 生成\n', 'execute @e[y=' + str(dire[1]) + ',dy=' + str(255 - dire[1]) + ',name=' + CmdData[
'Ent'] + '] ~ ~ ~ tp ~ ~1 ~\n',
'execute @e[y=255,dy=100,name=' + CmdData['Ent'] + '] ~ ~ ~ tp ~1 ' + str(dire[1]) + ' ~\n',
'#音·创 开发交流群 861684859']
return Cmds
# 传入音符列表生成方块至世界
def Datas2BlkWorld(NoteData, world: str, dire: list):
for i in range(len(NoteData)):
Blocks2World(world, [dire[0], dire[1], dire[2] + i], NoteData[i])

View File

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