koishi-plugin-aka-ai-generator 0.2.12 → 0.2.13

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.
Files changed (2) hide show
  1. package/lib/index.js +81 -47
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -883,7 +883,7 @@ function apply(ctx, config) {
883
883
  rateLimitMap.set(userId, userTimestamps);
884
884
  }
885
885
  __name(updateRateLimit, "updateRateLimit");
886
- async function checkDailyLimit(userId) {
886
+ async function checkDailyLimit(userId, numImages = 1) {
887
887
  if (isAdmin(userId)) {
888
888
  return { allowed: true, isAdmin: true };
889
889
  }
@@ -894,25 +894,33 @@ function apply(ctx, config) {
894
894
  const usersData = await loadUsersData();
895
895
  const userData = usersData[userId];
896
896
  if (!userData) {
897
+ if (numImages > config.dailyFreeLimit) {
898
+ return {
899
+ allowed: false,
900
+ message: `生成 ${numImages} 张图片需要 ${numImages} 次可用次数,但您的可用次数不足(今日免费:${config.dailyFreeLimit}次,充值:0次)`,
901
+ isAdmin: false
902
+ };
903
+ }
897
904
  return { allowed: true, isAdmin: false };
898
905
  }
899
906
  const today = (/* @__PURE__ */ new Date()).toDateString();
900
907
  const lastReset = new Date(userData.lastDailyReset || userData.createdAt).toDateString();
908
+ let dailyCount = userData.dailyUsageCount;
901
909
  if (today !== lastReset) {
910
+ dailyCount = 0;
902
911
  userData.dailyUsageCount = 0;
903
912
  userData.lastDailyReset = (/* @__PURE__ */ new Date()).toISOString();
904
913
  }
905
- if (userData.dailyUsageCount < config.dailyFreeLimit) {
906
- return { allowed: true, isAdmin: false };
907
- }
908
- if (userData.remainingPurchasedCount > 0) {
909
- return { allowed: true, isAdmin: false };
914
+ const remainingToday = Math.max(0, config.dailyFreeLimit - dailyCount);
915
+ const totalAvailable = remainingToday + userData.remainingPurchasedCount;
916
+ if (totalAvailable < numImages) {
917
+ return {
918
+ allowed: false,
919
+ message: `生成 ${numImages} 张图片需要 ${numImages} 次可用次数,但您的可用次数不足(今日免费剩余:${remainingToday}次,充值剩余:${userData.remainingPurchasedCount}次,共${totalAvailable}次)`,
920
+ isAdmin: false
921
+ };
910
922
  }
911
- return {
912
- allowed: false,
913
- message: `今日免费次数已用完(${config.dailyFreeLimit}次),充值次数也已用完。请联系管理员充值或明天再试`,
914
- isAdmin: false
915
- };
923
+ return { allowed: true, isAdmin: false };
916
924
  }
917
925
  __name(checkDailyLimit, "checkDailyLimit");
918
926
  async function getPromptInput(session, message) {
@@ -1002,7 +1010,7 @@ function apply(ctx, config) {
1002
1010
  return usersData[userId];
1003
1011
  }
1004
1012
  __name(getUserData, "getUserData");
1005
- async function updateUserData(userId, userName, commandName) {
1013
+ async function updateUserData(userId, userName, commandName, numImages = 1) {
1006
1014
  const usersData = await loadUsersData();
1007
1015
  const now = (/* @__PURE__ */ new Date()).toISOString();
1008
1016
  const today = (/* @__PURE__ */ new Date()).toDateString();
@@ -1010,8 +1018,8 @@ function apply(ctx, config) {
1010
1018
  usersData[userId] = {
1011
1019
  userId,
1012
1020
  userName: userId,
1013
- totalUsageCount: 1,
1014
- dailyUsageCount: 1,
1021
+ totalUsageCount: numImages,
1022
+ dailyUsageCount: numImages,
1015
1023
  lastDailyReset: now,
1016
1024
  purchasedCount: 0,
1017
1025
  remainingPurchasedCount: 0,
@@ -1021,35 +1029,49 @@ function apply(ctx, config) {
1021
1029
  createdAt: now
1022
1030
  };
1023
1031
  await saveUsersData(usersData);
1024
- return { userData: usersData[userId], consumptionType: "free" };
1032
+ return { userData: usersData[userId], consumptionType: "free", freeUsed: numImages, purchasedUsed: 0 };
1025
1033
  }
1026
- usersData[userId].totalUsageCount += 1;
1034
+ usersData[userId].totalUsageCount += numImages;
1027
1035
  usersData[userId].lastUsed = now;
1028
1036
  const lastReset = new Date(usersData[userId].lastDailyReset || usersData[userId].createdAt).toDateString();
1029
1037
  if (today !== lastReset) {
1030
1038
  usersData[userId].dailyUsageCount = 0;
1031
1039
  usersData[userId].lastDailyReset = now;
1032
1040
  }
1033
- if (usersData[userId].dailyUsageCount < config.dailyFreeLimit) {
1034
- usersData[userId].dailyUsageCount += 1;
1035
- await saveUsersData(usersData);
1036
- return { userData: usersData[userId], consumptionType: "free" };
1037
- }
1038
- if (usersData[userId].remainingPurchasedCount > 0) {
1039
- usersData[userId].remainingPurchasedCount -= 1;
1040
- await saveUsersData(usersData);
1041
- return { userData: usersData[userId], consumptionType: "purchased" };
1041
+ let remainingToConsume = numImages;
1042
+ let freeUsed = 0;
1043
+ let purchasedUsed = 0;
1044
+ const availableFree = Math.max(0, config.dailyFreeLimit - usersData[userId].dailyUsageCount);
1045
+ if (availableFree > 0) {
1046
+ const freeToUse = Math.min(availableFree, remainingToConsume);
1047
+ usersData[userId].dailyUsageCount += freeToUse;
1048
+ freeUsed = freeToUse;
1049
+ remainingToConsume -= freeToUse;
1050
+ }
1051
+ if (remainingToConsume > 0) {
1052
+ const purchasedToUse = Math.min(usersData[userId].remainingPurchasedCount, remainingToConsume);
1053
+ usersData[userId].remainingPurchasedCount -= purchasedToUse;
1054
+ purchasedUsed = purchasedToUse;
1055
+ remainingToConsume -= purchasedToUse;
1042
1056
  }
1043
1057
  await saveUsersData(usersData);
1044
- return { userData: usersData[userId], consumptionType: "free" };
1058
+ let consumptionType;
1059
+ if (freeUsed > 0 && purchasedUsed > 0) {
1060
+ consumptionType = "mixed";
1061
+ } else if (freeUsed > 0) {
1062
+ consumptionType = "free";
1063
+ } else {
1064
+ consumptionType = "purchased";
1065
+ }
1066
+ return { userData: usersData[userId], consumptionType, freeUsed, purchasedUsed };
1045
1067
  }
1046
1068
  __name(updateUserData, "updateUserData");
1047
- async function recordUserUsage(session, commandName) {
1069
+ async function recordUserUsage(session, commandName, numImages = 1) {
1048
1070
  const userId = session.userId;
1049
1071
  const userName = session.username || session.userId || "未知用户";
1050
1072
  if (!userId) return;
1051
1073
  updateRateLimit(userId);
1052
- const { userData, consumptionType } = await updateUserData(userId, userName, commandName);
1074
+ const { userData, consumptionType, freeUsed, purchasedUsed } = await updateUserData(userId, userName, commandName, numImages);
1053
1075
  if (isAdmin(userId)) {
1054
1076
  await session.send(`📊 使用统计 [管理员]
1055
1077
  用户:${userData.userName}
@@ -1057,10 +1079,18 @@ function apply(ctx, config) {
1057
1079
  状态:无限制使用`);
1058
1080
  } else {
1059
1081
  const remainingToday = Math.max(0, config.dailyFreeLimit - userData.dailyUsageCount);
1060
- const consumptionText = consumptionType === "free" ? "每日免费次数" : "充值次数";
1082
+ let consumptionText = "";
1083
+ if (consumptionType === "mixed") {
1084
+ consumptionText = `每日免费次数 -${freeUsed},充值次数 -${purchasedUsed}`;
1085
+ } else if (consumptionType === "free") {
1086
+ consumptionText = `每日免费次数 -${freeUsed}`;
1087
+ } else {
1088
+ consumptionText = `充值次数 -${purchasedUsed}`;
1089
+ }
1061
1090
  await session.send(`📊 使用统计
1062
1091
  用户:${userData.userName}
1063
- 本次消费:${consumptionText} -1
1092
+ 本次生成:${numImages}张图片
1093
+ 本次消费:${consumptionText}
1064
1094
  总调用次数:${userData.totalUsageCount}次
1065
1095
  今日剩余免费:${remainingToday}次
1066
1096
  充值剩余:${userData.remainingPurchasedCount}次`);
@@ -1069,10 +1099,13 @@ function apply(ctx, config) {
1069
1099
  userId,
1070
1100
  userName: userData.userName,
1071
1101
  commandName,
1102
+ numImages,
1103
+ consumptionType,
1104
+ freeUsed,
1105
+ purchasedUsed,
1072
1106
  totalUsageCount: userData.totalUsageCount,
1073
1107
  dailyUsageCount: userData.dailyUsageCount,
1074
1108
  remainingPurchasedCount: userData.remainingPurchasedCount,
1075
- consumptionType,
1076
1109
  isAdmin: isAdmin(userId)
1077
1110
  });
1078
1111
  }
@@ -1207,7 +1240,7 @@ ${infoParts.join("\n")}`;
1207
1240
  await new Promise((resolve) => setTimeout(resolve, 1e3));
1208
1241
  }
1209
1242
  }
1210
- await recordUserUsage(session, styleName);
1243
+ await recordUserUsage(session, styleName, images.length);
1211
1244
  activeTasks.delete(userId);
1212
1245
  } catch (error) {
1213
1246
  activeTasks.delete(userId);
@@ -1225,10 +1258,6 @@ ${infoParts.join("\n")}`;
1225
1258
  ctx.command(`${style.commandName} [img:text]`, "图像风格转换").option("num", "-n <num:number> 生成图片数量 (1-4)").action(async (argv, img) => {
1226
1259
  const { session, options } = argv;
1227
1260
  if (!session?.userId) return "会话无效";
1228
- const limitCheck = await checkDailyLimit(session.userId);
1229
- if (!limitCheck.allowed) {
1230
- return limitCheck.message;
1231
- }
1232
1261
  const modifiers = parseStyleCommandModifiers(argv, img);
1233
1262
  let userPromptParts = [];
1234
1263
  if (modifiers.customAdditions?.length) {
@@ -1250,13 +1279,18 @@ ${infoParts.join("\n")}`;
1250
1279
  }
1251
1280
  }
1252
1281
  }
1282
+ const numImages = options?.num || promptNumImages || config.defaultNumImages;
1283
+ const limitCheck = await checkDailyLimit(session.userId, numImages);
1284
+ if (!limitCheck.allowed) {
1285
+ return limitCheck.message;
1286
+ }
1253
1287
  const promptSegments = [style.prompt];
1254
1288
  if (cleanedUserPrompt) {
1255
1289
  promptSegments.push(cleanedUserPrompt);
1256
1290
  }
1257
1291
  const mergedPrompt = promptSegments.filter(Boolean).join(" - ");
1258
1292
  const requestContext = {
1259
- numImages: options?.num || promptNumImages
1293
+ numImages
1260
1294
  };
1261
1295
  if (modifiers.modelMapping?.provider) {
1262
1296
  requestContext.provider = modifiers.modelMapping.provider;
@@ -1280,10 +1314,6 @@ ${infoParts.join("\n")}`;
1280
1314
  }
1281
1315
  ctx.command(COMMANDS.GENERATE_IMAGE, "使用自定义prompt进行图像处理").option("num", "-n <num:number> 生成图片数量 (1-4)").action(async ({ session, options }) => {
1282
1316
  if (!session?.userId) return "会话无效";
1283
- const limitCheck = await checkDailyLimit(session.userId);
1284
- if (!limitCheck.allowed) {
1285
- return limitCheck.message;
1286
- }
1287
1317
  return Promise.race([
1288
1318
  (async () => {
1289
1319
  const userId = session.userId;
@@ -1350,6 +1380,10 @@ ${infoParts.join("\n")}`;
1350
1380
  if (imageCount < 1 || imageCount > 4) {
1351
1381
  return "生成数量必须在 1-4 之间";
1352
1382
  }
1383
+ const limitCheck = await checkDailyLimit(userId, imageCount);
1384
+ if (!limitCheck.allowed) {
1385
+ return limitCheck.message;
1386
+ }
1353
1387
  logger.info("开始自定义图像处理", {
1354
1388
  userId,
1355
1389
  imageUrl,
@@ -1372,7 +1406,7 @@ Prompt: ${prompt}`);
1372
1406
  await new Promise((resolve) => setTimeout(resolve, 1e3));
1373
1407
  }
1374
1408
  }
1375
- await recordUserUsage(session, COMMANDS.GENERATE_IMAGE);
1409
+ await recordUserUsage(session, COMMANDS.GENERATE_IMAGE, resultImages.length);
1376
1410
  activeTasks.delete(userId);
1377
1411
  } catch (error) {
1378
1412
  activeTasks.delete(userId);
@@ -1395,10 +1429,6 @@ Prompt: ${prompt}`);
1395
1429
  });
1396
1430
  ctx.command(COMMANDS.COMPOSE_IMAGE, "合成多张图片,使用自定义prompt控制合成效果").option("num", "-n <num:number> 生成图片数量 (1-4)").action(async ({ session, options }) => {
1397
1431
  if (!session?.userId) return "会话无效";
1398
- const limitCheck = await checkDailyLimit(session.userId);
1399
- if (!limitCheck.allowed) {
1400
- return limitCheck.message;
1401
- }
1402
1432
  return Promise.race([
1403
1433
  (async () => {
1404
1434
  const userId = session.userId;
@@ -1455,6 +1485,10 @@ Prompt: ${prompt}`);
1455
1485
  if (imageCount < 1 || imageCount > 4) {
1456
1486
  return "生成数量必须在 1-4 之间";
1457
1487
  }
1488
+ const limitCheck = await checkDailyLimit(userId, imageCount);
1489
+ if (!limitCheck.allowed) {
1490
+ return limitCheck.message;
1491
+ }
1458
1492
  logger.info("开始图片合成处理", {
1459
1493
  userId,
1460
1494
  imageUrls: collectedImages,
@@ -1478,7 +1512,7 @@ Prompt: ${prompt}`);
1478
1512
  await new Promise((resolve) => setTimeout(resolve, 1e3));
1479
1513
  }
1480
1514
  }
1481
- await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE);
1515
+ await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, resultImages.length);
1482
1516
  activeTasks.delete(userId);
1483
1517
  } catch (error) {
1484
1518
  activeTasks.delete(userId);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-aka-ai-generator",
3
3
  "description": "自用AI生成插件(GPTGod & Yunwu)",
4
- "version": "0.2.12",
4
+ "version": "0.2.13",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [