SnowCat 雪猫底层全源码:NapCat 4.18.28 底座 + SnowLuma 能力移植 + V8 通道适配 9.9.37

26 包 monorepo(TS 全源码):
- snowcat-core: NT 内核 API 封装 + listener(含 9.9.37 六回调适配)+ Packet 发包
- snowcat-onebot: OneBot v11 全动作 + MCP Streamable HTTP 适配器 + 稳定线
- snowcat-webui-frontend/backend: 雪猫控制台(React+HeroUI)
- snowcat-shell: 单文件 bundle 出口(vite inlineDynamicImports)
- snowcat-native: napi2native / MoeHoo / ffmpeg / pty 运行时
- 56 项 SnowLuma 独门动作移植(qzone 全家桶/群相册/装扮/闪照/收藏)
- 工具件: 解包器/启动器/便携制作器/doctor

GitHub 关联已全量指向 DandanLLab/SnowCatQQ
This commit is contained in:
天天的鸟蛋蛋 committed 2026-11-12 06:27:36 +08:00
commit b9655a5ab1
1048 files changed
+130851

No files matched your search

@@ -0,0 +1,322 @@
/**
* SnowCat · QQ空间公共空间(空友推荐)13 动作
*
* 底层:snowcat-core/apis/qzone-public-web.ts(SnowLuma qzone-public.ts 移植)
* 动作约定:feed/comment/reply 等复杂对象由调用方从 get_qzone_public_feeds /
* get_qzone_public_feed_detail 的返回中原样回传(透明通道,不做二次建模)。
*/
import { OneBotAction } from '@/snowcat-onebot/action/OneBotAction';
import { ActionName } from '@/snowcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
const FeedObject = Type.Any({ description: '完整动态对象(来自 get_qzone_public_feeds/feed_detail,原样回传)' });
const CommentObject = Type.Any({ description: '评论对象(原样回传)' });
const ReplyObject = Type.Optional(Type.Any({ description: '回复对象(原样回传)' }));
const UserObject = Type.Any({ description: '用户身份对象(详情/列表响应里的 user 形态)' });
/** 公共动作共用的 WebApi 快捷取凭证。 */
function publicApi (action: OneBotAction<unknown, unknown>) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (action as any).core.apis.WebApi;
}
// 1. get_qzone_public_capabilities —— 查询账号空友入口白名单
const CapPayload = Type.Object({});
export class GetQzonePublicCapabilities extends OneBotAction<Static<typeof CapPayload>, unknown> {
override actionName = ActionName.GetQzonePublicCapabilities;
override actionSummary = '查询空友入口能力';
override actionDescription = '查询当前账号在 QQ 空间公共空间(空友)各入口的白名单能力';
override actionTags = ['扩展接口'];
override payloadExample = {};
override returnExample = { entrance1: true, entrance15: false };
override payloadSchema = CapPayload;
override returnSchema = Type.Any();
async _handle () {
const api = publicApi(this);
const { uin, g_tk, cookie } = await api.getQzoneAuth();
return api.getQzonePublicCapabilities(cookie, g_tk, uin);
}
}
// 2. get_qzone_public_feeds —— 空友推荐动态流
const FeedsPayload = Type.Object({
cursor: Type.Optional(Type.String({ description: '上次返回的 next_cursor,续翻用' })),
});
export class GetQzonePublicFeeds extends OneBotAction<Static<typeof FeedsPayload>, unknown> {
override actionName = ActionName.GetQzonePublicFeeds;
override actionSummary = '获取空友推荐动态';
override actionDescription = '读取QQ空间公共空间(空友)推荐动态流,cursor 续翻';
override actionTags = ['扩展接口'];
override payloadExample = {};
override returnExample = { feeds: [], has_more: false, next_cursor: null };
override payloadSchema = FeedsPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof FeedsPayload>) {
const { uin, g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).getQzonePublicFeeds(cookie, g_tk, uin, payload.cursor);
}
}
// 3. get_qzone_public_feed_detail —— 空友单条动态详情
const DetailPayload = Type.Object({ feed: FeedObject });
export class GetQzonePublicFeedDetail extends OneBotAction<Static<typeof DetailPayload>, unknown> {
override actionName = ActionName.GetQzonePublicFeedDetail;
override actionSummary = '获取空友动态详情';
override actionDescription = '获取一条空友推荐动态的完整详情(含评论首屏)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {} };
override returnExample = {};
override payloadSchema = DetailPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof DetailPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).getQzonePublicFeedDetail(cookie, g_tk, payload.feed);
}
}
// 4. get_qzone_public_comments —— 空友评论分页
const CommentsPayload = Type.Object({
feed: FeedObject,
cursor: Type.String({ description: '详情/上页返回的评论 attach_info' }),
});
export class GetQzonePublicComments extends OneBotAction<Static<typeof CommentsPayload>, unknown> {
override actionName = ActionName.GetQzonePublicComments;
override actionSummary = '获取空友评论分页';
override actionDescription = '分页读取一条空友动态的评论';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, cursor: '' };
override returnExample = {};
override payloadSchema = CommentsPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof CommentsPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).getQzonePublicComments(cookie, g_tk, payload.feed, payload.cursor);
}
}
// 5. get_qzone_public_replies —— 空友楼中楼分页
const RepliesPayload = Type.Object({
feed: FeedObject,
comment: CommentObject,
cursor: Type.Optional(Type.String({ description: '回复 attach_info,省略用 comment 自带' })),
page_size: Type.Optional(Type.Union([Type.Number(), Type.String()], { default: 20, description: '每页条数' })),
});
export class GetQzonePublicReplies extends OneBotAction<Static<typeof RepliesPayload>, unknown> {
override actionName = ActionName.GetQzonePublicReplies;
override actionSummary = '获取空友楼中楼分页';
override actionDescription = '分页读取一条空友评论的楼中楼回复';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, comment: {}, cursor: '', page_size: 20 };
override returnExample = {};
override payloadSchema = RepliesPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof RepliesPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).getQzonePublicReplies(
cookie, g_tk, payload.feed, payload.comment,
payload.cursor ?? '', payload.page_size !== undefined ? +payload.page_size : 20,
);
}
}
// 6. set_qzone_public_upvote —— 空友动态点赞/取消(UFO Upvote)
const UpvotePayload = Type.Object({ feed: FeedObject, enable: Type.Boolean({ default: true }) });
export class SetQzonePublicUpvote extends OneBotAction<Static<typeof UpvotePayload>, unknown> {
override actionName = ActionName.SetQzonePublicUpvote;
override actionSummary = '空友动态点赞/取消';
override actionDescription = '对一条空友推荐动态点赞或取消点赞(UFO Upvote/Downvote)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, enable: true };
override returnExample = {};
override payloadSchema = UpvotePayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof UpvotePayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).setQzonePublicUpvote(cookie, g_tk, payload.feed, payload.enable);
}
}
// 7. set_qzone_public_like —— 空友动态点赞(DoLike 系)
const LikePayload = Type.Object({ feed: FeedObject, enable: Type.Boolean({ default: true }) });
export class SetQzonePublicLike extends OneBotAction<Static<typeof LikePayload>, unknown> {
override actionName = ActionName.SetQzonePublicLike;
override actionSummary = '空友动态点赞(DoLike)';
override actionDescription = '对一条空友动态点赞/取消赞(DoLike/UnLike,key 取 cur_like_key)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, enable: true };
override returnExample = {};
override payloadSchema = LikePayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof LikePayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).setQzonePublicLike(cookie, g_tk, payload.feed, payload.enable);
}
}
// 8. set_qzone_public_comment_like —— 空友评论/回复点赞
const CommentLikePayload = Type.Object({
feed: FeedObject,
comment: CommentObject,
reply: ReplyObject,
enable: Type.Boolean({ default: true }),
});
export class SetQzonePublicCommentLike extends OneBotAction<Static<typeof CommentLikePayload>, unknown> {
override actionName = ActionName.SetQzonePublicCommentLike;
override actionSummary = '空友评论/回复点赞';
override actionDescription = '给空友评论点赞(like_type=2)或给楼中楼回复点赞(like_type=3)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, comment: {}, enable: true };
override returnExample = {};
override payloadSchema = CommentLikePayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof CommentLikePayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).setQzonePublicCommentLike(
cookie, g_tk, payload.feed, payload.comment, payload.enable,
payload.reply as Record<string, unknown> | undefined,
);
}
}
// 9. comment_qzone_public_feed —— 空友发评论
const CommentPayload = Type.Object({
feed: FeedObject,
user: UserObject,
content: Type.Union([Type.String(), Type.Array(Type.Any())], { description: '评论内容:纯文本或富内容数组' }),
});
export class CommentQzonePublicFeed extends OneBotAction<Static<typeof CommentPayload>, unknown> {
override actionName = ActionName.CommentQzonePublicFeed;
override actionSummary = '空友发评论';
override actionDescription = '给一条空友推荐动态发评论';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, user: {}, content: '说得好' };
override returnExample = {};
override payloadSchema = CommentPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof CommentPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).commentQzonePublicFeed(
cookie, g_tk, payload.feed,
payload.user as Record<string, unknown>,
payload.content as string | Record<string, unknown>[],
);
}
}
// 10. reply_qzone_public_feed —— 空友回复评论/楼中楼
const ReplyPayload = Type.Object({
feed: FeedObject,
user: UserObject,
comment: CommentObject,
content: Type.Union([Type.String(), Type.Array(Type.Any())], { description: '回复内容' }),
reply: ReplyObject,
});
export class ReplyQzonePublicFeed extends OneBotAction<Static<typeof ReplyPayload>, unknown> {
override actionName = ActionName.ReplyQzonePublicFeed;
override actionSummary = '空友回复评论';
override actionDescription = '在空友动态的评论线程里回复(可点名楼中楼目标)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, user: {}, comment: {}, content: '同意' };
override returnExample = {};
override payloadSchema = ReplyPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof ReplyPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).replyQzonePublicFeed(
cookie, g_tk, payload.feed,
payload.user as Record<string, unknown>,
payload.comment as Record<string, unknown>,
payload.content as string | Record<string, unknown>[],
payload.reply as Record<string, unknown> | undefined,
);
}
}
// 11. delete_qzone_public_comment —— 删空友评论
const DelCommentPayload = Type.Object({ feed: FeedObject, comment: CommentObject });
export class DeleteQzonePublicComment extends OneBotAction<Static<typeof DelCommentPayload>, unknown> {
override actionName = ActionName.DeleteQzonePublicComment;
override actionSummary = '删空友评论';
override actionDescription = '删除一条空友动态的评论(自己的评论)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, comment: {} };
override returnExample = {};
override payloadSchema = DelCommentPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof DelCommentPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).deleteQzonePublicComment(
cookie, g_tk, payload.feed, payload.comment as Record<string, unknown>,
);
}
}
// 12. delete_qzone_public_reply —— 删空友楼中楼
const DelReplyPayload = Type.Object({ feed: FeedObject, comment: CommentObject, reply: Type.Any({ description: '回复对象(原样回传)' }) });
export class DeleteQzonePublicReply extends OneBotAction<Static<typeof DelReplyPayload>, unknown> {
override actionName = ActionName.DeleteQzonePublicReply;
override actionSummary = '删空友楼中楼';
override actionDescription = '删除一条空友评论的楼中楼回复(自己的回复)';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, comment: {}, reply: {} };
override returnExample = {};
override payloadSchema = DelReplyPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof DelReplyPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).deleteQzonePublicReply(
cookie, g_tk, payload.feed,
payload.comment as Record<string, unknown>,
payload.reply as Record<string, unknown>,
);
}
}
// 13. set_qzone_public_follow —— 空友关注/取关
const FollowPayload = Type.Object({ feed: FeedObject, enable: Type.Boolean({ default: true }) });
export class SetQzonePublicFollow extends OneBotAction<Static<typeof FollowPayload>, unknown> {
override actionName = ActionName.SetQzonePublicFollow;
override actionSummary = '空友关注/取关';
override actionDescription = '关注/取关一条空友动态的作者';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, enable: true };
override returnExample = {};
override payloadSchema = FollowPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof FollowPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).setQzonePublicFollow(cookie, g_tk, payload.feed, payload.enable);
}
}
// 14. forward_qzone_public_feed —— 转发空友动态
const ForwardPayload = Type.Object({ feed: FeedObject, reason: Type.String({ description: '转发理由/附言' }) });
export class ForwardQzonePublicFeed extends OneBotAction<Static<typeof ForwardPayload>, unknown> {
override actionName = ActionName.ForwardQzonePublicFeed;
override actionSummary = '转发空友动态';
override actionDescription = '转发一条空友推荐动态到自己的空间';
override actionTags = ['扩展接口'];
override payloadExample = { feed: {}, reason: '转发' };
override returnExample = {};
override payloadSchema = ForwardPayload;
override returnSchema = Type.Any();
async _handle (payload: Static<typeof ForwardPayload>) {
const { g_tk, cookie } = await publicApi(this).getQzoneAuth();
return publicApi(this).forwardQzonePublicFeed(cookie, g_tk, payload.feed, payload.reason);
}
}