【脚本开源】NodeSeek论坛倒狗监控V1.0.0 不喜欢倒狗?那就使用这个脚本吧!

cshaizhihao 2026-06-05 15:17 1

长话短说:


做了一个倒狗监控,可以自定义输入倒狗的ID、监控关键词。主页检测到倒狗发帖时右下角跳出提示。点击进入本帖自带一键回复功能。

让可爱的倒狗降低倒卖概率,减少MJJ金钱损失。本脚本默认附带上我群公认倒狗ID,请用户自行进行替换,或者补充。

添加监控目标后会在监控目标ID后添加醒目标签。


Greasy Fork安装连接


脚本界面:


image

image

image


脚本完整代码:
// ==UserScript==
// @name NodeSeek 倒狗雷达 V1.0.0
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 去你妈的倒狗。
// @author cshaizhihao
// @match *://*.nodeseek.com/*
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-end
// ==/UserScript==

(function() {
'use strict';

// ================== 默认配置 ==================
const defaultSettings = {
targets: "44627", // 默认测试ID,多个用逗号隔开
buyKeywords: "收,买,求购,收购",
buyReply: "+1块钱,楼主优先。",
sellKeywords: "卖,出,出售,明盘",
sellReply: "5折排队,楼主好出。",
enableBackgroundFetch: true
};

let config = GM_getValue('ns_daogou_config', defaultSettings);
let historyRecords = GM_getValue('ns_daogou_history', []);
let fetchErrorCount = 0;

const saveConfig = () => GM_setValue('ns_daogou_config', config);
const saveHistory = () => GM_setValue('ns_daogou_history', historyRecords);

// ================== 工具函数 ==================
const debounce = (func, wait) => {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
};

const waitForElement = (selector, timeout = 10000) => {
return new Promise((resolve, reject) => {
if (document.querySelector(selector)) return resolve(document.querySelector(selector));

const observer = new MutationObserver(() => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelector(selector));
}
});
observer.observe(document.body, { childList: true, subtree: true });

setTimeout(() => {
observer.disconnect();
reject(new Error(`等待元素 ${selector} 超时`));
}, timeout);
});
};

// ================== 注入 UI 样式 ==================
GM_addStyle(`
#ns-dg-app { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
#ns-dg-app .btn-float {
position: fixed; top: 80px; right: 20px; z-index: 9999;
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white; padding: 10px 14px; border-radius: 10px;
font-size: 14px; font-weight: bold; cursor: pointer;
box-shadow: 0 4px 15px rgba(217, 119, 6, 0.4); border: none; transition: 0.2s;
}
#ns-dg-app .btn-float:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(217, 119, 6, 0.6); }
@keyframes pulse-amber { 0% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(245, 158, 11, 0); } 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); } }
#ns-dg-app .has-unread { animation: pulse-amber 2s infinite !important; background: linear-gradient(135deg, #ef4444, #b91c1c); }

#ns-dg-app .panel {
position: fixed; top: 20%; left: 50%; transform: translateX(-50%);
width: 480px; max-height: 85vh; background: rgba(24, 24, 27, 0.95);
backdrop-filter: blur(10px); color: #e4e4e7; border-radius: 12px;
box-shadow: 0 20px 40px rgba(0,0,0,0.6); z-index: 10000; display: none;
flex-direction: column; border: 1px solid #3f3f46;
}
#ns-dg-app .header {
padding: 15px 20px; background: rgba(39, 39, 42, 0.8); border-bottom: 1px solid #3f3f46;
display: flex; justify-content: space-between; align-items: center;
border-radius: 12px 12px 0 0; cursor: move;
}
#ns-dg-app .header h3 { margin: 0; font-size: 16px; color: #f59e0b; user-select: none; }
#ns-dg-app .close-btn { cursor: pointer; font-size: 22px; color: #a1a1aa; transition: 0.2s; }
#ns-dg-app .close-btn:hover { color: #fff; }
#ns-dg-app .content { padding: 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }

#ns-dg-app .form-group { display: flex; flex-direction: column; gap: 6px; }
#ns-dg-app .form-group label { font-size: 12px; color: #a1a1aa; font-weight: 500; }
#ns-dg-app .form-group input {
background: #27272a; border: 1px solid #52525b; color: #fff;
padding: 10px; border-radius: 8px; font-size: 13px; outline: none; transition: 0.2s;
}
#ns-dg-app .form-group input:focus { border-color: #f59e0b; background: #3f3f46; }

#ns-dg-app .actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 5px; }
#ns-dg-app .btn { background: #3f3f46; color: white; border: none; padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 500;}
#ns-dg-app .btn:hover { background: #52525b; }
#ns-dg-app .btn.primary { background: #f59e0b; color: #18181b; }
#ns-dg-app .btn.primary:hover { background: #fbbf24; }

#ns-dg-app .history { margin-top: 10px; border-top: 1px dashed #52525b; padding-top: 15px;}
#ns-dg-app .history-item { background: #27272a; padding: 12px; border-radius: 8px; margin-bottom: 10px; font-size: 13px; border: 1px solid #3f3f46;}
#ns-dg-app .history-item.unread { border-left: 4px solid #f59e0b; }
#ns-dg-app .history-item a { color: #f59e0b; text-decoration: none; margin-top: 8px; display: inline-block; font-weight: 600;}

.daogou-tag {
background: linear-gradient(135deg, #f59e0b, #d97706) !important;
color: #ffffff !important;
font-size: 11px; padding: 2px 6px; border-radius: 6px; margin-left: 6px;
font-weight: bold; display: inline-flex; vertical-align: middle;
user-select: none; border: 1px solid #b45309; box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

#ns-dg-app .toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 10001; display: flex; flex-direction: column; gap: 10px; }
#ns-dg-app .toast {
background: rgba(24, 24, 27, 0.95); backdrop-filter: blur(5px);
border: 1px solid #3f3f46; border-left: 5px solid #f59e0b;
color: #fff; padding: 15px; border-radius: 8px; width: 320px;
box-shadow: 0 10px 25px rgba(0,0,0,0.5); animation: slideIn 0.3s forwards;
}
#ns-dg-app .toast h4 { margin: 0 0 8px 0; font-size: 14px; color: #f59e0b; }
#ns-dg-app .toast p { margin: 0 0 12px 0; font-size: 12px; color: #d4d4d8; line-height: 1.5; word-break: break-all; }
#ns-dg-app .toast-action { display: flex; justify-content: space-between; align-items: center;}
#ns-dg-app .toast-action a { background: #f59e0b; color: #18181b; padding: 6px 12px; border-radius: 6px; text-decoration: none; font-size: 12px; font-weight: bold; cursor: pointer; }
#ns-dg-app .toast-action span { color: #a1a1aa; font-size: 12px; cursor: pointer; }
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
`);

// ================== UI 构造与交互 ==================
const createUI = () => {
const appContainer = document.createElement('div');
appContainer.id = 'ns-dg-app';
document.body.appendChild(appContainer);

const btn = document.createElement('button');
btn.className = 'btn-float';
btn.id = 'dg-trigger-btn';
btn.innerHTML = '🐶 倒狗监控';
appContainer.appendChild(btn);

const panel = document.createElement('div');
panel.className = 'panel';
panel.id = 'dg-main-panel';
panel.innerHTML = `
<div class="header" id="dg-panel-header">
<h3>🐶 倒狗雷达 V3 控制中心</h3>
<span class="close-btn">&times;</span>
</div>
<div class="content">
<div class="form-group">
<label>监控用户ID (英文逗号隔开):</label>
<input type="text" id="dg-targets" value="${config.targets}">
</div>
<div class="form-group">
<label>【收/买】关键词 & 自动回复:</label>
<input type="text" id="dg-buy-keys" value="${config.buyKeywords}" placeholder="关键词...">
<input type="text" id="dg-buy-reply" value="${config.buyReply}" placeholder="回复内容...">
</div>
<div class="form-group">
<label>【出/卖】关键词 & 自动回复:</label>
<input type="text" id="dg-sell-keys" value="${config.sellKeywords}" placeholder="关键词...">
<input type="text" id="dg-sell-reply" value="${config.sellReply}" placeholder="回复内容...">
</div>
<div class="actions">
<button class="btn" id="dg-clear-history">清空历史</button>
<button class="btn primary" id="dg-save">保存配置</button>
</div>
<div class="history" id="dg-history-list"></div>
</div>
`;
appContainer.appendChild(panel);

const toasts = document.createElement('div');
toasts.className = 'toast-container';
appContainer.appendChild(toasts);

btn.addEventListener('click', () => {
panel.style.display = panel.style.display === 'flex' ? 'none' : 'flex';
if (panel.style.display === 'flex') renderHistory();
});
panel.querySelector('.close-btn').addEventListener('click', () => panel.style.display = 'none');

panel.querySelector('#dg-save').addEventListener('click', () => {
config.targets = document.getElementById('dg-targets').value;
config.buyKeywords = document.getElementById('dg-buy-keys').value;
config.buyReply = document.getElementById('dg-buy-reply').value;
config.sellKeywords = document.getElementById('dg-sell-keys').value;
config.sellReply = document.getElementById('dg-sell-reply').value;
saveConfig();
panel.style.display = 'none';
});

panel.querySelector('#dg-clear-history').addEventListener('click', () => {
historyRecords = []; saveHistory(); renderHistory(); updateUnreadStatus();
});

dragElement(panel, document.getElementById('dg-panel-header'));
};

const dragElement = (elmnt, header) => {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
header.onmousedown = (e) => {
e.preventDefault();
pos3 = e.clientX; pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
};
const elementDrag = (e) => {
e.preventDefault();
pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY;
pos3 = e.clientX; pos4 = e.clientY;
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
elmnt.style.transform = "none";
};
const closeDragElement = () => {
document.onmouseup = null; document.onmousemove = null;
};
};

const renderHistory = () => {
const list = document.getElementById('dg-history-list');
list.innerHTML = '<div style="font-size:13px; color:#f59e0b; margin-bottom:10px;">🕒 近期雷达记录</div>';
if (historyRecords.length === 0) return list.innerHTML += '<div style="color:#71717a; font-size: 12px;">太安静了,暂时没有发现目标。</div>';

[...historyRecords].reverse().slice(0, 30).forEach(record => {
list.innerHTML += `
<div class="history-item ${record.read ? '' : 'unread'}">
<div style="color:#a1a1aa; font-size:11px;">${new Date(record.time).toLocaleString()} | ID: ${record.authorId}</div>
<div style="margin-top:4px;">${record.title}</div>
<a href="${record.postUrl}?daogou_action=${record.type}" target="_blank" onclick="window.dgMarkRead('${record.id}')">🚀 去对线 (${record.type === 'buy' ? '收' : '出'})</a>
</div>
`;
});
};

window.dgMarkRead = (id) => {
let record = historyRecords.find(r => r.id === id);
if (record) { record.read = true; saveHistory(); updateUnreadStatus(); }
};

const updateUnreadStatus = () => {
const btn = document.getElementById('dg-trigger-btn');
if (btn) historyRecords.some(r => !r.read) ? btn.classList.add('has-unread') : btn.classList.remove('has-unread');
};

// ================== 核心检测引擎 ==================

const showToast = (record) => {
const toasts = document.querySelector('#ns-dg-app .toast-container');
const toast = document.createElement('div');
toast.className = 'toast';
toast.innerHTML = `
<h4>🚨 发现目标相关动态</h4>
<p><strong>[ID:${record.authorId}]</strong><br>${record.title}</p>
<div class="toast-action">
<a href="${record.postUrl}?daogou_action=${record.type}" target="_blank" class="go-btn">⚡ 去对线</a>
<span class="ignore-btn">忽略</span>
</div>
`;
toasts.appendChild(toast);

toast.querySelector('.go-btn').onclick = () => { window.dgMarkRead(record.id); toast.remove(); };
toast.querySelector('.ignore-btn').onclick = () => toast.remove();
setTimeout(() => { if (toast.parentNode) toast.remove(); }, 15000);
};

// 接收 cleanTitle 仅用于展示,实际匹配使用 blockText (全文)
const analyzePost = (cleanTitle, blockText, authorId, postUrl) => {
if (historyRecords.some(r => r.id === postUrl)) return;

let type = null;
const buyKeys = config.buyKeywords.split(',').map(s => s.trim()).filter(Boolean);
const sellKeys = config.sellKeywords.split(',').map(s => s.trim()).filter(Boolean);

// 使用全文文本进行暴力正则判定,避免 DOM 空文本陷阱
if (buyKeys.some(k => blockText.includes(k))) type = 'buy';
else if (sellKeys.some(k => blockText.includes(k))) type = 'sell';

if (type) {
const record = { id: postUrl, postUrl, title: cleanTitle, authorId, type, time: Date.now(), read: false };
historyRecords.push(record);
saveHistory(); updateUnreadStatus(); showToast(record);
}
};

// 【重构】双向兼容的 DOM 核心抽取器
const extractPostsFromDOM = (rootDoc, isBackground = false) => {
const targets = config.targets.split(',').map(s => s.trim()).filter(Boolean);
if (!targets.length) return;

// 1. 从目标用户出发 (哪怕主页结构再乱,TAG 能挂上去,就说明一定能抓到 userLink)
rootDoc.querySelectorAll('a[href*="/space/"]').forEach(userLink => {
const hasImg = userLink.querySelector('img');
const match = userLink.getAttribute('href').match(/\/space\/(\d+)/);
if (!match) return;
const userId = match[1];

if (targets.includes(userId)) {

// 2. 注入 TAG 逻辑 (如果是后台静默解析则跳过)
if (!isBackground && !hasImg && !userLink.dataset.dgTagged && userLink.textContent.trim().length > 0) {
const tag = document.createElement('span');
tag.className = 'daogou-tag'; tag.innerText = '🐶 导狗';
userLink.insertAdjacentElement('afterend', tag);
userLink.dataset.dgTagged = 'true';
}

// 3. 【核心修复】反向溯源:从用户标签往上找卡片容器
let container = userLink.closest('li, article, .post-list-item, .post-item, .item-container, .row')
|| userLink.parentElement?.parentElement?.parentElement;

if (container && (!isBackground ? !container.dataset.dgChecked : true)) {
// 提取整张卡片的纯文本!无论标题有没有 A 标签包裹都能兜底
const blockText = container.textContent || "";

// 寻找包含 URL 跳转的节点
let postLink = null;
const pLinks = container.querySelectorAll('a[href*="/post"], a[href*="/discussions"]');
for (let p of pLinks) {
if (p.textContent.trim().length > 1) { postLink = p; break; }
}
if (!postLink && pLinks.length > 0) postLink = pLinks[0]; // 兜底空连接

let fullUrl = postLink ? new URL(postLink.getAttribute('href'), window.location.origin).href.split(/[?#]/)[0] : null;
if (!fullUrl) return;

// 尽力获取干净的标题用于 Toast 显示
let cleanTitle = postLink ? postLink.textContent.trim() : "";
if (!cleanTitle || cleanTitle.length < 2) {
cleanTitle = blockText.split('\\n').map(s => s.trim()).filter(Boolean)[0] || "检测到目标新动态";
}
if (cleanTitle.length > 60) cleanTitle = cleanTitle.substring(0, 60) + '...';

if (!isBackground) container.dataset.dgChecked = 'true';

// 将标题和提取出的全文块都送入分析器
analyzePost(cleanTitle, blockText, userId, fullUrl);
}
}
});
};

const scanDOM = debounce(() => {
extractPostsFromDOM(document, false);
}, 500);

// ================== 反 CF 静默抓取引擎 ==================
const backgroundFetch = async () => {
if (!config.enableBackgroundFetch) return;
try {
const res = await fetch('/');
if (!res.ok) throw new Error(`HTTP ${res.status}`);

const html = await res.text();
const doc = new DOMParser().parseFromString(html, 'text/html');
// 后台解析同样享受新的反向查找机制的加持
extractPostsFromDOM(doc, true);

fetchErrorCount = 0;
} catch (e) {
fetchErrorCount++;
console.warn(`[倒狗雷达] 抓取受挫 (CF验证阻截?), 失败次数: ${fetchErrorCount}`, e);
}

let baseInterval = Math.floor(Math.random() * (75000 - 35000 + 1)) + 35000;
let nextInterval = baseInterval * Math.pow(1.5, fetchErrorCount);
if (nextInterval > 300000) nextInterval = 300000;
setTimeout(backgroundFetch, nextInterval);
};

// ================== SPA 健壮自动回复 ==================
const autoReplyEngine = async () => {
const action = new URLSearchParams(window.location.search).get('daogou_action');
if (!action) return;

const targetText = action === 'buy' ? config.buyReply : config.sellReply;

try {
const editor = await waitForElement('textarea, .ProseMirror, [contenteditable="true"]', 8000);

window.scrollTo(0, document.body.scrollHeight);
editor.focus();

if (editor.tagName.toLowerCase() === 'textarea') {
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
nativeSetter.call(editor, targetText);
editor.dispatchEvent(new Event('input', { bubbles: true }));
editor.dispatchEvent(new Event('change', { bubbles: true }));
} else {
document.execCommand('insertText', false, targetText);
}

window.history.replaceState({}, document.title, window.location.pathname);

const msg = document.createElement('div');
msg.innerHTML = `✅ 已就绪:<b>${targetText}</b> <br> <span style="font-size:12px;">(为防误触封号,请手动点击发送)</span>`;
msg.style.cssText = "position:fixed; top:20px; left:50%; transform:translateX(-50%); background:rgba(34, 197, 94, 0.9); backdrop-filter:blur(5px); color:white; padding:12px 24px; border-radius:8px; z-index:9999; box-shadow:0 10px 25px rgba(0,0,0,0.3); text-align:center;";
document.body.appendChild(msg);
setTimeout(() => msg.remove(), 4000);

} catch (error) {
console.warn("[倒狗雷达] 未找到评论框:", error);
}
};

// ================== 启动入口 ==================
const init = () => {
createUI();
updateUnreadStatus();

if (window.location.href.includes('/post') || window.location.href.includes('/discussions/')) {
autoReplyEngine();
}

scanDOM();
new MutationObserver(() => scanDOM()).observe(document.body, { childList: true, subtree: true });

setTimeout(backgroundFetch, 10000);
};

setTimeout(init, 1000);

})();


推荐论坛自带避免倒狗破坏交易的有效方式:https://www.nodeseek.com/setting#block

最新回复 (52)
  • ryan-zz 06-05 15:18
    1

    6666

  • 昶- 06-05 15:18
    2

    ^-^ 怎么没艾特我 还是我先看见的

  • NEO-GOGOGO 06-05 15:18
    3

    插眼

  • cshaizhihao 楼主 06-05 15:18
    4

    @昶- #2 我刚准备去那边叫你的。

  • hging 06-05 15:18
    5

    一会儿闻着味儿就来了

  • todesk 06-05 15:18
    6

    666

  • cshaizhihao 楼主 06-05 15:18
    7

    @hging #5 谁?

  • Mario1210 06-05 15:18
    8

    支持 先装为敬

  • 昶- 06-05 15:18
    9

    @cshaizhihao #4 发布于2026/6/5 15:18:22

    @昶- #2 我刚准备去那边叫你的。


    ^-^

  • 葡式蛋挞 06-05 15:19
    10

    帖子里面会有出现现身说法的

  • yaobaobao 06-05 15:19
    11

    高级

  • WhyUCry 06-05 15:19
    12

    666,还能这么玩 ^-^

  • lsdnine 06-05 15:19
    13

    ^-^ ^-^

  • hging 06-05 15:19
    14

    @cshaizhihao #7 那个男人。 问你脚本卖不卖(狗头

  • xiaowork 06-05 15:19
    15

    ^-^

  • domingokkk 06-05 15:20
    16

    倒狗专属监控 ^-^

  • 冬兵Pa-kee 06-05 15:21
    17

    照妖镜会不会照的倒狗无处遁形?

  • bffb42 06-05 15:21
    18

    66666

  • cyber66 06-05 15:22
    19

    66666

  • cshaizhihao 楼主 06-05 15:22
    20

    @hging #14 哪个男人

  • neilyo 06-05 15:22
    21

    ^-^

    脚本启动

  • madolche 06-05 15:22
    22

    我是倒狗,请添加我 ^-^

  • Liora 06-05 15:23
    23

    支持!

  • cyfrabit1976 06-05 15:24
    24

    牛,支持技术贴

  • Liora 06-05 15:25
    25

    image

    已生效 ^-^

  • vigor 06-05 15:26
    26

    nb ^-^

  • shuqinmao 06-05 15:27
    27

    bd

  • Determinant 06-05 15:27
    28

    必须支持,直接收藏

  • Tokin 06-05 15:29
    29

    太高级了,哈哈哈哈哈

  • cshaizhihao 楼主 06-05 15:30
    30

    @madolche #22 跟fencer哥比真的差一大截了还是。

  • SolitudeAlma 06-05 15:36
    31

    手机适配不太行

  • cshaizhihao 楼主 06-05 15:37
    32

    @SolitudeAlma #31 我的错,我道歉。

  • SolitudeAlma 06-05 15:40
    33

    @cshaizhihao #32 。。 提个建议而已

  • SolitudeAlma 06-05 15:41
    34

    @cshaizhihao #32 悬浮窗点开太大了

  • letdoit 06-05 15:42
    35

    已安装支持

  • IwasakiYouko 06-05 15:42
    36

    笑死我了,干得好

  • mmys0301 06-05 15:45
    37

    6666

  • MickeyXian 06-05 15:49
    38

    66666

  • cshaizhihao 楼主 06-05 15:53
    39

    @SolitudeAlma #34 我没考虑移动端。 我甚至没考虑这个脚本的实用性。

  • mmys0301 06-05 15:57
    40

    倒狗多少有点不尊重人

    建议改为炒鸡者

    ^-^ ^-^ ^-^

  • 花儿 06-05 15:58
    41

    这不得来个云端同步 ^-^

  • shari 06-05 16:02
    42

    @花儿 #41 可以可以 哈哈哈

  • etotakeo 06-05 16:03
    43

    ^-^

  • 小A在上网 06-05 16:03
    44

    支持 ^-^

  • Ariabennett 06-05 16:04
    45

    这不来个加精LOL

  • TokisakiKurumi 06-05 16:10
    46

    感谢分享

  • cshaizhihao 楼主 06-05 16:12
    47

    @花儿 #41 收到

  • cshaizhihao 楼主 06-05 16:13
    48

    @mmys0301 #40 倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗倒狗

  • NONG 06-05 16:18
    49

    666

  • gblaowang 06-05 16:19
    50

    image

    哈哈哈哈哈哈哈哈哈

  • asdfvf2 06-05 16:44
    52

    @Liora #25 这个人出了名的导狗,我都把它黑名单了

  • fencer 06-05 21:23
    60

    不错还可以多加些标签


    @cshaizhihao #30 发布于2026/6/5 15:30:41,编辑于2026/6/5 15:30:52

    @madolche #22 跟fencer哥比真的差一大截了还是。


* 帖子来源NodeSeek
返回