完善游戏通知文案与屏蔽逻辑
This commit is contained in:
@@ -63,6 +63,59 @@ function buildGameLabelChipHtml(label, accentColor) {
|
||||
return `<span style="display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;background:${accentColor};color:#fff;font-size:11px;font-weight:700;line-height:1;border:1px solid ${accentColor};">${escapeHtml(label)}</span>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前是否为礼包发放公告。
|
||||
*/
|
||||
function isRedPacketAnnouncementMessage(msg) {
|
||||
const content = String(msg?.content || "");
|
||||
|
||||
return String(msg?.from_user || "") === "系统公告"
|
||||
&& content.includes("发出了一个")
|
||||
&& content.includes("礼包")
|
||||
&& content.includes("立即抢包");
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建礼包发放公告的紧凑卡片,整体比例对齐猜谜活动。
|
||||
*/
|
||||
function buildRedPacketAnnouncementHtml(msg, timeStr) {
|
||||
const rawContent = String(msg?.content || "");
|
||||
const isExpPacket = rawContent.includes("经验的礼包");
|
||||
const accentColor = isExpPacket ? "#7c3aed" : "#dc2626";
|
||||
const typeLabel = isExpPacket ? "经验礼包" : "金币礼包";
|
||||
const icon = isExpPacket ? "✨" : "🧧";
|
||||
const buttonMatch = rawContent.match(/<button\b([^>]*)>([\s\S]*?)<\/button>/iu);
|
||||
const buttonLabel = String(buttonMatch?.[2] || "立即抢包").trim();
|
||||
const onclickMatch = String(buttonMatch?.[1] || "").match(/\bonclick=(["'])([\s\S]*?)\1/iu);
|
||||
const buttonOnclick = onclickMatch ? onclickMatch[2] : "";
|
||||
|
||||
const textOnlyContent = rawContent
|
||||
.replace(/<button\b[\s\S]*?<\/button>/giu, "")
|
||||
.replace(/<\/?b>/giu, "")
|
||||
.replace(/^🧧\s*/u, "")
|
||||
.trim();
|
||||
|
||||
const summary = escapeHtml(textOnlyContent);
|
||||
const actionButtonHtml = `<button type="button"${buttonOnclick ? ` onclick="${escapeHtml(buttonOnclick)}"` : ""} style="display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;background:${accentColor};color:#fff;font-size:11px;font-weight:700;line-height:1;border:1px solid ${accentColor};cursor:pointer;box-shadow:none;vertical-align:middle;">${escapeHtml(buttonLabel)}</button>`;
|
||||
|
||||
return `
|
||||
<div style="display:flex;align-items:center;gap:7px;padding:5px 9px;border-radius:11px;background:linear-gradient(135deg,${isExpPacket ? "#f5f3ff,#faf5ff" : "#fef2f2,#fff7ed"});border:1px solid ${isExpPacket ? "rgba(124,58,237,.16)" : "rgba(220,38,38,.16)"};box-shadow:0 4px 12px rgba(15,23,42,.045);overflow:hidden;">
|
||||
<div style="width:23px;height:23px;border-radius:7px;background:${accentColor};display:flex;align-items:center;justify-content:center;color:#fff;font-size:13px;box-shadow:0 2px 6px ${isExpPacket ? "rgba(124,58,237,.16)" : "rgba(220,38,38,.16)"};flex-shrink:0;">${icon}</div>
|
||||
<div style="min-width:0;flex:1;display:flex;align-items:center;gap:7px;flex-wrap:wrap;color:${isExpPacket ? "#5b21b6" : "#b91c1c"};">
|
||||
<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap;flex-shrink:0;">
|
||||
${buildGameLabelChipHtml("礼包红包", accentColor)}
|
||||
<span style="display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;background:${accentColor}1A;color:${accentColor};font-size:11px;font-weight:700;line-height:1;border:1px solid ${accentColor}33;">${escapeHtml(typeLabel)}</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:5px;flex-wrap:wrap;font-size:12px;line-height:1.25;font-weight:700;min-width:200px;flex:1;">
|
||||
<span>${summary}</span>
|
||||
<span class="msg-time" style="font-size:10px;color:#94a3b8;">(${timeStr})</span>
|
||||
${actionButtonHtml}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建统一的猜谜活动标题与题型标签。
|
||||
*/
|
||||
@@ -206,40 +259,68 @@ function extractSystemGameCardSummary(content, meta) {
|
||||
.replace(/^[📦💎☠️]\s*/u, "")
|
||||
.replace(/^【神秘箱子】/u, "")
|
||||
.replace(/^开箱播报[::]\s*/u, "")
|
||||
.replace(/投放了一个神秘箱子/u, "投放")
|
||||
.replace(/抢到了神秘/u, "抢到")
|
||||
.replace(/即可开箱!?/u, "开箱")
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (meta.label === "百家乐") {
|
||||
if (normalizedContent.includes("开局:")) {
|
||||
return normalizedContent
|
||||
.replace(/^[🎲]+\s*/u, "")
|
||||
.replace(/【百家乐】/u, "")
|
||||
.replace(/\s+/gu, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (/第\s*#?\d+\s*局开奖/u.test(normalizedContent)) {
|
||||
return normalizedContent
|
||||
.replace(/^[🎲🎉]+\s*/u, "")
|
||||
.replace(/^【百家乐】/u, "")
|
||||
.replace(/^第\s*#?\d+\s*局开奖!?\s*/u, "开奖:")
|
||||
.replace(/总点\s*(\d+)\s*→\s*/u, "$1点 · ")
|
||||
.replace(/本局无人获奖。?/u, "无人获奖")
|
||||
.replace(/\s+/gu, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
return normalizedContent
|
||||
.replace(/^[🎲🎉]\s*/u, "")
|
||||
.replace(/^[🎲🎉]+\s*/u, "")
|
||||
.replace(/^【百家乐】/u, "")
|
||||
.replace(/^开局:/u, "")
|
||||
.replace(/^第\s*#?\d+\s*局开奖!?\s*/u, "")
|
||||
.replace(/^第\s*#?\d+\s*局开始!?\s*/u, "")
|
||||
.replace(/总点\s*(\d+)\s*→\s*/u, "$1点 · ")
|
||||
.replace(/本局无人获奖。?/u, "无人获奖")
|
||||
.replace(/\s+/gu, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (meta.label === "赛马") {
|
||||
if (normalizedContent.startsWith("🐎 开赛:")) {
|
||||
return normalizedContent.replace(/^[🐎]+\s*/u, "").trim();
|
||||
}
|
||||
|
||||
if (normalizedContent.startsWith("🏇 比赛开始:")) {
|
||||
return normalizedContent.replace(/^[🏇]+\s*/u, "").trim();
|
||||
}
|
||||
|
||||
if (normalizedContent.startsWith("🏆 冠军:")) {
|
||||
return normalizedContent.replace(/^[🏆]+\s*/u, "").trim();
|
||||
}
|
||||
|
||||
return normalizedContent
|
||||
.replace(/^[🐎🏇🏆]\s*/u, "")
|
||||
.replace(/^[🐎🏇🏆]+\s*/u, "")
|
||||
.replace(/^【赛马】/u, "")
|
||||
.replace(/^第\s*#?\d+\s*场开始!?\s*/u, "")
|
||||
.replace(/^第\s*#?\d+\s*场押注截止!?\s*/u, "")
|
||||
.replace(/^第\s*#?\d+\s*场结束!?\s*/u, "")
|
||||
.replace(/^第\s*#?\d+\s*场开始!?\s*/u, "开赛:")
|
||||
.replace(/^第\s*#?\d+\s*场押注截止!?\s*/u, "比赛开始:")
|
||||
.replace(/^第\s*#?\d+\s*场结束!?\s*/u, "冠军:")
|
||||
.replace(/马匹已进入跑道,比赛开始!?/u, "比赛开始")
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (meta.label === "双色球彩票") {
|
||||
if (normalizedContent.includes("超级期")) {
|
||||
return normalizedContent.replace(/^[🎊🎟️]+\s*/u, "").trim();
|
||||
}
|
||||
|
||||
return normalizedContent
|
||||
.replace(/^[🎟️🎊]+\s*/u, "")
|
||||
.replace(/^【双色球[^】]*】/u, "")
|
||||
.replace(/^(\d+\s*期:)/u, "开奖:$1")
|
||||
.trim();
|
||||
}
|
||||
|
||||
@@ -247,16 +328,16 @@ function extractSystemGameCardSummary(content, meta) {
|
||||
return normalizedContent
|
||||
.replace(/^[♟️🏆]+\s*/u, "")
|
||||
.replace(/^【五子棋】/u, "")
|
||||
.replace(/^玩家对战结果!/u, "")
|
||||
.replace(/^棋神降临!/u, "")
|
||||
.replace(/^AI 大获全胜!/u, "")
|
||||
.replace(/^玩家对战结果!/u, "对战结果:")
|
||||
.replace(/^棋神降临!/u, "人机获胜:")
|
||||
.replace(/^AI 大获全胜!/u, "AI获胜:")
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (meta.label === "老虎机") {
|
||||
return normalizedContent
|
||||
.replace(/^[🎰🎉]+\s*/u, "")
|
||||
.replace(/^【老虎机大奖】/u, "")
|
||||
.replace(/^【老虎机大奖】/u, "大奖:")
|
||||
.trim();
|
||||
}
|
||||
|
||||
@@ -378,18 +459,18 @@ function buildQuizResultHtml(msg, timeStr) {
|
||||
: `第 #${quizMeta.endedRoundId || quizMeta.roundId || 0} 题已超时结束,正确答案:${answerText}`;
|
||||
|
||||
return `
|
||||
<div style="display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:12px;background:${accentBackground};border:1px solid ${accentBorder};box-shadow:0 6px 16px rgba(15,23,42,.05);overflow:hidden;">
|
||||
<div style="width:30px;height:30px;border-radius:10px;background:${iconBackground};display:flex;align-items:center;justify-content:center;color:#fff;font-size:16px;box-shadow:0 5px 12px ${accentBorder};flex-shrink:0;">${icon}</div>
|
||||
<div style="min-width:0;flex:1;display:flex;align-items:center;gap:8px;flex-wrap:wrap;color:${textColor};">
|
||||
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex-shrink:0;">${buildQuizBadgeHtml(msg, badgeColor)}</div>
|
||||
<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:13px;line-height:1.35;font-weight:700;min-width:220px;flex:1;">
|
||||
<div style="display:flex;align-items:center;gap:7px;padding:5px 9px;border-radius:11px;background:${accentBackground};border:1px solid ${accentBorder};box-shadow:0 4px 12px rgba(15,23,42,.045);overflow:hidden;">
|
||||
<div style="width:23px;height:23px;border-radius:7px;background:${iconBackground};display:flex;align-items:center;justify-content:center;color:#fff;font-size:13px;box-shadow:0 2px 6px ${accentBorder};flex-shrink:0;">${icon}</div>
|
||||
<div style="min-width:0;flex:1;display:flex;align-items:center;gap:7px;flex-wrap:wrap;color:${textColor};">
|
||||
<div style="display:flex;align-items:center;gap:7px;flex-wrap:wrap;flex-shrink:0;">${buildQuizBadgeHtml(msg, badgeColor)}</div>
|
||||
<div style="display:flex;align-items:center;gap:5px;flex-wrap:wrap;font-size:12px;line-height:1.25;font-weight:700;min-width:200px;flex:1;">
|
||||
<span>${summaryHtml}</span>
|
||||
<span class="msg-time" style="font-size:11px;color:#94a3b8;">(${timeStr})</span>
|
||||
<span class="msg-time" style="font-size:10px;color:#94a3b8;">(${timeStr})</span>
|
||||
</div>
|
||||
${isAnsweredResult ? `
|
||||
<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap;color:${textColor};font-size:11px;flex-shrink:0;margin-left:auto;">
|
||||
<span style="padding:1px 7px;border-radius:999px;background:#ffffff;box-shadow:inset 0 0 0 1px ${isAnsweredResult ? "rgba(22,163,74,.12)" : "rgba(217,119,6,.12)"};white-space:nowrap;">💰 ${quizMeta.rewardGold} 金币</span>
|
||||
<span style="padding:1px 7px;border-radius:999px;background:#ffffff;box-shadow:inset 0 0 0 1px ${isAnsweredResult ? "rgba(22,163,74,.12)" : "rgba(217,119,6,.12)"};white-space:nowrap;">⭐ ${quizMeta.rewardExp} 经验</span>
|
||||
<div style="display:flex;align-items:center;gap:5px;flex-wrap:wrap;color:${textColor};font-size:10px;flex-shrink:0;margin-left:auto;">
|
||||
<span style="padding:1px 6px;border-radius:999px;background:#ffffff;box-shadow:inset 0 0 0 1px ${isAnsweredResult ? "rgba(22,163,74,.12)" : "rgba(217,119,6,.12)"};white-space:nowrap;">💰 ${quizMeta.rewardGold} 金币</span>
|
||||
<span style="padding:1px 6px;border-radius:999px;background:#ffffff;box-shadow:inset 0 0 0 1px ${isAnsweredResult ? "rgba(22,163,74,.12)" : "rgba(217,119,6,.12)"};white-space:nowrap;">⭐ ${quizMeta.rewardExp} 经验</span>
|
||||
</div>
|
||||
` : ""}
|
||||
</div>
|
||||
@@ -613,11 +694,16 @@ export function appendMessage(msg, renderBatch = null) {
|
||||
timeStrOverride = true;
|
||||
} else if (SYSTEM_USERS.includes(msg.from_user)) {
|
||||
if (msg.from_user === "系统公告") {
|
||||
div.style.cssText =
|
||||
"background: linear-gradient(135deg, #fef2f2, #fff1f2); border: 2px solid #ef4444; border-radius: 8px; padding: 10px 14px; margin: 6px 0; box-shadow: 0 3px 8px rgba(239,68,68,0.16);";
|
||||
const parsedContent = parseBracketUsers(msg.content, "#dc2626");
|
||||
html = `<div style="font-size: 18px; line-height: 1.75; font-weight: 800; color: #dc2626;">${parsedContent} <span style="color: #999; font-size: 14px; font-weight: 500;">(${timeStr})</span></div>`;
|
||||
timeStrOverride = true;
|
||||
if (isRedPacketAnnouncementMessage(msg)) {
|
||||
html = buildRedPacketAnnouncementHtml(msg, timeStr);
|
||||
timeStrOverride = true;
|
||||
} else {
|
||||
div.style.cssText =
|
||||
"background: linear-gradient(135deg, #fef2f2, #fff1f2); border: 2px solid #ef4444; border-radius: 8px; padding: 10px 14px; margin: 6px 0; box-shadow: 0 3px 8px rgba(239,68,68,0.16);";
|
||||
const parsedContent = parseBracketUsers(msg.content, "#dc2626");
|
||||
html = `<div style="font-size: 18px; line-height: 1.75; font-weight: 800; color: #dc2626;">${parsedContent} <span style="color: #999; font-size: 14px; font-weight: 500;">(${timeStr})</span></div>`;
|
||||
timeStrOverride = true;
|
||||
}
|
||||
} else if (msg.from_user === "系统传音") {
|
||||
const content = msg.content || "";
|
||||
const isRedPacketClaimNotification = content.includes("抢到了") && content.includes("礼包");
|
||||
|
||||
Reference in New Issue
Block a user