diff --git a/docs/bbs.md b/docs/bbs.md
index 5ab4c9949..6db68a96b 100644
--- a/docs/bbs.md
+++ b/docs/bbs.md
@@ -112,42 +112,6 @@ pageClass: routes
-## A 岛匿名版
-
-### 串
-
-
-
-| 时间线 | 综合版 1 | 围炉 | 欢乐恶搞 | 速报 2 | 推理 | 跑团 | 技术宅 | 料理 | 猫版 | 音乐 | 考试 | 社畜 |
-| --- | ----- | --- | ---- | ---- | -- | --- | --- | -- | -- | -- | -- | --- |
-| -1 | 4 | 120 | 20 | 121 | 11 | 111 | 30 | 32 | 40 | 35 | 56 | 110 |
-
-| 科学 | 文学 | 创意 | 姐妹 1 | 数码 | 女装 | 日记 | 圈内 | 都市怪谈 | 买买买 | 动画 | 漫画 | 美漫 | 国漫 | 小说 |
-| -- | --- | -- | ---- | -- | -- | -- | -- | ---- | --- | -- | -- | -- | -- | -- |
-| 15 | 103 | 17 | 98 | 75 | 97 | 89 | 96 | 81 | 106 | 14 | 12 | 90 | 99 | 19 |
-
-| 轻小说 | GALGAME | 东方 Project | 舰娘 | 虚拟偶像 | VOCALOID | 游戏 | DNF | SE | 手游 |
-| --- | ------- | ---------- | -- | ---- | -------- | -- | --- | --- | -- |
-| 87 | 64 | 5 | 93 | 101 | 6 | 2 | 72 | 124 | 3 |
-
-| Steam | 索尼 | LOL | DOTA | 口袋妖怪 | 战争雷霆 | WOT | Minecraft | 怪物猎人 | 3A 游戏 |
-| ----- | -- | --- | ---- | ---- | ---- | --- | --------- | ---- | ----- |
-| 107 | 24 | 22 | 70 | 38 | 86 | 51 | 10 | 28 | 108 |
-
-| 彩虹六号 | 暴雪游戏 | 卡牌桌游 | MUG | AC 大逃杀 | 任天堂 | AKB | SNH48 | COSPLAY | 声优 |
-| ---- | ---- | ---- | --- | ------ | --- | --- | ----- | ------- | -- |
-| 119 | 23 | 45 | 34 | 29 | 25 | 16 | 100 | 13 | 55 |
-
-| 模型 | 影视 | 军武 | 体育 | 值班室 | 城墙 | 技术支持 | 询问 3 | 宠物 | 摄影 2 |
-| -- | -- | -- | -- | --- | --- | ---- | ---- | --- | ---- |
-| 39 | 31 | 37 | 33 | 18 | 112 | 117 | 114 | 118 | 115 |
-
-| 主播 | 育儿 | 围炉 | 旅行 | 特摄 |
-| --- | --- | --- | --- | -- |
-| 116 | 113 | 120 | 125 | 9 |
-
-
-
## Chiphell
### 子版块
@@ -394,6 +358,30 @@ pageClass: routes
+## X岛匿名版
+
+### 串
+
+
+
+| 综合线 | 非创作线 | 综合版 1 | 欢乐恶搞 | 买买买 (剁手) | 数码 (装机) | 技术 (码农) | 科学 (干货) | 二创 (画师) | 电影 / 电视 | ROLL 点 |
+| ------ | -------- | -------- | -------- | ------------- | ----------- | ----------- | ----------- | ----------- | ----------- | ------- |
+| 1 | 3 | 综合版1 | 欢乐恶搞 | 买买买 | 数码 | 技术宅 | 科学 | 二创 | 影视 | ROLL点 |
+
+| 动画 | 漫画 | 主播 (UP) | 特摄 | 胶佬 (手办) | 小马 (美漫) | 东方 Project | 舰娘 | VOCALOID |
+| ---- | ---- | --------- | ---- | ----------- | ----------- | ------------ | ---- | -------- |
+| 动画 | 漫画 | 主播 | 特摄 | 胶佬 | 小马 | 东方Project | 舰娘 | VOCALOID |
+
+| 游戏综合版 | 手游 | 卡牌桌游 | 任天堂 NS | LOL | SE(FF14) | DOTA & 自走棋 | 联机 (服务器发布) | 怪物猎人 | 鹰角游戏 | 米哈游 | 音乐游戏 |
+| ---------- | ---- | -------- | --------- | --- | -------- | ------------- | --------------------- | -------- | -------- | ------ | -------- |
+| 游戏 | 手游 | 卡牌桌游 | 任天堂 | LOL | SE | DOTA | 联机%28服务器发布%29 | 怪物猎人 | 鹰角游戏 | 米哈游 | 音游 |
+
+| 跑团 | 规则怪谈 | 都市怪谈 (灵异) | 脑洞 (推理) | 料理 (美食) | 宠物 | 学业 (校园) | 社畜 | 育儿 | 摄影 (cos) | 文学 (推书) | 音乐 (推歌) | 技术支持 |
+| ---- | -------- | --------------- | ----------- | ----------- | ---- | ----------- | ---- | ---- | ------------- | ----------- | ----------- | -------- |
+| 跑团 | 规则怪谈 | 都市怪谈 | 推理 | 料理 | 宠物 | 考试 | 社畜 | 育儿 | 摄影%28cos%29 | 文学 | 音乐 | 技术支持 |
+
+
+
## Zuvio
### 校園話題
diff --git a/lib/router.js b/lib/router.js
index fa8f76077..88d534d55 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -2661,9 +2661,6 @@ router.get('/hbut/cs/:type', lazyloadRouteHandler('./routes/universities/hbut/cs
// acwifi
router.get('/acwifi', lazyloadRouteHandler('./routes/acwifi'));
-// a岛匿名版
-router.get('/adnmb/:pid', lazyloadRouteHandler('./routes/adnmb/index'));
-
// MIT科技评论
router.get('/mittrchina/:type', lazyloadRouteHandler('./routes/mittrchina'));
diff --git a/lib/routes/adnmb/index.js b/lib/routes/adnmb/index.js
deleted file mode 100644
index b5025f08f..000000000
--- a/lib/routes/adnmb/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-const got = require('@/utils/got');
-
-const adnmbBaseUrl = 'https://adnmb3.com';
-const cdnBaseUrl = 'https://nmbimg.fastmirror.org/image/';
-
-async function getForumInfo(pid, ctx) {
- const cache_key = `adnmb::forum::${pid}`;
- const cache = await ctx.cache.get(cache_key);
- if (cache) {
- return JSON.parse(cache);
- }
- const forumListResponse = await got(`${adnmbBaseUrl}/Api/getForumList`);
- const matchedForum = forumListResponse.data
- .map((a) => a.forums)
- .flat()
- .filter((c) => c.id === pid || c.name === pid || c.showName === pid);
- if (matchedForum.length === 0) {
- throw 'Forum Not Found';
- }
- const basicForumInfo = (({ id, name, showName, msg }) => ({ id, name, showName, msg }))(matchedForum[0]);
- ctx.cache.set(cache_key, JSON.stringify(basicForumInfo));
- return basicForumInfo;
-}
-
-module.exports = async (ctx) => {
- const pid = ctx.params.pid;
-
- const forumInfo = await getForumInfo(pid, ctx);
-
- const url = forumInfo.name === '时间线' ? `${adnmbBaseUrl}/Api/timeline?page=1` : `${adnmbBaseUrl}/Api/showf?id=${forumInfo.id}&page=1`;
- const response = await got({
- method: 'get',
- url,
- });
- const data = response.data;
-
- const items = [];
- data.forEach((item) => {
- const newItems = {
- title: item.content,
- pubDate: new Date(item.now.replace(/\(.*?\)/g, ' ') + ' +0800').toUTCString(),
- link: `${adnmbBaseUrl}/t/${item.id}`,
- };
- const img = item.img !== '' ? '
' : '';
- let replys = '';
- item.replys.forEach((reply) => {
- const replyImg = reply.img !== '' ? '
' : '';
- replys += `
${reply.title} ${reply.name} ${reply.now} ID:${reply.userid} No.${reply.id}
- ${reply.content}
- ${replyImg}
-
- `;
- });
- newItems.description = `${item.title} ${item.name} ${item.now} ID:${item.userid} No.${item.id}
- ${item.content}
- ${img}
-
- ${replys}
- `;
- items.push(newItems);
- });
-
- ctx.state.data = {
- title: `${forumInfo.showName ? forumInfo.showName : forumInfo.name} - A岛匿名版`,
- link: `${adnmbBaseUrl}/f/${forumInfo.name}`,
- description: forumInfo.msg,
- item: items,
- };
-};
diff --git a/lib/v2/nmbxd1/forum.js b/lib/v2/nmbxd1/forum.js
new file mode 100644
index 000000000..db9cfc5cc
--- /dev/null
+++ b/lib/v2/nmbxd1/forum.js
@@ -0,0 +1,58 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+ const rootUrl = 'https://www.nmbxd1.com';
+ const currentUrl = /^\d+$/.test(id) ? `${rootUrl}/Forum/timeline/id/${id}` : `${rootUrl}/f/${id}`;
+ const response = await got(currentUrl);
+ const $ = cheerio.load(response.data);
+ $('.h-threads-img-tool').remove();
+ $('.h-threads-item-reply-icon').remove();
+ $('.h-admin-tool').remove();
+ $('.h-threads-tips').remove();
+ $('.h-threads-info-report-btn').remove();
+ $('.h-threads-info-reply-btn').remove();
+
+ const items = $('.h-threads-item')
+ .get()
+ .map((item) => {
+ item = $(item);
+ // Do not remove the info element to keep the description style consistent.
+ const info = item.find('.h-threads-item-main .h-threads-info');
+ const title = info.find('.h-threads-info-title').text();
+ const author = [info.find('.h-threads-info-uid font'), info.find('.h-threads-info-uid')]
+ .find((elem) => elem.length > 0)
+ .contents()
+ .first()
+ .text()
+ .replace(/^ID:/, '');
+ const category = info.find('spam').text();
+ const link = new URL(rootUrl + info.find('.h-threads-info-id').attr('href'));
+ // cleanup query paramter
+ link.query = link.search = '';
+ const pubDate = timezone(parseDate(info.find('.h-threads-info-createdat').text().replace(/\(.\)/, ' ')), +8);
+
+ return {
+ title,
+ author,
+ category,
+ description: art(path.join(__dirname, 'templates/description.art'), {
+ item: item.html(),
+ }),
+ pubDate,
+ link: link.toString(),
+ };
+ });
+
+ ctx.state.data = {
+ title: $('title').text(),
+ link: currentUrl,
+ description: $('meta[name=description]').attr('content'),
+ item: items,
+ };
+};
diff --git a/lib/v2/nmbxd1/maintainer.js b/lib/v2/nmbxd1/maintainer.js
new file mode 100644
index 000000000..ec6e77e91
--- /dev/null
+++ b/lib/v2/nmbxd1/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/:id': ['miles170'],
+};
diff --git a/lib/v2/nmbxd1/radar.js b/lib/v2/nmbxd1/radar.js
new file mode 100644
index 000000000..d5dbb1d2f
--- /dev/null
+++ b/lib/v2/nmbxd1/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'nmbxd1.com': {
+ _name: 'X岛匿名版',
+ www: [
+ {
+ title: '串',
+ docs: 'https://docs.rsshub.app/bbs.html#x-dao-ni-ming-ban',
+ source: ['/Forum/timeline/id/:id', '/f/:id'],
+ target: '/nmbxd1/:id',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/nmbxd1/router.js b/lib/v2/nmbxd1/router.js
new file mode 100644
index 000000000..49da3c692
--- /dev/null
+++ b/lib/v2/nmbxd1/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/:id', require('./forum'));
+};
diff --git a/lib/v2/nmbxd1/templates/description.art b/lib/v2/nmbxd1/templates/description.art
new file mode 100644
index 000000000..e22906784
--- /dev/null
+++ b/lib/v2/nmbxd1/templates/description.art
@@ -0,0 +1,65 @@
+
+{{@ item }}
+
+
\ No newline at end of file