我的通义灵码罢工了,没有内联建议,我也要罢工

This commit is contained in:
2026-02-13 19:19:08 +08:00
parent 62cd4a0c94
commit bbc67921d6
7 changed files with 128 additions and 31 deletions

View File

@@ -17,4 +17,9 @@ Terms & Conditions: License.md in the root directory
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from .main import MidiImportConfig, MidiImport2MusicPlugin
from .main import MidiImportConfig, MidiImport2MusicPlugin
__all__ = [
"MidiImportConfig",
"MidiImport2MusicPlugin",
]

View File

@@ -41,7 +41,6 @@ from .constants import (
MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
)
from .exceptions import (
MidiFormatError,
NoteOnOffMismatchError,
ChannelOverFlowError,
LyricMismatchError,

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 指令生成插件
"""
"""
版权所有 © 2026 金羿、玉衡Alioth
Copyright © 2026 Eilles, YuhengAlioth
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from .main import CommandConvertionConfig, NoteDataConvert2CommandPlugin
__all__ = [
"CommandConvertionConfig",
"NoteDataConvert2CommandPlugin",
]

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 指令生成插件
"""
"""
版权所有 © 2026 金羿、玉衡Alioth
Copyright © 2026 Eilles, YuhengAlioth
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import BinaryIO, Optional, Dict, List, Callable, Tuple, Mapping
from Musicreater import SingleMusic, SingleTrack, SingleNote, SoundAtmos
from Musicreater.plugins import (
library_plugin,
PluginConfig,
PluginMetaInformation,
PluginTypes,
LibraryPluginBase,
)
from Musicreater.exceptions import ZeroSpeedError, IllegalMinimumVolumeError
from Musicreater._utils import enumerated_stuffcopy_dictionary
@dataclass
class CommandConvertionConfig(PluginConfig): ...
@library_plugin("notedata_2_command_plugin")
class NoteDataConvert2CommandPlugin(LibraryPluginBase):
metainfo = PluginMetaInformation(
name="音符数据指令支持插件",
author="金羿、玉衡Alioth",
description="从音符数据转换为我的世界指令相关格式",
version=(0, 0, 1),
type=PluginTypes.LIBRARY,
license="Same as Musicreater",
)

View File

@@ -225,12 +225,19 @@ class PluginLoadError(MusicreaterOuterlyError):
super().__init__("插件加载错误 - ", *args)
class PluginDependencyNotFound(PluginLoadError):
"""插件依赖未找到"""
def __init__(self, *args):
super().__init__("未找到所需的插件依赖:", *args)
class PluginNotFoundError(PluginLoadError):
"""插件未找到"""
def __init__(self, *args):
"""插件未找到"""
super().__init__("插件未找到", *args)
super().__init__("无法找到插件:", *args)
class PluginRegisteredError(PluginLoadError):

View File

@@ -33,6 +33,7 @@ from typing import (
TypeVar,
Mapping,
Callable,
Type,
)
from itertools import chain
@@ -61,6 +62,7 @@ from .exceptions import (
PluginInstanceNotFoundError,
PluginRegisteredError,
PluginNotFoundError,
PluginDependencyNotFound,
)
@@ -147,6 +149,7 @@ class PluginRegistry:
self._track_output_plugins: Dict[str, TrackOutputPluginBase] = {}
self._service_plugins: Dict[str, ServicePluginBase] = {}
self._library_plugins: Dict[str, LibraryPluginBase] = {}
self._all_plugin_id: List = []
def __iter__(self) -> Iterator[Tuple[PluginTypes, Mapping[str, TopPluginBase]]]:
"""迭代器,返回所有插件"""
@@ -163,23 +166,25 @@ class PluginRegistry:
)
)
@staticmethod
def _register_plugin(cls_dict: dict, plg_class: type, plg_id: str) -> None:
def _register_plugin(
self, cls_dict: dict, plg_class: Type[TopPluginBase], plg_id: str
) -> None:
"""注册插件"""
if plg_id in cls_dict:
if cls_dict[plg_id].metainfo.version >= plg_class.metainfo.version:
raise PluginRegisteredError(
"插件惟一识别码`{}`所对应的插件已存在更高版本`{}`,请勿重复注册同一插件".format(
"插件惟一识别码`{}`所对应的插件已存在更高版本`{}`,请勿重复注册同一插件".format(
plg_id, plg_class.metainfo
)
)
if (i for i in plg_class.metainfo.dependencies if i not in self._all_plugin_id):
raise PluginDependencyNotFound(
"插件 `{}` 依赖于这些插件:`{}`。载入此插件时,请务必将后者提前载入。"
)
cls_dict[plg_id] = plg_class()
self._all_plugin_id.append(plg_id)
def register_music_input_plugin(
self,
plugin_class: type,
plugin_id: str,
) -> None:
def register_music_input_plugin(self, plugin_class: type, plugin_id: str) -> None:
"""注册输入插件-整首曲目"""
self._register_plugin(self._music_input_plugins, plugin_class, plugin_id)

View File

@@ -37,14 +37,17 @@ from itertools import chain
import mido
from Musicreater.constants import *
from Musicreater.exceptions import IllegalMinimumVolumeError, NoteBinaryFileVerificationFailed as MusicSequenceVerificationFailed, SingleNoteDecodeError, NoteBinaryFileTypeError as MusicSequenceTypeError, ZeroSpeedError
from Musicreater.builtin_plugins.midi_read.constants import MIDI_DEFAULT_PROGRAM_VALUE, MIDI_DEFAULT_VOLUME_VALUE, MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE, MM_TOUCH_PITCHED_INSTRUMENT_TABLE
from Musicreater.builtin_plugins.midi_read.exceptions import NoteOnOffMismatchError, LyricMismatchError
from Musicreater.builtin_plugins.midi_read.utils import volume_2_distance_natural, panning_2_rotation_trigonometric, panning_2_rotation_linear
from .old_exceptions import *
from .subclass import *
from .old_types import *
from .utils import *
from Musicreater.builtin_plugins.midi_read.constants import *
from Musicreater.builtin_plugins.midi_read.utils import *
from .old_utils import *
"""
学习笔记:
tempo: microseconds per quarter note 毫秒每四分音符,换句话说就是一拍占多少微秒
@@ -78,6 +81,10 @@ tick * tempo / 1000000.0 / ticks_per_beat * 一秒多少游戏刻
"""
MIDI_PAN = "midi-pan"
MIDI_PROGRAM = "midi-program"
MIDI_VOLUME = "midi-volume"
@dataclass(init=False)
class MusicSequence:
@@ -273,7 +280,7 @@ class MusicSequence:
8 : (stt_index := 8 + (group_1 >> 10))
].decode("GB18030")
channels_: MineNoteChannelType = enumerated_stuff_copy(staff=[])
channels_: MineNoteChannelType = enumerated_stuffcopy_dictionary(staff=[])
total_note_count = 0
if verify:
_header_index = stt_index
@@ -310,9 +317,9 @@ class MusicSequence:
stt_index = end_index
except Exception as _err:
# print(channels_)
raise MusicSequenceDecodeError(
_err, "当前全部通道数据:", channels_
)
raise SingleNoteDecodeError(
"当前全部通道数据:", channels_
) from _err
if verify:
if (
_count_verify := xxh3_64(
@@ -415,7 +422,7 @@ class MusicSequence:
_t6_buffer = _t2_buffer = 0
_channel_inst_chart: Dict[str, Dict[str, int]] = {}
channels_: MineNoteChannelType = enumerated_stuff_copy(staff=[])
channels_: MineNoteChannelType = enumerated_stuffcopy_dictionary(staff=[])
for i in range(total_note_count):
if verify:
@@ -468,9 +475,9 @@ class MusicSequence:
stt_index = end_index
except Exception as _err:
# print(bytes_buffer_in[stt_index:end_index])
raise MusicSequenceDecodeError(
_err, "所截取的音符码:", bytes_buffer_in[stt_index:end_index]
)
raise SingleNoteDecodeError(
"所截取的音符码:", bytes_buffer_in[stt_index:end_index]
) from _err
if _read_note.sound_name in _channel_inst_chart:
_channel_inst_chart[_read_note.sound_name]["CNT"] += 1
@@ -525,7 +532,7 @@ class MusicSequence:
music_name_ = bytes_buffer_in[
8 : (stt_index := 8 + (group_1 >> 10))
].decode("GB18030")
channels_: MineNoteChannelType = enumerated_stuff_copy(staff=[])
channels_: MineNoteChannelType = enumerated_stuffcopy_dictionary(staff=[])
for channel_index in channels_.keys():
for i in range(
int.from_bytes(
@@ -568,7 +575,7 @@ class MusicSequence:
music_name_ = bytes_buffer_in[
8 : (stt_index := 8 + (group_1 >> 10))
].decode("utf-8")
channels_: MineNoteChannelType = enumerated_stuff_copy(staff=[])
channels_: MineNoteChannelType = enumerated_stuffcopy_dictionary(staff=[])
for channel_index in channels_.keys():
for i in range(
int.from_bytes(
@@ -860,9 +867,9 @@ class MusicSequence:
raise ZeroSpeedError("播放速度不得为零,应为 (0,1] 范围内的实数。")
# 一个midi中仅有16个通道 我们通过通道来识别而不是音轨
midi_channels: MineNoteChannelType = enumerated_stuff_copy(staff=[])
midi_channels: MineNoteChannelType = enumerated_stuffcopy_dictionary(staff=[])
channel_controler: Dict[int, Dict[str, int]] = enumerated_stuff_copy(
channel_controler: Dict[int, Dict[str, int]] = enumerated_stuffcopy_dictionary(
staff={
MIDI_PROGRAM: default_program_value,
MIDI_VOLUME: default_volume_value,
@@ -883,7 +890,7 @@ class MusicSequence:
int,
]
],
] = enumerated_stuff_copy(staff=[])
] = enumerated_stuffcopy_dictionary(staff=[])
note_queue_B: Dict[
int,
List[
@@ -892,7 +899,7 @@ class MusicSequence:
int,
]
],
] = enumerated_stuff_copy(staff=[])
] = enumerated_stuffcopy_dictionary(staff=[])
lyric_cache: List[Tuple[int, str]] = []
@@ -973,7 +980,7 @@ class MusicSequence:
# 更新结果信息
midi_channels[msg.channel].append(
that_note := midi_msgs_to_minenote(
that_note := midi_msgs_to_minenote( # 无法强行兼容了pass
inst_=(
msg.note
if (_is_percussion := (msg.channel == 9))