feat: 更新 GAL 平台列表及修复搜索参数

*   重新对 YingZhiGuang 和 TianYouErCiYuan 平台支持
*   移除已失效或不再维护的 TaoHuaYuan(移除搜索功能) 和 Hikarinagi(网站转型) 平台。
*   修复 YouYuDeloli 平台的搜索请求,补充缺失的 submit 参数。
*   同步更新 src/platforms/gal/index.ts 中的平台导出列表。
This commit is contained in:
Jurangren
2025-12-20 08:47:04 +08:00
parent 65789b18be
commit c4839db8c9
5 changed files with 76 additions and 72 deletions

View File

@@ -1,55 +0,0 @@
import { fetchClient } from "../../utils/httpClient";
import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types";
const DATA_URL = "https://peach.sslswwdx.top/page/search/index.json";
interface TaoHuaYuanItem {
title: string;
permalink: string;
}
async function searchTaoHuaYuan(game: string): Promise<PlatformSearchResult> {
const searchResult: PlatformSearchResult = {
count: 0,
items: [],
};
try {
const response = await fetchClient(DATA_URL);
if (!response.ok) {
throw new Error(`Failed to fetch data from ${DATA_URL}`);
}
const data = await response.json() as TaoHuaYuanItem[];
const items: SearchResultItem[] = data
.filter(item => item.title.includes(game))
.map(item => ({
name: item.title.trim(),
url: item.permalink,
}));
searchResult.items = items;
searchResult.count = items.length;
} catch (error) {
if (error instanceof Error) {
searchResult.error = error.message;
} else {
searchResult.error = "An unknown error occurred";
}
searchResult.count = -1;
}
return searchResult;
}
const TaoHuaYuan: Platform = {
name: "桃花源",
color: "lime",
tags: ["NoReq", "SuDrive"],
magic: false,
search: searchTaoHuaYuan,
};
export default TaoHuaYuan;

View File

@@ -1,19 +1,18 @@
import { fetchClient } from "../../utils/httpClient";
import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types";
const API_URL = "https://www.hikarinagi.net/";
const REGEX = /" class="lazyload fit-cover radius8">.*?<h2 class="item-heading"><a target="_blank" href="(?<URL>.*?)">(?<NAME>.*?)<\/a><\/h2>/gs;
const API_URL = "https://www.tiangal.com/search/";
const REGEX = /<h2>\s*<a href="(?<URL>[^"]+)" title="(?<NAME>[^"]+)"/gs;
async function searchHikarinagi(game: string): Promise<PlatformSearchResult> {
async function searchTianYouErCiYuan(game: string): Promise<PlatformSearchResult> {
const searchResult: PlatformSearchResult = {
count: 0,
items: [],
};
try {
const url = new URL(API_URL);
url.searchParams.set("s", game);
const url = new URL(API_URL + encodeURIComponent(game)); // URL path parameter
const response = await fetchClient(url);
if (!response.ok) {
throw new Error(`资源平台 SearchAPI 响应异常状态码 ${response.status}`);
@@ -27,7 +26,7 @@ async function searchHikarinagi(game: string): Promise<PlatformSearchResult> {
if (match.groups?.NAME && match.groups?.URL) {
items.push({
name: match.groups.NAME.trim(),
url: match.groups.URL,
url: new URL(match.groups.URL, API_URL).toString(),
});
}
}
@@ -47,12 +46,12 @@ async function searchHikarinagi(game: string): Promise<PlatformSearchResult> {
return searchResult;
}
const Hikarinagi: Platform = {
name: "Hikarinagi",
const TianYouErCiYuan: Platform = {
name: "天游二次元",
color: "white",
tags: ["LoginPay", "SuDrive"],
magic: false,
search: searchHikarinagi,
tags: ["LoginPay", "MixDrive"],
magic: true,
search: searchTianYouErCiYuan,
};
export default Hikarinagi;
export default TianYouErCiYuan;

View File

@@ -0,0 +1,59 @@
import { fetchClient } from "../../utils/httpClient";
import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types";
const DATA_URL = "https://yinghu.netlify.app/search.xml";
const BASE_URL = "https://yinghu.netlify.app";
const REGEX = /<entry>.*?<title>(.*?)<\/title>.*?<url>(.*?)<\/url>.*?<\/entry>/gs;
async function searchYingZhiGuang(game: string): Promise<PlatformSearchResult> {
const searchResult: PlatformSearchResult = {
count: 0,
items: [],
};
try {
const response = await fetchClient(DATA_URL);
if (!response.ok) {
throw new Error(`Failed to fetch data from ${DATA_URL}`);
}
const xmlText = await response.text();
const matches = xmlText.matchAll(REGEX);
const items: SearchResultItem[] = [];
for (const match of matches) {
const title = match[1];
const urlPath = match[2];
if (title && urlPath && title.includes(game)) {
items.push({
name: title.trim(),
url: BASE_URL + urlPath,
});
}
}
searchResult.items = items;
searchResult.count = items.length;
} catch (error) {
if (error instanceof Error) {
searchResult.error = error.message;
} else {
searchResult.error = "An unknown error occurred";
}
searchResult.count = -1;
}
return searchResult;
}
const YingZhiGuang: Platform = {
name: "萤ノ光",
color: "lime",
tags: ["NoReq", "SuDrive"],
magic: false,
search: searchYingZhiGuang,
};
export default YingZhiGuang;

View File

@@ -13,6 +13,7 @@ async function searchYouYuDeloli(game: string): Promise<PlatformSearchResult> {
try {
const url = new URL(API_URL);
url.searchParams.set("s", game);
url.searchParams.set("submit", '');
const response = await fetchClient(url);
if (!response.ok) {

View File

@@ -7,7 +7,6 @@ import GalgameX from "./GalgameX";
import GalTuShuGuan from "./GalTuShuGuan";
import GGBases from "./GGBases";
import GGS from "./GGS";
import Hikarinagi from "./Hikarinagi";
import JiMengACG from "./JiMengACG";
import Koyso from "./Koyso";
import KunGalgame from "./KunGalgame";
@@ -18,11 +17,12 @@ import MiaoYuanLingYu from "./MiaoYuanLingYu";
import Nysoure from "./Nysoure";
import QingJiACG from "./QingJiACG";
import ShenShiTianTang from "./ShenShiTianTang";
import TaoHuaYuan from "./TaoHuaYuan";
import TianYouErCiYuan from "./TianYouErCiYuan";
import TouchGal from "./TouchGal";
import VikaACG from "./VikaACG";
import WeiZhiYunPan from "./WeiZhiYunPan";
import xxacg from "./xxacg";
import YingZhiGuang from "./YingZhiGuang";
import YouYuDeloli from "./YouYuDeloli";
import YueYao from "./YueYao";
import ZeroFive from "./ZeroFive";
@@ -39,7 +39,6 @@ const platforms: Platform[] = [
GalTuShuGuan,
GGBases,
GGS,
Hikarinagi,
JiMengACG,
Koyso,
KunGalgame,
@@ -50,11 +49,12 @@ const platforms: Platform[] = [
Nysoure,
QingJiACG,
ShenShiTianTang,
TaoHuaYuan,
TianYouErCiYuan,
TouchGal,
VikaACG,
WeiZhiYunPan,
xxacg,
YingZhiGuang,
YouYuDeloli,
YueYao,
ZeroFive,