Merge remote-tracking branch 'origin/master' into GowayLee/master

This commit is contained in:
Soulter
2025-05-16 10:23:30 +08:00
4 changed files with 150 additions and 19 deletions
@@ -217,9 +217,9 @@ class AiocqhttpAdapter(Platform):
for t, m_group in itertools.groupby(event.message, key=lambda x: x["type"]):
a = None
if t == "text":
# 合并相邻文本段
message_str = "".join(m["data"]["text"] for m in m_group).strip()
a = ComponentTypes[t](text=message_str) # noqa: F405
current_text = "".join(m["data"]["text"] for m in m_group).strip()
message_str += current_text
a = ComponentTypes[t](text=current_text) # noqa: F405
abm.message.append(a)
elif t == "file":
@@ -287,6 +287,42 @@ class AiocqhttpAdapter(Platform):
logger.error(f"获取引用消息失败: {e}")
a = ComponentTypes[t](**m["data"]) # noqa: F405
abm.message.append(a)
elif t == "at":
first_at_self_processed = False
for m in m_group:
try:
if m["data"]["qq"] == "all":
abm.message.append(At(qq="all", name="全体成员"))
continue
at_info = await self.bot.call_action(
action="get_stranger_info",
user_id=int(m["data"]["qq"]),
)
if at_info:
nickname = at_info.get("nick", "")
is_at_self = str(m["data"]["qq"]) in {abm.self_id, "all"}
abm.message.append(
At(
qq=m["data"]["qq"],
name=nickname,
)
)
if is_at_self and not first_at_self_processed:
# 第一个@是机器人,不添加到message_str
first_at_self_processed = True
else:
# 非第一个@机器人或@其他用户,添加到message_str
message_str += f" @{nickname} "
else:
abm.message.append(At(qq=str(m["data"]["qq"]), name=""))
except ActionFailed as e:
logger.error(f"获取 @ 用户信息失败: {e},此消息段将被忽略。")
except BaseException as e:
logger.error(f"获取 @ 用户信息失败: {e},此消息段将被忽略。")
else:
for m in m_group:
a = ComponentTypes[t](**m["data"]) # noqa: F405
@@ -282,10 +282,12 @@ class TelegramPlatformAdapter(Platform):
entity.offset + 1 : entity.offset + entity.length
]
message.message.append(Comp.At(qq=name, name=name))
plain_text = (
plain_text[: entity.offset]
+ plain_text[entity.offset + entity.length :]
)
# 如果mention是当前bot则移除;否则保留
if name.lower() == context.bot.username.lower():
plain_text = (
plain_text[: entity.offset]
+ plain_text[entity.offset + entity.length :]
)
if plain_text:
message.message.append(Comp.Plain(plain_text))
+15 -12
View File
@@ -2,7 +2,6 @@ import os
import psutil
import sys
import time
import subprocess
from .zip_updator import ReleaseInfo, RepoZipUpdator
from astrbot.core import logger
from astrbot.core.config.default import VERSION
@@ -43,28 +42,32 @@ class AstrBotUpdator(RepoZipUpdator):
pass
def _reboot(self, delay: int = 3):
"""
重启当前程序,使用 subprocess.Popen 启动新进程并退出旧进程
"""重启当前程序
在指定的延迟后,终止所有子进程并重新启动程序
这里只能使用 os.exec* 来重启程序
"""
time.sleep(delay)
self.terminate_child_processes()
py = sys.executable
if os.name == "nt":
py = f'"{sys.executable}"'
else:
py = sys.executable
try:
if "astrbot" in os.path.basename(sys.argv[0]): # 兼容cli
cmd = [py, "-m", "astrbot.cli.__main__"] + sys.argv[1:]
if os.name == "nt":
args = [
f'"{arg}"' if " " in arg else arg for arg in sys.argv[1:]
]
else:
args = sys.argv[1:]
os.execl(sys.executable, py, "-m", "astrbot.cli.__main__", *args)
else:
cmd = [py] + sys.argv
subprocess.Popen(cmd, start_new_session=True)
os.execl(sys.executable, py, *sys.argv)
except Exception as e:
logger.error(f"重启失败({py} {cmd},错误:{e}),请尝试手动重启。")
logger.error(f"重启失败({py}, {e}),请尝试手动重启。")
raise e
os._exit(0)
async def check_update(self, url: str, current_version: str) -> ReleaseInfo:
"""检查更新"""
return await super().check_update(self.ASTRBOT_RELEASE_API, VERSION)
@@ -1,3 +1,27 @@
<script setup>
import { VueMonacoEditor } from '@guolao/vue-monaco-editor'
import { ref } from 'vue'
const dialog = ref(false)
const currentEditingKey = ref('')
const currentEditingValue = ref('')
const currentEditingLanguage = ref('json')
function openEditorDialog(key, value, language) {
currentEditingKey.value = key
currentEditingValue.value = value
currentEditingLanguage.value = language || 'json'
dialog.value = true
}
function saveEditedContent() {
if (currentEditingKey.value && iterable[currentEditingKey.value] !== undefined) {
iterable[currentEditingKey.value] = currentEditingValue.value
}
dialog.value = false
}
</script>
<template>
<div class="config-section" v-if="iterable && metadata[metadataKey]?.type === 'object'">
<v-list-item-title class="config-title">
@@ -67,6 +91,28 @@
class="config-field"
hide-details
></v-select>
<!-- Code Editor with Full Screen Option -->
<div v-else-if="metadata[metadataKey].items[key]?.editor_mode && !metadata[metadataKey].items[key]?.invisible" class="editor-container">
<VueMonacoEditor
:theme="metadata[metadataKey].items[key]?.editor_theme || 'vs-light'"
:language="metadata[metadataKey].items[key]?.editor_language || 'json'"
style="min-height: 100px; flex-grow: 1; border: 1px solid rgba(0, 0, 0, 0.1);"
v-model:value="iterable[key]"
>
</VueMonacoEditor>
<v-btn
icon
size="small"
variant="text"
color="primary"
class="editor-fullscreen-btn"
@click="openEditorDialog(key, iterable[key], metadata[metadataKey].items[key]?.editor_language)"
title="全屏编辑"
>
<v-icon>mdi-fullscreen</v-icon>
</v-btn>
</div>
<!-- String input -->
<v-text-field
@@ -235,6 +281,31 @@
<v-divider class="my-2 config-divider"></v-divider>
</div>
</v-card-text>
<!-- Full Screen Editor Dialog -->
<v-dialog v-model="dialog" fullscreen transition="dialog-bottom-transition" scrollable>
<v-card>
<v-toolbar color="primary" dark>
<v-btn icon @click="dialog = false">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title>编辑内容 - {{ currentEditingKey }}</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn variant="text" @click="saveEditedContent">保存</v-btn>
</v-toolbar-items>
</v-toolbar>
<v-card-text class="pa-0">
<VueMonacoEditor
theme="vs-dark"
:language="currentEditingLanguage"
style="height: calc(100vh - 64px);"
v-model="currentEditingValue"
>
</VueMonacoEditor>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
@@ -357,6 +428,25 @@ export default {
margin: 4px 0;
}
.editor-container {
position: relative;
display: flex;
width: 100%;
}
.editor-fullscreen-btn {
position: absolute;
top: 4px;
right: 4px;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
.editor-fullscreen-btn:hover {
background-color: rgba(0, 0, 0, 0.5);
}
@media (max-width: 600px) {
.nested-object {
padding-left: 8px;