karin-plugin-kkk 1.3.0 → 1.4.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # 变更日志
2
2
 
3
+ ## [1.4.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.3.0...v1.4.0) (2025-05-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * close [#78](https://github.com/ikenxuan/karin-plugin-kkk/issues/78) ([39ae7e4](https://github.com/ikenxuan/karin-plugin-kkk/commit/39ae7e4b169c8c41fc11a8f685bf64af9d1aa9f1))
9
+ * close [#80](https://github.com/ikenxuan/karin-plugin-kkk/issues/80) ([f3b30b2](https://github.com/ikenxuan/karin-plugin-kkk/commit/f3b30b2b95936b1b0bae09d058f52a65a3ca3268))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * close [#74](https://github.com/ikenxuan/karin-plugin-kkk/issues/74) ([b16c890](https://github.com/ikenxuan/karin-plugin-kkk/commit/b16c8909fc1551bf54fc5945d5d44ee4cad6bfe5))
15
+ * close [#79](https://github.com/ikenxuan/karin-plugin-kkk/issues/79) ([41fb13b](https://github.com/ikenxuan/karin-plugin-kkk/commit/41fb13b2208c1efa1e22cd50103ab6157ea1c44f))
16
+ * 匹配m.douyin.com。close [#77](https://github.com/ikenxuan/karin-plugin-kkk/issues/77) ([c82c3f6](https://github.com/ikenxuan/karin-plugin-kkk/commit/c82c3f6b30f4dc0ef5588035786e3755aae2b451))
17
+ * 将打包工具从`tsup`迁移到`vite` 适配`node-kairn` 1.8.0 版本 ([#71](https://github.com/ikenxuan/karin-plugin-kkk/issues/71)) ([fbbc329](https://github.com/ikenxuan/karin-plugin-kkk/commit/fbbc3297fb3d1cd3b9a0a6a630f0602de8624c10))
18
+
3
19
  ## [1.3.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.2.3...v1.3.0) (2025-04-26)
4
20
 
5
21
 
@@ -13,6 +13,22 @@ numcomment: 5
13
13
  # 解析视频是否优先保内容,true为优先保证上传将使用最低分辨率,false为优先保清晰度将使用最高分辨率
14
14
  videopriority: false
15
15
 
16
+ # 视频画质偏好设置,0 为自动根据大小选择,其他为固定画质
17
+ # - 0: 自动根据大小选择
18
+ # - 6: 240P 极速 (仅MP4格式支持)
19
+ # - 16: 360P 流畅
20
+ # - 32: 480P 清晰
21
+ # - 64: 720P 高清 (WEB默认值)
22
+ # - 74: 720P60 高帧率 (需登录)
23
+ # - 80: 1080P 高清 (TV/APP默认值,需登录)
24
+ # - 112: 1080P+ 高码率 (需大会员)
25
+ # - 116: 1080P60 高帧率 (需大会员)
26
+ # - 120: 4K 超清 (需大会员且支持4K)
27
+ videoQuality: 0
28
+
29
+ # 自动画质模式下可接受的最大视频大小(单位:MB),仅在 videoQuality 为 0 时生效
30
+ maxAutoVideoSize: 50
31
+
16
32
  # 根据「视频拦截阈值」自动选择合适的分辨率,关闭后默认选择最大分辨率进行下载
17
33
  autoResolution: true
18
34
 
package/lib/Version.js ADDED
@@ -0,0 +1,16 @@
1
+ import fs from "node:fs";
2
+ import require$$7$1 from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { karinPathRoot } from "node-karin/root";
5
+ const pluginPath = require$$7$1.join(fileURLToPath(import.meta.url), "../..");
6
+ const pkg = JSON.parse(fs.readFileSync(require$$7$1.join(pluginPath, "package.json"), "utf-8"));
7
+ const Version = {
8
+ pluginName: pkg.name,
9
+ pluginVersion: pkg.version,
10
+ pluginPath,
11
+ karinVersion: process.env.KARIN_VERSION,
12
+ karinPath: karinPathRoot
13
+ };
14
+ export {
15
+ Version
16
+ };
package/lib/apps/admin.js CHANGED
@@ -1,52 +1,206 @@
1
- import { createRequire } from 'module';
2
- import '../chunk-KQITAYDY.js';
3
- import { bilibiliLogin, douyinLogin } from '../chunk-5WIDO4V7.js';
4
- import { Config, Common } from '../chunk-DSCWGW73.js';
5
- import { init_esm_shims } from '../chunk-XHTHHTBA.js';
6
- import fs from 'node:fs';
7
- import karin, { logger } from 'node-karin';
8
- import path from 'path';
9
-
10
- createRequire(import.meta.url);
11
-
12
- // src/apps/admin.ts
13
- init_esm_shims();
14
- var task = Config.app.rmmp4 && karin.task("[kkk-\u89C6\u9891\u7F13\u5B58\u81EA\u52A8\u5220\u9664]", "0 0 4 * * *", async () => {
1
+ import fs from "node:fs";
2
+ import karin, { handler, segment, logger } from "node-karin";
3
+ import require$$1 from "path";
4
+ import "sequelize";
5
+ import { d as Common, C as Config } from "../chunk/douyin-CpQOEMNX.js";
6
+ import { Version } from "../Version.js";
7
+ import "stream/promises";
8
+ import "node:path";
9
+ import { b as bilibiliLogin } from "../chunk/index-BoFo2rq6.js";
10
+ import "../chunk/index-BDlGFCbK.js";
11
+ import { execSync, spawn } from "node:child_process";
12
+ import { chromium } from "playwright";
13
+ const startXvfb = async () => {
14
+ if (process.platform !== "linux") return;
15
+ const DISPLAY_NUMBER = ":150";
16
+ const LOCK_FILE = "/tmp/.X150-lock";
17
+ try {
18
+ execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
19
+ logger.debug(`检测到 DISPLAY ${DISPLAY_NUMBER} 已经在运行,无需启动新的 Xvfb。`);
20
+ return;
21
+ } catch (err) {
22
+ logger.debug(logger.red(`未检测到 DISPLAY ${DISPLAY_NUMBER},尝试启动 Xvfb...`));
23
+ }
24
+ if (fs.existsSync(LOCK_FILE)) {
25
+ logger.debug(logger.red(`检测到锁文件 ${LOCK_FILE},可能存在冲突。尝试清理...`));
26
+ try {
27
+ fs.unlinkSync(LOCK_FILE);
28
+ logger.debug(`成功清理锁文件 ${LOCK_FILE}`);
29
+ } catch (err) {
30
+ logger.debug(logger.red(`无法清理锁文件 ${LOCK_FILE},请检查权限或手动处理。`));
31
+ throw err;
32
+ }
33
+ }
34
+ const xvfb = spawn("Xvfb", [DISPLAY_NUMBER, "-ac", "-screen", "0", "1280x1024x24"], {
35
+ stdio: "inherit"
36
+ });
37
+ xvfb.unref();
38
+ process.env.DISPLAY = DISPLAY_NUMBER;
39
+ let retries = 5;
40
+ while (retries > 0) {
41
+ try {
42
+ execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
43
+ logger.debug(`Xvfb (${DISPLAY_NUMBER}) 启动成功`);
44
+ return;
45
+ } catch (err) {
46
+ logger.debug(logger.yellow(`Xvfb (${DISPLAY_NUMBER}) 启动失败,正在重试...`));
47
+ retries -= 1;
48
+ if (retries > 0) {
49
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
50
+ } else {
51
+ logger.debug(logger.red("Xvfb 启动失败,重试多次后仍未成功"));
52
+ throw err;
53
+ }
54
+ }
55
+ }
56
+ };
57
+ const douyinLogin = async (e) => {
58
+ const hal = await handler.call("kkk.douyinLogin", { e });
59
+ if (hal) return true;
60
+ const msg_id = [];
61
+ const message1 = await e.reply("免责声明:\n您将通过扫码完成获取抖音网页端的用户登录凭证(ck),该ck将用于请求抖音WEB API接口。\n本BOT不会上传任何有关你的信息到第三方,所配置的 ck 只会用于请求官方 API 接口。\n我方仅提供视频解析及相关抖音内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~");
62
+ try {
63
+ startXvfb();
64
+ const browser = await chromium.launch({
65
+ headless: false,
66
+ args: [
67
+ "--disable-blink-features=AutomationControlled",
68
+ // 禁用自动化控制
69
+ "--window-position=-10000,-10000",
70
+ // 将窗口移到屏幕外
71
+ "--start-minimized",
72
+ // 启动时最小化
73
+ "--mute-audio",
74
+ // 静音
75
+ "--no-sandbox"
76
+ // 使用无沙箱模式,适合无桌面环境
77
+ ]
78
+ });
79
+ const page = await browser.newPage();
80
+ await page.goto("https://www.douyin.com", { timeout: 12e4 });
81
+ const timeout = new Promise((resolve) => setTimeout(async () => {
82
+ await browser.close();
83
+ }, 12e4));
84
+ const qrCodePromise = (async () => {
85
+ try {
86
+ const qrCodeBase64 = await waitQrcode(page);
87
+ const base64Data = qrCodeBase64 ? qrCodeBase64.replace(/^data:image\/\w+;base64,/, "") : "";
88
+ const buffer = Buffer.from(base64Data, "base64");
89
+ fs.writeFileSync(`${Common.tempDri.default}DouyinLoginQrcode.png`, buffer);
90
+ const message2 = await e.reply([segment.image("base64://" + base64Data), segment.text("请在120秒内通过抖音APP扫码进行登录")], { reply: true });
91
+ msg_id.push(message2.messageId, message1.messageId);
92
+ page.on("response", async (response) => {
93
+ try {
94
+ logger.debug(`接收到响应:${response.url()}`);
95
+ if (response.status() === 302 && response.url().includes("/passport/sso/login/callback")) {
96
+ const localCookies = await page.context().cookies();
97
+ const cookieString = localCookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
98
+ Config.Modify("cookies", "douyin", cookieString);
99
+ await e.reply("登录成功!用户登录凭证已保存至cookies.yaml", { reply: true });
100
+ await browser.close();
101
+ await Promise.all(msg_id.map(async (id) => {
102
+ await e.bot.recallMsg(e.contact, id);
103
+ }));
104
+ } else if (response.headers()["content-type"] && response.headers()["content-type"].includes("application/json") && response.url().includes("https://sso.douyin.com")) {
105
+ const responseBody = await response.body();
106
+ const jsonResponse = JSON.parse(responseBody.toString());
107
+ logger.debug(`SSO 回调 Code:${jsonResponse.error_code}`, `响应内容:${jsonResponse.description}`);
108
+ if (jsonResponse.error_code === 2046) {
109
+ logger.debug("需要短信验证码");
110
+ await page.getByText("接收短信验证").click();
111
+ const elements = page.locator(":has-text('为保护账号安全,请输入当前手机号')");
112
+ const texts = await elements.allInnerTexts();
113
+ await page.getByText("获取验证码").click();
114
+ const message3 = await e.reply(segment.text(texts.pop()));
115
+ msg_id.push(message3.messageId);
116
+ const ctx = await karin.ctx(e, { reply: true });
117
+ await page.getByPlaceholder("请输入验证码").click();
118
+ await page.getByPlaceholder("请输入验证码").fill(ctx.msg);
119
+ await page.getByText("验证", { exact: true }).click();
120
+ }
121
+ }
122
+ } catch (error) {
123
+ await browser.close();
124
+ await Promise.all(msg_id.map(async (id) => {
125
+ await e.bot.recallMsg(e.contact, id);
126
+ }));
127
+ }
128
+ });
129
+ } catch (error) {
130
+ await browser.close();
131
+ await Promise.all(msg_id.map(async (id) => {
132
+ await e.bot.recallMsg(e.contact, id);
133
+ }));
134
+ await e.reply("登录超时!二维码已失效!", { reply: true });
135
+ logger.error(error);
136
+ }
137
+ })();
138
+ await Promise.race([qrCodePromise, timeout]);
139
+ } catch (error) {
140
+ logger.error(error);
141
+ if (error.message.includes("npx playwright install")) {
142
+ const msg = await e.reply("首次使用,正在初始化 playwright 环境,请稍等片刻...");
143
+ execSync("npx playwright install chromium", { cwd: Version.pluginPath, stdio: "inherit" });
144
+ await e.reply(`playwright 初始化成功,请再次发送「${e.msg}」`);
145
+ await e.bot.recallMsg(e.contact, msg.messageId);
146
+ return true;
147
+ } else {
148
+ await e.reply("chromiun 环境初始化失败,请查看控制台错误日志", { reply: true });
149
+ }
150
+ }
151
+ return true;
152
+ };
153
+ const waitQrcode = async (page) => {
154
+ const qrCodeSelector = ".web-login-scan-code__content__qrcode-wrapper img";
155
+ const loginButton = page.getByRole("button", { name: "登录" });
156
+ const qrCodeImage = await page.waitForSelector(qrCodeSelector, { state: "attached", timeout: 3e4 });
157
+ if (qrCodeImage) {
158
+ const qrCodeBase64 = await qrCodeImage.getAttribute("src");
159
+ return qrCodeBase64;
160
+ } else {
161
+ await loginButton.click();
162
+ await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
163
+ const qrCodeImage2 = await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
164
+ const qrCodeBase64 = await qrCodeImage2.getAttribute("src");
165
+ return qrCodeBase64;
166
+ }
167
+ };
168
+ const task = Config.app.rmmp4 && karin.task("[kkk-视频缓存自动删除]", "0 0 4 * * *", async () => {
15
169
  try {
16
170
  await removeAllFiles(Common.tempDri.video);
17
- logger.mark(Common.tempDri.video + "\u76EE\u5F55\u4E0B\u6240\u6709\u6587\u4EF6\u5DF2\u5220\u9664");
171
+ logger.mark(Common.tempDri.video + "目录下所有文件已删除");
18
172
  } catch (err) {
19
- console.error("\u5220\u9664\u6587\u4EF6\u65F6\u51FA\u9519:", err);
173
+ console.error("删除文件时出错:", err);
20
174
  }
21
175
  });
22
- var biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (e) => {
176
+ const biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (e) => {
23
177
  await bilibiliLogin(e);
24
178
  return true;
25
- }, { perm: Config.bilibili.loginPerm, name: "kkk-ck\u7BA1\u7406" });
26
- var dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
179
+ }, { perm: Config.bilibili.loginPerm, name: "kkk-ck管理" });
180
+ const dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
27
181
  await douyinLogin(e);
28
182
  return true;
29
- }, { perm: Config.douyin.loginPerm, name: "kkk-ck\u7BA1\u7406" });
30
- var setdyck = karin.command(/^#?(kkk)?s*设置抖音ck$/i, async (e) => {
31
- const msg = await e.reply("\u8BF7\u53D1\u5728120\u79D2\u5185\u9001\u6296\u97F3ck\n\u6559\u7A0B\uFF1Ahttps://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
183
+ }, { perm: Config.douyin.loginPerm, name: "kkk-ck管理" });
184
+ const setdyck = karin.command(/^#?(kkk)?s*设置抖音ck$/i, async (e) => {
185
+ const msg = await e.reply("请发在120秒内送抖音ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
32
186
  const context = await karin.ctx(e);
33
187
  Config.Modify("cookies", "douyin", context.msg);
34
188
  await e.bot.recallMsg(e.contact, msg.messageId);
35
- await e.reply("\u8BBE\u7F6E\u6210\u529F\uFF01", { at: true });
189
+ await e.reply("设置成功!", { at: true });
36
190
  return true;
37
- }, { perm: "master", name: "kkk-ck\u7BA1\u7406", event: "message.friend" });
38
- var setbilick = karin.command(/^#?(kkk)?s*设置s*(B站)ck$/i, async (e) => {
39
- const msg = await e.reply("\u8BF7\u53D1\u5728120\u79D2\u5185\u9001B\u7AD9ck\n\u6559\u7A0B\uFF1Ahttps://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
191
+ }, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
192
+ const setbilick = karin.command(/^#?(kkk)?s*设置s*(B站)ck$/i, async (e) => {
193
+ const msg = await e.reply("请发在120秒内送B站ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
40
194
  const context = await karin.ctx(e);
41
195
  Config.Modify("cookies", "bilibili", context.msg);
42
196
  await e.bot.recallMsg(e.contact, msg.messageId);
43
- await e.reply("\u8BBE\u7F6E\u6210\u529F\uFF01", { at: true });
197
+ await e.reply("设置成功!", { at: true });
44
198
  return true;
45
- }, { perm: "master", name: "kkk-ck\u7BA1\u7406", event: "message.friend" });
199
+ }, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
46
200
  async function removeAllFiles(dir) {
47
201
  const files = await fs.promises.readdir(dir);
48
202
  for (const file of files) {
49
- const filePath = path.join(dir, file);
203
+ const filePath = require$$1.join(dir, file);
50
204
  const stats = await fs.promises.stat(filePath);
51
205
  if (stats.isDirectory()) {
52
206
  await removeAllFiles(filePath);
@@ -56,5 +210,10 @@ async function removeAllFiles(dir) {
56
210
  }
57
211
  }
58
212
  }
59
-
60
- export { biLogin, dylogin, setbilick, setdyck, task };
213
+ export {
214
+ biLogin,
215
+ dylogin,
216
+ setbilick,
217
+ setdyck,
218
+ task
219
+ };
package/lib/apps/help.js CHANGED
@@ -1,22 +1,19 @@
1
- import { createRequire } from 'module';
2
- import { Render, Config, Version, Common } from '../chunk-DSCWGW73.js';
3
- import { init_esm_shims } from '../chunk-XHTHHTBA.js';
4
- import { execSync } from 'node:child_process';
5
- import fs from 'node:fs';
6
- import { markdown } from '@karinjs/md-html';
7
- import karin, { mkdirSync, render, segment, isPackaged, updatePkg, updateGitPlugin, logger, common, restart } from 'node-karin';
8
- import { karinPathTemp } from 'node-karin/root';
9
-
10
- createRequire(import.meta.url);
11
-
12
- // src/apps/help.ts
13
- init_esm_shims();
14
- var help = karin.command(/^#?kkk帮助$/, async (e) => {
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import { m as markdown } from "../chunk/index-BDlGFCbK.js";
4
+ import karin, { mkdirSync, render, segment, isPackaged, updatePkg, updateGitPlugin, logger, common, restart } from "node-karin";
5
+ import { karinPathTemp } from "node-karin/root";
6
+ import "sequelize";
7
+ import { C as Config, d as Common } from "../chunk/douyin-CpQOEMNX.js";
8
+ import { Version } from "../Version.js";
9
+ import "stream/promises";
10
+ import { R as Render } from "../chunk/Render-CCORwrkI.js";
11
+ const help = karin.command(/^#?kkk帮助$/, async (e) => {
15
12
  const img = await Render("help/index");
16
13
  await e.reply(img);
17
14
  return true;
18
- }, { name: "kkk-\u5E2E\u52A9" });
19
- var version = karin.command(/^#?kkk版本$/, async (e) => {
15
+ }, { name: "kkk-帮助" });
16
+ const version = karin.command(/^#?kkk版本$/, async (e) => {
20
17
  Config.douyin.push.switch = false;
21
18
  const changelogs2 = fs.readFileSync(Version.pluginPath + "/CHANGELOG.md", "utf8");
22
19
  const html = markdown(changelogs2, {
@@ -28,8 +25,8 @@ var version = karin.command(/^#?kkk版本$/, async (e) => {
28
25
  const img = await render.renderHtml(htmlPath);
29
26
  await e.reply(segment.image("base64://" + img));
30
27
  return true;
31
- }, { name: "kkk-\u7248\u672C" });
32
- var changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
28
+ }, { name: "kkk-版本" });
29
+ const changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
33
30
  const commits = getLatestCommitsSync();
34
31
  let htmlString = "";
35
32
  for (const commit of commits) {
@@ -50,12 +47,12 @@ var changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
50
47
  const img = await render.renderHtml(htmlPath);
51
48
  await e.reply(segment.image("base64://" + img));
52
49
  return true;
53
- }, { name: "kkk-\u66F4\u65B0\u65E5\u5FD7" });
54
- var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
50
+ }, { name: "kkk-更新日志" });
51
+ const update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
55
52
  let status = "failed";
56
53
  let data = "";
57
54
  if (isPackaged) {
58
- if (e.msg.includes("\u9884\u89C8\u7248")) {
55
+ if (e.msg.includes("预览版")) {
59
56
  const resolve = await updatePkg(Version.pluginName, "beta");
60
57
  status = resolve.status;
61
58
  data = resolve.data;
@@ -66,7 +63,7 @@ var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
66
63
  }
67
64
  } else {
68
65
  let cmd = "git pull";
69
- if (e.msg.includes("\u5F3A\u5236")) {
66
+ if (e.msg.includes("强制")) {
70
67
  cmd = "git reset --hard && git pull --allow-unrelated-histories";
71
68
  }
72
69
  const resolve = await updateGitPlugin(Version.pluginPath, cmd);
@@ -74,21 +71,21 @@ var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
74
71
  data = resolve.data;
75
72
  }
76
73
  logger.debug(data);
77
- await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(`\u66F4\u65B0 ${Version.pluginName}...
74
+ await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(`更新 ${Version.pluginName}...
78
75
  ${JSON.stringify(data)}`)], e.sender.userId, e.sender.nick));
79
76
  if (status === "ok") {
80
77
  try {
81
78
  await e.reply(`
82
- \u66F4\u65B0\u5B8C\u6210\uFF0C\u5F00\u59CB\u91CD\u542F \u672C\u6B21\u8FD0\u884C\u65F6\u95F4\uFF1A${common.uptime()}`, { at: true });
79
+ 更新完成,开始重启 本次运行时间:${common.uptime()}`, { at: true });
83
80
  await restart(e.selfId, e.contact, e.messageId);
84
81
  return true;
85
82
  } catch (error) {
86
- await e.reply(`${Version.pluginName}\u91CD\u542F\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u91CD\u542F\u4EE5\u5E94\u7528\u66F4\u65B0\uFF01`);
83
+ await e.reply(`${Version.pluginName}重启失败,请手动重启以应用更新!`);
87
84
  }
88
85
  }
89
86
  return true;
90
- }, { name: "kkk-\u66F4\u65B0", perm: "master" });
91
- var getLatestCommitsSync = () => {
87
+ }, { name: "kkk-更新", perm: "master" });
88
+ const getLatestCommitsSync = () => {
92
89
  const command = 'git log -150 --pretty=format:"%h %an %s"';
93
90
  const output = execSync(command, { cwd: Version.pluginPath }).toString();
94
91
  const commits = output.trim().split("\n");
@@ -101,7 +98,7 @@ var getLatestCommitsSync = () => {
101
98
  return { sha, committer, message };
102
99
  }).slice(0, 50);
103
100
  };
104
- var setColor = (message) => {
101
+ const setColor = (message) => {
105
102
  switch (true) {
106
103
  case message.includes("feat"):
107
104
  return "10px solid #a9ffb9";
@@ -115,5 +112,9 @@ var setColor = (message) => {
115
112
  return "2px solid";
116
113
  }
117
114
  };
118
-
119
- export { changelogs, help, update, version };
115
+ export {
116
+ changelogs,
117
+ help,
118
+ update,
119
+ version
120
+ };