koishi-plugin-dew-bot 1.0.252 → 1.0.253
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.js +153 -13
- package/lib/plugin/serverHandel/qqMarkdownHelpers.d.ts +6 -0
- package/lib/plugin/serverHandel/qqPageMessage.d.ts +1 -4
- package/lib/plugin/serverHandel/qqRewardMessage.d.ts +9 -0
- package/lib/shared/face/index.d.ts +4 -0
- package/package.json +1 -1
- package/src/plugin/serverHandel/qqCommandMessage.ts +26 -3
- package/src/plugin/serverHandel/qqMarkdownHelpers.ts +17 -0
- package/src/plugin/serverHandel/qqPageMessage.ts +22 -21
- package/src/plugin/serverHandel/qqRewardMessage.ts +62 -0
- package/src/plugin/serverHandel/qqStoryMessage.ts +21 -4
- package/src/plugin/serverHandel/qqTransactionMessage.ts +18 -3
- package/src/plugin/serverHandel/text.ts +5 -2
- package/src/shared/bot/serviceProto.ts +17 -1
- package/src/shared/face/index.ts +4 -0
package/lib/index.js
CHANGED
|
@@ -689,7 +689,7 @@ var AnalysisMsg = class {
|
|
|
689
689
|
}
|
|
690
690
|
};
|
|
691
691
|
|
|
692
|
-
// src/plugin/serverHandel/
|
|
692
|
+
// src/plugin/serverHandel/qqMarkdownHelpers.ts
|
|
693
693
|
function escapeMarkdown(value) {
|
|
694
694
|
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, "\\$&");
|
|
695
695
|
}
|
|
@@ -704,6 +704,62 @@ function renderQQTitle(content) {
|
|
|
704
704
|
***`;
|
|
705
705
|
}
|
|
706
706
|
__name(renderQQTitle, "renderQQTitle");
|
|
707
|
+
|
|
708
|
+
// src/plugin/serverHandel/qqRewardMessage.ts
|
|
709
|
+
function hasRewardLines(data) {
|
|
710
|
+
return data.line.some((item) => item.type === 1 /* line */ && item.reward === true);
|
|
711
|
+
}
|
|
712
|
+
__name(hasRewardLines, "hasRewardLines");
|
|
713
|
+
function isRewardMessage(data) {
|
|
714
|
+
return data.reward === true || hasRewardLines(data);
|
|
715
|
+
}
|
|
716
|
+
__name(isRewardMessage, "isRewardMessage");
|
|
717
|
+
function renderRewardTitle(content) {
|
|
718
|
+
return `**${escapeMarkdown(compactDisplayText(content))}**`;
|
|
719
|
+
}
|
|
720
|
+
__name(renderRewardTitle, "renderRewardTitle");
|
|
721
|
+
function renderRewardLine(content) {
|
|
722
|
+
return content.replace(/\r\n?/g, "\n").split("\n").filter((line) => line.trim()).map((line) => {
|
|
723
|
+
const text = line.trim();
|
|
724
|
+
const quantity = /([++\-−×xX]\s*\d+(?:\.\d+)?)$/.exec(text);
|
|
725
|
+
const formatted = quantity ? escapeMarkdown(text.slice(0, quantity.index)) + `**${escapeMarkdown(quantity[1])}**` : escapeMarkdown(text);
|
|
726
|
+
return "> " + formatted;
|
|
727
|
+
}).join(" \n");
|
|
728
|
+
}
|
|
729
|
+
__name(renderRewardLine, "renderRewardLine");
|
|
730
|
+
function renderQQRewardMarkdown(data, showGreeting) {
|
|
731
|
+
const sections = [];
|
|
732
|
+
const bodyLines = [];
|
|
733
|
+
const rewardLines = [];
|
|
734
|
+
const flushBody = /* @__PURE__ */ __name(() => {
|
|
735
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
736
|
+
}, "flushBody");
|
|
737
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
738
|
+
for (const item of data.line) {
|
|
739
|
+
if (item.type === 1 /* line */ && item.reward) {
|
|
740
|
+
const reward = renderRewardLine(item.content);
|
|
741
|
+
if (reward) rewardLines.push(reward);
|
|
742
|
+
continue;
|
|
743
|
+
}
|
|
744
|
+
if (item.type === 0 /* title */) {
|
|
745
|
+
flushBody();
|
|
746
|
+
bodyLines.push(renderRewardTitle(item.content));
|
|
747
|
+
} else if (item.type === 1 /* line */) {
|
|
748
|
+
for (const line of item.content.replace(/\r\n?/g, "\n").split("\n")) {
|
|
749
|
+
if (!line.trim()) flushBody();
|
|
750
|
+
else bodyLines.push(escapeMarkdown(line));
|
|
751
|
+
}
|
|
752
|
+
} else if (item.type === 2 /* error */) {
|
|
753
|
+
bodyLines.push(`❌ ${escapeMarkdown(item.content)}`);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
flushBody();
|
|
757
|
+
if (rewardLines.length) sections.push(rewardLines.join(" \n"));
|
|
758
|
+
return sections.join("\n\n") || " ";
|
|
759
|
+
}
|
|
760
|
+
__name(renderQQRewardMarkdown, "renderQQRewardMarkdown");
|
|
761
|
+
|
|
762
|
+
// src/plugin/serverHandel/qqPageMessage.ts
|
|
707
763
|
function compactListLabel(value) {
|
|
708
764
|
const label = compactDisplayText(value);
|
|
709
765
|
return /[📖📚]/u.test(label) ? label.replace(/技能书(?=$|×\d+(?:\.\d+)?(?:||$)||)/g, "") : label;
|
|
@@ -758,6 +814,7 @@ function pageCommandLines(nav) {
|
|
|
758
814
|
}
|
|
759
815
|
__name(pageCommandLines, "pageCommandLines");
|
|
760
816
|
function renderQQPageMarkdown(data, showGreeting) {
|
|
817
|
+
const rewardMessage = isRewardMessage(data);
|
|
761
818
|
const nav = data.pageNav;
|
|
762
819
|
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
763
820
|
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/;
|
|
@@ -767,27 +824,42 @@ function renderQQPageMarkdown(data, showGreeting) {
|
|
|
767
824
|
const sections = [];
|
|
768
825
|
const bodyLines = [];
|
|
769
826
|
const listLines = [];
|
|
827
|
+
const rewardLines = [];
|
|
770
828
|
const flushBody = /* @__PURE__ */ __name(() => {
|
|
771
829
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
772
830
|
}, "flushBody");
|
|
773
831
|
const flushList = /* @__PURE__ */ __name(() => {
|
|
774
832
|
if (listLines.length) sections.push(listLines.splice(0).join("\n"));
|
|
775
833
|
}, "flushList");
|
|
834
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
835
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
836
|
+
}, "flushRewards");
|
|
776
837
|
const flush = /* @__PURE__ */ __name(() => {
|
|
777
838
|
flushList();
|
|
778
839
|
flushBody();
|
|
840
|
+
flushRewards();
|
|
779
841
|
}, "flush");
|
|
780
842
|
let hasPageSummary = false;
|
|
781
843
|
let hasHelp = false;
|
|
782
844
|
let pageFooter;
|
|
783
|
-
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
845
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
784
846
|
for (const [lineIndex, item] of data.line.entries()) {
|
|
785
847
|
switch (item.type) {
|
|
786
848
|
case 0 /* title */:
|
|
787
849
|
flush();
|
|
788
|
-
|
|
850
|
+
const titleText = `${isLeaderboardDirectory && !item.content.includes("🏆") ? "🏆" : ""}${item.content}`;
|
|
851
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(titleText));
|
|
852
|
+
else sections.push(renderQQTitle(titleText));
|
|
789
853
|
break;
|
|
790
854
|
case 1 /* line */: {
|
|
855
|
+
if (item.reward) {
|
|
856
|
+
flushList();
|
|
857
|
+
flushBody();
|
|
858
|
+
const reward = renderRewardLine(item.content);
|
|
859
|
+
if (reward) rewardLines.push(reward);
|
|
860
|
+
break;
|
|
861
|
+
}
|
|
862
|
+
flushRewards();
|
|
791
863
|
const listEntry = listPattern.exec(item.content);
|
|
792
864
|
if (listEntry) {
|
|
793
865
|
flushBody();
|
|
@@ -871,24 +943,31 @@ __name(sendQQMarkdown, "sendQQMarkdown");
|
|
|
871
943
|
|
|
872
944
|
// src/plugin/serverHandel/qqTransactionMessage.ts
|
|
873
945
|
function renderQQTransactionMarkdown(data, showGreeting) {
|
|
946
|
+
const rewardMessage = isRewardMessage(data);
|
|
874
947
|
const sections = [];
|
|
875
948
|
const bodyLines = [];
|
|
876
949
|
const actions = [];
|
|
950
|
+
const rewardLines = [];
|
|
877
951
|
const flushBody = /* @__PURE__ */ __name(() => {
|
|
878
952
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
879
953
|
}, "flushBody");
|
|
880
954
|
const flushActions = /* @__PURE__ */ __name(() => {
|
|
881
955
|
if (actions.length) sections.push(actions.splice(0).join(" · "));
|
|
882
956
|
}, "flushActions");
|
|
957
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
958
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
959
|
+
}, "flushRewards");
|
|
883
960
|
const flush = /* @__PURE__ */ __name(() => {
|
|
884
961
|
flushBody();
|
|
885
962
|
flushActions();
|
|
963
|
+
flushRewards();
|
|
886
964
|
}, "flush");
|
|
887
|
-
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
965
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
888
966
|
for (const item of data.line) {
|
|
889
967
|
if (item.type === 0 /* title */) {
|
|
890
968
|
flush();
|
|
891
|
-
|
|
969
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content));
|
|
970
|
+
else sections.push(renderQQTitle(item.content));
|
|
892
971
|
continue;
|
|
893
972
|
}
|
|
894
973
|
if (item.type === 2 /* error */) {
|
|
@@ -897,6 +976,14 @@ function renderQQTransactionMarkdown(data, showGreeting) {
|
|
|
897
976
|
continue;
|
|
898
977
|
}
|
|
899
978
|
if (item.type !== 1 /* line */) continue;
|
|
979
|
+
if (item.reward) {
|
|
980
|
+
flushBody();
|
|
981
|
+
flushActions();
|
|
982
|
+
const reward = renderRewardLine(item.content);
|
|
983
|
+
if (reward) rewardLines.push(reward);
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
986
|
+
flushRewards();
|
|
900
987
|
const action = data.transaction && (item.content === "[是]确认交易" ? { command: "是", label: "确认交易" } : item.content === "[否]取消交易" ? { command: "否", label: "取消交易" } : void 0);
|
|
901
988
|
if (action) {
|
|
902
989
|
flushBody();
|
|
@@ -927,29 +1014,48 @@ __name(sendQQTransaction, "sendQQTransaction");
|
|
|
927
1014
|
|
|
928
1015
|
// src/plugin/serverHandel/qqCommandMessage.ts
|
|
929
1016
|
function renderQQCommandMarkdown(data, showGreeting) {
|
|
1017
|
+
const rewardMessage = isRewardMessage(data);
|
|
1018
|
+
if (!data.commandHelp && !data.pageNav && data.line.some((item) => item.type === 1 /* line */ && !item.reward && /^\[\d+\]\s*[^\r\n]+$/.test(item.content))) {
|
|
1019
|
+
return renderQQPageMarkdown(data, showGreeting);
|
|
1020
|
+
}
|
|
930
1021
|
const sections = [];
|
|
931
1022
|
const bodyLines = [];
|
|
1023
|
+
const rewardLines = [];
|
|
932
1024
|
const flushBody = /* @__PURE__ */ __name(() => {
|
|
933
1025
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
934
1026
|
}, "flushBody");
|
|
935
|
-
|
|
1027
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
1028
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
1029
|
+
}, "flushRewards");
|
|
1030
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
936
1031
|
for (const item of data.line) {
|
|
937
1032
|
switch (item.type) {
|
|
938
1033
|
case 0 /* title */:
|
|
939
1034
|
flushBody();
|
|
940
|
-
|
|
1035
|
+
flushRewards();
|
|
1036
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content));
|
|
1037
|
+
else sections.push(renderQQTitle(item.content));
|
|
941
1038
|
break;
|
|
942
1039
|
case 1 /* line */:
|
|
1040
|
+
if (item.reward) {
|
|
1041
|
+
flushBody();
|
|
1042
|
+
const reward = renderRewardLine(item.content);
|
|
1043
|
+
if (reward) rewardLines.push(reward);
|
|
1044
|
+
break;
|
|
1045
|
+
}
|
|
1046
|
+
flushRewards();
|
|
943
1047
|
if (!item.content.trim()) flushBody();
|
|
944
1048
|
else bodyLines.push(renderInlineCommands(item.content));
|
|
945
1049
|
break;
|
|
946
1050
|
case 2 /* error */:
|
|
947
1051
|
flushBody();
|
|
1052
|
+
flushRewards();
|
|
948
1053
|
sections.push(`❌ 出错了!错误原因:${renderInlineCommands(item.content)},请反馈至联系开发者`);
|
|
949
1054
|
break;
|
|
950
1055
|
}
|
|
951
1056
|
}
|
|
952
1057
|
flushBody();
|
|
1058
|
+
flushRewards();
|
|
953
1059
|
return sections.join("\n\n") || " ";
|
|
954
1060
|
}
|
|
955
1061
|
__name(renderQQCommandMarkdown, "renderQQCommandMarkdown");
|
|
@@ -971,36 +1077,52 @@ function fencedStory(content) {
|
|
|
971
1077
|
}
|
|
972
1078
|
__name(fencedStory, "fencedStory");
|
|
973
1079
|
function renderQQStoryMarkdown(data, showGreeting) {
|
|
1080
|
+
const rewardMessage = isRewardMessage(data);
|
|
974
1081
|
const sections = [];
|
|
975
1082
|
const bodyLines = [];
|
|
1083
|
+
const rewardLines = [];
|
|
976
1084
|
const flushBody = /* @__PURE__ */ __name(() => {
|
|
977
1085
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
978
1086
|
}, "flushBody");
|
|
979
|
-
|
|
1087
|
+
const flushRewards = /* @__PURE__ */ __name(() => {
|
|
1088
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(" \n"));
|
|
1089
|
+
}, "flushRewards");
|
|
1090
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
980
1091
|
for (const item of data.line) {
|
|
981
1092
|
switch (item.type) {
|
|
982
1093
|
case 0 /* title */:
|
|
983
1094
|
flushBody();
|
|
984
|
-
|
|
1095
|
+
if (!data.reward) flushRewards();
|
|
1096
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content));
|
|
1097
|
+
else sections.push(renderQQTitle(item.content));
|
|
985
1098
|
break;
|
|
986
1099
|
case 1 /* line */:
|
|
1100
|
+
if (item.reward) {
|
|
1101
|
+
if (!data.reward) flushBody();
|
|
1102
|
+
const reward = renderRewardLine(item.content);
|
|
1103
|
+
if (reward) rewardLines.push(reward);
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1106
|
+
if (!data.reward) flushRewards();
|
|
987
1107
|
if (item.codeBlock) {
|
|
988
1108
|
flushBody();
|
|
989
1109
|
sections.push(fencedStory(item.content));
|
|
990
1110
|
} else {
|
|
991
1111
|
for (const line of item.content.replace(/\r\n?/g, "\n").split("\n")) {
|
|
992
1112
|
if (!line.trim()) flushBody();
|
|
993
|
-
else bodyLines.push(renderInlineCommands(line));
|
|
1113
|
+
else bodyLines.push(data.reward ? escapeMarkdown(line) : renderInlineCommands(line));
|
|
994
1114
|
}
|
|
995
1115
|
}
|
|
996
1116
|
break;
|
|
997
1117
|
case 2 /* error */:
|
|
998
1118
|
flushBody();
|
|
999
|
-
|
|
1119
|
+
if (!data.reward) flushRewards();
|
|
1120
|
+
sections.push("❌ 出错了!错误原因:" + (data.reward ? escapeMarkdown(item.content) : renderInlineCommands(item.content)) + ",请反馈至联系开发者");
|
|
1000
1121
|
break;
|
|
1001
1122
|
}
|
|
1002
1123
|
}
|
|
1003
1124
|
flushBody();
|
|
1125
|
+
flushRewards();
|
|
1004
1126
|
return sections.join("\n\n") || " ";
|
|
1005
1127
|
}
|
|
1006
1128
|
__name(renderQQStoryMarkdown, "renderQQStoryMarkdown");
|
|
@@ -1019,13 +1141,15 @@ var handelr_text = class extends handel_base {
|
|
|
1019
1141
|
const session = sessions_default.get(sessionKey(data.botId, data.userId, data.channelId));
|
|
1020
1142
|
const inlineCommands = data.line.some((item) => (item.type === 1 /* line */ || item.type === 2 /* error */) && hasInlineCommands(item.content));
|
|
1021
1143
|
const story = hasStoryCodeBlock(data);
|
|
1022
|
-
|
|
1144
|
+
const reward = isRewardMessage(data);
|
|
1145
|
+
if ((story || data.commandHelp || data.transaction || data.pageNav || inlineCommands || reward) && canSendQQPage(session, data)) {
|
|
1023
1146
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
1024
1147
|
try {
|
|
1025
1148
|
if (story) await sendQQStory(session, data);
|
|
1026
1149
|
else if (data.commandHelp) await sendQQCommand(session, data);
|
|
1027
1150
|
else if (data.transaction) await sendQQTransaction(session, data);
|
|
1028
1151
|
else if (data.pageNav) await sendQQPage(session, data);
|
|
1152
|
+
else if (reward) await sendQQMarkdown(session, renderQQRewardMarkdown(data, session.event?.channel?.type === 0));
|
|
1029
1153
|
else await sendQQCommand(session, data);
|
|
1030
1154
|
if (this.timing) {
|
|
1031
1155
|
this.timing.delivery = "qq-markdown";
|
|
@@ -1140,7 +1264,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
1140
1264
|
|
|
1141
1265
|
// src/shared/bot/serviceProto.ts
|
|
1142
1266
|
var serviceProto = {
|
|
1143
|
-
"version":
|
|
1267
|
+
"version": 15,
|
|
1144
1268
|
"services": [
|
|
1145
1269
|
{
|
|
1146
1270
|
"id": 0,
|
|
@@ -1291,6 +1415,14 @@ var serviceProto = {
|
|
|
1291
1415
|
},
|
|
1292
1416
|
"optional": true
|
|
1293
1417
|
},
|
|
1418
|
+
{
|
|
1419
|
+
"id": 10,
|
|
1420
|
+
"name": "reward",
|
|
1421
|
+
"type": {
|
|
1422
|
+
"type": "Boolean"
|
|
1423
|
+
},
|
|
1424
|
+
"optional": true
|
|
1425
|
+
},
|
|
1294
1426
|
{
|
|
1295
1427
|
"id": 1,
|
|
1296
1428
|
"name": "line",
|
|
@@ -2035,6 +2167,14 @@ var serviceProto = {
|
|
|
2035
2167
|
"type": "Boolean"
|
|
2036
2168
|
},
|
|
2037
2169
|
"optional": true
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
"id": 3,
|
|
2173
|
+
"name": "reward",
|
|
2174
|
+
"type": {
|
|
2175
|
+
"type": "Boolean"
|
|
2176
|
+
},
|
|
2177
|
+
"optional": true
|
|
2038
2178
|
}
|
|
2039
2179
|
]
|
|
2040
2180
|
},
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Escape server-provided text before embedding it in native QQ Markdown. */
|
|
2
|
+
export declare function escapeMarkdown(value: string): string;
|
|
3
|
+
/** Compact display padding while retaining spaces between English words. */
|
|
4
|
+
export declare function compactDisplayText(value: string): string;
|
|
5
|
+
/** Keep existing menu, help and transaction titles consistent. */
|
|
6
|
+
export declare function renderQQTitle(content: string): string;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { Session } from 'koishi';
|
|
2
2
|
import { type PageNavData } from '../../shared/face';
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage';
|
|
4
|
-
|
|
5
|
-
export declare function escapeMarkdown(value: string): string;
|
|
6
|
-
/** Keep native QQ Markdown titles consistent across message types. */
|
|
7
|
-
export declare function renderQQTitle(content: string): string;
|
|
4
|
+
export { escapeMarkdown, renderQQTitle } from './qqMarkdownHelpers';
|
|
8
5
|
export declare function inlineCommandUrl(command: string): string;
|
|
9
6
|
export declare function hasInlineCommands(content: string): boolean;
|
|
10
7
|
/** Escape surrounding prose while rendering boxed commands as inline links. */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MsgMessage } from '../../shared/bot/MsgMessage';
|
|
2
|
+
export declare function hasRewardLines(data: Pick<MsgMessage, 'line'>): boolean;
|
|
3
|
+
/** The message marker also covers empty rewards and attachments already claimed. */
|
|
4
|
+
export declare function isRewardMessage(data: Pick<MsgMessage, 'line' | 'reward'>): boolean;
|
|
5
|
+
export declare function renderRewardTitle(content: string): string;
|
|
6
|
+
/** Reward names remain literal text; only the final signed quantity is emphasized. */
|
|
7
|
+
export declare function renderRewardLine(content: string): string;
|
|
8
|
+
/** Compact result card: title and description, followed by one continuous reward quote. */
|
|
9
|
+
export declare function renderQQRewardMarkdown(data: MsgMessage, showGreeting: boolean): string;
|
|
@@ -103,6 +103,8 @@ export interface ILineMessage {
|
|
|
103
103
|
content: string;
|
|
104
104
|
/** 原文长故事:支持的平台使用 Markdown 代码块,其余平台按普通文字显示。 */
|
|
105
105
|
codeBlock?: boolean;
|
|
106
|
+
/** 奖励明细;支持的平台合并为引用区,普通文字仍使用 content。 */
|
|
107
|
+
reward?: boolean;
|
|
106
108
|
}
|
|
107
109
|
/** 错误消息项 **/
|
|
108
110
|
export interface IErrorMessage {
|
|
@@ -136,6 +138,8 @@ export interface IMessage {
|
|
|
136
138
|
transaction?: boolean;
|
|
137
139
|
/** 指令系统与指令提示;客户端可用 Markdown 展示可点击的方框指令。 */
|
|
138
140
|
commandHelp?: boolean;
|
|
141
|
+
/** 奖励结果卡:标题、描述、奖励;空奖励时也保留同一种布局。 */
|
|
142
|
+
reward?: boolean;
|
|
139
143
|
/** 消息项列表 **/
|
|
140
144
|
line: IMessageItem[];
|
|
141
145
|
}
|
package/package.json
CHANGED
|
@@ -1,33 +1,56 @@
|
|
|
1
1
|
import type { Session } from 'koishi'
|
|
2
2
|
import { MessageType } from '../../shared/face'
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
|
-
import { escapeMarkdown, renderInlineCommands, renderQQTitle, sendQQMarkdown } from './qqPageMessage'
|
|
4
|
+
import { escapeMarkdown, renderInlineCommands, renderQQPageMarkdown, renderQQTitle, sendQQMarkdown } from './qqPageMessage'
|
|
5
|
+
import { isRewardMessage, renderRewardLine, renderRewardTitle } from './qqRewardMessage'
|
|
5
6
|
|
|
6
7
|
/** Render command help and ordinary prose with clickable bracketed commands. */
|
|
7
8
|
export function renderQQCommandMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
9
|
+
const rewardMessage = isRewardMessage(data)
|
|
10
|
+
// Menus without pagination still need native list markers. Escaped [n]
|
|
11
|
+
// markers can become separate centered blocks in QQ's Markdown renderer.
|
|
12
|
+
if (!data.commandHelp && !data.pageNav && data.line.some(item =>
|
|
13
|
+
item.type === MessageType.line && !item.reward && /^\[\d+\]\s*[^\r\n]+$/.test(item.content))) {
|
|
14
|
+
return renderQQPageMarkdown(data, showGreeting)
|
|
15
|
+
}
|
|
8
16
|
const sections: string[] = []
|
|
9
17
|
const bodyLines: string[] = []
|
|
18
|
+
const rewardLines: string[] = []
|
|
10
19
|
const flushBody = () => {
|
|
11
20
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
12
21
|
}
|
|
13
|
-
|
|
22
|
+
const flushRewards = () => {
|
|
23
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(' \n'))
|
|
24
|
+
}
|
|
25
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
14
26
|
for (const item of data.line) {
|
|
15
27
|
switch (item.type) {
|
|
16
28
|
case MessageType.title:
|
|
17
29
|
flushBody()
|
|
18
|
-
|
|
30
|
+
flushRewards()
|
|
31
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content))
|
|
32
|
+
else sections.push(renderQQTitle(item.content))
|
|
19
33
|
break
|
|
20
34
|
case MessageType.line:
|
|
35
|
+
if (item.reward) {
|
|
36
|
+
flushBody()
|
|
37
|
+
const reward = renderRewardLine(item.content)
|
|
38
|
+
if (reward) rewardLines.push(reward)
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
flushRewards()
|
|
21
42
|
if (!item.content.trim()) flushBody()
|
|
22
43
|
else bodyLines.push(renderInlineCommands(item.content))
|
|
23
44
|
break
|
|
24
45
|
case MessageType.error:
|
|
25
46
|
flushBody()
|
|
47
|
+
flushRewards()
|
|
26
48
|
sections.push(`❌ 出错了!错误原因:${renderInlineCommands(item.content)},请反馈至联系开发者`)
|
|
27
49
|
break
|
|
28
50
|
}
|
|
29
51
|
}
|
|
30
52
|
flushBody()
|
|
53
|
+
flushRewards()
|
|
31
54
|
return sections.join('\n\n') || ' '
|
|
32
55
|
}
|
|
33
56
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Escape server-provided text before embedding it in native QQ Markdown. */
|
|
2
|
+
export function escapeMarkdown(value: string): string {
|
|
3
|
+
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, '\\$&')
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** Compact display padding while retaining spaces between English words. */
|
|
7
|
+
export function compactDisplayText(value: string): string {
|
|
8
|
+
return value.trim()
|
|
9
|
+
.replace(/[ \t\u3000]*([·×+|])[ \t\u3000]*/g, '$1')
|
|
10
|
+
.replace(/([\p{Script=Han}\p{Extended_Pictographic}\p{Emoji_Modifier}\p{Regional_Indicator}\uFE0F])[ \t\u3000]+/gu, '$1')
|
|
11
|
+
.replace(/[ \t\u3000]+(?=[\p{Script=Han}\p{Extended_Pictographic}\p{Regional_Indicator}])/gu, '')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Keep existing menu, help and transaction titles consistent. */
|
|
15
|
+
export function renderQQTitle(content: string): string {
|
|
16
|
+
return `**${escapeMarkdown(compactDisplayText(content))}**\n\n***`
|
|
17
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Session } from 'koishi'
|
|
2
2
|
import { MessageType, type PageNavData } from '../../shared/face'
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
|
+
import { compactDisplayText, escapeMarkdown, renderQQTitle } from './qqMarkdownHelpers'
|
|
5
|
+
import { isRewardMessage, renderRewardLine, renderRewardTitle } from './qqRewardMessage'
|
|
6
|
+
|
|
7
|
+
export { escapeMarkdown, renderQQTitle } from './qqMarkdownHelpers'
|
|
4
8
|
|
|
5
9
|
type QQRequest = {
|
|
6
10
|
content: string
|
|
@@ -22,24 +26,6 @@ type QQResponse = {
|
|
|
22
26
|
data?: { message_audit?: { audit_id?: string } }
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
/** Escape server-provided lines before embedding them in native QQ Markdown. */
|
|
26
|
-
export function escapeMarkdown(value: string): string {
|
|
27
|
-
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, '\\$&')
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Compact display padding while retaining spaces between English words. */
|
|
31
|
-
function compactDisplayText(value: string): string {
|
|
32
|
-
return value.trim()
|
|
33
|
-
.replace(/[ \t\u3000]*([·×+|])[ \t\u3000]*/g, '$1')
|
|
34
|
-
.replace(/([\p{Script=Han}\p{Extended_Pictographic}\p{Emoji_Modifier}\p{Regional_Indicator}\uFE0F])[ \t\u3000]+/gu, '$1')
|
|
35
|
-
.replace(/[ \t\u3000]+(?=[\p{Script=Han}\p{Extended_Pictographic}\p{Regional_Indicator}])/gu, '')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Keep native QQ Markdown titles consistent across message types. */
|
|
39
|
-
export function renderQQTitle(content: string): string {
|
|
40
|
-
return `**${escapeMarkdown(compactDisplayText(content))}**\n\n***`
|
|
41
|
-
}
|
|
42
|
-
|
|
43
29
|
function compactListLabel(value: string): string {
|
|
44
30
|
const label = compactDisplayText(value)
|
|
45
31
|
// The book icon already identifies skill books. Only shorten the displayed
|
|
@@ -106,6 +92,7 @@ export function pageCommandLines(nav: PageNavData): string[] {
|
|
|
106
92
|
}
|
|
107
93
|
|
|
108
94
|
export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
95
|
+
const rewardMessage = isRewardMessage(data)
|
|
109
96
|
const nav = data.pageNav
|
|
110
97
|
const entryCommands = new Map(nav?.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
|
|
111
98
|
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/
|
|
@@ -116,24 +103,38 @@ export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean): s
|
|
|
116
103
|
const sections: string[] = []
|
|
117
104
|
const bodyLines: string[] = []
|
|
118
105
|
const listLines: string[] = []
|
|
106
|
+
const rewardLines: string[] = []
|
|
119
107
|
const flushBody = () => {
|
|
120
108
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
121
109
|
}
|
|
122
110
|
const flushList = () => {
|
|
123
111
|
if (listLines.length) sections.push(listLines.splice(0).join('\n'))
|
|
124
112
|
}
|
|
125
|
-
const
|
|
113
|
+
const flushRewards = () => {
|
|
114
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(' \n'))
|
|
115
|
+
}
|
|
116
|
+
const flush = () => { flushList(); flushBody(); flushRewards() }
|
|
126
117
|
let hasPageSummary = false
|
|
127
118
|
let hasHelp = false
|
|
128
119
|
let pageFooter: string | undefined
|
|
129
|
-
if (showGreeting) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
120
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
130
121
|
for (const [lineIndex, item] of data.line.entries()) {
|
|
131
122
|
switch (item.type) {
|
|
132
123
|
case MessageType.title:
|
|
133
124
|
flush()
|
|
134
|
-
|
|
125
|
+
const titleText = `${isLeaderboardDirectory && !item.content.includes('🏆') ? '🏆' : ''}${item.content}`
|
|
126
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(titleText))
|
|
127
|
+
else sections.push(renderQQTitle(titleText))
|
|
135
128
|
break
|
|
136
129
|
case MessageType.line: {
|
|
130
|
+
if (item.reward) {
|
|
131
|
+
flushList()
|
|
132
|
+
flushBody()
|
|
133
|
+
const reward = renderRewardLine(item.content)
|
|
134
|
+
if (reward) rewardLines.push(reward)
|
|
135
|
+
break
|
|
136
|
+
}
|
|
137
|
+
flushRewards()
|
|
137
138
|
const listEntry = listPattern.exec(item.content)
|
|
138
139
|
if (listEntry) {
|
|
139
140
|
flushBody()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MessageType } from '../../shared/face'
|
|
2
|
+
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
3
|
+
import { compactDisplayText, escapeMarkdown } from './qqMarkdownHelpers'
|
|
4
|
+
|
|
5
|
+
export function hasRewardLines(data: Pick<MsgMessage, 'line'>): boolean {
|
|
6
|
+
return data.line.some(item => item.type === MessageType.line && item.reward === true)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** The message marker also covers empty rewards and attachments already claimed. */
|
|
10
|
+
export function isRewardMessage(data: Pick<MsgMessage, 'line' | 'reward'>): boolean {
|
|
11
|
+
return data.reward === true || hasRewardLines(data)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function renderRewardTitle(content: string): string {
|
|
15
|
+
return `**${escapeMarkdown(compactDisplayText(content))}**`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Reward names remain literal text; only the final signed quantity is emphasized. */
|
|
19
|
+
export function renderRewardLine(content: string): string {
|
|
20
|
+
return content.replace(/\r\n?/g, '\n').split('\n').filter(line => line.trim()).map(line => {
|
|
21
|
+
const text = line.trim()
|
|
22
|
+
const quantity = /([++\-−×xX]\s*\d+(?:\.\d+)?)$/.exec(text)
|
|
23
|
+
const formatted = quantity
|
|
24
|
+
? escapeMarkdown(text.slice(0, quantity.index)) + `**${escapeMarkdown(quantity[1])}**`
|
|
25
|
+
: escapeMarkdown(text)
|
|
26
|
+
return '> ' + formatted
|
|
27
|
+
}).join(' \n')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Compact result card: title and description, followed by one continuous reward quote. */
|
|
31
|
+
export function renderQQRewardMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
32
|
+
const sections: string[] = []
|
|
33
|
+
const bodyLines: string[] = []
|
|
34
|
+
const rewardLines: string[] = []
|
|
35
|
+
const flushBody = () => {
|
|
36
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
37
|
+
}
|
|
38
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
39
|
+
for (const item of data.line) {
|
|
40
|
+
if (item.type === MessageType.line && item.reward) {
|
|
41
|
+
const reward = renderRewardLine(item.content)
|
|
42
|
+
if (reward) rewardLines.push(reward)
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
if (item.type === MessageType.title) {
|
|
46
|
+
flushBody()
|
|
47
|
+
bodyLines.push(renderRewardTitle(item.content))
|
|
48
|
+
} else if (item.type === MessageType.line) {
|
|
49
|
+
for (const line of item.content.replace(/\r\n?/g, '\n').split('\n')) {
|
|
50
|
+
if (!line.trim()) flushBody()
|
|
51
|
+
else bodyLines.push(escapeMarkdown(line))
|
|
52
|
+
}
|
|
53
|
+
} else if (item.type === MessageType.error) {
|
|
54
|
+
bodyLines.push(`❌ ${escapeMarkdown(item.content)}`)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
flushBody()
|
|
58
|
+
// Runtime notices and level-up summaries may be appended after the source
|
|
59
|
+
// reward rows. Keep every description above one final reward quote.
|
|
60
|
+
if (rewardLines.length) sections.push(rewardLines.join(' \n'))
|
|
61
|
+
return sections.join('\n\n') || ' '
|
|
62
|
+
}
|
|
@@ -2,6 +2,7 @@ import type { Session } from 'koishi'
|
|
|
2
2
|
import { MessageType } from '../../shared/face'
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
4
|
import { escapeMarkdown, renderInlineCommands, renderQQTitle, sendQQMarkdown } from './qqPageMessage'
|
|
5
|
+
import { isRewardMessage, renderRewardLine, renderRewardTitle } from './qqRewardMessage'
|
|
5
6
|
|
|
6
7
|
export function hasStoryCodeBlock(data: Pick<MsgMessage, 'line'>): boolean {
|
|
7
8
|
return data.line.some(item => item.type === MessageType.line && item.codeBlock === true)
|
|
@@ -18,36 +19,52 @@ function fencedStory(content: string): string {
|
|
|
18
19
|
|
|
19
20
|
/** Only marked story lines become code blocks; result summaries remain prose. */
|
|
20
21
|
export function renderQQStoryMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
22
|
+
const rewardMessage = isRewardMessage(data)
|
|
21
23
|
const sections: string[] = []
|
|
22
24
|
const bodyLines: string[] = []
|
|
25
|
+
const rewardLines: string[] = []
|
|
23
26
|
const flushBody = () => {
|
|
24
27
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
25
28
|
}
|
|
26
|
-
|
|
29
|
+
const flushRewards = () => {
|
|
30
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(' \n'))
|
|
31
|
+
}
|
|
32
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
27
33
|
for (const item of data.line) {
|
|
28
34
|
switch (item.type) {
|
|
29
35
|
case MessageType.title:
|
|
30
36
|
flushBody()
|
|
31
|
-
|
|
37
|
+
if (!data.reward) flushRewards()
|
|
38
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content))
|
|
39
|
+
else sections.push(renderQQTitle(item.content))
|
|
32
40
|
break
|
|
33
41
|
case MessageType.line:
|
|
42
|
+
if (item.reward) {
|
|
43
|
+
if (!data.reward) flushBody()
|
|
44
|
+
const reward = renderRewardLine(item.content)
|
|
45
|
+
if (reward) rewardLines.push(reward)
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
if (!data.reward) flushRewards()
|
|
34
49
|
if (item.codeBlock) {
|
|
35
50
|
flushBody()
|
|
36
51
|
sections.push(fencedStory(item.content))
|
|
37
52
|
} else {
|
|
38
53
|
for (const line of item.content.replace(/\r\n?/g, '\n').split('\n')) {
|
|
39
54
|
if (!line.trim()) flushBody()
|
|
40
|
-
else bodyLines.push(renderInlineCommands(line))
|
|
55
|
+
else bodyLines.push(data.reward ? escapeMarkdown(line) : renderInlineCommands(line))
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
break
|
|
44
59
|
case MessageType.error:
|
|
45
60
|
flushBody()
|
|
46
|
-
|
|
61
|
+
if (!data.reward) flushRewards()
|
|
62
|
+
sections.push('❌ 出错了!错误原因:' + (data.reward ? escapeMarkdown(item.content) : renderInlineCommands(item.content)) + ',请反馈至联系开发者')
|
|
47
63
|
break
|
|
48
64
|
}
|
|
49
65
|
}
|
|
50
66
|
flushBody()
|
|
67
|
+
flushRewards()
|
|
51
68
|
return sections.join('\n\n') || ' '
|
|
52
69
|
}
|
|
53
70
|
|
|
@@ -2,24 +2,31 @@ import type { Session } from 'koishi'
|
|
|
2
2
|
import { MessageType } from '../../shared/face'
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
4
|
import { escapeMarkdown, inlineCommandUrl, renderInlineCommands, renderQQTitle, sendQQMarkdown } from './qqPageMessage'
|
|
5
|
+
import { isRewardMessage, renderRewardLine, renderRewardTitle } from './qqRewardMessage'
|
|
5
6
|
|
|
6
7
|
/** Render only explicitly marked transactions; line content never enables this channel. */
|
|
7
8
|
export function renderQQTransactionMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
9
|
+
const rewardMessage = isRewardMessage(data)
|
|
8
10
|
const sections: string[] = []
|
|
9
11
|
const bodyLines: string[] = []
|
|
10
12
|
const actions: string[] = []
|
|
13
|
+
const rewardLines: string[] = []
|
|
11
14
|
const flushBody = () => {
|
|
12
15
|
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
13
16
|
}
|
|
14
17
|
const flushActions = () => {
|
|
15
18
|
if (actions.length) sections.push(actions.splice(0).join(' · '))
|
|
16
19
|
}
|
|
17
|
-
const
|
|
18
|
-
|
|
20
|
+
const flushRewards = () => {
|
|
21
|
+
if (rewardLines.length) sections.push(rewardLines.splice(0).join(' \n'))
|
|
22
|
+
}
|
|
23
|
+
const flush = () => { flushBody(); flushActions(); flushRewards() }
|
|
24
|
+
if (showGreeting && !data.reward) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
19
25
|
for (const item of data.line) {
|
|
20
26
|
if (item.type === MessageType.title) {
|
|
21
27
|
flush()
|
|
22
|
-
|
|
28
|
+
if (rewardMessage) bodyLines.push(renderRewardTitle(item.content))
|
|
29
|
+
else sections.push(renderQQTitle(item.content))
|
|
23
30
|
continue
|
|
24
31
|
}
|
|
25
32
|
if (item.type === MessageType.error) {
|
|
@@ -28,6 +35,14 @@ export function renderQQTransactionMarkdown(data: MsgMessage, showGreeting: bool
|
|
|
28
35
|
continue
|
|
29
36
|
}
|
|
30
37
|
if (item.type !== MessageType.line) continue
|
|
38
|
+
if (item.reward) {
|
|
39
|
+
flushBody()
|
|
40
|
+
flushActions()
|
|
41
|
+
const reward = renderRewardLine(item.content)
|
|
42
|
+
if (reward) rewardLines.push(reward)
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
flushRewards()
|
|
31
46
|
// Keep the common trade actions grouped; other bracketed commands render inline.
|
|
32
47
|
const action = data.transaction && (item.content === '[是]确认交易'
|
|
33
48
|
? { command: '是', label: '确认交易' }
|
|
@@ -3,10 +3,11 @@ import { AnalysisMsg } from '../../shared/bot/analysisMsg'
|
|
|
3
3
|
import { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
4
|
import sessions, { sessionKey } from '../sessions'
|
|
5
5
|
import handel_base from './handel_base'
|
|
6
|
-
import { canSendQQPage, hasInlineCommands, pageCommandLines, sendQQPage } from './qqPageMessage'
|
|
6
|
+
import { canSendQQPage, hasInlineCommands, pageCommandLines, sendQQMarkdown, sendQQPage } from './qqPageMessage'
|
|
7
7
|
import { sendQQTransaction } from './qqTransactionMessage'
|
|
8
8
|
import { sendQQCommand } from './qqCommandMessage'
|
|
9
9
|
import { hasStoryCodeBlock, sendQQStory } from './qqStoryMessage'
|
|
10
|
+
import { isRewardMessage, renderQQRewardMarkdown } from './qqRewardMessage'
|
|
10
11
|
|
|
11
12
|
export default class handelr_text extends handel_base {
|
|
12
13
|
async start(data: MsgMessage) {
|
|
@@ -14,13 +15,15 @@ export default class handelr_text extends handel_base {
|
|
|
14
15
|
const session = sessions.get(sessionKey(data.botId, data.userId, data.channelId))
|
|
15
16
|
const inlineCommands = data.line.some(item => (item.type === MessageType.line || item.type === MessageType.error) && hasInlineCommands(item.content))
|
|
16
17
|
const story = hasStoryCodeBlock(data)
|
|
17
|
-
|
|
18
|
+
const reward = isRewardMessage(data)
|
|
19
|
+
if ((story || data.commandHelp || data.transaction || data.pageNav || inlineCommands || reward) && canSendQQPage(session, data)) {
|
|
18
20
|
const sendStartedAt = this.timing ? performance.now() : 0
|
|
19
21
|
try {
|
|
20
22
|
if (story) await sendQQStory(session, data)
|
|
21
23
|
else if (data.commandHelp) await sendQQCommand(session, data)
|
|
22
24
|
else if (data.transaction) await sendQQTransaction(session, data)
|
|
23
25
|
else if (data.pageNav) await sendQQPage(session, data)
|
|
26
|
+
else if (reward) await sendQQMarkdown(session, renderQQRewardMarkdown(data, session.event?.channel?.type === 0))
|
|
24
27
|
else await sendQQCommand(session, data)
|
|
25
28
|
if (this.timing) {
|
|
26
29
|
this.timing.delivery = 'qq-markdown'
|
|
@@ -20,7 +20,7 @@ export interface ServiceType {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const serviceProto: ServiceProto<ServiceType> = {
|
|
23
|
-
"version":
|
|
23
|
+
"version": 15,
|
|
24
24
|
"services": [
|
|
25
25
|
{
|
|
26
26
|
"id": 0,
|
|
@@ -171,6 +171,14 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
171
171
|
},
|
|
172
172
|
"optional": true
|
|
173
173
|
},
|
|
174
|
+
{
|
|
175
|
+
"id": 10,
|
|
176
|
+
"name": "reward",
|
|
177
|
+
"type": {
|
|
178
|
+
"type": "Boolean"
|
|
179
|
+
},
|
|
180
|
+
"optional": true
|
|
181
|
+
},
|
|
174
182
|
{
|
|
175
183
|
"id": 1,
|
|
176
184
|
"name": "line",
|
|
@@ -915,6 +923,14 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
915
923
|
"type": "Boolean"
|
|
916
924
|
},
|
|
917
925
|
"optional": true
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"id": 3,
|
|
929
|
+
"name": "reward",
|
|
930
|
+
"type": {
|
|
931
|
+
"type": "Boolean"
|
|
932
|
+
},
|
|
933
|
+
"optional": true
|
|
918
934
|
}
|
|
919
935
|
]
|
|
920
936
|
},
|
package/src/shared/face/index.ts
CHANGED
|
@@ -75,6 +75,8 @@ export interface ILineMessage {
|
|
|
75
75
|
content: string;
|
|
76
76
|
/** 原文长故事:支持的平台使用 Markdown 代码块,其余平台按普通文字显示。 */
|
|
77
77
|
codeBlock?: boolean;
|
|
78
|
+
/** 奖励明细;支持的平台合并为引用区,普通文字仍使用 content。 */
|
|
79
|
+
reward?: boolean;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
/** 错误消息项 **/
|
|
@@ -109,6 +111,8 @@ export interface IMessage {
|
|
|
109
111
|
transaction?: boolean;
|
|
110
112
|
/** 指令系统与指令提示;客户端可用 Markdown 展示可点击的方框指令。 */
|
|
111
113
|
commandHelp?: boolean;
|
|
114
|
+
/** 奖励结果卡:标题、描述、奖励;空奖励时也保留同一种布局。 */
|
|
115
|
+
reward?: boolean;
|
|
112
116
|
/** 消息项列表 **/
|
|
113
117
|
line: IMessageItem[];
|
|
114
118
|
}
|