@takaro/modules 0.0.11 → 0.0.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.
- package/dist/modules/economyUtils/commands/shop.js +14 -2
- package/dist/modules/economyUtils/commands/shop.js.map +1 -1
- package/dist/modules/economyUtils/commands/transfer.js +1 -1
- package/dist/modules/economyUtils/commands/transfer.js.map +1 -1
- package/dist/modules.json +2 -2
- package/package.json +1 -1
- package/scripts/buildBuiltinJson.ts +0 -1
- package/src/__tests__/bugRepros.integration.test.ts +53 -0
- package/src/__tests__/economy/shop.integration.test.ts +15 -12
- package/src/modules/economyUtils/commands/shop.js +15 -5
- package/src/modules/economyUtils/commands/transfer.js +1 -1
|
@@ -2,6 +2,17 @@ import { takaro, data, TakaroUserError } from '@takaro/helpers';
|
|
|
2
2
|
async function main() {
|
|
3
3
|
const { arguments: args, player, gameServerId, user } = data;
|
|
4
4
|
const { page, item, action } = args;
|
|
5
|
+
const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;
|
|
6
|
+
// If command is called without any arguments
|
|
7
|
+
const messageWithoutPrefix = data.chatMessage.msg.slice(prefix.length).trim();
|
|
8
|
+
if (!messageWithoutPrefix.includes(' ')) {
|
|
9
|
+
await player.pm('This command allows you to browse the shop and view available items.');
|
|
10
|
+
await player.pm(`Usage: ${prefix}shop [page] [item] [action]`);
|
|
11
|
+
await player.pm(`${prefix}shop 2 - View the second page of shop items`);
|
|
12
|
+
await player.pm(`${prefix}shop 1 3 - View details about the third item on the first page`);
|
|
13
|
+
await player.pm(`${prefix}shop 1 3 buy - Purchase the third item on the first page`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
5
16
|
const shopItems = await takaro.shopListing.shopListingControllerSearch({
|
|
6
17
|
limit: 5,
|
|
7
18
|
page: page - 1,
|
|
@@ -43,12 +54,13 @@ async function main() {
|
|
|
43
54
|
if (action === 'buy') {
|
|
44
55
|
if (!user)
|
|
45
56
|
throw new TakaroUserError('You must link your account to Takaro to use this command.');
|
|
46
|
-
await takaro.shopOrder.shopOrderControllerCreate({
|
|
57
|
+
const orderRes = await takaro.shopOrder.shopOrderControllerCreate({
|
|
47
58
|
amount: 1,
|
|
48
59
|
listingId: selectedItem.id,
|
|
49
60
|
userId: user.id,
|
|
50
61
|
});
|
|
51
|
-
await player.pm(`You have purchased ${selectedItem.name} for ${selectedItem.price} ${currencyName.value}
|
|
62
|
+
await player.pm(`You have purchased ${selectedItem.name} for ${selectedItem.price} ${currencyName.value}.`);
|
|
63
|
+
await takaro.shopOrder.shopOrderControllerClaim(orderRes.data.data.id);
|
|
52
64
|
return;
|
|
53
65
|
}
|
|
54
66
|
throw new TakaroUserError('Invalid action. Valid actions are "buy".');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shop.js","sourceRoot":"","sources":["../../../../src/modules/economyUtils/commands/shop.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEhE,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"shop.js","sourceRoot":"","sources":["../../../../src/modules/economyUtils/commands/shop.js"],"names":[],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ async function main() {
|
|
|
34
34
|
currency: args.amount,
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
catch
|
|
37
|
+
catch {
|
|
38
38
|
throw new TakaroUserError(`Failed to transfer ${args.amount} ${currencyName} to ${receiverName}. Are you sure you have enough balance?`);
|
|
39
39
|
}
|
|
40
40
|
const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../../../src/modules/economyUtils/commands/transfer.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEhE,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAEzE,MAAM,YAAY,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAEpH,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAE/G,wHAAwH;IACxH,gJAAgJ;IAChJ,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAChG,MAAM,YAAY,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAEpG,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;QACtF,sDAAsD;QACtD,mFAAmF;QACnF,MAAM,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC7C,GAAG,EAAE,iBAAiB;YACtB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;gBACpB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE;oBACR,EAAE,EAAE,QAAQ,CAAC,EAAE;oBACf,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;iBAC5B;aACF,CAAC;YACF,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY;SACb,CAAC,CAAC;QAEH,+IAA+I;QAC/I,MAAM,MAAM,CAAC,EAAE,CACb,yBAAyB,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO,YAAY,+BAA+B,MAAM,kBAAkB,CAC/H,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,kBAAkB,CAAC,kDAAkD,CAChF,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,EAAE,EACT,QAAQ,CAAC,EAAE,EACX;YACE,QAAQ,EAAE,IAAI,CAAC,MAAM;SACtB,CACF,CAAC;IACJ,CAAC;IAAC,
|
|
1
|
+
{"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../../../src/modules/economyUtils/commands/transfer.js"],"names":[],"mappings":"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"}
|
package/dist/modules.json
CHANGED
|
@@ -373,7 +373,7 @@
|
|
|
373
373
|
"arguments": []
|
|
374
374
|
},
|
|
375
375
|
{
|
|
376
|
-
"function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog: sender, arguments: args, gameServerId, module: mod } = data;\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n // args.receiver has an argument type of \"player\". Arguments of this type are automatically resolved to the player's id.\n // If the player doesn't exist or multiple players with the same name where found, it will have thrown an error before this command is executed.\n const receiver = args.receiver;\n const senderName = (await takaro.player.playerControllerGetOne(sender.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n if (mod.userConfig.pendingAmount !== 0 && args.amount >= mod.userConfig.pendingAmount) {\n // create a variable to store confirmation requirement\n // TODO: in the future, we should probably add an expiration date to this variable.\n await takaro.variable.variableControllerCreate({\n key: 'confirmTransfer',\n value: JSON.stringify({\n amount: args.amount,\n receiver: {\n id: receiver.id,\n gameId: receiver.gameId,\n playerId: receiver.playerId,\n },\n }),\n moduleId: mod.moduleId,\n playerId: sender.playerId,\n gameServerId,\n });\n // NOTE: we should maybe check if the player has enough balance to send the amount since this is only checked when the transaction is executed.\n await sender.pm(`You are about to send ${args.amount} ${currencyName} to ${receiverName}. (Please confirm by typing ${prefix}confirmtransfer)`);\n return;\n }\n try {\n await takaro.playerOnGameserver.playerOnGameServerControllerTransactBetweenPlayers(sender.gameServerId, sender.id, receiver.id, {\n currency: args.amount,\n });\n }\n catch
|
|
376
|
+
"function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog: sender, arguments: args, gameServerId, module: mod } = data;\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n // args.receiver has an argument type of \"player\". Arguments of this type are automatically resolved to the player's id.\n // If the player doesn't exist or multiple players with the same name where found, it will have thrown an error before this command is executed.\n const receiver = args.receiver;\n const senderName = (await takaro.player.playerControllerGetOne(sender.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n if (mod.userConfig.pendingAmount !== 0 && args.amount >= mod.userConfig.pendingAmount) {\n // create a variable to store confirmation requirement\n // TODO: in the future, we should probably add an expiration date to this variable.\n await takaro.variable.variableControllerCreate({\n key: 'confirmTransfer',\n value: JSON.stringify({\n amount: args.amount,\n receiver: {\n id: receiver.id,\n gameId: receiver.gameId,\n playerId: receiver.playerId,\n },\n }),\n moduleId: mod.moduleId,\n playerId: sender.playerId,\n gameServerId,\n });\n // NOTE: we should maybe check if the player has enough balance to send the amount since this is only checked when the transaction is executed.\n await sender.pm(`You are about to send ${args.amount} ${currencyName} to ${receiverName}. (Please confirm by typing ${prefix}confirmtransfer)`);\n return;\n }\n try {\n await takaro.playerOnGameserver.playerOnGameServerControllerTransactBetweenPlayers(sender.gameServerId, sender.id, receiver.id, {\n currency: args.amount,\n });\n }\n catch {\n throw new TakaroUserError(`Failed to transfer ${args.amount} ${currencyName} to ${receiverName}. Are you sure you have enough balance?`);\n }\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `You received ${args.amount} ${currencyName} from ${senderName}`,\n opts: {\n recipient: {\n gameId: receiver.gameId,\n },\n },\n });\n await Promise.all([\n sender.pm(`You successfully transferred ${args.amount} ${currencyName} to ${receiverName}`),\n messageToReceiver,\n ]);\n return;\n}\nawait main();\n//# sourceMappingURL=transfer.js.map",
|
|
377
377
|
"name": "transfer",
|
|
378
378
|
"trigger": "transfer",
|
|
379
379
|
"helpText": "Transfer money to another player.",
|
|
@@ -410,7 +410,7 @@
|
|
|
410
410
|
]
|
|
411
411
|
},
|
|
412
412
|
{
|
|
413
|
-
"function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { arguments: args, player, gameServerId, user } = data;\n const { page, item, action } = args;\n const shopItems = await takaro.shopListing.shopListingControllerSearch({\n limit: 5,\n page: page - 1,\n sortBy: 'name',\n sortDirection: 'asc',\n filters: {\n gameServerId: [gameServerId],\n draft: false,\n },\n });\n if (shopItems.data.data.length === 0) {\n await player.pm('No items found.');\n return;\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', data.gameServerId)).data.data;\n if (!item) {\n // List the shop items\n for (const listing of shopItems.data.data) {\n const items = listing.items.slice(0, 3).map((item) => {\n return `${item.amount}x ${item.item.name}`;\n });\n await player.pm(`- ${listing.name} - ${listing.price} ${currencyName.value}. ${items.join(', ')}`);\n }\n return;\n }\n const selectedItem = shopItems.data.data[item - 1];\n if (!selectedItem)\n throw new TakaroUserError(`Item not found. Please select an item from the list, valid options are 1-${shopItems.data.data.length}.`);\n if (action === 'none') {\n // Display more info about the item\n await player.pm(`Listing ${selectedItem.name} - ${selectedItem.price} ${currencyName.value}`);\n await Promise.all(selectedItem.items.map((item) => {\n const quality = item.quality ? `Quality: ${item.quality}` : '';\n const description = (item.item.description ? `Description: ${item.item.description}` : '').replaceAll('\\\\n', ' ');\n return player.pm(`- ${item.amount}x ${item.item.name}. ${quality} ${description}`);\n }));\n return;\n }\n if (action === 'buy') {\n if (!user)\n throw new TakaroUserError('You must link your account to Takaro to use this command.');\n await takaro.shopOrder.shopOrderControllerCreate({\n amount: 1,\n listingId: selectedItem.id,\n userId: user.id,\n });\n await player.pm(`You have purchased ${selectedItem.name} for ${selectedItem.price} ${currencyName.value}
|
|
413
|
+
"function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { arguments: args, player, gameServerId, user } = data;\n const { page, item, action } = args;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n // If command is called without any arguments\n const messageWithoutPrefix = data.chatMessage.msg.slice(prefix.length).trim();\n if (!messageWithoutPrefix.includes(' ')) {\n await player.pm('This command allows you to browse the shop and view available items.');\n await player.pm(`Usage: ${prefix}shop [page] [item] [action]`);\n await player.pm(`${prefix}shop 2 - View the second page of shop items`);\n await player.pm(`${prefix}shop 1 3 - View details about the third item on the first page`);\n await player.pm(`${prefix}shop 1 3 buy - Purchase the third item on the first page`);\n return;\n }\n const shopItems = await takaro.shopListing.shopListingControllerSearch({\n limit: 5,\n page: page - 1,\n sortBy: 'name',\n sortDirection: 'asc',\n filters: {\n gameServerId: [gameServerId],\n draft: false,\n },\n });\n if (shopItems.data.data.length === 0) {\n await player.pm('No items found.');\n return;\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', data.gameServerId)).data.data;\n if (!item) {\n // List the shop items\n for (const listing of shopItems.data.data) {\n const items = listing.items.slice(0, 3).map((item) => {\n return `${item.amount}x ${item.item.name}`;\n });\n await player.pm(`- ${listing.name} - ${listing.price} ${currencyName.value}. ${items.join(', ')}`);\n }\n return;\n }\n const selectedItem = shopItems.data.data[item - 1];\n if (!selectedItem)\n throw new TakaroUserError(`Item not found. Please select an item from the list, valid options are 1-${shopItems.data.data.length}.`);\n if (action === 'none') {\n // Display more info about the item\n await player.pm(`Listing ${selectedItem.name} - ${selectedItem.price} ${currencyName.value}`);\n await Promise.all(selectedItem.items.map((item) => {\n const quality = item.quality ? `Quality: ${item.quality}` : '';\n const description = (item.item.description ? `Description: ${item.item.description}` : '').replaceAll('\\\\n', ' ');\n return player.pm(`- ${item.amount}x ${item.item.name}. ${quality} ${description}`);\n }));\n return;\n }\n if (action === 'buy') {\n if (!user)\n throw new TakaroUserError('You must link your account to Takaro to use this command.');\n const orderRes = await takaro.shopOrder.shopOrderControllerCreate({\n amount: 1,\n listingId: selectedItem.id,\n userId: user.id,\n });\n await player.pm(`You have purchased ${selectedItem.name} for ${selectedItem.price} ${currencyName.value}.`);\n await takaro.shopOrder.shopOrderControllerClaim(orderRes.data.data.id);\n return;\n }\n throw new TakaroUserError('Invalid action. Valid actions are \"buy\".');\n}\nawait main();\n//# sourceMappingURL=shop.js.map",
|
|
414
414
|
"name": "shop",
|
|
415
415
|
"trigger": "shop",
|
|
416
416
|
"helpText": "Browse the shop and view available items.",
|
package/package.json
CHANGED
|
@@ -172,6 +172,59 @@ const tests = [
|
|
|
172
172
|
expect((await eventsAfter)[0].data.meta.msg).to.be.eq('pong');
|
|
173
173
|
},
|
|
174
174
|
}),
|
|
175
|
+
/**
|
|
176
|
+
* Repro for https://github.com/gettakaro/takaro/issues/1405
|
|
177
|
+
* When providing invalid code, Takaro trips over itself and throws a nasty error
|
|
178
|
+
* Instead, it should catch it properly and return an actionable message for the user
|
|
179
|
+
*/
|
|
180
|
+
new IntegrationTest<IModuleTestsSetupData>({
|
|
181
|
+
group,
|
|
182
|
+
snapshot: false,
|
|
183
|
+
name: 'Bug repro: invalid module code throws bad error #1405',
|
|
184
|
+
setup: modulesTestSetup,
|
|
185
|
+
test: async function () {
|
|
186
|
+
const mod = (
|
|
187
|
+
await this.client.module.moduleControllerCreate({
|
|
188
|
+
name: 'Test module',
|
|
189
|
+
})
|
|
190
|
+
).data.data;
|
|
191
|
+
await this.client.command.commandControllerCreate({
|
|
192
|
+
name: 'testcmd',
|
|
193
|
+
moduleId: mod.id,
|
|
194
|
+
trigger: 'test',
|
|
195
|
+
// Yes, very bad code! This is what a user might accidentally do
|
|
196
|
+
function: `import { data, takaro } from '@takaro/helpers';
|
|
197
|
+
|
|
198
|
+
const messed = (await takaro.variable.variableControllerSearch({ search: { key: [\`object Object\`] } })).data.data
|
|
199
|
+
for (const thisVar of messed) {
|
|
200
|
+
let originalString = thisVar.key;
|
|
201
|
+
let newString = originalString.replace("[object Object]", "2024-09-20");
|
|
202
|
+
|
|
203
|
+
await takaro.variable.variableControllerUpdate(thisVar.id, { key: newString, value: thisVar.value });
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
data.player.pm(\`done\`).
|
|
207
|
+
`,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await this.client.gameserver.gameServerControllerInstallModule(this.setupData.gameserver.id, mod.id, {
|
|
211
|
+
userConfig: JSON.stringify({}),
|
|
212
|
+
systemConfig: JSON.stringify({}),
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.COMMAND_EXECUTED, 1);
|
|
216
|
+
|
|
217
|
+
await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
|
|
218
|
+
msg: '/test',
|
|
219
|
+
playerId: this.setupData.players[0].id,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
console.log(JSON.stringify((await events)[0].data.meta.result, null, 2));
|
|
223
|
+
const result = (await events)[0].data.meta.result;
|
|
224
|
+
expect(result.success).to.be.false;
|
|
225
|
+
expect(result.reason).to.include('SyntaxError: Unexpected end of input.');
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
175
228
|
];
|
|
176
229
|
|
|
177
230
|
describe(group, function () {
|
|
@@ -8,17 +8,22 @@ const tests = [
|
|
|
8
8
|
group,
|
|
9
9
|
snapshot: false,
|
|
10
10
|
setup: shopSetup,
|
|
11
|
-
name: '
|
|
11
|
+
name: 'Calling /shop without arguments displays help information',
|
|
12
12
|
test: async function () {
|
|
13
|
-
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE,
|
|
13
|
+
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE, 5);
|
|
14
14
|
await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
|
|
15
15
|
msg: '/shop',
|
|
16
16
|
playerId: this.setupData.players[0].id,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
expect(await events).to.have.length(
|
|
20
|
-
expect((await events)[0].data.meta.msg).to.eq(
|
|
21
|
-
|
|
19
|
+
expect(await events).to.have.length(5);
|
|
20
|
+
expect((await events)[0].data.meta.msg).to.eq(
|
|
21
|
+
'This command allows you to browse the shop and view available items.',
|
|
22
|
+
);
|
|
23
|
+
expect((await events)[1].data.meta.msg).to.eq('Usage: /shop [page] [item] [action]');
|
|
24
|
+
expect((await events)[2].data.meta.msg).to.eq('/shop 2 - View the second page of shop items');
|
|
25
|
+
expect((await events)[3].data.meta.msg).to.eq('/shop 1 3 - View details about the third item on the first page');
|
|
26
|
+
expect((await events)[4].data.meta.msg).to.eq('/shop 1 3 buy - Purchase the third item on the first page');
|
|
22
27
|
},
|
|
23
28
|
}),
|
|
24
29
|
new IntegrationTest<IShopSetup>({
|
|
@@ -30,7 +35,7 @@ const tests = [
|
|
|
30
35
|
await this.setupData.createListings(this.client, { gameServerId: this.setupData.gameserver.id, amount: 5 });
|
|
31
36
|
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE, 5);
|
|
32
37
|
await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
|
|
33
|
-
msg: '/shop',
|
|
38
|
+
msg: '/shop 1',
|
|
34
39
|
playerId: this.setupData.players[0].id,
|
|
35
40
|
});
|
|
36
41
|
|
|
@@ -122,23 +127,21 @@ const tests = [
|
|
|
122
127
|
);
|
|
123
128
|
},
|
|
124
129
|
}),
|
|
125
|
-
|
|
126
130
|
new IntegrationTest<IShopSetup>({
|
|
127
131
|
group,
|
|
128
132
|
snapshot: false,
|
|
129
133
|
setup: shopSetup,
|
|
130
134
|
name: 'Can buy an item',
|
|
131
135
|
test: async function () {
|
|
132
|
-
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE,
|
|
136
|
+
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE, 2);
|
|
133
137
|
await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
|
|
134
138
|
msg: '/shop 1 1 buy',
|
|
135
139
|
playerId: this.setupData.players[0].id,
|
|
136
140
|
});
|
|
137
141
|
|
|
138
|
-
expect(await events).to.have.length(
|
|
139
|
-
expect((await events)[0].data.meta.msg).to.equal(
|
|
140
|
-
|
|
141
|
-
);
|
|
142
|
+
expect(await events).to.have.length(2);
|
|
143
|
+
expect((await events)[0].data.meta.msg).to.equal('You have purchased Test item for 100 test coin.');
|
|
144
|
+
expect((await events)[1].data.meta.msg).to.equal('You have received items from a shop order.');
|
|
142
145
|
},
|
|
143
146
|
}),
|
|
144
147
|
];
|
|
@@ -2,8 +2,19 @@ import { takaro, data, TakaroUserError } from '@takaro/helpers';
|
|
|
2
2
|
|
|
3
3
|
async function main() {
|
|
4
4
|
const { arguments: args, player, gameServerId, user } = data;
|
|
5
|
-
|
|
6
5
|
const { page, item, action } = args;
|
|
6
|
+
const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;
|
|
7
|
+
|
|
8
|
+
// If command is called without any arguments
|
|
9
|
+
const messageWithoutPrefix = data.chatMessage.msg.slice(prefix.length).trim();
|
|
10
|
+
if (!messageWithoutPrefix.includes(' ')) {
|
|
11
|
+
await player.pm('This command allows you to browse the shop and view available items.');
|
|
12
|
+
await player.pm(`Usage: ${prefix}shop [page] [item] [action]`);
|
|
13
|
+
await player.pm(`${prefix}shop 2 - View the second page of shop items`);
|
|
14
|
+
await player.pm(`${prefix}shop 1 3 - View details about the third item on the first page`);
|
|
15
|
+
await player.pm(`${prefix}shop 1 3 buy - Purchase the third item on the first page`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
7
18
|
|
|
8
19
|
const shopItems = await takaro.shopListing.shopListingControllerSearch({
|
|
9
20
|
limit: 5,
|
|
@@ -60,14 +71,13 @@ async function main() {
|
|
|
60
71
|
if (action === 'buy') {
|
|
61
72
|
if (!user) throw new TakaroUserError('You must link your account to Takaro to use this command.');
|
|
62
73
|
|
|
63
|
-
await takaro.shopOrder.shopOrderControllerCreate({
|
|
74
|
+
const orderRes = await takaro.shopOrder.shopOrderControllerCreate({
|
|
64
75
|
amount: 1,
|
|
65
76
|
listingId: selectedItem.id,
|
|
66
77
|
userId: user.id,
|
|
67
78
|
});
|
|
68
|
-
await player.pm(
|
|
69
|
-
|
|
70
|
-
);
|
|
79
|
+
await player.pm(`You have purchased ${selectedItem.name} for ${selectedItem.price} ${currencyName.value}.`);
|
|
80
|
+
await takaro.shopOrder.shopOrderControllerClaim(orderRes.data.data.id);
|
|
71
81
|
return;
|
|
72
82
|
}
|
|
73
83
|
|