




















@@ -34,15 +34,16 @@ export {
3434} from "./outbound-media-send.js";
35353636import type { GatewayAccount } from "../types.js";
37+import type { EngineLogger } from "../types.js";
3738import { formatErrorMessage } from "../utils/format.js";
3839import { debugError, debugLog, debugWarn } from "../utils/log.js";
3940import { normalizeMediaTags } from "../utils/media-tags.js";
4041import { decodeCronPayload } from "../utils/payload.js";
41-import { normalizePath } from "../utils/platform.js";
4242import {
4343normalizeLowercaseStringOrEmpty,
4444normalizeOptionalString,
4545} from "../utils/string-normalize.js";
46+import { decodeMediaPath } from "./decode-media-path.js";
4647import {
4748isImageFile as coreIsImageFile,
4849isVideoFile as coreIsVideoFile,
@@ -77,6 +78,11 @@ import {
77787879const isImageFile = coreIsImageFile;
7980const isVideoFile = coreIsVideoFile;
81+const mediaPathDecodeLog = {
82+info: (message: string) => debugLog(`[qqbot] sendText: ${message}`),
83+error: (message: string) => debugError(`[qqbot] sendText: ${message}`),
84+debug: (message: string) => debugLog(`[qqbot] sendText: ${message}`),
85+} satisfies EngineLogger;
80868187/**
8288 * Send text, optionally falling back from passive reply mode to proactive mode.
@@ -155,52 +161,10 @@ export async function sendText(ctx: OutboundContext): Promise<OutboundResult> {
155161156162const tagName = normalizeLowercaseStringOrEmpty(match[1]);
157163158-let mediaPath = normalizeOptionalString(match[2]) ?? "";
159-if (mediaPath.startsWith("MEDIA:")) {
160-mediaPath = mediaPath.slice("MEDIA:".length);
161-}
162-mediaPath = normalizePath(mediaPath);
163-164-mediaPath = mediaPath.replace(/\\\\/g, "\\");
165-166-const isWinLocal = /^[a-zA-Z]:[\\/]/.test(mediaPath) || mediaPath.startsWith("\\\\");
167-try {
168-const hasOctal = /\\[0-7]{1,3}/.test(mediaPath);
169-const hasNonASCII = /[\u0080-\u00FF]/.test(mediaPath);
170-171-if (!isWinLocal && (hasOctal || hasNonASCII)) {
172-debugLog(`[qqbot] sendText: Decoding path with mixed encoding: ${mediaPath}`);
173-174-let decoded = mediaPath.replace(/\\([0-7]{1,3})/g, (_: string, octal: string) => {
175-return String.fromCharCode(Number.parseInt(octal, 8));
176-});
177-178-const bytes: number[] = [];
179-for (let i = 0; i < decoded.length; i++) {
180-const code = decoded.charCodeAt(i);
181-if (code <= 0xff) {
182-bytes.push(code);
183-} else {
184-const charBytes = Buffer.from(decoded[i], "utf8");
185-bytes.push(...charBytes);
186-}
187-}
188-189-const buffer = Buffer.from(bytes);
190-const utf8Decoded = buffer.toString("utf8");
191-192-if (!utf8Decoded.includes("\uFFFD") || utf8Decoded.length < decoded.length) {
193-mediaPath = utf8Decoded;
194-debugLog(`[qqbot] sendText: Successfully decoded path: ${mediaPath}`);
195-}
196-}
197-} catch (decodeErr) {
198-debugError(
199-`[qqbot] sendText: Path decode error: ${
200- decodeErr instanceof Error ? decodeErr.message : JSON.stringify(decodeErr)
201- }`,
202-);
203-}
164+const mediaPath = decodeMediaPath(
165+normalizeOptionalString(match[2]) ?? "",
166+mediaPathDecodeLog,
167+);
204168205169if (mediaPath) {
206170if (tagName === "qqmedia") {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。