koishi-plugin-noah 1.0.19 → 1.1.2
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/asset/config.d.ts +2 -0
- package/lib/asset/index.d.ts +5 -0
- package/lib/asset/service.d.ts +42 -0
- package/lib/constants.d.ts +13 -0
- package/lib/fun/poke/config.d.ts +2 -0
- package/lib/fun/poke/index.d.ts +4 -0
- package/lib/fun/poke/types.d.ts +12 -0
- package/lib/index.js +531 -60
- package/lib/types/config.d.ts +16 -0
- package/package.json +4 -1
- package/lib/assets/index.d.ts +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { AssetConfig } from '../types/config';
|
|
3
|
+
export declare class AssetService {
|
|
4
|
+
private ctx;
|
|
5
|
+
private logger;
|
|
6
|
+
private config;
|
|
7
|
+
private updateTimer;
|
|
8
|
+
private basePath;
|
|
9
|
+
constructor(ctx: Context, config: AssetConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Initialize the asset service
|
|
12
|
+
*/
|
|
13
|
+
initialize(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Stop the asset service
|
|
16
|
+
*/
|
|
17
|
+
dispose(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Get the latest release information from GitHub
|
|
20
|
+
*/
|
|
21
|
+
private getLatestRelease;
|
|
22
|
+
/**
|
|
23
|
+
* Check for asset updates and download if available
|
|
24
|
+
*/
|
|
25
|
+
checkForUpdates(): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Force an immediate update check
|
|
28
|
+
*/
|
|
29
|
+
forceUpdate(): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Download an asset by its ID
|
|
32
|
+
*/
|
|
33
|
+
private downloadAsset;
|
|
34
|
+
/**
|
|
35
|
+
* Extract the assets from the downloaded zip file
|
|
36
|
+
*/
|
|
37
|
+
private extractAssets;
|
|
38
|
+
/**
|
|
39
|
+
* Ensure a directory exists
|
|
40
|
+
*/
|
|
41
|
+
private ensureDirectoryExists;
|
|
42
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize global constants with application context
|
|
4
|
+
* @param ctx Koishi Context
|
|
5
|
+
*/
|
|
6
|
+
export declare function initConstants(ctx: Context): void;
|
|
7
|
+
/**
|
|
8
|
+
* Get the full asset path combining baseDir and asset data path
|
|
9
|
+
* @param ctx Koishi Context
|
|
10
|
+
* @param assetPath Relative path within the asset directory
|
|
11
|
+
* @returns Full resolved path to the asset
|
|
12
|
+
*/
|
|
13
|
+
export declare function getAssetPath(ctx: Context, assetPath: string): string;
|
package/lib/index.js
CHANGED
|
@@ -6,8 +6,8 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
8
|
var __export = (target, all) => {
|
|
9
|
-
for (var
|
|
10
|
-
__defProp(target,
|
|
9
|
+
for (var name13 in all)
|
|
10
|
+
__defProp(target, name13, { get: all[name13], enumerable: true });
|
|
11
11
|
};
|
|
12
12
|
var __copyProps = (to, from, except, desc) => {
|
|
13
13
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,9 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
Config: () => Config,
|
|
34
|
-
apply: () =>
|
|
34
|
+
apply: () => apply12,
|
|
35
35
|
inject: () => inject3,
|
|
36
|
-
name: () =>
|
|
36
|
+
name: () => name12
|
|
37
37
|
});
|
|
38
38
|
module.exports = __toCommonJS(src_exports);
|
|
39
39
|
|
|
@@ -48,10 +48,10 @@ __export(core_exports, {
|
|
|
48
48
|
var import_koishi3 = require("koishi");
|
|
49
49
|
|
|
50
50
|
// src/core/locales/en-US.yml
|
|
51
|
-
var en_US_default = { _config: { $desc: "Core Module Settings", adminUsers: "**Plugin Admin** User ID (use inspect command to get)" }, commands: { timeout: "Noah didn't wait for your reply, please try again!", noah: { help: { description: "Show Noah help information", messages: { content: "<p>
|
|
51
|
+
var en_US_default = { _config: { $desc: "Core Module Settings", adminUsers: "**Plugin Admin** User ID (use inspect command to get)" }, commands: { timeout: "Noah didn't wait for your reply, please try again!", noah: { help: { description: "Show Noah help information", messages: { content: "<p>Guide:</p>\n<a>https://docs.logthm.cn/noah</a>" } } }, bind: { description: "Bind card", messages: { prompt: "<p>Please enter your card number:</p>", "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", duplicate: "<p>This card has already been bound (︶^︶)</p>", name: "<p>Received! Please give this card a name, no spaces allowed:</p>", invalid_name: "<p>No spaces allowed! Please try again o(一︿一+)o</p>", success: "<p>Bound successfully, your card information is as follows:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "Manage cards", messages: { "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "invalid-select": "<p>No such option!</p>", "menu-select": "<p>[Card Management]</p>\n{card_list}\n<p>0. Add new card</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>Bound server: {defaultServerName}</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected card is the same as the old default card!</p>", "menu-2-prompt": "<p>Card number: {code}</p>\n<p>Please enter the new card number:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-2-error-invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "menu-5": "{server_list}\n<p>Please enter the serial number:</p>", "menu-5-success": "<p>Set successfully!</p>", "menu-5-error-duplicate": "<p>The selected server is the same as the old default server!</p>" } }, server: { description: "Manage servers", messages: { "invalid-select": "<p>No such option!</p>", "no-auth": "<p>Only group admins can use this feature~</p>", "admin-menu-select": "<p>[Group server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", "menu-select": "<p>[Server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>Type: {type}</p>\n<p>1. Set as default server</p>\n<p>2. View or modify url</p>\n<p>3. Delete the server</p>\n<p>4. Rename the server</p>\n<p>0. Return to server selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected server is the same as the old default server!</p>", "menu-2-prompt": "<p>The server's url: {baseUrl}</p>\n<p>Please enter the new server url:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "add-type": "<p>Please select the server type:</p>\n{server_type_list}", "add-url": "<p>Please enter the server url:</p>", "add-name": "<p>Received! Please give the server a name, no spaces allowed:</p>", "add-invalid_name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "add-success": "<p>Added successfully, the server information is as follows:</p>\n<p>[{serverName}]</p>\n<p>Type: {serverType}</p>" } } } };
|
|
52
52
|
|
|
53
53
|
// src/core/locales/zh-CN.yml
|
|
54
|
-
var zh_CN_default = { _config: { $desc: "Core 模块设置", adminUsers: "**插件管理员** 的用户id (使用 inspect 指令获取)" }, commands: { timeout: "Noah 没等到你的回复,请重试!", noah: { help: { description: "显示 Noah 帮助信息", messages: { content: "<p
|
|
54
|
+
var zh_CN_default = { _config: { $desc: "Core 模块设置", adminUsers: "**插件管理员** 的用户id (使用 inspect 指令获取)" }, commands: { timeout: "Noah 没等到你的回复,请重试!", noah: { help: { description: "显示 Noah 帮助信息", messages: { content: "<p>使用文档:</p>\n<a>https://docs.logthm.cn/noah</a>" } } }, bind: { description: "绑定卡片", messages: { prompt: "<p>请输入你的卡号:</p>", "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", duplicate: "<p>这张卡已经被绑定啦 (︶^︶)</p>", name: "<p>收到!为这张卡取一个名字吧,不要带空格哦:</p>", invalid_name: "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", success: "<p>绑好啦,你的卡片信息如下:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "管理卡片", messages: { "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "menu-select": "<p>[卡片管理]</p>\n{card_list}\n<p>0. 添加新卡片</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>已绑定服务器:{defaultServerName}</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的卡片与旧的默认卡片相同!</p>", "menu-2-prompt": "<p>卡号:{code}</p>\n<p>请输入新的卡号:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-2-error-invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "menu-5": "<p>请选择一个服务器:</p>\n{server_list}\n<p>q. 退出</p>", "menu-5-success": "<p>设置成功!</p>", "menu-5-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>" } }, server: { description: "管理服务器", messages: { "invalid-select": "<p>没有该选项!</p>", "no-auth": "<p>只有群管理员能使用本功能哦~</p>", quit: "<p>已退出~</p>", "admin-menu-select": "<p>[群聊服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-select": "<p>[服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>类型:{type}</p>\n<p>1. 设为默认服务器</p>\n<p>2. 查看或修改 url</p>\n<p>3. 删除该服务器</p>\n<p>4. 重命名该服务器</p>\n<p>0. 返回服务器选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>", "menu-2-prompt": "<p>该服务器的 url:{baseUrl}</p>\n<p>请输入新的服务器 url:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "add-type": "<p>请选择服务器的类型:</p>\n{server_type_list}\n<p>q. 退出</p>", "add-url": "<p>请输入服务器的 url:</p>\n<p>q. 退出</p>", "add-name": "<p>收到!为服务器取一个名字吧,不要带空格哦:</p>\n<p>q. 退出</p>", "add-invalid_name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "add-success": "<p>添加成功啦,服务器信息如下:</p>\n<p>[{serverName}]</p>\n<p>类型:{serverType}</p>" } } } };
|
|
55
55
|
|
|
56
56
|
// src/core/database.ts
|
|
57
57
|
var database_exports = {};
|
|
@@ -287,10 +287,9 @@ function classifyCardId(input) {
|
|
|
287
287
|
if (uidRegex.test(input)) {
|
|
288
288
|
try {
|
|
289
289
|
toKonamiId(input);
|
|
290
|
+
return "uid";
|
|
290
291
|
} catch (e) {
|
|
291
|
-
return "invalid";
|
|
292
292
|
}
|
|
293
|
-
return "uid";
|
|
294
293
|
}
|
|
295
294
|
const ALPHABET2 = "0123456789ABCDEFGHJKLMNPRSTUWXYZ";
|
|
296
295
|
const isKonami = input.split("").every((ch) => ALPHABET2.includes(ch));
|
|
@@ -380,8 +379,8 @@ var CardService = class {
|
|
|
380
379
|
/**
|
|
381
380
|
* 根据 name 获取卡片信息
|
|
382
381
|
*/
|
|
383
|
-
async getCardByName(
|
|
384
|
-
const rows = await this.ctx.database.get(this.tableName, { name:
|
|
382
|
+
async getCardByName(name13) {
|
|
383
|
+
const rows = await this.ctx.database.get(this.tableName, { name: name13 });
|
|
385
384
|
if (!rows[0]) return null;
|
|
386
385
|
return {
|
|
387
386
|
...rows[0],
|
|
@@ -396,10 +395,10 @@ var CardService = class {
|
|
|
396
395
|
* @param defaultServerId 默认服务器 ID(若没有默认服务器则为 0)
|
|
397
396
|
* @returns 创建成功后包含自动填充 id 等字段的完整对象
|
|
398
397
|
*/
|
|
399
|
-
async createCard(uid, code,
|
|
398
|
+
async createCard(uid, code, name13, defaultServerId = 0) {
|
|
400
399
|
const data = {
|
|
401
400
|
code,
|
|
402
|
-
name:
|
|
401
|
+
name: name13,
|
|
403
402
|
defaultServerId
|
|
404
403
|
};
|
|
405
404
|
const res = await this.ctx.database.create(this.tableName, data);
|
|
@@ -551,8 +550,8 @@ var ServerService = class {
|
|
|
551
550
|
/**
|
|
552
551
|
* 根据名称查找服务器
|
|
553
552
|
*/
|
|
554
|
-
async getServerByName(
|
|
555
|
-
const rows = await this.ctx.database.get(this.tableName, { name:
|
|
553
|
+
async getServerByName(name13) {
|
|
554
|
+
const rows = await this.ctx.database.get(this.tableName, { name: name13 });
|
|
556
555
|
return rows[0] ?? null;
|
|
557
556
|
}
|
|
558
557
|
/**
|
|
@@ -1023,10 +1022,10 @@ __export(sdvx_exports, {
|
|
|
1023
1022
|
var import_koishi8 = require("koishi");
|
|
1024
1023
|
|
|
1025
1024
|
// src/games/sdvx/locales/en-US.yml
|
|
1026
|
-
var en_US_default2 = { _config: { $desc: "SDVX Module Settings", default_model: "<p>Default model value (e.g. `2024110700`)</p>" }, commands: { vf: { description: "Show Noah help information", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>" } } } };
|
|
1025
|
+
var en_US_default2 = { _config: { $desc: "SDVX Module Settings", default_model: "<p>Default model value (e.g. `2024110700`)</p>", sdvx_data_url: "<p>The URL of the SDVX data service</p>" }, commands: { vf: { description: "Show Noah help information", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>" } } } };
|
|
1027
1026
|
|
|
1028
1027
|
// src/games/sdvx/locales/zh-CN.yml
|
|
1029
|
-
var zh_CN_default2 = { _config: { $desc: "SDVX 模块设置", default_model: "<p>默认的 model 值(如 `2024110700`)</p>" }, commands: { vf: { description: "查询 SDVX VOLFORCE", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>" } }, recent: { description: "查询 SDVX 最近分数", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>" } } } };
|
|
1028
|
+
var zh_CN_default2 = { _config: { $desc: "SDVX 模块设置", default_model: "<p>默认的 model 值(如 `2024110700`)</p>", sdvx_data_url: "<p>SDVX 数据服务的 URL</p>" }, commands: { vf: { description: "查询 SDVX VOLFORCE", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>" } }, recent: { description: "查询 SDVX 最近分数", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>" } } } };
|
|
1030
1029
|
|
|
1031
1030
|
// src/games/sdvx/database.ts
|
|
1032
1031
|
var database_exports2 = {};
|
|
@@ -1063,12 +1062,12 @@ var import_koishi4 = require("koishi");
|
|
|
1063
1062
|
// src/servers/utils/xml.ts
|
|
1064
1063
|
var xml2js = __toESM(require("xml2js"));
|
|
1065
1064
|
var xmlToJson = /* @__PURE__ */ __name((xml) => {
|
|
1066
|
-
return new Promise((
|
|
1065
|
+
return new Promise((resolve3, reject) => {
|
|
1067
1066
|
xml2js.parseString(xml, (err, result) => {
|
|
1068
1067
|
if (err) {
|
|
1069
1068
|
reject(new Error("Error parsing XML: " + err));
|
|
1070
1069
|
} else {
|
|
1071
|
-
|
|
1070
|
+
resolve3(result);
|
|
1072
1071
|
}
|
|
1073
1072
|
});
|
|
1074
1073
|
});
|
|
@@ -1081,12 +1080,12 @@ var SDVXService = class _SDVXService {
|
|
|
1081
1080
|
}
|
|
1082
1081
|
static instance;
|
|
1083
1082
|
logger;
|
|
1084
|
-
constructor(
|
|
1085
|
-
this.logger =
|
|
1083
|
+
constructor(logger4) {
|
|
1084
|
+
this.logger = logger4;
|
|
1086
1085
|
}
|
|
1087
|
-
static getInstance(
|
|
1086
|
+
static getInstance(logger4) {
|
|
1088
1087
|
if (!_SDVXService.instance) {
|
|
1089
|
-
_SDVXService.instance = new _SDVXService(
|
|
1088
|
+
_SDVXService.instance = new _SDVXService(logger4);
|
|
1090
1089
|
}
|
|
1091
1090
|
return _SDVXService.instance;
|
|
1092
1091
|
}
|
|
@@ -1172,12 +1171,12 @@ var IIDXService = class _IIDXService {
|
|
|
1172
1171
|
}
|
|
1173
1172
|
static instance;
|
|
1174
1173
|
logger;
|
|
1175
|
-
constructor(
|
|
1176
|
-
this.logger =
|
|
1174
|
+
constructor(logger4) {
|
|
1175
|
+
this.logger = logger4;
|
|
1177
1176
|
}
|
|
1178
|
-
static getInstance(
|
|
1177
|
+
static getInstance(logger4) {
|
|
1179
1178
|
if (!_IIDXService.instance) {
|
|
1180
|
-
_IIDXService.instance = new _IIDXService(
|
|
1179
|
+
_IIDXService.instance = new _IIDXService(logger4);
|
|
1181
1180
|
}
|
|
1182
1181
|
return _IIDXService.instance;
|
|
1183
1182
|
}
|
|
@@ -1352,12 +1351,12 @@ var SDVXService2 = class _SDVXService {
|
|
|
1352
1351
|
}
|
|
1353
1352
|
static instance;
|
|
1354
1353
|
logger;
|
|
1355
|
-
constructor(
|
|
1356
|
-
this.logger =
|
|
1354
|
+
constructor(logger4) {
|
|
1355
|
+
this.logger = logger4;
|
|
1357
1356
|
}
|
|
1358
|
-
static getInstance(
|
|
1357
|
+
static getInstance(logger4) {
|
|
1359
1358
|
if (!_SDVXService.instance) {
|
|
1360
|
-
_SDVXService.instance = new _SDVXService(
|
|
1359
|
+
_SDVXService.instance = new _SDVXService(logger4);
|
|
1361
1360
|
}
|
|
1362
1361
|
return _SDVXService.instance;
|
|
1363
1362
|
}
|
|
@@ -1802,8 +1801,28 @@ var CoreDrawer = class extends BaseDrawer {
|
|
|
1802
1801
|
};
|
|
1803
1802
|
|
|
1804
1803
|
// src/drawer/sdvx/index.ts
|
|
1805
|
-
var import_path = require("path");
|
|
1806
1804
|
var fs = __toESM(require("fs"));
|
|
1805
|
+
|
|
1806
|
+
// src/constants.ts
|
|
1807
|
+
var import_path = require("path");
|
|
1808
|
+
var ASSET_DATA_PATH = "noah_assets";
|
|
1809
|
+
function initConstants(ctx) {
|
|
1810
|
+
try {
|
|
1811
|
+
if (ctx.config?.asset?.data_path) {
|
|
1812
|
+
ASSET_DATA_PATH = ctx.config.asset.data_path;
|
|
1813
|
+
}
|
|
1814
|
+
ctx.logger("Noah").info(`Asset data path configured as: ${ASSET_DATA_PATH}`);
|
|
1815
|
+
} catch (error) {
|
|
1816
|
+
ctx.logger("Noah").error(`Failed to initialize constants: ${error.message}`);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
__name(initConstants, "initConstants");
|
|
1820
|
+
function getAssetPath(ctx, assetPath) {
|
|
1821
|
+
return (0, import_path.resolve)(ctx.baseDir, ASSET_DATA_PATH, "assets", assetPath);
|
|
1822
|
+
}
|
|
1823
|
+
__name(getAssetPath, "getAssetPath");
|
|
1824
|
+
|
|
1825
|
+
// src/drawer/sdvx/index.ts
|
|
1807
1826
|
var SDVXDrawer = class extends BaseDrawer {
|
|
1808
1827
|
constructor(ctx) {
|
|
1809
1828
|
super(ctx);
|
|
@@ -1824,7 +1843,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1824
1843
|
if (!compression) {
|
|
1825
1844
|
compression = { lossless: true };
|
|
1826
1845
|
}
|
|
1827
|
-
const bgImage = await loadImage((
|
|
1846
|
+
const bgImage = await loadImage(getAssetPath(this.ctx, "assets/sdvx/vf/main_bg.png"));
|
|
1828
1847
|
const canvas = new Canvas(bgImage.width, bgImage.height);
|
|
1829
1848
|
const ctx = canvas.getContext("2d");
|
|
1830
1849
|
ctx.imageSmoothingEnabled = true;
|
|
@@ -1845,10 +1864,10 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1845
1864
|
compression = { lossless: true };
|
|
1846
1865
|
}
|
|
1847
1866
|
try {
|
|
1848
|
-
const notoSansPath = (
|
|
1849
|
-
const slantPath = (
|
|
1850
|
-
const fredokaPath = (
|
|
1851
|
-
const notoSansJPPath = (
|
|
1867
|
+
const notoSansPath = getAssetPath(this.ctx, "assets/fonts/NotoSans-VariableFont_wdth,wght.ttf");
|
|
1868
|
+
const slantPath = getAssetPath(this.ctx, "assets/fonts/Slant.ttf");
|
|
1869
|
+
const fredokaPath = getAssetPath(this.ctx, "assets/fonts/FredokaOne.ttf");
|
|
1870
|
+
const notoSansJPPath = getAssetPath(this.ctx, "assets/fonts/NotoSansJP-VariableFont_wght.ttf");
|
|
1852
1871
|
if (fs.existsSync(notoSansPath)) {
|
|
1853
1872
|
FontLibrary.use("Noto Sans", notoSansPath);
|
|
1854
1873
|
this.ctx.logger("SDVX-Drawer").debug("Loaded Noto Sans font successfully");
|
|
@@ -1876,7 +1895,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1876
1895
|
} catch (error) {
|
|
1877
1896
|
this.ctx.logger("SDVX-Drawer").warn(`Error loading fonts: ${error.message}`);
|
|
1878
1897
|
}
|
|
1879
|
-
const bgImage = await loadImage((
|
|
1898
|
+
const bgImage = await loadImage(getAssetPath(this.ctx, "assets/sdvx/vf/main_bg.png"));
|
|
1880
1899
|
const canvas = new Canvas(bgImage.width, bgImage.height);
|
|
1881
1900
|
const ctx = canvas.getContext("2d");
|
|
1882
1901
|
ctx.imageSmoothingEnabled = true;
|
|
@@ -1890,7 +1909,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1890
1909
|
ctx.font = '300 128px "Noto Sans"';
|
|
1891
1910
|
ctx.fillText(options.playerName, 1451, 187);
|
|
1892
1911
|
ctx.fillText(averageVF.toFixed(3), 3849, 187);
|
|
1893
|
-
const cardBgImage = await loadImage((
|
|
1912
|
+
const cardBgImage = await loadImage(getAssetPath(this.ctx, "assets/sdvx/vf/card_bg.png"));
|
|
1894
1913
|
const sortedScores = [...options.scores].sort((a, b) => b.extra.volforce - a.extra.volforce).slice(0, 50);
|
|
1895
1914
|
await this.drawScoreCards(ctx, sortedScores, cardBgImage, loadImage, options.config);
|
|
1896
1915
|
return this.compressImage(canvas, compression);
|
|
@@ -1916,7 +1935,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1916
1935
|
const grades = ["D", "C", "B", "A", "A+", "AA", "AA+", "AAA", "AAA+", "S"];
|
|
1917
1936
|
for (const grade of grades) {
|
|
1918
1937
|
try {
|
|
1919
|
-
const gradePath = (
|
|
1938
|
+
const gradePath = getAssetPath(this.ctx, `assets/sdvx/vf/grade/Type=${grade}.png`);
|
|
1920
1939
|
gradeImages[grade] = await loadImage(gradePath);
|
|
1921
1940
|
} catch (error) {
|
|
1922
1941
|
this.ctx.logger("SDVX-Drawer").warn(`Failed to load grade image for ${grade}: ${error.message}`);
|
|
@@ -1924,7 +1943,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1924
1943
|
}
|
|
1925
1944
|
for (let i = 1; i <= 10; i++) {
|
|
1926
1945
|
try {
|
|
1927
|
-
const circlePath = (
|
|
1946
|
+
const circlePath = getAssetPath(this.ctx, `assets/sdvx/vf/circle/Class=${i}.png`);
|
|
1928
1947
|
circleImages[i] = await loadImage(circlePath);
|
|
1929
1948
|
} catch (error) {
|
|
1930
1949
|
this.ctx.logger("SDVX-Drawer").warn(`Failed to load circle image for class ${i}: ${error.message}`);
|
|
@@ -1932,7 +1951,7 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
1932
1951
|
}
|
|
1933
1952
|
for (let i = 1; i <= 10; i++) {
|
|
1934
1953
|
try {
|
|
1935
|
-
const badgePath = (
|
|
1954
|
+
const badgePath = getAssetPath(this.ctx, `assets/sdvx/vf/badge/Class=${i}.png`);
|
|
1936
1955
|
vfBadges[i] = await loadImage(badgePath);
|
|
1937
1956
|
} catch (error) {
|
|
1938
1957
|
this.ctx.logger("SDVX-Drawer").warn(`Failed to load badge image for class ${i}: ${error.message}`);
|
|
@@ -2474,22 +2493,433 @@ async function apply9(ctx, config) {
|
|
|
2474
2493
|
ctx.plugin(database_exports2, config.sdvx);
|
|
2475
2494
|
ctx.plugin(command_exports2, config.sdvx);
|
|
2476
2495
|
ctx.plugin(event_exports, config.sdvx);
|
|
2477
|
-
const serverManager = ServerManager.getInstance();
|
|
2478
|
-
const sdvxService = serverManager.getGameService("mao", "sdvx");
|
|
2479
|
-
const musicService = MusicService.getInstance(config.sdvx);
|
|
2480
|
-
const music = await musicService.getMusic(ctx, [1438, 1259]);
|
|
2481
2496
|
}
|
|
2482
2497
|
__name(apply9, "apply");
|
|
2483
2498
|
|
|
2499
|
+
// src/fun/poke/index.ts
|
|
2500
|
+
var poke_exports = {};
|
|
2501
|
+
__export(poke_exports, {
|
|
2502
|
+
apply: () => apply10,
|
|
2503
|
+
name: () => name10
|
|
2504
|
+
});
|
|
2505
|
+
var import_koishi9 = require("koishi");
|
|
2506
|
+
var fs2 = __toESM(require("fs"));
|
|
2507
|
+
var path = __toESM(require("path"));
|
|
2508
|
+
|
|
2509
|
+
// src/fun/poke/locales/zh-CN.yml
|
|
2510
|
+
var zh_CN_default3 = { _config: { $desc: "Poke 模块设置", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: { $desc: "警告内容", content: "消息", weight: "权重" }, messages: { $desc: "消息内容", content: "消息", weight: "权重" } }, commands: { poke: { description: "戳一戳" } } };
|
|
2511
|
+
|
|
2512
|
+
// src/fun/poke/locales/en-US.yml
|
|
2513
|
+
var en_US_default3 = { _config: { $desc: "Poke Module Settings", interval: "最小触发间隔(毫秒)", warning: "频繁触发是否发送警告", prompt: "警告内容", messages: { $desc: "消息内容", content: "消息内容", weight: "权重" } }, commands: { poke: { description: "poke" } } };
|
|
2514
|
+
|
|
2515
|
+
// src/fun/poke/index.ts
|
|
2516
|
+
var name10 = "Noah-Poke";
|
|
2517
|
+
function apply10(ctx, config) {
|
|
2518
|
+
[["en-US", en_US_default3], ["zh-CN", zh_CN_default3]].forEach(([lang, file]) => ctx.i18n.define(lang, file));
|
|
2519
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2520
|
+
const pokeConfig2 = config.poke;
|
|
2521
|
+
const IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".webp"];
|
|
2522
|
+
function isImageFile(filename) {
|
|
2523
|
+
const ext = path.extname(filename).toLowerCase();
|
|
2524
|
+
return IMAGE_EXTENSIONS.includes(ext);
|
|
2525
|
+
}
|
|
2526
|
+
__name(isImageFile, "isImageFile");
|
|
2527
|
+
function getMimeType(filename) {
|
|
2528
|
+
const ext = path.extname(filename).toLowerCase();
|
|
2529
|
+
switch (ext) {
|
|
2530
|
+
case ".png":
|
|
2531
|
+
return "image/png";
|
|
2532
|
+
case ".jpg":
|
|
2533
|
+
case ".jpeg":
|
|
2534
|
+
return "image/jpeg";
|
|
2535
|
+
case ".gif":
|
|
2536
|
+
return "image/gif";
|
|
2537
|
+
case ".webp":
|
|
2538
|
+
return "image/webp";
|
|
2539
|
+
default:
|
|
2540
|
+
return "image/png";
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
__name(getMimeType, "getMimeType");
|
|
2544
|
+
async function sendRandomNoahStamp(ctx2) {
|
|
2545
|
+
try {
|
|
2546
|
+
const stampsPath = getAssetPath(ctx2, "stamps/noah_stamp");
|
|
2547
|
+
const stampDirs = fs2.readdirSync(stampsPath).filter((dir) => dir.startsWith("stamp_"));
|
|
2548
|
+
if (stampDirs.length === 0) {
|
|
2549
|
+
return "No stamps found!";
|
|
2550
|
+
}
|
|
2551
|
+
const allStamps = [];
|
|
2552
|
+
for (const dir of stampDirs) {
|
|
2553
|
+
const stampDirPath = path.join(stampsPath, dir);
|
|
2554
|
+
const stampFiles = fs2.readdirSync(stampDirPath).filter((file) => file.startsWith(dir) && isImageFile(file));
|
|
2555
|
+
stampFiles.forEach((file) => {
|
|
2556
|
+
allStamps.push({
|
|
2557
|
+
path: path.join(stampDirPath, file),
|
|
2558
|
+
dirName: dir
|
|
2559
|
+
});
|
|
2560
|
+
});
|
|
2561
|
+
}
|
|
2562
|
+
if (allStamps.length === 0) {
|
|
2563
|
+
return "No stamps found in any directory!";
|
|
2564
|
+
}
|
|
2565
|
+
const randomStamp = allStamps[Math.floor(Math.random() * allStamps.length)];
|
|
2566
|
+
ctx2.logger("Noah-Poke").debug(`Selected stamp from ${randomStamp.dirName}`);
|
|
2567
|
+
if (!fs2.existsSync(randomStamp.path)) {
|
|
2568
|
+
return "Selected stamp not found!";
|
|
2569
|
+
}
|
|
2570
|
+
const imageBuffer = fs2.readFileSync(randomStamp.path);
|
|
2571
|
+
return import_koishi9.h.image(imageBuffer, getMimeType(randomStamp.path));
|
|
2572
|
+
} catch (error) {
|
|
2573
|
+
ctx2.logger("Noah-Poke").error(`Error sending noah stamp: ${error.message}`);
|
|
2574
|
+
return "Failed to send noah stamp.";
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
__name(sendRandomNoahStamp, "sendRandomNoahStamp");
|
|
2578
|
+
async function sendRandomChatStamp(ctx2) {
|
|
2579
|
+
try {
|
|
2580
|
+
const stampsPath = getAssetPath(ctx2, "stamps/chat_stamp");
|
|
2581
|
+
const stampFiles = fs2.readdirSync(stampsPath).filter((file) => isImageFile(file));
|
|
2582
|
+
if (stampFiles.length === 0) {
|
|
2583
|
+
return "No chat stamps found!";
|
|
2584
|
+
}
|
|
2585
|
+
const randomStamp = stampFiles[Math.floor(Math.random() * stampFiles.length)];
|
|
2586
|
+
const stampPath = path.join(stampsPath, randomStamp);
|
|
2587
|
+
if (!fs2.existsSync(stampPath)) {
|
|
2588
|
+
return "Selected stamp not found!";
|
|
2589
|
+
}
|
|
2590
|
+
const imageBuffer = fs2.readFileSync(stampPath);
|
|
2591
|
+
return import_koishi9.h.image(imageBuffer, getMimeType(stampPath));
|
|
2592
|
+
} catch (error) {
|
|
2593
|
+
ctx2.logger("Noah-Poke").error(`Error sending chat stamp: ${error.message}`);
|
|
2594
|
+
return "Failed to send chat stamp.";
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
__name(sendRandomChatStamp, "sendRandomChatStamp");
|
|
2598
|
+
ctx.command("stamp").option("type", "-t [type]").action(async ({ session, options }) => {
|
|
2599
|
+
if (options.type == "noah") {
|
|
2600
|
+
return sendRandomNoahStamp(ctx);
|
|
2601
|
+
} else if (options.type == "chat") {
|
|
2602
|
+
return sendRandomChatStamp(ctx);
|
|
2603
|
+
} else {
|
|
2604
|
+
return sendRandomChatStamp(ctx);
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
ctx.platform("onebot").command("poke [target:user]").action(async ({ session }, target) => {
|
|
2608
|
+
if (!session.onebot) {
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
const params = { user_id: session.userId };
|
|
2612
|
+
if (target) {
|
|
2613
|
+
const [platform, id] = parsePlatform(target);
|
|
2614
|
+
if (platform != "onebot") {
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
params.user_id = id;
|
|
2618
|
+
}
|
|
2619
|
+
if (session.isDirect) {
|
|
2620
|
+
await session.onebot._request("friend_poke", params);
|
|
2621
|
+
} else {
|
|
2622
|
+
params["group_id"] = session.guildId;
|
|
2623
|
+
await session.onebot._request("group_poke", params);
|
|
2624
|
+
}
|
|
2625
|
+
});
|
|
2626
|
+
ctx.platform("onebot").on("notice", async (session) => {
|
|
2627
|
+
if (session.subtype != "poke") {
|
|
2628
|
+
return;
|
|
2629
|
+
}
|
|
2630
|
+
if (session.targetId != session.selfId) {
|
|
2631
|
+
return;
|
|
2632
|
+
}
|
|
2633
|
+
if (pokeConfig2.interval > 0 && cache.has(session.userId)) {
|
|
2634
|
+
const ts = cache.get(session.userId);
|
|
2635
|
+
if (session.timestamp - ts < pokeConfig2.interval) {
|
|
2636
|
+
if (pokeConfig2.warning) {
|
|
2637
|
+
const msg = randomMessage(pokeConfig2.prompt);
|
|
2638
|
+
const content = import_koishi9.h.parse(msg, session);
|
|
2639
|
+
session.sendQueued(content);
|
|
2640
|
+
}
|
|
2641
|
+
return;
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
cache.set(session.userId, session.timestamp);
|
|
2645
|
+
if (pokeConfig2.messages.length > 0) {
|
|
2646
|
+
const msg = randomMessage(pokeConfig2.messages);
|
|
2647
|
+
const content = import_koishi9.h.parse(msg, session);
|
|
2648
|
+
await session.sendQueued(content);
|
|
2649
|
+
}
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2652
|
+
__name(apply10, "apply");
|
|
2653
|
+
function randomMessage(messages) {
|
|
2654
|
+
const totalWeight = messages.reduce((sum2, cur) => sum2 + cur.weight, 0);
|
|
2655
|
+
const random = Math.random() * totalWeight;
|
|
2656
|
+
let sum = 0;
|
|
2657
|
+
for (const message of messages) {
|
|
2658
|
+
sum += message.weight;
|
|
2659
|
+
if (random < sum) return message.content;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
__name(randomMessage, "randomMessage");
|
|
2663
|
+
function parsePlatform(target) {
|
|
2664
|
+
const index = target.indexOf(":");
|
|
2665
|
+
const platform = target.slice(0, index);
|
|
2666
|
+
const id = target.slice(index + 1);
|
|
2667
|
+
return [platform, id];
|
|
2668
|
+
}
|
|
2669
|
+
__name(parsePlatform, "parsePlatform");
|
|
2670
|
+
|
|
2671
|
+
// src/asset/index.ts
|
|
2672
|
+
var asset_exports = {};
|
|
2673
|
+
__export(asset_exports, {
|
|
2674
|
+
apply: () => apply11,
|
|
2675
|
+
logger: () => logger3,
|
|
2676
|
+
name: () => name11
|
|
2677
|
+
});
|
|
2678
|
+
|
|
2679
|
+
// src/asset/locales/zh-CN.yml
|
|
2680
|
+
var zh_CN_default4 = { _config: { $desc: "Asset 模块设置", data_path: "Noah 的资源文件路径", auto_update: "是否自动检查资源更新", update_url: "资源更新的基础URL", update_interval: "检查更新的时间间隔(毫秒)", github_token: "GitHub 访问令牌,用于访问私有仓库" }, commands: { update: { messages: { success: "资源更新成功!", already_up_to_date: "资源已是最新版本,无需更新。", failed: "资源更新失败,请查看日志获取详细信息。" } } } };
|
|
2681
|
+
|
|
2682
|
+
// src/asset/locales/en-US.yml
|
|
2683
|
+
var en_US_default4 = { _config: { $desc: "Asset Module Settings", data_path: "Path to Noah resource files", auto_update: "Whether to automatically check for asset updates", update_url: "Base URL for asset updates", update_interval: "Time interval in milliseconds to check for updates", github_token: "GitHub access token for private repository access" }, commands: { update: { messages: { success: "Asset update successful!", already_up_to_date: "Asset is already up to date.", failed: "Asset update failed, please check the logs for more details." } } } };
|
|
2684
|
+
|
|
2685
|
+
// src/asset/index.ts
|
|
2686
|
+
var import_koishi10 = require("koishi");
|
|
2687
|
+
|
|
2688
|
+
// src/asset/service.ts
|
|
2689
|
+
var import_fs = __toESM(require("fs"));
|
|
2690
|
+
var import_path2 = __toESM(require("path"));
|
|
2691
|
+
var import_path3 = require("path");
|
|
2692
|
+
var import_promises = require("fs/promises");
|
|
2693
|
+
var import_adm_zip = __toESM(require("adm-zip"));
|
|
2694
|
+
var AssetService = class {
|
|
2695
|
+
constructor(ctx, config) {
|
|
2696
|
+
this.ctx = ctx;
|
|
2697
|
+
this.logger = ctx.logger("Noah-Asset-Service");
|
|
2698
|
+
this.config = config;
|
|
2699
|
+
this.basePath = import_path2.default.resolve(this.ctx.baseDir, this.config.data_path);
|
|
2700
|
+
}
|
|
2701
|
+
static {
|
|
2702
|
+
__name(this, "AssetService");
|
|
2703
|
+
}
|
|
2704
|
+
logger;
|
|
2705
|
+
config;
|
|
2706
|
+
updateTimer = null;
|
|
2707
|
+
basePath;
|
|
2708
|
+
/**
|
|
2709
|
+
* Initialize the asset service
|
|
2710
|
+
*/
|
|
2711
|
+
async initialize() {
|
|
2712
|
+
this.logger.info("Initializing asset service");
|
|
2713
|
+
this.ensureDirectoryExists(this.basePath);
|
|
2714
|
+
if (this.config.auto_update) {
|
|
2715
|
+
await this.checkForUpdates();
|
|
2716
|
+
if (this.config.update_interval) {
|
|
2717
|
+
this.updateTimer = setInterval(() => {
|
|
2718
|
+
this.checkForUpdates().catch((err) => {
|
|
2719
|
+
this.logger.error(`Scheduled update check failed: ${err.message}`);
|
|
2720
|
+
});
|
|
2721
|
+
}, this.config.update_interval);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
/**
|
|
2726
|
+
* Stop the asset service
|
|
2727
|
+
*/
|
|
2728
|
+
dispose() {
|
|
2729
|
+
if (this.updateTimer) {
|
|
2730
|
+
clearInterval(this.updateTimer);
|
|
2731
|
+
this.updateTimer = null;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* Get the latest release information from GitHub
|
|
2736
|
+
*/
|
|
2737
|
+
async getLatestRelease() {
|
|
2738
|
+
try {
|
|
2739
|
+
const repoUrl = this.config.update_url.match(/github\.com\/([^/]+\/[^/]+)/);
|
|
2740
|
+
if (!repoUrl?.[1]) {
|
|
2741
|
+
throw new Error("Invalid GitHub repository URL");
|
|
2742
|
+
}
|
|
2743
|
+
const options = {
|
|
2744
|
+
headers: {
|
|
2745
|
+
"Accept": "application/vnd.github+json",
|
|
2746
|
+
"User-Agent": "Noah-Asset-Service"
|
|
2747
|
+
}
|
|
2748
|
+
};
|
|
2749
|
+
if (this.config.github_token) {
|
|
2750
|
+
options.headers["Authorization"] = `token ${this.config.github_token}`;
|
|
2751
|
+
}
|
|
2752
|
+
const response = await this.ctx.http.get(
|
|
2753
|
+
`https://api.github.com/repos/${repoUrl[1]}/releases/latest`,
|
|
2754
|
+
options
|
|
2755
|
+
);
|
|
2756
|
+
return response;
|
|
2757
|
+
} catch (error) {
|
|
2758
|
+
this.logger.error(`Failed to get latest release info: ${error.message}`);
|
|
2759
|
+
return null;
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
/**
|
|
2763
|
+
* Check for asset updates and download if available
|
|
2764
|
+
*/
|
|
2765
|
+
async checkForUpdates() {
|
|
2766
|
+
if (!this.config.update_url) {
|
|
2767
|
+
this.logger.warn("Update URL not configured, skipping update check");
|
|
2768
|
+
return false;
|
|
2769
|
+
}
|
|
2770
|
+
try {
|
|
2771
|
+
this.logger.info("Checking for asset updates...");
|
|
2772
|
+
const release = await this.getLatestRelease();
|
|
2773
|
+
if (!release) {
|
|
2774
|
+
throw new Error("Could not fetch release information");
|
|
2775
|
+
}
|
|
2776
|
+
const assetFile = release.assets.find((asset) => asset.name.startsWith("noah_assets_") && asset.name.endsWith(".zip"));
|
|
2777
|
+
if (!assetFile) {
|
|
2778
|
+
throw new Error("No asset file found in release");
|
|
2779
|
+
}
|
|
2780
|
+
const downloadPath = import_path2.default.join(this.basePath, "downloads");
|
|
2781
|
+
this.ensureDirectoryExists(downloadPath);
|
|
2782
|
+
const localPath = import_path2.default.join(downloadPath, assetFile.name);
|
|
2783
|
+
let shouldDownload = true;
|
|
2784
|
+
if (import_fs.default.existsSync(localPath)) {
|
|
2785
|
+
const currentTag = release.tag_name;
|
|
2786
|
+
const localTag = import_path2.default.basename(localPath, ".zip").replace("noah_assets_", "assets-");
|
|
2787
|
+
if (currentTag === localTag) {
|
|
2788
|
+
this.logger.info("Assets are up to date, no update needed");
|
|
2789
|
+
shouldDownload = false;
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
if (shouldDownload) {
|
|
2793
|
+
this.logger.info(`Downloading asset ${assetFile.id} from release`);
|
|
2794
|
+
await this.downloadAsset(assetFile.id, localPath);
|
|
2795
|
+
await this.extractAssets(localPath);
|
|
2796
|
+
return true;
|
|
2797
|
+
}
|
|
2798
|
+
return false;
|
|
2799
|
+
} catch (error) {
|
|
2800
|
+
this.logger.error(`Failed to check for updates: ${error.message}`);
|
|
2801
|
+
return false;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
/**
|
|
2805
|
+
* Force an immediate update check
|
|
2806
|
+
*/
|
|
2807
|
+
async forceUpdate() {
|
|
2808
|
+
this.logger.info("Forcing asset update");
|
|
2809
|
+
return this.checkForUpdates();
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Download an asset by its ID
|
|
2813
|
+
*/
|
|
2814
|
+
async downloadAsset(assetId, destination) {
|
|
2815
|
+
this.logger.info(`Downloading asset ${assetId} to ${destination}`);
|
|
2816
|
+
try {
|
|
2817
|
+
const repoUrl = this.config.update_url.match(/github\.com\/([^/]+\/[^/]+)/);
|
|
2818
|
+
if (!repoUrl?.[1]) {
|
|
2819
|
+
throw new Error("Invalid GitHub repository URL");
|
|
2820
|
+
}
|
|
2821
|
+
const assetUrl = `https://api.github.com/repos/${repoUrl[1]}/releases/assets/${assetId}`;
|
|
2822
|
+
const options = {
|
|
2823
|
+
headers: {
|
|
2824
|
+
"User-Agent": "Noah-Asset-Service",
|
|
2825
|
+
"Accept": "application/octet-stream",
|
|
2826
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
2827
|
+
},
|
|
2828
|
+
responseType: "arraybuffer",
|
|
2829
|
+
maxRedirects: 0
|
|
2830
|
+
// Don't auto-follow redirects
|
|
2831
|
+
};
|
|
2832
|
+
if (this.config.github_token) {
|
|
2833
|
+
options.headers["Authorization"] = `token ${this.config.github_token}`;
|
|
2834
|
+
}
|
|
2835
|
+
try {
|
|
2836
|
+
const response = await this.ctx.http.get(assetUrl, options);
|
|
2837
|
+
import_fs.default.writeFileSync(destination, Buffer.from(response));
|
|
2838
|
+
this.logger.info(`Download complete: ${destination}`);
|
|
2839
|
+
} catch (error) {
|
|
2840
|
+
if (error.response?.status === 302) {
|
|
2841
|
+
const redirectUrl = error.response.headers.location;
|
|
2842
|
+
this.logger.info(`Following redirect to ${redirectUrl}`);
|
|
2843
|
+
const redirectResponse = await this.ctx.http.get(redirectUrl, {
|
|
2844
|
+
...options,
|
|
2845
|
+
maxRedirects: 5
|
|
2846
|
+
// Allow some redirects for the actual download
|
|
2847
|
+
});
|
|
2848
|
+
import_fs.default.writeFileSync(destination, Buffer.from(redirectResponse.data));
|
|
2849
|
+
this.logger.info(`Download complete: ${destination}`);
|
|
2850
|
+
} else {
|
|
2851
|
+
throw error;
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
} catch (error) {
|
|
2855
|
+
this.logger.error(`Download failed: ${error.message}`);
|
|
2856
|
+
if (error.response) {
|
|
2857
|
+
this.logger.error(`Response status: ${error.response.status}`);
|
|
2858
|
+
this.logger.error(`Response headers: ${JSON.stringify(error.response.headers, null, 2)}`);
|
|
2859
|
+
}
|
|
2860
|
+
throw error;
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Extract the assets from the downloaded zip file
|
|
2865
|
+
*/
|
|
2866
|
+
async extractAssets(archivePath) {
|
|
2867
|
+
const extractPath = (0, import_path3.resolve)(this.basePath, "assets");
|
|
2868
|
+
await (0, import_promises.mkdir)(extractPath, { recursive: true });
|
|
2869
|
+
this.logger.info(`Extracting assets to ${extractPath}`);
|
|
2870
|
+
const zip = new import_adm_zip.default(archivePath);
|
|
2871
|
+
zip.extractAllTo(extractPath, true);
|
|
2872
|
+
}
|
|
2873
|
+
/**
|
|
2874
|
+
* Ensure a directory exists
|
|
2875
|
+
*/
|
|
2876
|
+
ensureDirectoryExists(dir) {
|
|
2877
|
+
if (!import_fs.default.existsSync(dir)) {
|
|
2878
|
+
this.logger.info(`Creating directory: ${dir}`);
|
|
2879
|
+
import_fs.default.mkdirSync(dir, { recursive: true });
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
};
|
|
2883
|
+
|
|
2884
|
+
// src/asset/index.ts
|
|
2885
|
+
var name11 = "Noah-Asset";
|
|
2886
|
+
var logger3 = new import_koishi10.Logger("Noah-Asset");
|
|
2887
|
+
function apply11(ctx, config) {
|
|
2888
|
+
[["en-US", en_US_default4], ["zh-CN", zh_CN_default4]].forEach(([lang, file]) => ctx.i18n.define(lang, file));
|
|
2889
|
+
const assetConfig2 = config.asset;
|
|
2890
|
+
logger3.info(`Asset path: ${assetConfig2.data_path}`);
|
|
2891
|
+
const assetService = new AssetService(ctx, assetConfig2);
|
|
2892
|
+
assetService.initialize().catch((err) => {
|
|
2893
|
+
logger3.error(`Failed to initialize asset service: ${err.message}`);
|
|
2894
|
+
});
|
|
2895
|
+
ctx.command("update").action(async ({ session }) => {
|
|
2896
|
+
try {
|
|
2897
|
+
const updated = await assetService.forceUpdate();
|
|
2898
|
+
if (updated) {
|
|
2899
|
+
return session.text(".success");
|
|
2900
|
+
} else {
|
|
2901
|
+
return session.text(".already_up_to_date");
|
|
2902
|
+
}
|
|
2903
|
+
} catch (error) {
|
|
2904
|
+
logger3.error(`Update command failed: ${error.message}`);
|
|
2905
|
+
return session.text(".failed");
|
|
2906
|
+
}
|
|
2907
|
+
});
|
|
2908
|
+
ctx.on("dispose", () => {
|
|
2909
|
+
assetService.dispose();
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
__name(apply11, "apply");
|
|
2913
|
+
|
|
2484
2914
|
// src/config.ts
|
|
2485
|
-
var
|
|
2915
|
+
var import_koishi15 = require("koishi");
|
|
2486
2916
|
|
|
2487
2917
|
// src/core/config.ts
|
|
2488
|
-
var
|
|
2489
|
-
var coreConfig =
|
|
2490
|
-
adminUsers:
|
|
2491
|
-
|
|
2492
|
-
|
|
2918
|
+
var import_koishi11 = require("koishi");
|
|
2919
|
+
var coreConfig = import_koishi11.Schema.object({
|
|
2920
|
+
adminUsers: import_koishi11.Schema.union([
|
|
2921
|
+
import_koishi11.Schema.array(String),
|
|
2922
|
+
import_koishi11.Schema.transform(String, (adminUsers) => [adminUsers])
|
|
2493
2923
|
])
|
|
2494
2924
|
}).i18n({
|
|
2495
2925
|
"en-US": en_US_default._config,
|
|
@@ -2497,31 +2927,72 @@ var coreConfig = import_koishi9.Schema.object({
|
|
|
2497
2927
|
});
|
|
2498
2928
|
|
|
2499
2929
|
// src/games/sdvx/config.ts
|
|
2500
|
-
var
|
|
2501
|
-
var sdvxConfig =
|
|
2502
|
-
default_model:
|
|
2503
|
-
sdvx_data_url:
|
|
2930
|
+
var import_koishi12 = require("koishi");
|
|
2931
|
+
var sdvxConfig = import_koishi12.Schema.object({
|
|
2932
|
+
default_model: import_koishi12.Schema.string().default("2024110700"),
|
|
2933
|
+
sdvx_data_url: import_koishi12.Schema.string().required()
|
|
2504
2934
|
}).i18n({
|
|
2505
2935
|
"en-US": en_US_default2._config,
|
|
2506
2936
|
"zh-CN": zh_CN_default2._config
|
|
2507
2937
|
});
|
|
2508
2938
|
|
|
2939
|
+
// src/fun/poke/config.ts
|
|
2940
|
+
var import_koishi13 = require("koishi");
|
|
2941
|
+
var pokeConfig = import_koishi13.Schema.object({
|
|
2942
|
+
interval: import_koishi13.Schema.number().default(1e3).step(100),
|
|
2943
|
+
warning: import_koishi13.Schema.boolean().default(false),
|
|
2944
|
+
prompt: import_koishi13.Schema.array(
|
|
2945
|
+
import_koishi13.Schema.object({
|
|
2946
|
+
content: import_koishi13.Schema.string().required(),
|
|
2947
|
+
weight: import_koishi13.Schema.number().min(0).max(100).default(50)
|
|
2948
|
+
})
|
|
2949
|
+
).role("table"),
|
|
2950
|
+
messages: import_koishi13.Schema.array(
|
|
2951
|
+
import_koishi13.Schema.object({
|
|
2952
|
+
content: import_koishi13.Schema.string().required(),
|
|
2953
|
+
weight: import_koishi13.Schema.number().min(0).max(100).default(50)
|
|
2954
|
+
})
|
|
2955
|
+
).role("table")
|
|
2956
|
+
}).i18n({
|
|
2957
|
+
"en-US": en_US_default3._config,
|
|
2958
|
+
"zh-CN": zh_CN_default3._config
|
|
2959
|
+
});
|
|
2960
|
+
|
|
2961
|
+
// src/asset/config.ts
|
|
2962
|
+
var import_koishi14 = require("koishi");
|
|
2963
|
+
var assetConfig = import_koishi14.Schema.object({
|
|
2964
|
+
data_path: import_koishi14.Schema.string().default("noah_assets"),
|
|
2965
|
+
auto_update: import_koishi14.Schema.boolean().default(true),
|
|
2966
|
+
update_url: import_koishi14.Schema.string().default("https://github.com/logthm/noah/releases/latest/download/"),
|
|
2967
|
+
update_interval: import_koishi14.Schema.number().default(24 * 60 * 60 * 1e3),
|
|
2968
|
+
// 24 hours in milliseconds
|
|
2969
|
+
github_token: import_koishi14.Schema.string().description("GitHub token for accessing private repositories").role("secret")
|
|
2970
|
+
}).i18n({
|
|
2971
|
+
"en-US": en_US_default4._config,
|
|
2972
|
+
"zh-CN": zh_CN_default4._config
|
|
2973
|
+
});
|
|
2974
|
+
|
|
2509
2975
|
// src/config.ts
|
|
2510
|
-
var Config =
|
|
2976
|
+
var Config = import_koishi15.Schema.object({
|
|
2511
2977
|
core: coreConfig,
|
|
2512
|
-
sdvx: sdvxConfig
|
|
2978
|
+
sdvx: sdvxConfig,
|
|
2979
|
+
poke: pokeConfig,
|
|
2980
|
+
asset: assetConfig
|
|
2513
2981
|
});
|
|
2514
2982
|
|
|
2515
2983
|
// src/index.ts
|
|
2516
|
-
var
|
|
2984
|
+
var name12 = "noah";
|
|
2517
2985
|
var inject3 = ["database", "skia"];
|
|
2518
|
-
function
|
|
2986
|
+
function apply12(ctx, config) {
|
|
2987
|
+
initConstants(ctx);
|
|
2519
2988
|
ctx.plugin(core_exports, config);
|
|
2520
2989
|
ctx.plugin(sdvx_exports, config);
|
|
2521
2990
|
ctx.plugin(servers_exports, config);
|
|
2522
2991
|
ctx.plugin(drawer_exports, config);
|
|
2992
|
+
ctx.plugin(poke_exports, config);
|
|
2993
|
+
ctx.plugin(asset_exports, config);
|
|
2523
2994
|
}
|
|
2524
|
-
__name(
|
|
2995
|
+
__name(apply12, "apply");
|
|
2525
2996
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2526
2997
|
0 && (module.exports = {
|
|
2527
2998
|
Config,
|
package/lib/types/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MessageReply } from "../fun/poke/types";
|
|
1
2
|
export interface BaseConfig {
|
|
2
3
|
}
|
|
3
4
|
export interface CoreConfig extends BaseConfig {
|
|
@@ -7,7 +8,22 @@ export interface SDVXConfig extends BaseConfig {
|
|
|
7
8
|
default_model: string;
|
|
8
9
|
sdvx_data_url: string;
|
|
9
10
|
}
|
|
11
|
+
export interface PokeConfig extends BaseConfig {
|
|
12
|
+
interval?: number;
|
|
13
|
+
warning?: boolean;
|
|
14
|
+
prompt?: MessageReply[];
|
|
15
|
+
messages?: MessageReply[];
|
|
16
|
+
}
|
|
17
|
+
export interface AssetConfig extends BaseConfig {
|
|
18
|
+
data_path: string;
|
|
19
|
+
auto_update?: boolean;
|
|
20
|
+
update_url?: string;
|
|
21
|
+
update_interval?: number;
|
|
22
|
+
github_token?: string;
|
|
23
|
+
}
|
|
10
24
|
export interface AppConfig {
|
|
11
25
|
core: CoreConfig;
|
|
12
26
|
sdvx: SDVXConfig;
|
|
27
|
+
poke: PokeConfig;
|
|
28
|
+
asset: AssetConfig;
|
|
13
29
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-noah",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"contributors": [
|
|
5
5
|
"Logthm <logthm@outlook.com>"
|
|
6
6
|
],
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"koishi": "^4.18.7"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"adm-zip": "^0.5.16",
|
|
25
|
+
"koishi-plugin-adapter-onebot": "^6.8.0",
|
|
24
26
|
"sharp": "^0.33.5",
|
|
25
27
|
"xml2js": "^0.6.2"
|
|
26
28
|
},
|
|
@@ -42,6 +44,7 @@
|
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@ltxhhz/koishi-plugin-skia-canvas": "^0.0.8",
|
|
47
|
+
"@types/adm-zip": "^0",
|
|
45
48
|
"@types/xml2js": "^0"
|
|
46
49
|
}
|
|
47
50
|
}
|
package/lib/assets/index.d.ts
DELETED
|
File without changes
|