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

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 # 若需转载或借鉴 许可声明请查看仓库目录下的 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, MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
) )
from .exceptions import ( from .exceptions import (
MidiFormatError,
NoteOnOffMismatchError, NoteOnOffMismatchError,
ChannelOverFlowError, ChannelOverFlowError,
LyricMismatchError, 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) super().__init__("插件加载错误 - ", *args)
class PluginDependencyNotFound(PluginLoadError):
"""插件依赖未找到"""
def __init__(self, *args):
super().__init__("未找到所需的插件依赖:", *args)
class PluginNotFoundError(PluginLoadError): class PluginNotFoundError(PluginLoadError):
"""插件未找到""" """插件未找到"""
def __init__(self, *args): def __init__(self, *args):
"""插件未找到""" """插件未找到"""
super().__init__("插件未找到", *args) super().__init__("无法找到插件:", *args)
class PluginRegisteredError(PluginLoadError): class PluginRegisteredError(PluginLoadError):

View File

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

View File

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