koishi-plugin-vrchat 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +7 -0
- package/lib/index.js +175 -0
- package/package.json +33 -0
- package/readme.md +5 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "vrchat";
|
|
3
|
+
export declare const inject: string[];
|
|
4
|
+
export interface Config {
|
|
5
|
+
}
|
|
6
|
+
export declare const Config: Schema<Config>;
|
|
7
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name2 in all)
|
|
8
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
Config: () => Config,
|
|
24
|
+
apply: () => apply,
|
|
25
|
+
inject: () => inject,
|
|
26
|
+
name: () => name
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var import_koishi = require("koishi");
|
|
30
|
+
var name = "vrchat";
|
|
31
|
+
var inject = ["http"];
|
|
32
|
+
var Config = import_koishi.Schema.object({});
|
|
33
|
+
function apply(ctx, config) {
|
|
34
|
+
let auth;
|
|
35
|
+
ctx.command("vrchat-login", "登录 VRChat API").action(async ({ session }) => {
|
|
36
|
+
if (!session.isDirect) return "请通过私聊进行登录";
|
|
37
|
+
await session.send("请输入用户名或邮箱地址:");
|
|
38
|
+
const username = await session.prompt();
|
|
39
|
+
if (!username) return "输入超时。";
|
|
40
|
+
await session.send("请输入密码:");
|
|
41
|
+
const password = await session.prompt();
|
|
42
|
+
if (!password) return "输入超时。";
|
|
43
|
+
const bytes = new TextEncoder().encode(`${encodeURIComponent(username)}:${encodeURIComponent(password)}`);
|
|
44
|
+
const authResp = await ctx.http("https://api.vrchat.cloud/api/1/auth/user", {
|
|
45
|
+
headers: {
|
|
46
|
+
"Authorization": `Basic ${import_koishi.Binary.toBase64(bytes)}`,
|
|
47
|
+
"User-Agent": "VRCX 2026.02.11"
|
|
48
|
+
},
|
|
49
|
+
responseType: "json",
|
|
50
|
+
validateStatus: /* @__PURE__ */ __name((status) => status < 500, "validateStatus")
|
|
51
|
+
});
|
|
52
|
+
if (authResp.data.error) {
|
|
53
|
+
return authResp.data.error.message.slice(1, -1);
|
|
54
|
+
}
|
|
55
|
+
if (authResp.data.requiresTwoFactorAuth?.[0] === "emailOtp") {
|
|
56
|
+
await session.send("请输入发送到邮箱的验证码:");
|
|
57
|
+
const code = await session.prompt();
|
|
58
|
+
if (!code) return "输入超时。";
|
|
59
|
+
const cookie = authResp.headers.get("set-cookie").split("; ")[0];
|
|
60
|
+
const emailOtpResp = await ctx.http.post("https://api.vrchat.cloud/api/1/auth/twofactorauth/emailotp/verify", { code }, {
|
|
61
|
+
headers: {
|
|
62
|
+
"User-Agent": "VRCX 2026.02.11",
|
|
63
|
+
"Cookie": cookie
|
|
64
|
+
},
|
|
65
|
+
responseType: "json",
|
|
66
|
+
validateStatus: /* @__PURE__ */ __name((status) => status < 500, "validateStatus")
|
|
67
|
+
});
|
|
68
|
+
if (emailOtpResp.verified) {
|
|
69
|
+
auth = cookie;
|
|
70
|
+
return "登录成功";
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
ctx.logger.info(authResp);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
ctx.command("vrchat-avatars <keyword:text>", "检索 VRChat 模型").option("number", "-n <value:number>", { fallback: 10 }).action(async ({ session, options }, keyword) => {
|
|
77
|
+
if (!auth) return "请先登录";
|
|
78
|
+
if (!keyword) return "请输入关键词";
|
|
79
|
+
const [msgId] = await session.send("检索中…");
|
|
80
|
+
const resp = await ctx.http.get(`https://api.avtrdb.com/v3/avatar/search/vrcx?search=${encodeURIComponent(keyword)}&n=${options.number}`, {
|
|
81
|
+
responseType: "json"
|
|
82
|
+
});
|
|
83
|
+
const avatarlist = [];
|
|
84
|
+
for (const item of resp) {
|
|
85
|
+
try {
|
|
86
|
+
const resp2 = await ctx.http.get(`https://api.vrchat.cloud/api/1/avatars/${item.id}`, {
|
|
87
|
+
headers: {
|
|
88
|
+
"User-Agent": "VRCX 2026.02.11",
|
|
89
|
+
"Cookie": auth
|
|
90
|
+
},
|
|
91
|
+
responseType: "json"
|
|
92
|
+
});
|
|
93
|
+
avatarlist.push(resp2);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
await session.send(`<message forward>${avatarlist.map(
|
|
98
|
+
(e) => `<message>模型名:
|
|
99
|
+
${e.name}
|
|
100
|
+
|
|
101
|
+
描述:
|
|
102
|
+
${e.description}
|
|
103
|
+
|
|
104
|
+
模型 ID:
|
|
105
|
+
${e.id}
|
|
106
|
+
|
|
107
|
+
作者名:
|
|
108
|
+
${e.authorName}
|
|
109
|
+
|
|
110
|
+
状态:
|
|
111
|
+
${e.releaseStatus}
|
|
112
|
+
|
|
113
|
+
创建时间:
|
|
114
|
+
${new Date(e.created_at).toLocaleString()}
|
|
115
|
+
|
|
116
|
+
最后更新时间:
|
|
117
|
+
${new Date(e.updated_at).toLocaleString()}<img src="${e.imageUrl}"></img></message>`
|
|
118
|
+
).join("")}</message>`);
|
|
119
|
+
await session.bot.deleteMessage(session.channelId, msgId);
|
|
120
|
+
});
|
|
121
|
+
ctx.command("vrchat-worlds <keyword:text>", "检索 VRChat 世界").option("number", "-n <value:number>", { fallback: 10 }).action(async ({ session, options }, keyword) => {
|
|
122
|
+
if (!auth) return "请先登录";
|
|
123
|
+
if (!keyword) return "请输入关键词";
|
|
124
|
+
const [msgId] = await session.send("检索中…");
|
|
125
|
+
const resp = await ctx.http.get(`https://api.vrchat.cloud/api/1/worlds/?n=${options.number}&offset=0&sort=relevance&search=${encodeURIComponent(keyword)}&order=descending&tag=system_approved`, {
|
|
126
|
+
headers: {
|
|
127
|
+
"User-Agent": "VRCX 2026.02.11",
|
|
128
|
+
"Cookie": auth
|
|
129
|
+
},
|
|
130
|
+
responseType: "json"
|
|
131
|
+
});
|
|
132
|
+
const messages = [];
|
|
133
|
+
for (const item of resp) {
|
|
134
|
+
let tags = [];
|
|
135
|
+
for (const tag of item.tags) {
|
|
136
|
+
if (tag.startsWith("author_tag_")) {
|
|
137
|
+
tags.push(tag.replace("author_tag_", ""));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
messages.push(`<message>世界名:
|
|
141
|
+
${item.name}
|
|
142
|
+
|
|
143
|
+
作者名:
|
|
144
|
+
${item.authorName}
|
|
145
|
+
|
|
146
|
+
地图内总在线人数:
|
|
147
|
+
${item.occupants}
|
|
148
|
+
|
|
149
|
+
世界 ID:
|
|
150
|
+
${item.id}
|
|
151
|
+
|
|
152
|
+
作者添加的标签:
|
|
153
|
+
${tags.join(", ")}
|
|
154
|
+
|
|
155
|
+
收藏人数:
|
|
156
|
+
${item.favorites}
|
|
157
|
+
|
|
158
|
+
创建时间:
|
|
159
|
+
${new Date(item.created_at).toLocaleString()}
|
|
160
|
+
|
|
161
|
+
最后更新时间:
|
|
162
|
+
${new Date(item.updated_at).toLocaleString()}<img src="${item.imageUrl}"></img></message>`);
|
|
163
|
+
}
|
|
164
|
+
await session.send(`<message forward>${messages.join("")}</message>`);
|
|
165
|
+
await session.bot.deleteMessage(session.channelId, msgId);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
__name(apply, "apply");
|
|
169
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
170
|
+
0 && (module.exports = {
|
|
171
|
+
Config,
|
|
172
|
+
apply,
|
|
173
|
+
inject,
|
|
174
|
+
name
|
|
175
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-vrchat",
|
|
3
|
+
"description": "Search VRChat Avatars and Worlds",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"chatbot",
|
|
14
|
+
"koishi",
|
|
15
|
+
"plugin",
|
|
16
|
+
"vrchat",
|
|
17
|
+
"vrc"
|
|
18
|
+
],
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"koishi": "^4.17.7"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/idranme/koishi-plugin-vrchat.git"
|
|
25
|
+
},
|
|
26
|
+
"koishi": {
|
|
27
|
+
"description": {
|
|
28
|
+
"zh": "检索 VRChat 模型与世界",
|
|
29
|
+
"en": "Search VRChat Avatars and Worlds"
|
|
30
|
+
},
|
|
31
|
+
"browser": true
|
|
32
|
+
}
|
|
33
|
+
}
|