mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2025-02-07 19:36:46 +08:00
bug fixed
This commit is contained in:
parent
032bbb81c4
commit
8b9d9a78a3
17
magicDemo.py
17
magicDemo.py
@ -92,20 +92,17 @@ except ModuleNotFoundError as E:
|
|||||||
try:
|
try:
|
||||||
from msctPkgver.magicBeing import *
|
from msctPkgver.magicBeing import *
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
# import zhdate
|
|
||||||
except ModuleNotFoundError as E:
|
except ModuleNotFoundError as E:
|
||||||
if input(
|
if input(
|
||||||
"您需要安装以下模块才能使用这个样例\nrequests==2.28.1\nrich==12.6.0\nzhdate==0.1\n请问是否安装?(y/n):"
|
"您需要安装以下模块才能使用这个样例\nrequests==2.28.1\nrich==12.6.0\nzhdate==0.1\n请问是否安装?(y/n):"
|
||||||
).lower() in ("y", "1"):
|
).lower() in ("y", "1"):
|
||||||
open("Demo_Requirements.txt", "w").write(
|
open("Demo_Requirements.txt", "w").write(
|
||||||
"requests==2.28.1\nrich==12.6.0\nzhdate==0.1"
|
"requests==2.28.1\nrich==12.6.0"
|
||||||
)
|
)
|
||||||
os.system("pip install -r Demo_Requirements.txt")
|
os.system("pip install -r Demo_Requirements.txt")
|
||||||
os.remove("./Demo_Requirements.txt")
|
os.remove("./Demo_Requirements.txt")
|
||||||
from rich.console import Console
|
from msctPkgver.magicBeing import *
|
||||||
import requests
|
import requests
|
||||||
import zhdate
|
|
||||||
else:
|
else:
|
||||||
raise E
|
raise E
|
||||||
|
|
||||||
@ -172,7 +169,7 @@ def format_ipt(
|
|||||||
try:
|
try:
|
||||||
fun_result = fun(result, *extraArg)
|
fun_result = fun(result, *extraArg)
|
||||||
break
|
break
|
||||||
except BaseError:
|
except ValueError:
|
||||||
prt(err_note)
|
prt(err_note)
|
||||||
continue
|
continue
|
||||||
return result, fun_result
|
return result, fun_result
|
||||||
@ -239,13 +236,13 @@ debug = False
|
|||||||
def bool_str(sth: str) -> bool:
|
def bool_str(sth: str) -> bool:
|
||||||
try:
|
try:
|
||||||
return bool(int(sth))
|
return bool(int(sth))
|
||||||
except BaseError:
|
except ValueError:
|
||||||
if str(sth).lower() == "true":
|
if str(sth).lower() == "true":
|
||||||
return True
|
return True
|
||||||
elif str(sth).lower() == "false":
|
elif str(sth).lower() == "false":
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
raise "布尔字符串啊?"
|
raise ValueError("布尔字符串啊?")
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists("./demo_config.json"):
|
if os.path.exists("./demo_config.json"):
|
||||||
@ -314,9 +311,9 @@ for singleMidi in midis:
|
|||||||
conversion.to_mcpack(2, *prompts)
|
conversion.to_mcpack(2, *prompts)
|
||||||
if fileFormat == 0
|
if fileFormat == 0
|
||||||
else (
|
else (
|
||||||
conversion.toBDXfile(2, *prompts)
|
conversion.to_BDX_file(2, *prompts)
|
||||||
if playerFormat == 1
|
if playerFormat == 1
|
||||||
else conversion.toBDXfile_withDelay(2, *prompts)
|
else conversion.to_BDX_file_with_delay(2, *prompts)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,9 +65,3 @@ class NotDefineProgramError(MSCTBaseException):
|
|||||||
"""没有Program设定导致没有乐器可以选择的错误"""
|
"""没有Program设定导致没有乐器可以选择的错误"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BaseError(BaseException):
|
|
||||||
"""专门骗过PEP8的错误"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from exceptions import *
|
from .exceptions import *
|
||||||
from typing import Any, Literal, Optional, TextIO
|
from typing import Any, Literal, Optional, TextIO
|
||||||
|
|
||||||
MainConsole = Console()
|
MainConsole = Console()
|
||||||
@ -138,10 +138,11 @@ def format_ipt(
|
|||||||
*extraArg: 对于函数的其他参数"""
|
*extraArg: 对于函数的其他参数"""
|
||||||
while True:
|
while True:
|
||||||
result = ipt(notice)
|
result = ipt(notice)
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
fun_result = fun(result, *extraArg)
|
fun_result = fun(result, *extraArg)
|
||||||
break
|
break
|
||||||
except BaseError:
|
except:
|
||||||
prt(err_note)
|
prt(err_note)
|
||||||
continue
|
continue
|
||||||
return result, fun_result
|
return result, fun_result
|
||||||
|
@ -139,7 +139,7 @@ class midiConvert:
|
|||||||
self.midFileName: str = ""
|
self.midFileName: str = ""
|
||||||
self.exeHead = ""
|
self.exeHead = ""
|
||||||
self.methods = MethodList(
|
self.methods = MethodList(
|
||||||
[self._toCmdList_m1(), self._toCmdList_m2(), self._toCmdList_m3()]
|
[self._toCmdList_m1, self._toCmdList_m2, self._toCmdList_m3]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.methods_byDelay = MethodList(
|
self.methods_byDelay = MethodList(
|
||||||
@ -325,7 +325,7 @@ class midiConvert:
|
|||||||
126: ("note.bd", 7), # 打击乐器无音域
|
126: ("note.bd", 7), # 打击乐器无音域
|
||||||
127: ("note.snare", 7), # 打击乐器无音域
|
127: ("note.snare", 7), # 打击乐器无音域
|
||||||
}[instrumentID]
|
}[instrumentID]
|
||||||
except BaseError:
|
except KeyError:
|
||||||
a = ("note.flute", 5)
|
a = ("note.flute", 5)
|
||||||
return a
|
return a
|
||||||
|
|
||||||
@ -382,9 +382,9 @@ class midiConvert:
|
|||||||
79: ("note.bell", 4),
|
79: ("note.bell", 4),
|
||||||
80: ("note.bell", 4),
|
80: ("note.bell", 4),
|
||||||
}[instrumentID]
|
}[instrumentID]
|
||||||
except BaseError:
|
except KeyError:
|
||||||
return "note.bd", 7
|
return "note.bd", 7
|
||||||
except BaseError:
|
except KeyError:
|
||||||
print("WARN", "无法使用打击乐器列表库,可能是不支持当前环境,打击乐器使用Dislink算法代替。")
|
print("WARN", "无法使用打击乐器列表库,可能是不支持当前环境,打击乐器使用Dislink算法代替。")
|
||||||
if instrumentID == 55:
|
if instrumentID == 55:
|
||||||
return "note.cow_bell", 5
|
return "note.cow_bell", 5
|
||||||
@ -433,14 +433,6 @@ class midiConvert:
|
|||||||
if r"%^t" in pgs_style:
|
if r"%^t" in pgs_style:
|
||||||
pgs_style = pgs_style.replace(r"%^t", self.__score2time(maxscore))
|
pgs_style = pgs_style.replace(r"%^t", self.__score2time(maxscore))
|
||||||
|
|
||||||
def replaceBar(_i):
|
|
||||||
try:
|
|
||||||
return pgs_style.replace("_", progressbar[1][0], _i + 1).replace(
|
|
||||||
"_", progressbar[1][1]
|
|
||||||
)
|
|
||||||
except BaseError:
|
|
||||||
return pgs_style.replace("_", progressbar[1][0], _i + 1)
|
|
||||||
|
|
||||||
sbn_pc = scoreboard_name[:2]
|
sbn_pc = scoreboard_name[:2]
|
||||||
if r"%%%" in pgs_style:
|
if r"%%%" in pgs_style:
|
||||||
result.append(
|
result.append(
|
||||||
@ -531,9 +523,13 @@ class midiConvert:
|
|||||||
|
|
||||||
for i in range(pgs_style.count("_")):
|
for i in range(pgs_style.count("_")):
|
||||||
npg_stl = (
|
npg_stl = (
|
||||||
replaceBar(i).replace(r"%%N", self.midFileName)
|
pgs_style.replace("_", progressbar[1][0], i + 1)
|
||||||
|
.replace("_", progressbar[1][1])
|
||||||
|
.replace(r"%%N", self.midFileName)
|
||||||
if r"%%N" in pgs_style
|
if r"%%N" in pgs_style
|
||||||
else replaceBar(i)
|
else pgs_style.replace("_", progressbar[1][0], i + 1).replace(
|
||||||
|
"_", progressbar[1][1]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if r"%%s" in npg_stl:
|
if r"%%s" in npg_stl:
|
||||||
npg_stl = npg_stl.replace(
|
npg_stl = npg_stl.replace(
|
||||||
@ -545,9 +541,9 @@ class midiConvert:
|
|||||||
if r"%%%" in npg_stl:
|
if r"%%%" in npg_stl:
|
||||||
npg_stl = npg_stl.replace(
|
npg_stl = npg_stl.replace(
|
||||||
r"%%%",
|
r"%%%",
|
||||||
'"},{"score":{"name":"*","objective":"'
|
r'"},{"score":{"name":"*","objective":"'
|
||||||
+ sbn_pc
|
+ sbn_pc
|
||||||
+ 'PercT"}},{"text":"%',
|
+ r'PercT"}},{"text":"%',
|
||||||
)
|
)
|
||||||
if r"%%t" in npg_stl:
|
if r"%%t" in npg_stl:
|
||||||
npg_stl = npg_stl.replace(
|
npg_stl = npg_stl.replace(
|
||||||
@ -559,10 +555,10 @@ class midiConvert:
|
|||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
self.exeHead.format(
|
self.exeHead.format(
|
||||||
"@a[scores={"
|
r"@a[scores={"
|
||||||
+ scoreboard_name
|
+ scoreboard_name
|
||||||
+ f"={int(i * perEach)}..{math.ceil((i + 1) * perEach)}"
|
+ f"={int(i * perEach)}..{math.ceil((i + 1) * perEach)}"
|
||||||
+ "}]"
|
+ r"}]"
|
||||||
)
|
)
|
||||||
+ r'titleraw @s actionbar {"rawtext":[{"text":"'
|
+ r'titleraw @s actionbar {"rawtext":[{"text":"'
|
||||||
+ npg_stl
|
+ npg_stl
|
||||||
@ -710,7 +706,7 @@ class midiConvert:
|
|||||||
try:
|
try:
|
||||||
if msg.channel > 15:
|
if msg.channel > 15:
|
||||||
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
||||||
except BaseError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if msg.type == "program_change":
|
if msg.type == "program_change":
|
||||||
@ -839,14 +835,12 @@ class midiConvert:
|
|||||||
tempo = msg.tempo
|
tempo = msg.tempo
|
||||||
else:
|
else:
|
||||||
|
|
||||||
try:
|
if self.debugMode:
|
||||||
# msg.channel
|
try:
|
||||||
channelMsg = True
|
if msg.channel > 15:
|
||||||
except BaseError:
|
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
||||||
channelMsg = False
|
except AttributeError:
|
||||||
if channelMsg:
|
pass
|
||||||
if msg.channel > 15:
|
|
||||||
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
|
||||||
|
|
||||||
if msg.type == "program_change":
|
if msg.type == "program_change":
|
||||||
channels[msg.channel].append(
|
channels[msg.channel].append(
|
||||||
@ -1027,7 +1021,7 @@ class midiConvert:
|
|||||||
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg.velocity / 128} "
|
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg.velocity / 128} "
|
||||||
f"{2 ** ((msg.note - 60 - _X) / 12)}"
|
f"{2 ** ((msg.note - 60 - _X) / 12)}"
|
||||||
)
|
)
|
||||||
except BaseError:
|
except KeyError:
|
||||||
tracks[now_tick] = [
|
tracks[now_tick] = [
|
||||||
self.exeHead.format(player)
|
self.exeHead.format(player)
|
||||||
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg.velocity / 128} "
|
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg.velocity / 128} "
|
||||||
@ -1121,7 +1115,7 @@ class midiConvert:
|
|||||||
try:
|
try:
|
||||||
if msg.channel > 15:
|
if msg.channel > 15:
|
||||||
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
raise ChannelOverFlowError(f"当前消息 {msg} 的通道超限(≤15)")
|
||||||
except BaseError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if msg.type == "program_change":
|
if msg.type == "program_change":
|
||||||
@ -1190,7 +1184,7 @@ class midiConvert:
|
|||||||
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg[2] / 128} "
|
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg[2] / 128} "
|
||||||
f"{2 ** ((msg[1] - 60 - _X) / 12)}"
|
f"{2 ** ((msg[1] - 60 - _X) / 12)}"
|
||||||
)
|
)
|
||||||
except BaseError:
|
except KeyError:
|
||||||
tracks[score_now] = [
|
tracks[score_now] = [
|
||||||
self.exeHead.format(player)
|
self.exeHead.format(player)
|
||||||
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg[2] / 128} "
|
+ f"playsound {soundID} @s ^ ^ ^{1 / MaxVolume - 1} {msg[2] / 128} "
|
||||||
@ -1225,7 +1219,7 @@ class midiConvert:
|
|||||||
method: int = 1,
|
method: int = 1,
|
||||||
volume: float = 1.0,
|
volume: float = 1.0,
|
||||||
speed: float = 1.0,
|
speed: float = 1.0,
|
||||||
progressbar=None,
|
progressbar: Union[bool, tuple] = None,
|
||||||
scoreboard_name: str = "mscplay",
|
scoreboard_name: str = "mscplay",
|
||||||
isAutoReset: bool = False,
|
isAutoReset: bool = False,
|
||||||
) -> tuple:
|
) -> tuple:
|
||||||
@ -1350,7 +1344,7 @@ class midiConvert:
|
|||||||
|
|
||||||
if os.path.exists(f"{self.outputPath}/{self.midFileName}.mcpack"):
|
if os.path.exists(f"{self.outputPath}/{self.midFileName}.mcpack"):
|
||||||
os.remove(f"{self.outputPath}/{self.midFileName}.mcpack")
|
os.remove(f"{self.outputPath}/{self.midFileName}.mcpack")
|
||||||
makeZip(
|
compressZipFile(
|
||||||
f"{self.outputPath}/temp/", f"{self.outputPath}/{self.midFileName}.mcpack"
|
f"{self.outputPath}/temp/", f"{self.outputPath}/{self.midFileName}.mcpack"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1358,7 +1352,7 @@ class midiConvert:
|
|||||||
|
|
||||||
return True, maxlen, maxscore
|
return True, maxlen, maxscore
|
||||||
|
|
||||||
def toBDXfile(
|
def to_BDX_file(
|
||||||
self,
|
self,
|
||||||
method: int = 1,
|
method: int = 1,
|
||||||
volume: float = 1.0,
|
volume: float = 1.0,
|
||||||
@ -1418,12 +1412,12 @@ class midiConvert:
|
|||||||
+ scoreboard_name,
|
+ scoreboard_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
cmdBytes, size, finalPos = toBDX_bytes(
|
cmdBytes, size, finalPos = to_BDX_bytes(
|
||||||
[(i, 0) for i in commands], max_height - 1
|
[(i, 0) for i in commands], max_height - 1
|
||||||
)
|
)
|
||||||
# 此处是对于仅有 True 的参数和自定义参数的判断
|
# 此处是对于仅有 True 的参数和自定义参数的判断
|
||||||
if progressbar:
|
if progressbar:
|
||||||
pgbBytes, pgbSize, pgbNowPos = toBDX_bytes(
|
pgbBytes, pgbSize, pgbNowPos = to_BDX_bytes(
|
||||||
[
|
[
|
||||||
(i, 0)
|
(i, 0)
|
||||||
for i in (
|
for i in (
|
||||||
@ -1455,12 +1449,12 @@ class midiConvert:
|
|||||||
|
|
||||||
return True, total_count, maxScore, size, finalPos
|
return True, total_count, maxScore, size, finalPos
|
||||||
|
|
||||||
def toBDXfile_withDelay(
|
def to_BDX_file_with_delay(
|
||||||
self,
|
self,
|
||||||
method: int = 1,
|
method: int = 1,
|
||||||
volume: float = 1.0,
|
volume: float = 1.0,
|
||||||
speed: float = 1.0,
|
speed: float = 1.0,
|
||||||
progressbar=False,
|
progressbar: Union[bool, tuple] = False,
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
author: str = "Eilles",
|
author: str = "Eilles",
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
@ -1508,24 +1502,24 @@ class midiConvert:
|
|||||||
("§e=§r", "§7=§r"),
|
("§e=§r", "§7=§r"),
|
||||||
)
|
)
|
||||||
|
|
||||||
cmdBytes, size, finalPos = toBDX_bytes(cmdlist, max_height - 1)
|
cmdBytes, size, finalPos = to_BDX_bytes(cmdlist, max_height - 1)
|
||||||
|
|
||||||
if progressbar:
|
if progressbar:
|
||||||
scb_name = self.midFileName[:5] + "Pgb"
|
scb_name = self.midFileName[:5] + "Pgb"
|
||||||
_bytes += formCMD_blk(
|
_bytes += form_command_block_in_BDX_bytes(
|
||||||
r"scoreboard objectives add {} dummy {}播放用".replace(r"{}", scb_name),
|
r"scoreboard objectives add {} dummy {}播放用".replace(r"{}", scb_name),
|
||||||
1,
|
1,
|
||||||
customName="初始化进度条",
|
customName="初始化进度条",
|
||||||
)
|
)
|
||||||
_bytes += move(z, 2)
|
_bytes += move(z, 2)
|
||||||
_bytes += formCMD_blk(
|
_bytes += form_command_block_in_BDX_bytes(
|
||||||
r"scoreboard players add {} {} 1".format(player, scb_name),
|
r"scoreboard players add {} {} 1".format(player, scb_name),
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
customName="显示进度条并加分",
|
customName="显示进度条并加分",
|
||||||
)
|
)
|
||||||
_bytes += move(y, 1)
|
_bytes += move(y, 1)
|
||||||
pgbBytes, pgbSize, pgbNowPos = toBDX_bytes(
|
pgbBytes, pgbSize, pgbNowPos = to_BDX_bytes(
|
||||||
[
|
[
|
||||||
(i, 0)
|
(i, 0)
|
||||||
for i in self.__formProgressBar(max_delay, scb_name, progressbar)
|
for i in self.__formProgressBar(max_delay, scb_name, progressbar)
|
||||||
@ -1536,7 +1530,7 @@ class midiConvert:
|
|||||||
_bytes += move(y, -1 - pgbNowPos[1])
|
_bytes += move(y, -1 - pgbNowPos[1])
|
||||||
_bytes += move(z, -2 - pgbNowPos[2])
|
_bytes += move(z, -2 - pgbNowPos[2])
|
||||||
_bytes += move(x, 2)
|
_bytes += move(x, 2)
|
||||||
_bytes += formCMD_blk(
|
_bytes += form_command_block_in_BDX_bytes(
|
||||||
r"scoreboard players reset {} {}".format(player, scb_name),
|
r"scoreboard players reset {} {}".format(player, scb_name),
|
||||||
1,
|
1,
|
||||||
customName="置零进度条",
|
customName="置零进度条",
|
||||||
@ -1576,7 +1570,7 @@ class midiConvert:
|
|||||||
try:
|
try:
|
||||||
microseconds += msg.time * tempo / self.midi.ticks_per_beat
|
microseconds += msg.time * tempo / self.midi.ticks_per_beat
|
||||||
# print(microseconds)
|
# print(microseconds)
|
||||||
except BaseError:
|
except NameError:
|
||||||
microseconds += (
|
microseconds += (
|
||||||
msg.time
|
msg.time
|
||||||
* mido.midifiles.midifiles.DEFAULT_TEMPO
|
* mido.midifiles.midifiles.DEFAULT_TEMPO
|
||||||
|
@ -35,7 +35,7 @@ def move(axis: str, value: int):
|
|||||||
return key[axis][pointer] + value.to_bytes(2 ** (pointer - 2), "big", signed=True)
|
return key[axis][pointer] + value.to_bytes(2 ** (pointer - 2), "big", signed=True)
|
||||||
|
|
||||||
|
|
||||||
def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
|
def compressZipFile(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||||
"""使用compression指定的算法打包目录为zip文件\n
|
"""使用compression指定的算法打包目录为zip文件\n
|
||||||
默认算法为DEFLATED(8),可用算法如下:\n
|
默认算法为DEFLATED(8),可用算法如下:\n
|
||||||
STORED = 0\n
|
STORED = 0\n
|
||||||
@ -57,7 +57,7 @@ def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
|
|||||||
zipf.close()
|
zipf.close()
|
||||||
|
|
||||||
|
|
||||||
def formCMD_blk(
|
def form_command_block_in_BDX_bytes(
|
||||||
command: str,
|
command: str,
|
||||||
particularValue: int,
|
particularValue: int,
|
||||||
impluse: int = 0,
|
impluse: int = 0,
|
||||||
@ -137,7 +137,7 @@ def __fillSquareSideLength(total: int, maxHeight: int):
|
|||||||
return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
|
return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
|
||||||
|
|
||||||
|
|
||||||
def toBDX_bytes(
|
def to_BDX_bytes(
|
||||||
commands: list,
|
commands: list,
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
):
|
):
|
||||||
@ -165,7 +165,7 @@ def toBDX_bytes(
|
|||||||
customName = ""
|
customName = ""
|
||||||
executeOnFirstTick = False
|
executeOnFirstTick = False
|
||||||
trackOutput = True
|
trackOutput = True
|
||||||
_bytes += formCMD_blk(
|
_bytes += form_command_block_in_BDX_bytes(
|
||||||
cmd,
|
cmd,
|
||||||
(1 if y_forward else 0)
|
(1 if y_forward else 0)
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,2 @@
|
|||||||
Brotli==1.0.9
|
Brotli==1.0.9
|
||||||
mido==1.2.10
|
mido==1.2.10
|
||||||
rich==13.2.0
|
|
||||||
zhdate==0.1
|
|
||||||
requests==2.27.1
|
|
Loading…
x
Reference in New Issue
Block a user