mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2024-11-11 01:27:35 +08:00
代码架构升级,功能分割,减少强制性依赖,API全新换代,文档全面更新,新一代音·创,音·创1.0.0
This commit is contained in:
parent
ffe5837c9f
commit
3da472052e
@ -3,7 +3,7 @@
|
||||
1. 音·创的全部开发者享有其完整版权,其开发者可以在任一时刻终止以后音·创源代码开放,若经由其开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作
|
||||
2. 音·创或(及)其代码允许在 Apache2.0 协议的条款与说明下进行非商业使用
|
||||
3. 除部分代码特殊声明外,音·创允许对其或(及)其代码进行商业化使用,但是需要经过音·创主要开发者(诸葛亮与八卦阵、金羿)的一致授权,同时,授权对象在商业化授权的使用过程中必须依照 Apache2.0 协议的条款与说明
|
||||
4. 若存在对于音·创包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用,或默认依照 Apache2.0 协议进行商业化使用
|
||||
4. 若存在对于音·创包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用
|
||||
5. Apache2.0 协议的英文原文副本可见下文
|
||||
|
||||
> The English Translation of the TERMS AND CONDITIONS above is listed below
|
||||
@ -203,7 +203,7 @@
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
Copyright 2022 TriM-Organization 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & all the developers of Musicreater
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -8,17 +8,16 @@ A free open source library used for convert midi file into formats that is suita
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../License.md
|
||||
Terms & Conditions: ../License.md
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
from .main import *
|
||||
|
||||
__version__ = "0.5.1.1"
|
||||
__version__ = "1.0.0"
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"), ("鸣凤鸽子", "MingFengPigeon"))
|
||||
|
@ -1,7 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
存放常量与数值性内容
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
x = "x"
|
||||
"""
|
||||
|
@ -1,25 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
存放一堆报错类型
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
"""一个简单的我的世界音频转换库
|
||||
音·创 (Musicreater)
|
||||
是一款免费开源的针对《我的世界》的midi音乐转换库
|
||||
Musicreater(音·创)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft**.
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../License.md
|
||||
Terms & Conditions: ../License.md
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
|
||||
|
||||
class MSCTBaseException(Exception):
|
||||
"""音·创库版本的所有错误均继承于此"""
|
||||
|
@ -1,18 +1,32 @@
|
||||
'''
|
||||
新版本功能以及即将启用的函数
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
新版本功能以及即将启用的函数
|
||||
"""
|
||||
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
from .exceptions import *
|
||||
from .main import MidiConvert, mido
|
||||
from .subclass import *
|
||||
from .utils import *
|
||||
from .main import midiConvert, mido
|
||||
|
||||
|
||||
# 简单的单音填充
|
||||
def _toCmdList_m4(
|
||||
self: midiConvert,
|
||||
self: MidiConvert,
|
||||
scoreboard_name: str = "mscplay",
|
||||
MaxVolume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
@ -58,9 +72,7 @@ def _toCmdList_m4(
|
||||
pass
|
||||
|
||||
if msg.type == "program_change":
|
||||
channels[msg.channel].append(
|
||||
("PgmC", msg.program, microseconds)
|
||||
)
|
||||
channels[msg.channel].append(("PgmC", msg.program, microseconds))
|
||||
|
||||
elif msg.type == "note_on" and msg.velocity != 0:
|
||||
channels[msg.channel].append(
|
||||
@ -193,7 +205,6 @@ def _toCmdList_m4(
|
||||
return [tracks, cmdAmount, maxScore]
|
||||
|
||||
|
||||
|
||||
def to_note_list(
|
||||
self,
|
||||
speed: float = 1.0,
|
||||
@ -227,9 +238,7 @@ def to_note_list(
|
||||
for msg in track:
|
||||
if msg.time != 0:
|
||||
try:
|
||||
microseconds += (
|
||||
msg.time * tempo / self.midi.ticks_per_beat / 1000
|
||||
)
|
||||
microseconds += msg.time * tempo / self.midi.ticks_per_beat / 1000
|
||||
# print(microseconds)
|
||||
except NameError:
|
||||
if self.debug_mode:
|
||||
@ -347,12 +356,10 @@ def to_note_list(
|
||||
0
|
||||
if j != 0
|
||||
else (
|
||||
all_ticks[i] - all_ticks[i - 1]
|
||||
if i != 0
|
||||
else all_ticks[i]
|
||||
all_ticks[i] - all_ticks[i - 1] if i != 0 else all_ticks[i]
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
return [results, max(all_ticks)]
|
||||
return [results, max(all_ticks)]
|
||||
|
1144
Musicreater/main.py
1144
Musicreater/main.py
File diff suppressed because it is too large
Load Diff
@ -5,15 +5,16 @@
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../../License.md
|
||||
Terms & Conditions: ../../License.md
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"), ("鸣凤鸽子", "MingFengPigeon"))
|
||||
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"))
|
||||
|
||||
from .main import *
|
@ -1,8 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放关于文件打包的内容
|
||||
"""
|
||||
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import zipfile
|
||||
from typing import List
|
||||
|
||||
|
||||
def compress_zipfile(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||
@ -23,4 +41,35 @@ def compress_zipfile(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||
pathfile = os.path.join(parent, filename)
|
||||
arc_name = pathfile[pre_len:].strip(os.path.sep) # 相对路径
|
||||
zipf.write(pathfile, arc_name)
|
||||
zipf.close()
|
||||
zipf.close()
|
||||
|
||||
|
||||
def behavior_mcpack_manifest(
|
||||
pack_description: str = "",
|
||||
pack_version: List[int] = [0, 0, 1],
|
||||
pack_name: str = "",
|
||||
pack_uuid: str = None,
|
||||
modules_description: str = "",
|
||||
modules_version: List[int] = [0, 0, 1],
|
||||
modules_uuid: str = None,
|
||||
):
|
||||
"""
|
||||
生成一个我的世界行为包组件的定义清单文件
|
||||
"""
|
||||
return {
|
||||
"format_version": 1,
|
||||
"header": {
|
||||
"description": pack_description,
|
||||
"version": pack_version,
|
||||
"name": pack_name,
|
||||
"uuid": str(uuid.uuid4()) if not pack_uuid else pack_uuid,
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": modules_description,
|
||||
"type": "data",
|
||||
"version": modules_version,
|
||||
"uuid": str(uuid.uuid4()) if not modules_uuid else modules_uuid,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
@ -1,11 +1,25 @@
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放有关BDX结构操作的内容
|
||||
'''
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
from typing import List
|
||||
|
||||
from ..constants import x, y, z
|
||||
from ..subclass import SingleCommand
|
||||
from .common import bottem_side_length_of_smallest_square_bottom_box
|
||||
from ..constants import x,y,z
|
||||
|
||||
|
||||
bdx_key = {
|
||||
"x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"],
|
||||
@ -26,11 +40,11 @@ def bdx_move(axis: str, value: int):
|
||||
[
|
||||
1 if i else 0
|
||||
for i in (
|
||||
value != -1,
|
||||
value < -1 or value > 1,
|
||||
value < -128 or value > 127,
|
||||
value < -32768 or value > 32767,
|
||||
)
|
||||
value != -1,
|
||||
value < -1 or value > 1,
|
||||
value < -128 or value > 127,
|
||||
value < -32768 or value > 32767,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@ -39,17 +53,16 @@ def bdx_move(axis: str, value: int):
|
||||
)
|
||||
|
||||
|
||||
|
||||
def form_command_block_in_BDX_bytes(
|
||||
command: str,
|
||||
particularValue: int,
|
||||
impluse: int = 0,
|
||||
condition: bool = False,
|
||||
needRedstone: bool = True,
|
||||
tickDelay: int = 0,
|
||||
customName: str = "",
|
||||
executeOnFirstTick: bool = False,
|
||||
trackOutput: bool = True,
|
||||
command: str,
|
||||
particularValue: int,
|
||||
impluse: int = 0,
|
||||
condition: bool = False,
|
||||
needRedstone: bool = True,
|
||||
tickDelay: int = 0,
|
||||
customName: str = "",
|
||||
executeOnFirstTick: bool = False,
|
||||
trackOutput: bool = True,
|
||||
):
|
||||
"""
|
||||
使用指定项目返回指定的指令方块放置指令项
|
||||
@ -113,8 +126,8 @@ def form_command_block_in_BDX_bytes(
|
||||
|
||||
|
||||
def commands_to_BDX_bytes(
|
||||
commands: list,
|
||||
max_height: int = 64,
|
||||
commands_list: List[SingleCommand],
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
:param commands: 指令列表(指令, 延迟)
|
||||
@ -123,7 +136,7 @@ def commands_to_BDX_bytes(
|
||||
"""
|
||||
|
||||
_sideLength = bottem_side_length_of_smallest_square_bottom_box(
|
||||
len(commands), max_height
|
||||
len(commands_list), max_height
|
||||
)
|
||||
_bytes = b""
|
||||
|
||||
@ -134,34 +147,28 @@ def commands_to_BDX_bytes(
|
||||
now_z = 0
|
||||
now_x = 0
|
||||
|
||||
for cmd, delay in commands:
|
||||
impluse = 2
|
||||
condition = False
|
||||
needRedstone = False
|
||||
tickDelay = delay
|
||||
customName = ""
|
||||
executeOnFirstTick = False
|
||||
trackOutput = True
|
||||
for command in commands_list:
|
||||
|
||||
_bytes += form_command_block_in_BDX_bytes(
|
||||
cmd,
|
||||
command.command_text,
|
||||
(1 if y_forward else 0)
|
||||
if (
|
||||
((now_y != 0) and (not y_forward))
|
||||
or (y_forward and (now_y != (max_height - 1)))
|
||||
((now_y != 0) and (not y_forward))
|
||||
or (y_forward and (now_y != (max_height - 1)))
|
||||
)
|
||||
else (3 if z_forward else 2)
|
||||
if (
|
||||
((now_z != 0) and (not z_forward))
|
||||
or (z_forward and (now_z != _sideLength - 1))
|
||||
((now_z != 0) and (not z_forward))
|
||||
or (z_forward and (now_z != _sideLength - 1))
|
||||
)
|
||||
else 5,
|
||||
impluse=impluse,
|
||||
condition=condition,
|
||||
needRedstone=needRedstone,
|
||||
tickDelay=tickDelay,
|
||||
customName=customName,
|
||||
executeOnFirstTick=executeOnFirstTick,
|
||||
trackOutput=trackOutput,
|
||||
impluse=2,
|
||||
condition=command.conditional,
|
||||
needRedstone=False,
|
||||
tickDelay=command.delay,
|
||||
customName=command.annotation_text,
|
||||
executeOnFirstTick=False,
|
||||
trackOutput=True,
|
||||
)
|
||||
|
||||
now_y += 1 if y_forward else -1
|
||||
@ -174,7 +181,7 @@ def commands_to_BDX_bytes(
|
||||
now_z += 1 if z_forward else -1
|
||||
|
||||
if ((now_z >= _sideLength) and z_forward) or (
|
||||
(now_z < 0) and (not z_forward)
|
||||
(now_z < 0) and (not z_forward)
|
||||
):
|
||||
now_z -= 1 if z_forward else -1
|
||||
z_forward = not z_forward
|
||||
@ -195,5 +202,3 @@ def commands_to_BDX_bytes(
|
||||
],
|
||||
[now_x, now_y, now_z],
|
||||
)
|
||||
|
||||
|
||||
|
21
Musicreater/plugin/bdxfile/__init__.py
Normal file
21
Musicreater/plugin/bdxfile/__init__.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
用以生成BDX结构文件的附加功能
|
||||
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"),)
|
||||
|
||||
from .main import *
|
||||
|
219
Musicreater/plugin/bdxfile/main.py
Normal file
219
Musicreater/plugin/bdxfile/main.py
Normal file
@ -0,0 +1,219 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
import os
|
||||
import brotli
|
||||
|
||||
from ...main import MidiConvert
|
||||
from ..bdx import commands_to_BDX_bytes, bdx_move, x, y, z, form_command_block_in_BDX_bytes
|
||||
from ..main import ConvertConfig
|
||||
from ...subclass import SingleCommand
|
||||
|
||||
|
||||
def to_BDX_file_in_score(
|
||||
midi_cvt: MidiConvert,
|
||||
data_cfg: ConvertConfig,
|
||||
scoreboard_name: str = "mscplay",
|
||||
auto_reset: bool = False,
|
||||
author: str = "Eilles",
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
将midi以计分播放器形式转换为BDX结构文件
|
||||
|
||||
Parameters
|
||||
----------
|
||||
midi_cvt: MidiConvert 对象
|
||||
用于转换的MidiConvert对象
|
||||
data_cfg: ConvertConfig 对象
|
||||
部分转换通用参数
|
||||
scoreboard_name: str
|
||||
我的世界的计分板名称
|
||||
auto_reset: bool
|
||||
是否自动重置计分板
|
||||
author: str
|
||||
作者名称
|
||||
max_height: int
|
||||
生成结构最大高度
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[int指令数量, int音乐总延迟, tuple[int,]结构大小, tuple[int,]终点坐标]
|
||||
"""
|
||||
|
||||
cmdlist, command_count, max_score = midi_cvt.to_command_list_in_score(
|
||||
scoreboard_name, data_cfg.volume_ratio, data_cfg.speed_multiplier
|
||||
)
|
||||
|
||||
if not os.path.exists(data_cfg.dist_path):
|
||||
os.makedirs(data_cfg.dist_path)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.midi_music_name}.bdx")
|
||||
),
|
||||
"w+",
|
||||
) as f:
|
||||
f.write("BD@")
|
||||
|
||||
_bytes = (
|
||||
b"BDX\x00" + author.encode("utf-8") + b" & Musicreater\x00\x01command_block\x00"
|
||||
)
|
||||
|
||||
cmdBytes, size, finalPos = commands_to_BDX_bytes(
|
||||
midi_cvt.music_command_list
|
||||
+ (
|
||||
[
|
||||
SingleCommand(
|
||||
command="scoreboard players reset @a[scores={"
|
||||
+ scoreboard_name
|
||||
+ "="
|
||||
+ str(max_score + 20)
|
||||
+ "}] "
|
||||
+ scoreboard_name,
|
||||
annotation="自动重置计分板",
|
||||
)
|
||||
]
|
||||
if auto_reset
|
||||
else []
|
||||
),
|
||||
max_height - 1,
|
||||
)
|
||||
|
||||
if data_cfg.progressbar_style:
|
||||
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
||||
midi_cvt.form_progress_bar(
|
||||
max_score, scoreboard_name, data_cfg.progressbar_style
|
||||
),
|
||||
max_height - 1,
|
||||
)
|
||||
_bytes += pgbBytes
|
||||
_bytes += bdx_move(y, -pgbNowPos[1])
|
||||
_bytes += bdx_move(z, -pgbNowPos[2])
|
||||
_bytes += bdx_move(x, 2)
|
||||
|
||||
size[0] += 2 + pgbSize[0]
|
||||
size[1] = max(size[1], pgbSize[1])
|
||||
size[2] = max(size[2], pgbSize[2])
|
||||
|
||||
_bytes += cmdBytes
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.midi_music_name}.bdx")
|
||||
),
|
||||
"ab+",
|
||||
) as f:
|
||||
f.write(brotli.compress(_bytes + b"XE"))
|
||||
|
||||
return command_count, max_score, size, finalPos
|
||||
|
||||
|
||||
def to_BDX_file_in_delay(
|
||||
midi_cvt: MidiConvert,
|
||||
data_cfg: ConvertConfig,
|
||||
player: str = "@a",
|
||||
author: str = "Eilles",
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
使用method指定的转换算法,将midi转换为BDX结构文件
|
||||
|
||||
Parameters
|
||||
----------
|
||||
midi_cvt: MidiConvert 对象
|
||||
用于转换的MidiConvert对象
|
||||
data_cfg: ConvertConfig 对象
|
||||
部分转换通用参数
|
||||
player: str
|
||||
玩家选择器,默认为`@a`
|
||||
author: str
|
||||
作者名称
|
||||
max_height: int
|
||||
生成结构最大高度
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[int指令数量, int音乐总延迟, tuple[int,]结构大小, tuple[int,]终点坐标]
|
||||
"""
|
||||
|
||||
cmdlist, max_delay = midi_cvt.to_command_list_in_delay(
|
||||
data_cfg.volume_ratio,
|
||||
data_cfg.speed_multiplier,
|
||||
player,
|
||||
)
|
||||
|
||||
if not os.path.exists(data_cfg.dist_path):
|
||||
os.makedirs(data_cfg.dist_path)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.midi_music_name}.bdx")
|
||||
),
|
||||
"w+",
|
||||
) as f:
|
||||
f.write("BD@")
|
||||
|
||||
_bytes = (
|
||||
b"BDX\x00" + author.encode("utf-8") + b" & Musicreater\x00\x01command_block\x00"
|
||||
)
|
||||
|
||||
|
||||
cmdBytes, size, finalPos = commands_to_BDX_bytes(cmdlist, max_height - 1)
|
||||
|
||||
if data_cfg.progressbar_style:
|
||||
scb_name = midi_cvt.midi_music_name[:3] + "Pgb"
|
||||
_bytes += form_command_block_in_BDX_bytes(
|
||||
r"scoreboard objectives add {} dummy {}计".replace(r"{}", scb_name),
|
||||
1,
|
||||
customName="初始化进度条",
|
||||
)
|
||||
_bytes += bdx_move(z, 2)
|
||||
_bytes += form_command_block_in_BDX_bytes(
|
||||
r"scoreboard players add {} {} 1".format(player, scb_name),
|
||||
1,
|
||||
1,
|
||||
customName="显示进度条并加分",
|
||||
)
|
||||
_bytes += bdx_move(y, 1)
|
||||
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
||||
midi_cvt.form_progress_bar(max_delay, scb_name, data_cfg.progressbar_style),
|
||||
max_height - 1,
|
||||
)
|
||||
_bytes += pgbBytes
|
||||
_bytes += bdx_move(y, -1 - pgbNowPos[1])
|
||||
_bytes += bdx_move(z, -2 - pgbNowPos[2])
|
||||
_bytes += bdx_move(x, 2)
|
||||
_bytes += form_command_block_in_BDX_bytes(
|
||||
r"scoreboard players reset {} {}".format(player, scb_name),
|
||||
1,
|
||||
customName="置零进度条",
|
||||
)
|
||||
_bytes += bdx_move(y, 1)
|
||||
size[0] += 2 + pgbSize[0]
|
||||
size[1] = max(size[1], pgbSize[1])
|
||||
size[2] = max(size[2], pgbSize[2])
|
||||
|
||||
size[1] += 1
|
||||
_bytes += cmdBytes
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.midi_music_name}.bdx")
|
||||
),
|
||||
"ab+",
|
||||
) as f:
|
||||
f.write(brotli.compress(_bytes + b"XE"))
|
||||
|
||||
return len(cmdlist), max_delay, size, finalPos
|
@ -1,6 +1,20 @@
|
||||
'''
|
||||
存放通用的普遍性的内容
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放通用的普遍性的插件内容
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
import math
|
||||
|
||||
@ -11,4 +25,3 @@ def bottem_side_length_of_smallest_square_bottom_box(total: int, maxHeight: int)
|
||||
:param maxHeight: 最大高度
|
||||
:return: 外切正方形的边长 int"""
|
||||
return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
|
||||
|
||||
|
21
Musicreater/plugin/funcpack/__init__.py
Normal file
21
Musicreater/plugin/funcpack/__init__.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
用以生成函数附加包的附加功能
|
||||
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"),)
|
||||
|
||||
from .main import *
|
||||
|
128
Musicreater/plugin/funcpack/main.py
Normal file
128
Musicreater/plugin/funcpack/main.py
Normal file
@ -0,0 +1,128 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from typing import Tuple
|
||||
|
||||
from ...main import MidiConvert
|
||||
from ..archive import behavior_mcpack_manifest, compress_zipfile
|
||||
from ..main import ConvertConfig
|
||||
|
||||
|
||||
def to_function_addon_in_score(
|
||||
midi_cvt: MidiConvert,
|
||||
data_cfg: ConvertConfig,
|
||||
scoreboard_name: str = "mscplay",
|
||||
auto_reset: bool = False,
|
||||
) -> Tuple[int, int]:
|
||||
"""
|
||||
将midi以计分播放器形式转换为我的世界函数附加包
|
||||
|
||||
Parameters
|
||||
----------
|
||||
midi_cvt: MidiConvert 对象
|
||||
用于转换的MidiConvert对象
|
||||
data_cfg: ConvertConfig 对象
|
||||
部分转换通用参数
|
||||
scoreboard_name: str
|
||||
我的世界的计分板名称
|
||||
auto_reset: bool
|
||||
是否自动重置计分板
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[int指令数量, int音乐总延迟]
|
||||
"""
|
||||
|
||||
cmdlist, maxlen, maxscore = midi_cvt.to_command_list_in_score(
|
||||
scoreboard_name, data_cfg.volume_ratio, data_cfg.speed_multiplier
|
||||
)
|
||||
|
||||
# 当文件f夹{self.outputPath}/temp/functions存在时清空其下所有项目,然后创建
|
||||
if os.path.exists(f"{data_cfg.dist_path}/temp/functions/"):
|
||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/functions/")
|
||||
os.makedirs(f"{data_cfg.dist_path}/temp/functions/mscplay")
|
||||
|
||||
# 写入manifest.json
|
||||
open(f"{data_cfg.dist_path}/temp/manifest.json", "w", encoding="utf-8").write(
|
||||
json.dumps(
|
||||
behavior_mcpack_manifest("midiPlay"),
|
||||
indent=4,
|
||||
)
|
||||
)
|
||||
|
||||
# 将命令列表写入文件
|
||||
index_file = open(
|
||||
f"{data_cfg.dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||
)
|
||||
for i in range(len(cmdlist)):
|
||||
index_file.write(f"function mscplay/track{i + 1}\n")
|
||||
with open(
|
||||
f"{data_cfg.dist_path}/temp/functions/mscplay/track{i + 1}.mcfunction",
|
||||
"w",
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
f.write("\n".join([single_cmd.cmd for single_cmd in cmdlist[i]]))
|
||||
index_file.writelines(
|
||||
(
|
||||
"scoreboard players add @a[scores={"
|
||||
+ scoreboard_name
|
||||
+ "=1..}] "
|
||||
+ scoreboard_name
|
||||
+ " 1\n",
|
||||
(
|
||||
"scoreboard players reset @a[scores={"
|
||||
+ scoreboard_name
|
||||
+ "="
|
||||
+ str(maxscore + 20)
|
||||
+ "..}]"
|
||||
+ f" {scoreboard_name}\n"
|
||||
)
|
||||
if auto_reset
|
||||
else "",
|
||||
f"function mscplay/progressShow\n" if data_cfg.progressbar_style else "",
|
||||
)
|
||||
)
|
||||
|
||||
if data_cfg.progressbar_style:
|
||||
with open(
|
||||
f"{data_cfg.dist_path}/temp/functions/mscplay/progressShow.mcfunction",
|
||||
"w",
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
f.writelines(
|
||||
"\n".join(
|
||||
[
|
||||
single_cmd.cmd
|
||||
for single_cmd in midi_cvt.form_progress_bar(
|
||||
maxscore, scoreboard_name, data_cfg.progressbar_style
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
index_file.close()
|
||||
|
||||
if os.path.exists(f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack"):
|
||||
os.remove(f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack")
|
||||
compress_zipfile(
|
||||
f"{data_cfg.dist_path}/temp/",
|
||||
f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack",
|
||||
)
|
||||
|
||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
||||
|
||||
return maxlen, maxscore
|
86
Musicreater/plugin/main.py
Normal file
86
Musicreater/plugin/main.py
Normal file
@ -0,0 +1,86 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放附加内容功能
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Tuple, Union
|
||||
|
||||
from ..constants import DEFAULT_PROGRESSBAR_STYLE
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class ConvertConfig:
|
||||
"""
|
||||
转换通用设置存储类
|
||||
"""
|
||||
|
||||
volume_ratio: float
|
||||
"""音量比例"""
|
||||
|
||||
speed_multiplier: float
|
||||
"""速度倍率"""
|
||||
|
||||
progressbar_style: Tuple[str, Tuple[str, str]]
|
||||
"""进度条样式组"""
|
||||
|
||||
dist_path: str
|
||||
"""输出目录"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
output_path: str,
|
||||
volume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
progressbar: Union[bool, Tuple[str, Tuple[str, str]]] = True,
|
||||
):
|
||||
"""
|
||||
将已经转换好的数据内容指令载入MC可读格式
|
||||
|
||||
Parameters
|
||||
----------
|
||||
output_path: str
|
||||
生成内容的输出目录
|
||||
volume: float
|
||||
音量比率,范围为(0,1],其原理为在距离玩家 (1 / volume -1) 的地方播放音频
|
||||
speed: float
|
||||
速度倍率,注意:这里的速度指的是播放速度倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
|
||||
progressbar: bool|tuple[str, Tuple[str,]]
|
||||
进度条,当此参数为 `True` 时使用默认进度条,为其他的**值为真**的参数时识别为进度条自定义参数,为其他**值为假**的时候不生成进度条
|
||||
|
||||
"""
|
||||
|
||||
self.dist_path = output_path
|
||||
"""输出目录"""
|
||||
|
||||
self.volume_ratio = volume
|
||||
"""音量比例"""
|
||||
|
||||
self.speed_multiplier = speed
|
||||
"""速度倍率"""
|
||||
|
||||
if progressbar:
|
||||
# 此处是对于仅有 True 的参数和自定义参数的判断
|
||||
# 改这一段没🐎
|
||||
if progressbar is True:
|
||||
self.progressbar_style = DEFAULT_PROGRESSBAR_STYLE
|
||||
"""进度条样式组"""
|
||||
else:
|
||||
self.progressbar_style = progressbar
|
||||
"""进度条样式组"""
|
||||
else:
|
||||
self.progressbar_style = None
|
||||
"""进度条样式组"""
|
21
Musicreater/plugin/mcstructfile/__init__.py
Normal file
21
Musicreater/plugin/mcstructfile/__init__.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
用以生成单个mcstructure文件的附加功能
|
||||
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"),)
|
||||
|
||||
from .main import *
|
||||
|
69
Musicreater/plugin/mcstructfile/main.py
Normal file
69
Musicreater/plugin/mcstructfile/main.py
Normal file
@ -0,0 +1,69 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
import os
|
||||
|
||||
from ...exceptions import CommandFormatError
|
||||
from ...main import MidiConvert
|
||||
from ..main import ConvertConfig
|
||||
from ..mcstructure import commands_to_structure
|
||||
|
||||
|
||||
def to_mcstructure_file_in_delay(
|
||||
midi_cvt: MidiConvert,
|
||||
data_cfg: ConvertConfig,
|
||||
player: str = "@a",
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
将midi以延迟播放器形式转换为mcstructure结构文件
|
||||
|
||||
Parameters
|
||||
----------
|
||||
midi_cvt: MidiConvert 对象
|
||||
用于转换的MidiConvert对象
|
||||
data_cfg: ConvertConfig 对象
|
||||
部分转换通用参数
|
||||
player: str
|
||||
玩家选择器,默认为`@a`
|
||||
max_height: int
|
||||
生成结构最大高度
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[tuple[int,]结构大小, int音乐总延迟]
|
||||
"""
|
||||
|
||||
if midi_cvt.enable_old_exe_format:
|
||||
raise CommandFormatError("使用mcstructure结构文件导出时不支持旧版本的指令格式。")
|
||||
|
||||
cmd_list, max_delay = midi_cvt.to_command_list_in_delay(
|
||||
data_cfg.volume_ratio,
|
||||
data_cfg.speed_multiplier,
|
||||
player,
|
||||
)
|
||||
|
||||
if not os.path.exists(data_cfg.dist_path):
|
||||
os.makedirs(data_cfg.dist_path)
|
||||
|
||||
struct, size, end_pos = commands_to_structure(cmd_list, max_height - 1)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.midi_music_name}.mcstructure")
|
||||
),
|
||||
"wb+",
|
||||
) as f:
|
||||
struct.dump(f)
|
||||
|
||||
return size, max_delay
|
21
Musicreater/plugin/mcstructpack/__init__.py
Normal file
21
Musicreater/plugin/mcstructpack/__init__.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
用以生成结构附加包的附加功能
|
||||
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__all__ = []
|
||||
__author__ = (("金羿", "Eilles Wan"),)
|
||||
|
||||
from .main import *
|
||||
|
205
Musicreater/plugin/mcstructpack/main.py
Normal file
205
Musicreater/plugin/mcstructpack/main.py
Normal file
@ -0,0 +1,205 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from TrimMCStruct import Structure
|
||||
|
||||
from ...exceptions import CommandFormatError
|
||||
from ...main import MidiConvert
|
||||
from ..archive import behavior_mcpack_manifest, compress_zipfile
|
||||
from ..main import ConvertConfig
|
||||
from ..mcstructure import (commands_to_structure,
|
||||
form_command_block_in_NBT_struct)
|
||||
|
||||
|
||||
def to_mcstructure_addon_in_delay(
|
||||
midi_cvt: MidiConvert,
|
||||
data_cfg: ConvertConfig,
|
||||
player: str = "@a",
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
将midi以延迟播放器形式转换为mcstructure结构文件后打包成附加包,并在附加包中生成相应地导入函数
|
||||
|
||||
Parameters
|
||||
----------
|
||||
midi_cvt: MidiConvert 对象
|
||||
用于转换的MidiConvert对象
|
||||
data_cfg: ConvertConfig 对象
|
||||
部分转换通用参数
|
||||
player: str
|
||||
玩家选择器,默认为`@a`
|
||||
max_height: int
|
||||
生成结构最大高度
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[int指令数量, int音乐总延迟]
|
||||
"""
|
||||
|
||||
if midi_cvt.enable_old_exe_format:
|
||||
raise CommandFormatError("使用mcstructure结构文件导出时不支持旧版本的指令格式。")
|
||||
|
||||
command_list, max_delay = midi_cvt.to_command_list_in_delay(
|
||||
data_cfg.volume_ratio,
|
||||
data_cfg.speed_multiplier,
|
||||
player,
|
||||
)
|
||||
|
||||
if not os.path.exists(data_cfg.dist_path):
|
||||
os.makedirs(data_cfg.dist_path)
|
||||
|
||||
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
||||
if os.path.exists(f"{data_cfg.dist_path}/temp/"):
|
||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
||||
os.makedirs(f"{data_cfg.dist_path}/temp/functions/")
|
||||
os.makedirs(f"{data_cfg.dist_path}/temp/structures/")
|
||||
|
||||
# 写入manifest.json
|
||||
with open(f"{data_cfg.dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
||||
json.dump(
|
||||
behavior_mcpack_manifest(
|
||||
pack_description=f"Music {midi_cvt.midi_music_name} Play pack, structure in delay - Generated by Musicreater",
|
||||
pack_name=midi_cvt.midi_music_name,
|
||||
modules_description=f"None - Generated by Musicreater",
|
||||
),
|
||||
fp=f,
|
||||
)
|
||||
|
||||
# 将命令列表写入文件
|
||||
index_file = open(
|
||||
f"{data_cfg.dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||
)
|
||||
|
||||
struct, size, end_pos = commands_to_structure(command_list, max_height - 1)
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(
|
||||
data_cfg.dist_path,
|
||||
"temp/structures/",
|
||||
f"{midi_cvt.midi_music_name}_main.mcstructure",
|
||||
)
|
||||
),
|
||||
"wb+",
|
||||
) as f:
|
||||
struct.dump(f)
|
||||
|
||||
del struct
|
||||
|
||||
if data_cfg.progressbar_style:
|
||||
scb_name = midi_cvt.midi_music_name[:3] + "Pgb"
|
||||
index_file.write("scoreboard objectives add {0} dummy {0}计\n".format(scb_name))
|
||||
|
||||
struct_a = Structure(
|
||||
(1, 1, 1),
|
||||
)
|
||||
struct_a.set_block(
|
||||
(0, 0, 0),
|
||||
form_command_block_in_NBT_struct(
|
||||
r"scoreboard players add {} {} 1".format(player, scb_name),
|
||||
(0, 0, 0),
|
||||
1,
|
||||
1,
|
||||
alwaysRun=False,
|
||||
customName="显示进度条并加分",
|
||||
),
|
||||
)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(
|
||||
data_cfg.dist_path,
|
||||
"temp/structures/",
|
||||
f"{midi_cvt.midi_music_name}_start.mcstructure",
|
||||
)
|
||||
),
|
||||
"wb+",
|
||||
) as f:
|
||||
struct_a.dump(f)
|
||||
|
||||
index_file.write(f"structure load {midi_cvt.midi_music_name}_start ~ ~ ~1\n")
|
||||
|
||||
pgb_struct, pgbSize, pgbNowPos = commands_to_structure(
|
||||
midi_cvt.form_progress_bar(max_delay, scb_name, data_cfg.progressbar_style),
|
||||
max_height - 1,
|
||||
)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(
|
||||
data_cfg.dist_path,
|
||||
"temp/structures/",
|
||||
f"{midi_cvt.midi_music_name}_pgb.mcstructure",
|
||||
)
|
||||
),
|
||||
"wb+",
|
||||
) as f:
|
||||
pgb_struct.dump(f)
|
||||
|
||||
index_file.write(f"structure load {midi_cvt.midi_music_name}_pgb ~ ~1 ~1\n")
|
||||
|
||||
struct_a = Structure(
|
||||
(1, 1, 1),
|
||||
)
|
||||
struct_a.set_block(
|
||||
(0, 0, 0),
|
||||
form_command_block_in_NBT_struct(
|
||||
r"scoreboard players reset {} {}".format(player, scb_name),
|
||||
(0, 0, 0),
|
||||
1,
|
||||
0,
|
||||
alwaysRun=False,
|
||||
customName="重置进度条计分板",
|
||||
),
|
||||
)
|
||||
|
||||
with open(
|
||||
os.path.abspath(
|
||||
os.path.join(
|
||||
data_cfg.dist_path,
|
||||
"temp/structures/",
|
||||
f"{midi_cvt.midi_music_name}_reset.mcstructure",
|
||||
)
|
||||
),
|
||||
"wb+",
|
||||
) as f:
|
||||
struct_a.dump(f)
|
||||
|
||||
del struct_a, pgb_struct
|
||||
|
||||
index_file.write(
|
||||
f"structure load {midi_cvt.midi_music_name}_reset ~{pgbSize[0] + 2} ~ ~1\n"
|
||||
)
|
||||
|
||||
index_file.write(
|
||||
f"structure load {midi_cvt.midi_music_name}_main ~{pgbSize[0] + 2} ~1 ~1\n"
|
||||
)
|
||||
|
||||
else:
|
||||
index_file.write(f"structure load {midi_cvt.midi_music_name}_main ~ ~ ~1\n")
|
||||
|
||||
index_file.close()
|
||||
|
||||
if os.path.exists(f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack"):
|
||||
os.remove(f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack")
|
||||
compress_zipfile(
|
||||
f"{data_cfg.dist_path}/temp/",
|
||||
f"{data_cfg.dist_path}/{midi_cvt.midi_music_name}.mcpack",
|
||||
)
|
||||
|
||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
||||
|
||||
return len(command_list), max_delay
|
@ -1,12 +1,31 @@
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放有关MCSTRUCTURE结构操作的内容
|
||||
'''
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
from typing import List
|
||||
|
||||
from TrimMCStruct import Block, Structure, TAG_Byte, TAG_Long
|
||||
|
||||
from ..subclass import SingleCommand
|
||||
from .common import bottem_side_length_of_smallest_square_bottom_box
|
||||
from TrimMCStruct import Structure, Block, TAG_Long, TAG_Byte
|
||||
|
||||
|
||||
def form_note_block_in_NBT_struct(
|
||||
note: int, coordinate: tuple, instrument: str = "note.harp", powered: bool = False
|
||||
note: int, coordinate: tuple, instrument: str = "note.harp", powered: bool = False
|
||||
):
|
||||
"""生成音符盒方块
|
||||
:param note: `int`(0~24)
|
||||
@ -40,15 +59,12 @@ def form_note_block_in_NBT_struct(
|
||||
)
|
||||
|
||||
|
||||
def form_repeater_in_NBT_struct(
|
||||
delay: int, facing: int
|
||||
):
|
||||
def form_repeater_in_NBT_struct(delay: int, facing: int):
|
||||
"""生成中继器方块
|
||||
:param facing:
|
||||
:param delay: 1~4
|
||||
:return Block()"""
|
||||
|
||||
|
||||
return Block(
|
||||
"minecraft",
|
||||
"unpowered_repeater",
|
||||
@ -60,16 +76,16 @@ def form_repeater_in_NBT_struct(
|
||||
|
||||
|
||||
def form_command_block_in_NBT_struct(
|
||||
command: str,
|
||||
coordinate: tuple,
|
||||
particularValue: int,
|
||||
impluse: int = 0,
|
||||
condition: bool = False,
|
||||
alwaysRun: bool = True,
|
||||
tickDelay: int = 0,
|
||||
customName: str = "",
|
||||
executeOnFirstTick: bool = False,
|
||||
trackOutput: bool = True,
|
||||
command: str,
|
||||
coordinate: tuple,
|
||||
particularValue: int,
|
||||
impluse: int = 0,
|
||||
condition: bool = False,
|
||||
alwaysRun: bool = True,
|
||||
tickDelay: int = 0,
|
||||
customName: str = "",
|
||||
executeOnFirstTick: bool = False,
|
||||
trackOutput: bool = True,
|
||||
):
|
||||
"""
|
||||
使用指定项目返回指定的指令方块结构
|
||||
@ -116,7 +132,6 @@ def form_command_block_in_NBT_struct(
|
||||
:return:str
|
||||
"""
|
||||
|
||||
|
||||
return Block(
|
||||
"minecraft",
|
||||
"command_block"
|
||||
@ -154,16 +169,15 @@ def form_command_block_in_NBT_struct(
|
||||
|
||||
|
||||
def commands_to_structure(
|
||||
commands: list,
|
||||
max_height: int = 64,
|
||||
commands: List[SingleCommand],
|
||||
max_height: int = 64,
|
||||
):
|
||||
"""
|
||||
:param commands: 指令列表(指令, 延迟)
|
||||
:param commands: 指令列表
|
||||
:param max_height: 生成结构最大高度
|
||||
:return 成功与否,成功返回(结构类,结构占用大小),失败返回(False,str失败原因)
|
||||
:return 结构类,结构占用大小,终点坐标
|
||||
"""
|
||||
|
||||
|
||||
_sideLength = bottem_side_length_of_smallest_square_bottom_box(
|
||||
len(commands), max_height
|
||||
)
|
||||
@ -179,31 +193,31 @@ def commands_to_structure(
|
||||
now_z = 0
|
||||
now_x = 0
|
||||
|
||||
for cmd, delay in commands:
|
||||
for command in commands:
|
||||
coordinate = (now_x, now_y, now_z)
|
||||
struct.set_block(
|
||||
coordinate,
|
||||
form_command_block_in_NBT_struct(
|
||||
command=cmd,
|
||||
command=command.command_text,
|
||||
coordinate=coordinate,
|
||||
particularValue=(1 if y_forward else 0)
|
||||
if (
|
||||
((now_y != 0) and (not y_forward))
|
||||
or (y_forward and (now_y != (max_height - 1)))
|
||||
((now_y != 0) and (not y_forward))
|
||||
or (y_forward and (now_y != (max_height - 1)))
|
||||
)
|
||||
else (
|
||||
(3 if z_forward else 2)
|
||||
if (
|
||||
((now_z != 0) and (not z_forward))
|
||||
or (z_forward and (now_z != _sideLength - 1))
|
||||
((now_z != 0) and (not z_forward))
|
||||
or (z_forward and (now_z != _sideLength - 1))
|
||||
)
|
||||
else 5
|
||||
),
|
||||
impluse=2,
|
||||
condition=False,
|
||||
alwaysRun=True,
|
||||
tickDelay=delay,
|
||||
customName="",
|
||||
tickDelay=command.delay,
|
||||
customName=command.annotation_text,
|
||||
executeOnFirstTick=False,
|
||||
trackOutput=True,
|
||||
),
|
||||
@ -219,7 +233,7 @@ def commands_to_structure(
|
||||
now_z += 1 if z_forward else -1
|
||||
|
||||
if ((now_z >= _sideLength) and z_forward) or (
|
||||
(now_z < 0) and (not z_forward)
|
||||
(now_z < 0) and (not z_forward)
|
||||
):
|
||||
now_z -= 1 if z_forward else -1
|
||||
z_forward = not z_forward
|
||||
@ -234,4 +248,3 @@ def commands_to_structure(
|
||||
),
|
||||
(now_x, now_y, now_z),
|
||||
)
|
||||
|
||||
|
@ -1,13 +1,27 @@
|
||||
'''
|
||||
旧版本功能以及已经弃用的函数
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
旧版本转换功能以及已经弃用的函数
|
||||
"""
|
||||
|
||||
from .exceptions import *
|
||||
from .main import midiConvert
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
from ..exceptions import *
|
||||
from ..main import MidiConvert
|
||||
|
||||
|
||||
def to_command_list_method1(
|
||||
self: midiConvert,
|
||||
self: MidiConvert,
|
||||
scoreboard_name: str = "mscplay",
|
||||
MaxVolume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
@ -77,7 +91,7 @@ def to_command_list_method1(
|
||||
|
||||
# 原本这个算法的转换效果应该和上面的算法相似的
|
||||
def _toCmdList_m2(
|
||||
self: midiConvert,
|
||||
self: MidiConvert,
|
||||
scoreboard_name: str = "mscplay",
|
||||
MaxVolume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
@ -214,7 +228,7 @@ def _toCmdList_m2(
|
||||
|
||||
|
||||
def _toCmdList_withDelay_m1(
|
||||
self: midiConvert,
|
||||
self: MidiConvert,
|
||||
MaxVolume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
player: str = "@a",
|
||||
@ -288,7 +302,7 @@ def _toCmdList_withDelay_m1(
|
||||
|
||||
|
||||
def _toCmdList_withDelay_m2(
|
||||
self: midiConvert,
|
||||
self: MidiConvert,
|
||||
MaxVolume: float = 1.0,
|
||||
speed: float = 1.0,
|
||||
player: str = "@a",
|
@ -1,6 +1,20 @@
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
存储许多非主要的相关类
|
||||
'''
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
from dataclasses import dataclass
|
||||
@ -11,14 +25,20 @@ T = TypeVar("T") # Declare type variable
|
||||
|
||||
@dataclass(init=False)
|
||||
class SingleNote:
|
||||
"""存储单个音符的类"""
|
||||
|
||||
instrument: int
|
||||
"""乐器编号"""
|
||||
|
||||
note: int
|
||||
"""音符编号"""
|
||||
|
||||
velocity: int
|
||||
"""力度/响度"""
|
||||
|
||||
startTime: int
|
||||
"""开始之时 ms"""
|
||||
|
||||
lastTime: int
|
||||
"""音符持续时间 ms"""
|
||||
|
||||
@ -76,6 +96,80 @@ class SingleNote:
|
||||
}
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class SingleCommand:
|
||||
"""存储单个指令的类"""
|
||||
|
||||
command_text: str
|
||||
"""指令文本"""
|
||||
|
||||
conditional: bool
|
||||
"""执行是否有条件"""
|
||||
|
||||
delay: int
|
||||
"""执行的延迟"""
|
||||
|
||||
annotation_text: str
|
||||
"""指令注释"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
command: str,
|
||||
condition: bool = False,
|
||||
tick_delay: int = 0,
|
||||
annotation: str = "",
|
||||
):
|
||||
"""
|
||||
存储单个指令的类
|
||||
|
||||
Parameters
|
||||
----------
|
||||
command: str
|
||||
指令
|
||||
condition: bool
|
||||
是否有条件
|
||||
tick_delay: int
|
||||
执行延时
|
||||
annotation: str
|
||||
注释
|
||||
"""
|
||||
self.command_text = command
|
||||
self.conditional = condition
|
||||
self.delay = tick_delay
|
||||
self.annotation_text = annotation
|
||||
|
||||
def copy(self):
|
||||
return SingleCommand(
|
||||
command=self.command_text,
|
||||
condition=self.conditional,
|
||||
tick_delay=self.delay,
|
||||
annotation=self.annotation_text,
|
||||
)
|
||||
|
||||
@property
|
||||
def cmd(self) -> str:
|
||||
"""
|
||||
我的世界函数字符串(包含注释)
|
||||
"""
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""
|
||||
转为我的世界函数文件格式(包含注释)
|
||||
"""
|
||||
return "#[{cdt}]<{delay}> {ant}\n{cmd}".format(
|
||||
cdt="CDT" if self.conditional else "",
|
||||
delay=self.delay,
|
||||
ant=self.annotation_text,
|
||||
cmd=self.command_text,
|
||||
)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
return self.__str__() == other.__str__()
|
||||
|
||||
|
||||
class MethodList(list):
|
||||
"""函数列表,列表中的所有元素均为函数"""
|
||||
|
||||
|
@ -1,16 +1,30 @@
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
存放主程序所必须的功能性内容
|
||||
'''
|
||||
"""
|
||||
|
||||
"""
|
||||
版权所有 © 2023 音·创 开发者
|
||||
Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
def mctick2timestr(mc_tick: int):
|
||||
开源相关声明请见 仓库根目录下的 License.md
|
||||
Terms & Conditions: License.md in the root directory
|
||||
"""
|
||||
|
||||
# 睿穆组织 开发交流群 861684859
|
||||
# Email TriM-Organization@hotmail.com
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
from typing import Dict
|
||||
|
||||
def mctick2timestr(mc_tick: int) -> str:
|
||||
"""
|
||||
将《我的世界》的游戏刻计转为表示时间的字符串
|
||||
"""
|
||||
return str(int(int(mc_tick / 20) / 60)) + ":" + str(int(int(mc_tick / 20) % 60))
|
||||
|
||||
|
||||
def empty_midi_channels(channel_count: int = 17) -> dict:
|
||||
def empty_midi_channels(channel_count: int = 17) -> Dict[int, Dict]:
|
||||
"""
|
||||
空MIDI通道字典
|
||||
"""
|
||||
|
@ -10,19 +10,104 @@
|
||||
|
||||
# 库的简单调用
|
||||
|
||||
参见[example.py的相关部分](../example.py#L120),使用此库进行MIDI转换非常简单。
|
||||
参见[example.py的相关部分](../example.py),使用此库进行MIDI转换非常简单。
|
||||
|
||||
- 在导入转换库后,使用 MidiConvert 类建立转换对象(读取Midi文件)
|
||||
|
||||
音·创库支持新旧两种execute语法,需要在对象实例化时指定
|
||||
```python
|
||||
# 导入音·创库
|
||||
import Musicreater
|
||||
|
||||
# 指定是否使用旧的execute指令语法(即1.18及以前的《我的世界:基岩版》语法)
|
||||
old_execute_format = False
|
||||
|
||||
# 可以通过文件地址自动读取
|
||||
cvt_mid = Musicreater.MidiConvert.from_midi_file(
|
||||
"Midi文件地址",
|
||||
old_exe_format=old_execute_format
|
||||
)
|
||||
|
||||
# 也可以导入Mido对象
|
||||
cvt_mid = Musicreater.MidiConvert(
|
||||
mido.MidiFile("Midi文件地址"),
|
||||
"音乐名称",
|
||||
old_exe_format=old_execute_format
|
||||
)
|
||||
```
|
||||
|
||||
- 获取 Midi 音乐经转换后的播放指令
|
||||
|
||||
```python
|
||||
# 通过函数 to_command_list_in_score, to_command_list_in_delay
|
||||
# 分别可以得到
|
||||
# 以计分板作为播放器的指令对象列表、以延迟作为播放器的指令对象列表
|
||||
# 数据不仅存储在对象本身内,也会以返回值的形式返回,详见代码内文档
|
||||
|
||||
# 使用 to_command_list_in_score 函数进行转换之后,返回值有三个
|
||||
# 值得注意的是第一个返回值返回的是依照midi频道存储的指令对象列表
|
||||
# 也就是列表套列表
|
||||
# 但是,在对象内部所存储的数据却不会如此嵌套
|
||||
command_channel_list, command_count, max_score = cvt_mid.to_command_list_in_score(
|
||||
"计分板名称",
|
||||
1.0, # 音量比率
|
||||
1.0, # 速度倍率
|
||||
)
|
||||
|
||||
# 使用 to_command_list_in_delay 转换后的返回值只有两个
|
||||
# 但是第一个返回值没有列表套列表
|
||||
command_list, max_delay = cvt_mid.to_command_list_in_delay(
|
||||
1.0, # 音量比率
|
||||
1.0, # 速度倍率
|
||||
"@a", # 玩家选择器
|
||||
)
|
||||
|
||||
# 运行之后,指令和总延迟会存储至对象内
|
||||
print(
|
||||
"音乐长度:{}/游戏刻".format(
|
||||
cvt_mid.music_tick_num
|
||||
)
|
||||
)
|
||||
print(
|
||||
"指令如下:\n{}".format(
|
||||
cvt_mid.music_command_list
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
- 除了获取播放指令外,还可以获取进度条指令
|
||||
|
||||
```python
|
||||
# 通过函数 form_progress_bar 可以获得
|
||||
# 以计分板为载体所生成的进度条的指令对象列表
|
||||
# 数据不仅存储在对象本身内,也会以返回值的形式返回,详见代码内文档
|
||||
|
||||
# 使用 form_progress_bar 函数进行转换之后,返回值有三个
|
||||
# 值得注意的是第一个返回值返回的是依照midi频道存储的指令对象列表
|
||||
# 也就是列表套列表
|
||||
cvt_mid.form_progress_bar(
|
||||
max_score, # 音乐时长游戏刻
|
||||
scoreboard_name, # 进度条使用的计分板名称
|
||||
progressbar_style, # 进度条样式组(详见下方)
|
||||
)
|
||||
|
||||
# 同上面生成播放指令的理,进度条指令也混存储至对象内
|
||||
print(
|
||||
"进度条指令如下:\n{}".format(
|
||||
cvt_mid.progress_bar_command
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
在上面的代码中,进度条样式是可以自定义的,详见[下方说明](%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#进度条自定义)。
|
||||
|
||||
- 转换成指令是一个方面,接下来是再转换为可以导入MC的格式
|
||||
|
||||
***诶哟我好累不想写了,等有时间再写,你们就看样例程序的用法吧,无量天尊***
|
||||
|
||||
***这后面一直到下一个小节的内容全是没改的旧内容,肯定有问题***
|
||||
|
||||
```python
|
||||
import Musicreater # 导入转换库
|
||||
|
||||
old_execute_format = False # 指定是否使用旧的execute指令语法(即1.18及以前的《我的世界:基岩版》语法)
|
||||
|
||||
# 首先新建转换对象。
|
||||
conversion = Musicreater.midiConvert(enable_old_exe_format = old_execute_format)
|
||||
# 值得注意的是,一个转换对象可以转换多个文件。
|
||||
# 也就是在实例化的时候不进行对文件的绑定。
|
||||
# 如果有调试需要,可以在实例化时传入参数 debug = True
|
||||
# 如:conversion = Musicreater.midiConvert(debug=True)
|
||||
|
||||
# 设置输入输出地址,并指定execute指令语法
|
||||
# 地址都为字符串类型,不能传入文件流
|
||||
@ -51,7 +136,7 @@ convertion_result = conversion.to_BDX_file(method_id,*prompts)
|
||||
convertion_result = conversion.to_BDX_file_with_delay(method_id,*prompts)
|
||||
|
||||
# 转换结果是一个元组。
|
||||
# 若其转换成功,则前三位必为
|
||||
# 若其转换成功,则前二位必为
|
||||
# True, 指令数量, 最大延迟
|
||||
# 其中,最大延迟可以理解为计分板的最大值
|
||||
# 如果转换失败,暂时还没有定返回值的规则
|
||||
@ -101,11 +186,11 @@ print(convertion_result)
|
||||
|
||||
所以,结构的生成形状依照给定的高度和内含指令的数量决定。其 $Z$ 轴延伸长度为指令方块数量对于给定高度之商的向下取整结果的平方根的向下取整。用数学公式的方式表达,则是:
|
||||
|
||||
$$MaxZ = \left\lfloor\sqrt{\left\lfloor{\frac{NoC}{MaxH}}\right\rfloor}\right\rfloor$$
|
||||
$$ MaxZ = \left\lfloor\sqrt{\left\lfloor{\frac{NoC}{MaxH}}\right\rfloor}\right\rfloor $$
|
||||
|
||||
其中,$MaxZ$即生成结构的$Z$轴最大延伸长度,$NoC$表示链结构中所含指令方块的个数,$MaxH$表示给定的生成结构的最大高度。
|
||||
其中,$MaxZ$ 即生成结构的$Z$轴最大延伸长度,$NoC$ 表示链结构中所含指令方块的个数,$MaxH$ 表示给定的生成结构的最大高度。
|
||||
|
||||
我们的结构生成器在生成指令链时,将首先以相对坐标系 $(0, 0, 0)$ (即相对原点)开始,自下向上堆叠高度轴(即 $Y$ 轴)的长,当高度轴达到了限制的高度时,便将 $Z$ 轴向正方向堆叠`1`个方块,并开始自上向下重新堆叠,直至高度轴坐标达到相对为`0`。若当所生成结构的 $Z$ 轴长达到了其最大延伸长度,则此结构生成器将反转 $Z$ 轴的堆叠方向,直至 $Z$ 轴坐标相对为`0`。如此往复,直至指令链堆叠完成。
|
||||
我们的结构生成器在生成指令链时,将首先以相对坐标系 $(0, 0, 0)$ (即相对原点)开始,自下向上堆叠高度轴(即 $Y$ 轴)的长,当高度轴达到了限制的高度时,便将 $Z$ 轴向正方向堆叠`1`个方块,并开始自上向下重新堆叠,直至高度轴坐标达到相对为 `0`。若当所生成结构的 $Z$ 轴长达到了其最大延伸长度,则此结构生成器将反转 $Z$ 轴的堆叠方向,直至 $Z$ 轴坐标相对为 `0`。如此往复,直至指令链堆叠完成。
|
||||
|
||||
## 播放器
|
||||
|
||||
@ -200,5 +285,5 @@ print(convertion_result)
|
||||
|
||||
`(r'▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
|
||||
|
||||
*对了!为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
|
||||
*为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
|
||||
|
||||
|
@ -16,14 +16,24 @@
|
||||
|
||||
支持的文件后缀:`.MCPACK`
|
||||
|
||||
1. 导入附加包
|
||||
2. 在一个循环方块中输入指令 `function index`
|
||||
3. 将需要聆听音乐的实体的播放所用计分板设置为 `1`
|
||||
4. 激活循环方块
|
||||
5. 若想要暂停播放,可以停止循环指令方块的激活状态
|
||||
6. 若想要重置某实体的播放,可以将其播放用的计分板重置
|
||||
- 计分板播放器
|
||||
|
||||
> 其中 步骤三 和 步骤四 的顺序可以调换。
|
||||
1. 导入附加包
|
||||
2. 在一个循环方块中输入指令 `function index`
|
||||
3. 将需要聆听音乐的实体的播放所用计分板设置为 `1`
|
||||
4. 激活循环方块
|
||||
5. 若想要暂停播放,可以停止循环指令方块的激活状态
|
||||
6. 若想要重置某实体的播放,可以将其播放用的计分板重置
|
||||
|
||||
> 其中 步骤三 和 步骤四 的顺序可以调换。
|
||||
|
||||
- 延迟播放器
|
||||
|
||||
1. 导入附加包
|
||||
2. 在聊天框输入指令 `function index`
|
||||
3. 同时激活所生成的循环和脉冲指令方块
|
||||
|
||||
> 需要注意的是,循环指令方块需要一直激活直到音乐结束
|
||||
|
||||
## 结构格式
|
||||
|
||||
@ -41,7 +51,7 @@
|
||||
- 计分板播放器
|
||||
|
||||
2. 在所生成的第一个指令方块前,放置一个循环指令方块,其朝向应当对着所生成的第一个方块
|
||||
3. 在循环指令方块中输入使播放对象的播放用计分板加分的指令,延迟为`0`,每次循环增加`1`分
|
||||
3. 在循环指令方块中输入使播放对象的播放用计分板加分的指令,延迟为 `0`,每次循环增加 `1` 分
|
||||
4. 激活循环方块
|
||||
5. 若想要暂停播放,可以停止循环指令方块的激活状态
|
||||
6. 若想要重置某实体的播放,可以将其播放用的计分板重置
|
||||
|
198
docs/转换乐器对照表.md
198
docs/转换乐器对照表.md
@ -1,2 +1,198 @@
|
||||
**_注意!本文档中的对照表,版权归属于音·创作者,并按照本仓库根目录下 LICENSE.md 中规定开源_**
|
||||
|
||||
# 暂无
|
||||
**_使用时请遵循规定_**
|
||||
|
||||
- 版权所有 © 2023 音·创 开发者
|
||||
- Copyright © 2023 all the developers of Musicreater
|
||||
|
||||
* 开源相关声明请见 仓库根目录下的 License.md
|
||||
* Terms & Conditions: License.md in the root directory
|
||||
|
||||
音·创 开发交流群 861684859\
|
||||
Email TriM-Organization@hotmail.com\
|
||||
若需转载或借鉴 许可声明请查看仓库根目录下的 License.md
|
||||
|
||||
# 乐音乐器
|
||||
|
||||
| Midi 乐器值 | 我的世界音符名称 | 我的世界音调偏移参数 |
|
||||
| ----------- | ------------------- | -------------------- |
|
||||
| 0 | note.harp | 6 |
|
||||
| 1 | note.harp | 6 |
|
||||
| 2 | note.pling | 6 |
|
||||
| 3 | note.harp | 6 |
|
||||
| 4 | note.pling | 6 |
|
||||
| 5 | note.pling | 6 |
|
||||
| 6 | note.harp | 6 |
|
||||
| 7 | note.harp | 6 |
|
||||
| 8 | note.share | 7 |
|
||||
| 9 | note.harp | 6 |
|
||||
| 10 | note.didgeridoo | 8 |
|
||||
| 11 | note.harp | 6 |
|
||||
| 12 | note.xylophone | 4 |
|
||||
| 13 | note.chime | 4 |
|
||||
| 14 | note.harp | 6 |
|
||||
| 15 | note.harp | 6 |
|
||||
| 16 | note.bass | 8 |
|
||||
| 17 | note.harp | 6 |
|
||||
| 18 | note.harp | 6 |
|
||||
| 19 | note.harp | 6 |
|
||||
| 20 | note.harp | 6 |
|
||||
| 21 | note.harp | 6 |
|
||||
| 22 | note.harp | 6 |
|
||||
| 23 | note.guitar | 7 |
|
||||
| 24 | note.guitar | 7 |
|
||||
| 25 | note.guitar | 7 |
|
||||
| 26 | note.guitar | 7 |
|
||||
| 27 | note.guitar | 7 |
|
||||
| 28 | note.guitar | 7 |
|
||||
| 29 | note.guitar | 7 |
|
||||
| 30 | note.guitar | 7 |
|
||||
| 31 | note.bass | 8 |
|
||||
| 32 | note.bass | 8 |
|
||||
| 33 | note.bass | 8 |
|
||||
| 34 | note.bass | 8 |
|
||||
| 35 | note.bass | 8 |
|
||||
| 36 | note.bass | 8 |
|
||||
| 37 | note.bass | 8 |
|
||||
| 38 | note.bass | 8 |
|
||||
| 39 | note.bass | 8 |
|
||||
| 40 | note.harp | 6 |
|
||||
| 41 | note.harp | 6 |
|
||||
| 42 | note.harp | 6 |
|
||||
| 43 | note.harp | 6 |
|
||||
| 44 | note.iron_xylophone | 6 |
|
||||
| 45 | note.guitar | 7 |
|
||||
| 46 | note.harp | 6 |
|
||||
| 47 | note.harp | 6 |
|
||||
| 48 | note.guitar | 7 |
|
||||
| 49 | note.guitar | 7 |
|
||||
| 50 | note.bit | 6 |
|
||||
| 51 | note.bit | 6 |
|
||||
| 52 | note.harp | 6 |
|
||||
| 53 | note.harp | 6 |
|
||||
| 54 | note.bit | 6 |
|
||||
| 55 | note.flute | 5 |
|
||||
| 56 | note.flute | 5 |
|
||||
| 57 | note.flute | 5 |
|
||||
| 58 | note.flute | 5 |
|
||||
| 59 | note.flute | 5 |
|
||||
| 60 | note.flute | 5 |
|
||||
| 61 | note.flute | 5 |
|
||||
| 62 | note.flute | 5 |
|
||||
| 63 | note.flute | 5 |
|
||||
| 64 | note.bit | 6 |
|
||||
| 65 | note.bit | 6 |
|
||||
| 66 | note.bit | 6 |
|
||||
| 67 | note.bit | 6 |
|
||||
| 68 | note.flute | 5 |
|
||||
| 69 | note.harp | 6 |
|
||||
| 70 | note.harp | 6 |
|
||||
| 71 | note.flute | 5 |
|
||||
| 72 | note.flute | 5 |
|
||||
| 73 | note.flute | 5 |
|
||||
| 74 | note.harp | 6 |
|
||||
| 75 | note.flute | 5 |
|
||||
| 76 | note.harp | 6 |
|
||||
| 77 | note.harp | 6 |
|
||||
| 78 | note.harp | 6 |
|
||||
| 79 | note.harp | 6 |
|
||||
| 80 | note.bit | 6 |
|
||||
| 81 | note.bit | 6 |
|
||||
| 82 | note.bit | 6 |
|
||||
| 83 | note.bit | 6 |
|
||||
| 84 | note.bit | 6 |
|
||||
| 85 | note.bit | 6 |
|
||||
| 86 | note.bit | 6 |
|
||||
| 87 | note.bit | 6 |
|
||||
| 88 | note.bit | 6 |
|
||||
| 89 | note.bit | 6 |
|
||||
| 90 | note.bit | 6 |
|
||||
| 91 | note.bit | 6 |
|
||||
| 92 | note.bit | 6 |
|
||||
| 93 | note.bit | 6 |
|
||||
| 94 | note.bit | 6 |
|
||||
| 95 | note.bit | 6 |
|
||||
| 96 | note.bit | 6 |
|
||||
| 97 | note.bit | 6 |
|
||||
| 98 | note.bit | 6 |
|
||||
| 99 | note.bit | 6 |
|
||||
| 100 | note.bit | 6 |
|
||||
| 101 | note.bit | 6 |
|
||||
| 102 | note.bit | 6 |
|
||||
| 103 | note.bit | 6 |
|
||||
| 104 | note.harp | 6 |
|
||||
| 105 | note.banjo | 6 |
|
||||
| 106 | note.harp | 6 |
|
||||
| 107 | note.harp | 6 |
|
||||
| 108 | note.harp | 6 |
|
||||
| 109 | note.harp | 6 |
|
||||
| 110 | note.harp | 6 |
|
||||
| 111 | note.guitar | 7 |
|
||||
| 112 | note.harp | 6 |
|
||||
| 113 | note.bell | 4 |
|
||||
| 114 | note.harp | 6 |
|
||||
| 115 | note.cow_bell | 5 |
|
||||
| 116 | note.bd | 7 |
|
||||
| 117 | note.bass | 8 |
|
||||
| 118 | note.bit | 6 |
|
||||
| 119 | note.bd | 7 |
|
||||
| 120 | note.guitar | 7 |
|
||||
| 121 | note.harp | 6 |
|
||||
| 122 | note.harp | 6 |
|
||||
| 123 | note.harp | 6 |
|
||||
| 124 | note.harp | 6 |
|
||||
| 125 | note.hat | 7 |
|
||||
| 126 | note.bd | 7 |
|
||||
| 127 | note.snare | 7 |
|
||||
|
||||
# 打击乐器
|
||||
|
||||
| Midi 打击乐器值 | 我的世界音符名称 | 我的世界音调偏移参数 |
|
||||
| --------------- | ------------------- | -------------------- |
|
||||
| 34 | note.bd | 7 |
|
||||
| 35 | note.bd | 7 |
|
||||
| 36 | note.hat | 7 |
|
||||
| 37 | note.snare | 7 |
|
||||
| 38 | note.snare | 7 |
|
||||
| 39 | note.snare | 7 |
|
||||
| 40 | note.hat | 7 |
|
||||
| 41 | note.snare | 7 |
|
||||
| 42 | note.hat | 7 |
|
||||
| 43 | note.snare | 7 |
|
||||
| 44 | note.snare | 7 |
|
||||
| 45 | note.bell | 4 |
|
||||
| 46 | note.snare | 7 |
|
||||
| 47 | note.snare | 7 |
|
||||
| 48 | note.bell | 4 |
|
||||
| 49 | note.hat | 7 |
|
||||
| 50 | note.bell | 4 |
|
||||
| 51 | note.bell | 4 |
|
||||
| 52 | note.bell | 4 |
|
||||
| 53 | note.bell | 4 |
|
||||
| 54 | note.bell | 4 |
|
||||
| 55 | note.bell | 4 |
|
||||
| 56 | note.snare | 7 |
|
||||
| 57 | note.hat | 7 |
|
||||
| 58 | note.chime | 4 |
|
||||
| 59 | note.iron_xylophone | 6 |
|
||||
| 60 | note.bd | 7 |
|
||||
| 61 | note.bd | 7 |
|
||||
| 62 | note.xylophone | 4 |
|
||||
| 63 | note.xylophone | 4 |
|
||||
| 64 | note.xylophone | 4 |
|
||||
| 65 | note.hat | 7 |
|
||||
| 66 | note.bell | 4 |
|
||||
| 67 | note.bell | 4 |
|
||||
| 68 | note.hat | 7 |
|
||||
| 69 | note.hat | 7 |
|
||||
| 70 | note.flute | 5 |
|
||||
| 71 | note.flute | 5 |
|
||||
| 72 | note.hat | 7 |
|
||||
| 73 | note.hat | 7 |
|
||||
| 74 | note.xylophone | 4 |
|
||||
| 75 | note.hat | 7 |
|
||||
| 76 | note.hat | 7 |
|
||||
| 77 | note.xylophone | 4 |
|
||||
| 78 | note.xylophone | 4 |
|
||||
| 79 | note.bell | 4 |
|
||||
| 80 | note.bell | 4 |
|
||||
|
69
example.py
69
example.py
@ -17,8 +17,12 @@ Terms & Conditions: ./License.md
|
||||
"""
|
||||
|
||||
import os
|
||||
import Musicreater
|
||||
|
||||
import Musicreater
|
||||
from Musicreater.plugin import ConvertConfig
|
||||
from Musicreater.plugin.bdxfile import to_BDX_file_in_delay, to_BDX_file_in_score
|
||||
from Musicreater.plugin.funcpack import to_function_addon_in_score
|
||||
from Musicreater.plugin.mcstructpack import to_mcstructure_addon_in_delay
|
||||
|
||||
# 获取midi列表
|
||||
midi_path = input(f"请输入MIDI路径:")
|
||||
@ -27,17 +31,6 @@ midi_path = input(f"请输入MIDI路径:")
|
||||
# 获取输出地址
|
||||
out_path = input(f"请输入输出路径:")
|
||||
|
||||
conversion = Musicreater.midiConvert()
|
||||
|
||||
|
||||
def isMethodOK(sth: str):
|
||||
if int(sth) in range(1, len(conversion.methods) + 1):
|
||||
return int(sth)
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
|
||||
convert_method = int(input(f"请输入转换算法[1~{len(conversion.methods)}]:"))
|
||||
|
||||
# 选择输出格式
|
||||
fileFormat = int(input(f"请输入输出格式[BDX(1) 或 MCPACK(0)]:").lower())
|
||||
@ -57,14 +50,10 @@ def bool_str(sth: str) -> bool:
|
||||
raise ValueError("布尔字符串啊?")
|
||||
|
||||
|
||||
debug = False
|
||||
|
||||
if os.path.exists("./demo_config.json"):
|
||||
import json
|
||||
|
||||
prompts = json.load(open("./demo_config.json", "r", encoding="utf-8"))
|
||||
if prompts[-1] == "debug":
|
||||
debug = True
|
||||
prompts = prompts[:-1]
|
||||
else:
|
||||
prompts = []
|
||||
@ -103,45 +92,39 @@ else:
|
||||
)
|
||||
if fileFormat == 1
|
||||
else (),
|
||||
(
|
||||
()
|
||||
if playerFormat == 1
|
||||
else (
|
||||
f"最大结构高度:",
|
||||
int,
|
||||
)
|
||||
if fileFormat == 1
|
||||
else (),
|
||||
),
|
||||
]:
|
||||
if args:
|
||||
prompts.append(args[1](input(args[0])))
|
||||
|
||||
conversion = Musicreater.midiConvert(debug=debug, enable_old_exe_format=False)
|
||||
|
||||
|
||||
print(f"正在处理 {midi_path} :")
|
||||
conversion.convert(midi_path, out_path)
|
||||
if debug:
|
||||
with open("./records.json", "a", encoding="utf-8") as f:
|
||||
json.dump(conversion.toDICT(), f)
|
||||
f.write(5 * "\n")
|
||||
conversion_result = (
|
||||
(
|
||||
conversion.to_mcpack(convert_method, *prompts)
|
||||
if playerFormat == 1
|
||||
else conversion.to_mcpack_with_delay(convert_method, *prompts)
|
||||
cvt_mid = Musicreater.MidiConvert.from_midi_file(midi_path, old_exe_format=False)
|
||||
cvt_cfg = ConvertConfig(out_path, *prompts[:3])
|
||||
|
||||
print(
|
||||
" 指令总长:{},最高延迟:{}".format(
|
||||
*(
|
||||
to_function_addon_in_score(cvt_mid, cvt_cfg, *prompts[3:])
|
||||
if playerFormat == 1
|
||||
else to_mcstructure_addon_in_delay(cvt_mid, cvt_cfg, *prompts[3:])
|
||||
)
|
||||
)
|
||||
if fileFormat == 0
|
||||
else (
|
||||
conversion.to_BDX_file(convert_method, *prompts)
|
||||
if playerFormat == 1
|
||||
else conversion.to_BDX_file_with_delay(convert_method, *prompts)
|
||||
) if fileFormat == 0 else print(
|
||||
" 指令总长:{},最高延迟:{},结构大小{},终点坐标{}".format(
|
||||
*(
|
||||
to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:])
|
||||
if playerFormat == 1
|
||||
else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:])
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if conversion_result[0]:
|
||||
print(
|
||||
f" 指令总长:{conversion_result[1]},最高延迟:{conversion_result[2]}{f''',结构大小{conversion_result[3]},最末坐标{conversion_result[4]}''' if fileFormat == 1 else ''}"
|
||||
)
|
||||
else:
|
||||
print(f"失败:{conversion_result}")
|
||||
|
||||
exitSth = input("回车退出").lower()
|
||||
if exitSth == "record":
|
||||
|
@ -1,8 +1,12 @@
|
||||
from Musicreater import midiConvert
|
||||
import Musicreater
|
||||
import Musicreater.plugin
|
||||
import Musicreater.plugin.mcstructfile
|
||||
|
||||
conversion = midiConvert(enable_old_exe_format=False)
|
||||
conversion.convert(input("midi路径:"), input("输出路径:"))
|
||||
|
||||
conversion.to_mcstructure_file_with_delay(
|
||||
3,
|
||||
print(
|
||||
Musicreater.plugin.mcstructfile.to_mcstructure_file_in_delay(
|
||||
Musicreater.MidiConvert.from_midi_file(input("midi路径:"), old_exe_format=False),
|
||||
Musicreater.plugin.ConvertConfig(
|
||||
input("输出路径:"),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user