@takaro/modules 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/BuiltinModule.d.ts +3 -0
  2. package/dist/BuiltinModule.d.ts.map +1 -1
  3. package/dist/BuiltinModule.js +17 -0
  4. package/dist/BuiltinModule.js.map +1 -1
  5. package/dist/dto/index.d.ts +1 -0
  6. package/dist/dto/index.d.ts.map +1 -1
  7. package/dist/dto/takaroEvents.d.ts +7 -0
  8. package/dist/dto/takaroEvents.d.ts.map +1 -1
  9. package/dist/dto/takaroEvents.js +23 -1
  10. package/dist/dto/takaroEvents.js.map +1 -1
  11. package/dist/modules/chatBridge/index.d.ts.map +1 -1
  12. package/dist/modules/chatBridge/index.js +2 -0
  13. package/dist/modules/chatBridge/index.js.map +1 -1
  14. package/dist/modules/dailyRewards/commands/daily.js +1 -4
  15. package/dist/modules/dailyRewards/commands/daily.js.map +1 -1
  16. package/dist/modules/dailyRewards/index.d.ts.map +1 -1
  17. package/dist/modules/dailyRewards/index.js +4 -1
  18. package/dist/modules/dailyRewards/index.js.map +1 -1
  19. package/dist/modules/economyUtils/commands/confirmTransfer.js +4 -4
  20. package/dist/modules/economyUtils/commands/confirmTransfer.js.map +1 -1
  21. package/dist/modules/economyUtils/commands/grantCurrency.js +1 -4
  22. package/dist/modules/economyUtils/commands/grantCurrency.js.map +1 -1
  23. package/dist/modules/economyUtils/commands/revokeCurrency.js +1 -4
  24. package/dist/modules/economyUtils/commands/revokeCurrency.js.map +1 -1
  25. package/dist/modules/economyUtils/index.d.ts.map +1 -1
  26. package/dist/modules/economyUtils/index.js +5 -1
  27. package/dist/modules/economyUtils/index.js.map +1 -1
  28. package/dist/modules/geoBlock/index.d.ts.map +1 -1
  29. package/dist/modules/geoBlock/index.js +2 -0
  30. package/dist/modules/geoBlock/index.js.map +1 -1
  31. package/dist/modules/gimme/index.d.ts.map +1 -1
  32. package/dist/modules/gimme/index.js +2 -0
  33. package/dist/modules/gimme/index.js.map +1 -1
  34. package/dist/modules/highPingKicker/index.d.ts.map +1 -1
  35. package/dist/modules/highPingKicker/index.js +2 -0
  36. package/dist/modules/highPingKicker/index.js.map +1 -1
  37. package/dist/modules/lottery/commands/buyTicket.js +1 -4
  38. package/dist/modules/lottery/commands/buyTicket.js.map +1 -1
  39. package/dist/modules/lottery/commands/viewTickets.js +5 -8
  40. package/dist/modules/lottery/commands/viewTickets.js.map +1 -1
  41. package/dist/modules/lottery/index.d.ts.map +1 -1
  42. package/dist/modules/lottery/index.js +5 -1
  43. package/dist/modules/lottery/index.js.map +1 -1
  44. package/dist/modules/playerOnboarding/index.d.ts.map +1 -1
  45. package/dist/modules/playerOnboarding/index.js +2 -0
  46. package/dist/modules/playerOnboarding/index.js.map +1 -1
  47. package/dist/modules/serverMessages/index.d.ts.map +1 -1
  48. package/dist/modules/serverMessages/index.js +2 -0
  49. package/dist/modules/serverMessages/index.js.map +1 -1
  50. package/dist/modules/teleports/commands/deletewaypoint.js +1 -4
  51. package/dist/modules/teleports/commands/deletewaypoint.js.map +1 -1
  52. package/dist/modules/teleports/commands/setpublic.js +0 -3
  53. package/dist/modules/teleports/commands/setpublic.js.map +1 -1
  54. package/dist/modules/teleports/commands/settp.js +1 -4
  55. package/dist/modules/teleports/commands/settp.js.map +1 -1
  56. package/dist/modules/teleports/commands/setwaypoint.js +1 -4
  57. package/dist/modules/teleports/commands/setwaypoint.js.map +1 -1
  58. package/dist/modules/teleports/commands/teleport.js +1 -4
  59. package/dist/modules/teleports/commands/teleport.js.map +1 -1
  60. package/dist/modules/teleports/index.d.ts.map +1 -1
  61. package/dist/modules/teleports/index.js +9 -1
  62. package/dist/modules/teleports/index.js.map +1 -1
  63. package/dist/modules/timedShutdown/index.d.ts.map +1 -1
  64. package/dist/modules/timedShutdown/index.js +2 -0
  65. package/dist/modules/timedShutdown/index.js.map +1 -1
  66. package/dist/modules/utils/commands/help.js +60 -6
  67. package/dist/modules/utils/commands/help.js.map +1 -1
  68. package/dist/modules/utils/index.d.ts.map +1 -1
  69. package/dist/modules/utils/index.js +11 -2
  70. package/dist/modules/utils/index.js.map +1 -1
  71. package/dist/modules.json +112 -18
  72. package/package.json +1 -1
  73. package/src/BuiltinModule.ts +11 -0
  74. package/src/__tests__/economy/economyUtils.integration.test.ts +6 -2
  75. package/src/__tests__/help.integration.test.ts +230 -62
  76. package/src/__tests__/lottery.integration.test.ts +5 -1
  77. package/src/__tests__/modulePermission.integration.test.ts +197 -11
  78. package/src/__tests__/roleExpiry.integration.test.ts +6 -2
  79. package/src/__tests__/teleports/publicteleports.integration.test.ts +1 -1
  80. package/src/__tests__/teleports/waypoints.integration.test.ts +6 -2
  81. package/src/dto/takaroEvents.ts +16 -0
  82. package/src/modules/chatBridge/index.ts +2 -0
  83. package/src/modules/dailyRewards/commands/daily.js +1 -5
  84. package/src/modules/dailyRewards/index.ts +4 -1
  85. package/src/modules/economyUtils/commands/confirmTransfer.js +6 -6
  86. package/src/modules/economyUtils/commands/grantCurrency.js +1 -5
  87. package/src/modules/economyUtils/commands/revokeCurrency.js +1 -5
  88. package/src/modules/economyUtils/index.ts +5 -1
  89. package/src/modules/geoBlock/index.ts +2 -0
  90. package/src/modules/gimme/index.ts +2 -0
  91. package/src/modules/highPingKicker/index.ts +2 -0
  92. package/src/modules/lottery/commands/buyTicket.js +1 -5
  93. package/src/modules/lottery/commands/viewTickets.js +5 -9
  94. package/src/modules/lottery/index.ts +5 -1
  95. package/src/modules/playerOnboarding/index.ts +2 -0
  96. package/src/modules/serverMessages/index.ts +2 -0
  97. package/src/modules/teleports/commands/deletewaypoint.js +1 -5
  98. package/src/modules/teleports/commands/setpublic.js +1 -5
  99. package/src/modules/teleports/commands/settp.js +1 -6
  100. package/src/modules/teleports/commands/setwaypoint.js +1 -5
  101. package/src/modules/teleports/commands/teleport.js +1 -5
  102. package/src/modules/teleports/index.ts +9 -1
  103. package/src/modules/timedShutdown/index.ts +2 -0
  104. package/src/modules/utils/commands/help.js +70 -8
  105. package/src/modules/utils/index.ts +11 -2
package/dist/modules.json CHANGED
@@ -1,9 +1,13 @@
1
1
  [
2
2
  {
3
3
  "name": "utils",
4
+ "author": "Takaro",
5
+ "supportedGames": [
6
+ "all"
7
+ ],
4
8
  "versions": [
5
9
  {
6
- "tag": "0.0.1",
10
+ "tag": "0.0.2",
7
11
  "description": "A collection of useful commands",
8
12
  "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"additionalProperties\":false}",
9
13
  "commands": [
@@ -15,7 +19,7 @@
15
19
  "arguments": []
16
20
  },
17
21
  {
18
- "function": "import { data, takaro, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const enabledModules = await takaro.module.moduleInstallationsControllerGetInstalledModules({\n filters: { gameserverId: [data.gameServerId] },\n });\n const moduleCommands = await Promise.all(enabledModules.data.data.map(async (mod) => {\n const installedVersion = await takaro.module.moduleVersionControllerGetModuleVersion(mod.versionId);\n return installedVersion.data.data.commands;\n }));\n const allCommandsFlat = moduleCommands.flat();\n if (data.arguments.command === 'all') {\n await data.player.pm('Available commands:');\n await Promise.all(allCommandsFlat.map(async (command) => {\n await data.player.pm(`${command.name}: ${command.helpText}`);\n }));\n }\n else {\n const requestedCommand = allCommandsFlat.find((c) => {\n return c.name === data.arguments.command;\n });\n if (!requestedCommand) {\n throw new TakaroUserError(`Unknown command \"${data.arguments.command}\", use this command without arguments to see all available commands.`);\n }\n else {\n await data.player.pm(`${requestedCommand.name}: ${requestedCommand.helpText}`);\n }\n }\n}\nawait main();\n//# sourceMappingURL=help.js.map",
22
+ "function": "import { data, takaro, TakaroUserError, checkPermission } from '@takaro/helpers';\nasync function main() {\n const enabledModules = await takaro.module.moduleInstallationsControllerGetInstalledModules({\n filters: { gameserverId: [data.gameServerId] },\n });\n const moduleCommands = await Promise.all(enabledModules.data.data.map(async (mod) => {\n // Check if the module itself is enabled\n if (!mod.systemConfig.enabled) {\n return [];\n }\n const installedVersion = await takaro.module.moduleVersionControllerGetModuleVersion(mod.versionId);\n const commands = installedVersion.data.data.commands;\n // Filter out disabled commands\n return commands.filter((command) => {\n const commandConfig = mod.systemConfig.commands && mod.systemConfig.commands[command.name];\n return commandConfig && commandConfig.enabled;\n });\n }));\n const allCommandsFlat = moduleCommands.flat();\n // Filter commands based on player permissions\n const accessibleCommands = allCommandsFlat.filter((command) => {\n // If command has no required permissions, it's accessible to all\n if (!command.requiredPermissions || command.requiredPermissions.length === 0) {\n return true;\n }\n // Check if player has all required permissions\n return command.requiredPermissions.every((permission) => checkPermission(data.pog, permission));\n });\n if (data.arguments.command === 'search') {\n // Check if a search term was actually provided (not the default 'none')\n if (data.arguments.searchTerm === 'none') {\n throw new TakaroUserError('Please provide a search term. Usage: /help search <term>');\n }\n // Search functionality\n const searchTerm = data.arguments.searchTerm.toLowerCase();\n const matchingCommands = accessibleCommands.filter((command) => {\n // Check if command name contains search term\n const nameMatch = command.name.toLowerCase().includes(searchTerm);\n // Check if help text contains search term\n const helpTextMatch = command.helpText.toLowerCase().includes(searchTerm);\n return nameMatch || helpTextMatch;\n });\n if (matchingCommands.length === 0) {\n await data.player.pm(`No commands found matching \"${data.arguments.searchTerm}\".`);\n }\n else {\n await data.player.pm(`Commands matching \"${data.arguments.searchTerm}\":`);\n await Promise.all(matchingCommands.map(async (command) => {\n await data.player.pm(`${command.name}: ${command.helpText}`);\n }));\n }\n }\n else if (data.arguments.command === 'all') {\n await data.player.pm('Available commands:');\n if (accessibleCommands.length === 0) {\n await data.player.pm('No commands available to you.');\n }\n else {\n await Promise.all(accessibleCommands.map(async (command) => {\n await data.player.pm(`${command.name}: ${command.helpText}`);\n }));\n }\n }\n else {\n const requestedCommand = allCommandsFlat.find((c) => {\n return c.name === data.arguments.command;\n });\n if (!requestedCommand) {\n throw new TakaroUserError(`Unknown command \"${data.arguments.command}\", use this command without arguments to see all available commands.`);\n }\n else {\n // Check if player has permission to use this command\n const hasAccess = !requestedCommand.requiredPermissions ||\n requestedCommand.requiredPermissions.length === 0 ||\n requestedCommand.requiredPermissions.every((permission) => checkPermission(data.pog, permission));\n if (!hasAccess) {\n throw new TakaroUserError(`You don't have permission to use the \"${data.arguments.command}\" command.`);\n }\n await data.player.pm(`${requestedCommand.name}: ${requestedCommand.helpText}`);\n }\n }\n}\nawait main();\n//# sourceMappingURL=help.js.map",
19
23
  "name": "help",
20
24
  "trigger": "help",
21
25
  "helpText": "The text you are reading right now, displays information about commands.",
@@ -24,8 +28,15 @@
24
28
  "name": "command",
25
29
  "type": "string",
26
30
  "defaultValue": "all",
27
- "helpText": "The command to get help for",
31
+ "helpText": "The command to get help for, or \"search\" to search for commands",
28
32
  "position": 0
33
+ },
34
+ {
35
+ "name": "searchTerm",
36
+ "type": "string",
37
+ "defaultValue": "none",
38
+ "helpText": "Search term to find commands (when first argument is \"search\")",
39
+ "position": 1
29
40
  }
30
41
  ]
31
42
  }
@@ -35,9 +46,15 @@
35
46
  },
36
47
  {
37
48
  "name": "teleports",
49
+ "author": "Takaro",
50
+ "supportedGames": [
51
+ "7 days to die",
52
+ "rust",
53
+ "minecraft"
54
+ ],
38
55
  "versions": [
39
56
  {
40
- "tag": "0.0.3",
57
+ "tag": "0.0.4",
41
58
  "description": "A set of commands to allow players to set their own teleport points and teleport to them.",
42
59
  "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"timeout\":{\"title\":\"Timeout\",\"description\":\"The time one has to wait before teleporting again.\",\"x-component\":\"duration\",\"type\":\"number\",\"minimum\":0,\"default\":1000},\"allowPublicTeleports\":{\"type\":\"boolean\",\"description\":\"Players can create public teleports.\",\"default\":false}},\"required\":[],\"additionalProperties\":false}",
43
60
  "uiSchema": "{\"timeout\":{\"ui:widget\":\"duration\"}}",
@@ -69,10 +86,13 @@
69
86
  ],
70
87
  "commands": [
71
88
  {
72
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { findTp } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n if (!checkPermission(pog, 'TELEPORTS_USE')) {\n throw new TakaroUserError('You do not have permission to use teleports.');\n }\n const ownedTeleportRes = await findTp(args.tp, pog.playerId);\n let teleports = ownedTeleportRes.data.data;\n if (mod.userConfig.allowPublicTeleports) {\n const publicTeleportRes = await findTp(args.tp, null, true);\n teleports = teleports.concat(publicTeleportRes.data.data);\n }\n if (teleports.length === 0) {\n throw new TakaroUserError(`Teleport ${args.tp} does not exist.`);\n }\n const timeout = mod.userConfig.timeout;\n if (timeout > 0) {\n const lastExecuted = await takaro.variable.variableControllerSearch({\n filters: {\n key: ['lastExecuted'],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n let lastExecutedRecord = lastExecuted.data.data[0];\n if (!lastExecutedRecord) {\n const createRes = await takaro.variable.variableControllerCreate({\n key: 'lastExecuted',\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n value: new Date().toISOString(),\n });\n lastExecutedRecord = createRes.data.data;\n }\n else {\n const lastExecutedTime = new Date(lastExecutedRecord.value);\n const now = new Date();\n const diff = now.getTime() - lastExecutedTime.getTime();\n if (diff < timeout) {\n throw new TakaroUserError('You cannot teleport yet. Please wait before trying again.');\n }\n }\n const teleport = JSON.parse(teleports[0].value);\n await takaro.gameserver.gameServerControllerTeleportPlayer(gameServerId, pog.playerId, {\n x: teleport.x,\n y: teleport.y,\n z: teleport.z,\n dimension: teleport.dimension,\n });\n await data.player.pm(`Teleported to ${teleport.name}.`);\n if (timeout !== 0 && lastExecutedRecord) {\n await takaro.variable.variableControllerUpdate(lastExecutedRecord.id, {\n value: new Date().toISOString(),\n });\n }\n return;\n }\n const teleport = JSON.parse(teleports[0].value);\n await takaro.gameserver.gameServerControllerTeleportPlayer(gameServerId, pog.playerId, {\n x: teleport.x,\n y: teleport.y,\n z: teleport.z,\n dimension: teleport.dimension,\n });\n await data.player.pm(`Teleported to ${teleport.name}.`);\n}\nawait main();\n//# sourceMappingURL=teleport.js.map",
89
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nimport { findTp } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n const ownedTeleportRes = await findTp(args.tp, pog.playerId);\n let teleports = ownedTeleportRes.data.data;\n if (mod.userConfig.allowPublicTeleports) {\n const publicTeleportRes = await findTp(args.tp, null, true);\n teleports = teleports.concat(publicTeleportRes.data.data);\n }\n if (teleports.length === 0) {\n throw new TakaroUserError(`Teleport ${args.tp} does not exist.`);\n }\n const timeout = mod.userConfig.timeout;\n if (timeout > 0) {\n const lastExecuted = await takaro.variable.variableControllerSearch({\n filters: {\n key: ['lastExecuted'],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n let lastExecutedRecord = lastExecuted.data.data[0];\n if (!lastExecutedRecord) {\n const createRes = await takaro.variable.variableControllerCreate({\n key: 'lastExecuted',\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n value: new Date().toISOString(),\n });\n lastExecutedRecord = createRes.data.data;\n }\n else {\n const lastExecutedTime = new Date(lastExecutedRecord.value);\n const now = new Date();\n const diff = now.getTime() - lastExecutedTime.getTime();\n if (diff < timeout) {\n throw new TakaroUserError('You cannot teleport yet. Please wait before trying again.');\n }\n }\n const teleport = JSON.parse(teleports[0].value);\n await takaro.gameserver.gameServerControllerTeleportPlayer(gameServerId, pog.playerId, {\n x: teleport.x,\n y: teleport.y,\n z: teleport.z,\n dimension: teleport.dimension,\n });\n await data.player.pm(`Teleported to ${teleport.name}.`);\n if (timeout !== 0 && lastExecutedRecord) {\n await takaro.variable.variableControllerUpdate(lastExecutedRecord.id, {\n value: new Date().toISOString(),\n });\n }\n return;\n }\n const teleport = JSON.parse(teleports[0].value);\n await takaro.gameserver.gameServerControllerTeleportPlayer(gameServerId, pog.playerId, {\n x: teleport.x,\n y: teleport.y,\n z: teleport.z,\n dimension: teleport.dimension,\n });\n await data.player.pm(`Teleported to ${teleport.name}.`);\n}\nawait main();\n//# sourceMappingURL=teleport.js.map",
73
90
  "name": "teleport",
74
91
  "trigger": "tp",
75
92
  "helpText": "Teleports to one of your set locations.",
93
+ "requiredPermissions": [
94
+ "TELEPORTS_USE"
95
+ ],
76
96
  "arguments": [
77
97
  {
78
98
  "name": "tp",
@@ -88,13 +108,19 @@
88
108
  "name": "tplist",
89
109
  "trigger": "tplist",
90
110
  "helpText": "Lists all your set locations.",
111
+ "requiredPermissions": [
112
+ "TELEPORTS_USE"
113
+ ],
91
114
  "arguments": []
92
115
  },
93
116
  {
94
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getVariableKey, findTp } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod, arguments: args } = data;\n const hasPermission = checkPermission(pog, 'TELEPORTS_USE');\n if (!hasPermission) {\n throw new TakaroUserError('You do not have permission to use teleports.');\n }\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n const existingVariable = await findTp(args.tp, pog.playerId);\n if (existingVariable.data.data.length > 0) {\n throw new TakaroUserError(`Teleport ${args.tp} already exists, use ${prefix}deletetp ${args.tp} to delete it.`);\n }\n const allPlayerTeleports = await takaro.variable.variableControllerSearch({\n search: {\n key: [getVariableKey(undefined), getVariableKey(undefined, true)],\n },\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (allPlayerTeleports.data.data.length >= hasPermission.count) {\n throw new TakaroUserError(`You have reached the maximum number of teleports for your role, maximum allowed is ${hasPermission.count}`);\n }\n await takaro.variable.variableControllerCreate({\n key: getVariableKey(args.tp),\n value: JSON.stringify({\n name: args.tp,\n x: data.pog.positionX,\n y: data.pog.positionY,\n z: data.pog.positionZ,\n dimension: data.pog.dimension,\n }),\n gameServerId,\n moduleId: mod.moduleId,\n playerId: pog.playerId,\n });\n await data.player.pm(`Teleport ${args.tp} set.`);\n}\nawait main();\n//# sourceMappingURL=settp.js.map",
117
+ "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getVariableKey, findTp } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod, arguments: args } = data;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n const existingVariable = await findTp(args.tp, pog.playerId);\n if (existingVariable.data.data.length > 0) {\n throw new TakaroUserError(`Teleport ${args.tp} already exists, use ${prefix}deletetp ${args.tp} to delete it.`);\n }\n const hasPermission = checkPermission(pog, 'TELEPORTS_USE');\n const allPlayerTeleports = await takaro.variable.variableControllerSearch({\n search: {\n key: [getVariableKey(undefined), getVariableKey(undefined, true)],\n },\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (allPlayerTeleports.data.data.length >= hasPermission.count) {\n throw new TakaroUserError(`You have reached the maximum number of teleports for your role, maximum allowed is ${hasPermission.count}`);\n }\n await takaro.variable.variableControllerCreate({\n key: getVariableKey(args.tp),\n value: JSON.stringify({\n name: args.tp,\n x: data.pog.positionX,\n y: data.pog.positionY,\n z: data.pog.positionZ,\n dimension: data.pog.dimension,\n }),\n gameServerId,\n moduleId: mod.moduleId,\n playerId: pog.playerId,\n });\n await data.player.pm(`Teleport ${args.tp} set.`);\n}\nawait main();\n//# sourceMappingURL=settp.js.map",
95
118
  "name": "settp",
96
119
  "trigger": "settp",
97
120
  "helpText": "Sets a location to teleport to.",
121
+ "requiredPermissions": [
122
+ "TELEPORTS_USE"
123
+ ],
98
124
  "arguments": [
99
125
  {
100
126
  "name": "tp",
@@ -121,10 +147,13 @@
121
147
  ]
122
148
  },
123
149
  {
124
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getVariableKey } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod, arguments: args } = data;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n if (!mod.userConfig.allowPublicTeleports) {\n throw new TakaroUserError('Public teleports are disabled.');\n }\n const hasPermission = checkPermission(pog, 'TELEPORTS_CREATE_PUBLIC');\n if (!hasPermission) {\n throw new TakaroUserError('You do not have permission to create public teleports.');\n }\n const existingPublicTeleportsForPlayerRes = await takaro.variable.variableControllerSearch({\n search: {\n key: ['pubtp_'],\n },\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (existingPublicTeleportsForPlayerRes.data.data.length >= hasPermission.count) {\n throw new TakaroUserError(`You have reached the maximum number of public teleports for your role, maximum allowed is ${hasPermission.count}`);\n }\n const teleports = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n key: [getVariableKey(args.tp)],\n },\n sortBy: 'key',\n sortDirection: 'asc',\n })).data.data;\n if (teleports.length === 0) {\n throw new TakaroUserError(`No teleport with name ${args.tp} found, use ${prefix}settp <name> to set one first.`);\n }\n const teleportRecord = teleports[0];\n const teleport = JSON.parse(teleportRecord.value);\n await takaro.variable.variableControllerUpdate(teleportRecord.id, {\n key: getVariableKey(args.tp, true),\n value: JSON.stringify(teleport),\n });\n await data.player.pm(`Teleport ${args.tp} is now public.`);\n}\nawait main();\n//# sourceMappingURL=setpublic.js.map",
150
+ "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getVariableKey } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod, arguments: args } = data;\n const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;\n if (!mod.userConfig.allowPublicTeleports) {\n throw new TakaroUserError('Public teleports are disabled.');\n }\n const hasPermission = checkPermission(pog, 'TELEPORTS_CREATE_PUBLIC');\n const existingPublicTeleportsForPlayerRes = await takaro.variable.variableControllerSearch({\n search: {\n key: ['pubtp_'],\n },\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (existingPublicTeleportsForPlayerRes.data.data.length >= hasPermission.count) {\n throw new TakaroUserError(`You have reached the maximum number of public teleports for your role, maximum allowed is ${hasPermission.count}`);\n }\n const teleports = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n key: [getVariableKey(args.tp)],\n },\n sortBy: 'key',\n sortDirection: 'asc',\n })).data.data;\n if (teleports.length === 0) {\n throw new TakaroUserError(`No teleport with name ${args.tp} found, use ${prefix}settp <name> to set one first.`);\n }\n const teleportRecord = teleports[0];\n const teleport = JSON.parse(teleportRecord.value);\n await takaro.variable.variableControllerUpdate(teleportRecord.id, {\n key: getVariableKey(args.tp, true),\n value: JSON.stringify(teleport),\n });\n await data.player.pm(`Teleport ${args.tp} is now public.`);\n}\nawait main();\n//# sourceMappingURL=setpublic.js.map",
125
151
  "name": "setpublic",
126
152
  "trigger": "setpublic",
127
153
  "helpText": "Sets a teleport to be public, allowing other players to teleport to it.",
154
+ "requiredPermissions": [
155
+ "TELEPORTS_CREATE_PUBLIC"
156
+ ],
128
157
  "arguments": [
129
158
  {
130
159
  "name": "tp",
@@ -151,10 +180,13 @@
151
180
  ]
152
181
  },
153
182
  {
154
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getWaypointName, waypointReconciler } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n if (!checkPermission(pog, 'TELEPORTS_MANAGE_WAYPOINTS')) {\n throw new TakaroUserError('You do not have permission to manage waypoints.');\n }\n try {\n await takaro.variable.variableControllerCreate({\n moduleId: mod.moduleId,\n gameServerId,\n key: getWaypointName(args.waypoint),\n value: JSON.stringify({\n x: pog.positionX,\n y: pog.positionY,\n z: pog.positionZ,\n dimension: pog.dimension,\n }),\n });\n }\n catch (error) {\n if (error.message === 'Request failed with status code 409') {\n throw new TakaroUserError(`Waypoint ${args.waypoint} already exists.`);\n }\n throw error;\n }\n await waypointReconciler();\n await pog.pm(`Waypoint ${args.waypoint} set.`);\n}\nawait main();\n//# sourceMappingURL=setwaypoint.js.map",
183
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nimport { getWaypointName, waypointReconciler } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n try {\n await takaro.variable.variableControllerCreate({\n moduleId: mod.moduleId,\n gameServerId,\n key: getWaypointName(args.waypoint),\n value: JSON.stringify({\n x: pog.positionX,\n y: pog.positionY,\n z: pog.positionZ,\n dimension: pog.dimension,\n }),\n });\n }\n catch (error) {\n if (error.message === 'Request failed with status code 409') {\n throw new TakaroUserError(`Waypoint ${args.waypoint} already exists.`);\n }\n throw error;\n }\n await waypointReconciler();\n await pog.pm(`Waypoint ${args.waypoint} set.`);\n}\nawait main();\n//# sourceMappingURL=setwaypoint.js.map",
155
184
  "name": "setwaypoint",
156
185
  "trigger": "setwaypoint",
157
186
  "helpText": "Creates a new waypoint.",
187
+ "requiredPermissions": [
188
+ "TELEPORTS_MANAGE_WAYPOINTS"
189
+ ],
158
190
  "arguments": [
159
191
  {
160
192
  "name": "waypoint",
@@ -166,10 +198,13 @@
166
198
  ]
167
199
  },
168
200
  {
169
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nimport { getWaypointName, waypointReconciler } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n if (!checkPermission(pog, 'TELEPORTS_MANAGE_WAYPOINTS')) {\n throw new TakaroUserError('You do not have permission to manage waypoints.');\n }\n const variable = await takaro.variable.variableControllerSearch({\n filters: {\n key: [getWaypointName(args.waypoint)],\n gameServerId: [gameServerId],\n moduleId: [mod.moduleId],\n },\n });\n if (!variable.data.data.length) {\n throw new TakaroUserError(`Waypoint ${args.waypoint} doesn't exist.`);\n }\n await takaro.variable.variableControllerDelete(variable.data.data[0].id);\n await waypointReconciler();\n await pog.pm(`Waypoint ${args.waypoint} deleted.`);\n}\nawait main();\n//# sourceMappingURL=deletewaypoint.js.map",
201
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nimport { getWaypointName, waypointReconciler } from './utils.js';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n const variable = await takaro.variable.variableControllerSearch({\n filters: {\n key: [getWaypointName(args.waypoint)],\n gameServerId: [gameServerId],\n moduleId: [mod.moduleId],\n },\n });\n if (!variable.data.data.length) {\n throw new TakaroUserError(`Waypoint ${args.waypoint} doesn't exist.`);\n }\n await takaro.variable.variableControllerDelete(variable.data.data[0].id);\n await waypointReconciler();\n await pog.pm(`Waypoint ${args.waypoint} deleted.`);\n}\nawait main();\n//# sourceMappingURL=deletewaypoint.js.map",
170
202
  "name": "deletewaypoint",
171
203
  "trigger": "deletewaypoint",
172
204
  "helpText": "Deletes a waypoint.",
205
+ "requiredPermissions": [
206
+ "TELEPORTS_MANAGE_WAYPOINTS"
207
+ ],
173
208
  "arguments": [
174
209
  {
175
210
  "name": "waypoint",
@@ -207,6 +242,10 @@
207
242
  },
208
243
  {
209
244
  "name": "playerOnboarding",
245
+ "author": "Takaro",
246
+ "supportedGames": [
247
+ "all"
248
+ ],
210
249
  "versions": [
211
250
  {
212
251
  "tag": "0.0.3",
@@ -234,6 +273,10 @@
234
273
  },
235
274
  {
236
275
  "name": "serverMessages",
276
+ "author": "Takaro",
277
+ "supportedGames": [
278
+ "all"
279
+ ],
237
280
  "versions": [
238
281
  {
239
282
  "tag": "0.0.1",
@@ -251,6 +294,10 @@
251
294
  },
252
295
  {
253
296
  "name": "chatBridge",
297
+ "author": "Takaro",
298
+ "supportedGames": [
299
+ "all"
300
+ ],
254
301
  "versions": [
255
302
  {
256
303
  "tag": "0.0.1",
@@ -283,6 +330,12 @@
283
330
  },
284
331
  {
285
332
  "name": "gimme",
333
+ "author": "Takaro",
334
+ "supportedGames": [
335
+ "7 days to die",
336
+ "rust",
337
+ "minecraft"
338
+ ],
286
339
  "versions": [
287
340
  {
288
341
  "tag": "0.0.3",
@@ -303,6 +356,12 @@
303
356
  },
304
357
  {
305
358
  "name": "highPingKicker",
359
+ "author": "Takaro",
360
+ "supportedGames": [
361
+ "7 days to die",
362
+ "rust",
363
+ "minecraft"
364
+ ],
306
365
  "versions": [
307
366
  {
308
367
  "tag": "0.0.2",
@@ -320,9 +379,13 @@
320
379
  },
321
380
  {
322
381
  "name": "economyUtils",
382
+ "author": "Takaro",
383
+ "supportedGames": [
384
+ "all"
385
+ ],
323
386
  "versions": [
324
387
  {
325
- "tag": "0.0.1",
388
+ "tag": "0.0.2",
326
389
  "description": "A set of commands to allow players to manage their currency.",
327
390
  "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"pendingAmount\":{\"title\":\"Pending amount\",\"type\":\"number\",\"description\":\"When a player transfers money, they must confirm the transfer when the amount is equal or above this value. Set to 0 to disable.\",\"default\":0},\"zombieKillReward\":{\"title\":\"Zombie kill reward\",\"type\":\"number\",\"description\":\"The default amount of currency a player receives for killing a zombie. This can be overridden by roles.\",\"default\":1}},\"required\":[],\"additionalProperties\":false}",
328
391
  "permissions": [
@@ -362,10 +425,13 @@
362
425
  "arguments": []
363
426
  },
364
427
  {
365
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog: granter, arguments: args, gameServerId } = data;\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 if (!checkPermission(granter, 'ECONOMY_UTILS_MANAGE_CURRENCY')) {\n throw new TakaroUserError('You do not have permission to use grant currency command.');\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const granterName = (await takaro.player.playerControllerGetOne(granter.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(receiver.gameServerId, receiver.playerId, {\n currency: args.amount,\n });\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `Granted ${args.amount} ${currencyName} by ${granterName}`,\n opts: {\n recipient: {\n gameId: receiver.gameId,\n },\n },\n });\n await Promise.all([\n granter.pm(`You successfully granted ${args.amount} ${currencyName} to ${receiverName}`),\n messageToReceiver,\n ]);\n return;\n}\nawait main();\n//# sourceMappingURL=grantCurrency.js.map",
428
+ "function": "import { takaro, data } from '@takaro/helpers';\nasync function main() {\n const { pog: granter, arguments: args, gameServerId } = data;\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 currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const granterName = (await takaro.player.playerControllerGetOne(granter.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(receiver.gameServerId, receiver.playerId, {\n currency: args.amount,\n });\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `Granted ${args.amount} ${currencyName} by ${granterName}`,\n opts: {\n recipient: {\n gameId: receiver.gameId,\n },\n },\n });\n await Promise.all([\n granter.pm(`You successfully granted ${args.amount} ${currencyName} to ${receiverName}`),\n messageToReceiver,\n ]);\n return;\n}\nawait main();\n//# sourceMappingURL=grantCurrency.js.map",
366
429
  "name": "grantCurrency",
367
430
  "trigger": "grantcurrency",
368
431
  "helpText": "Grant money to a player. The money is not taken from your own balance but is new currency.",
432
+ "requiredPermissions": [
433
+ "ECONOMY_UTILS_MANAGE_CURRENCY"
434
+ ],
369
435
  "arguments": [
370
436
  {
371
437
  "name": "receiver",
@@ -384,10 +450,13 @@
384
450
  ]
385
451
  },
386
452
  {
387
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog: revoker, arguments: args, gameServerId } = data;\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 if (!checkPermission(revoker, 'ECONOMY_UTILS_MANAGE_CURRENCY')) {\n throw new TakaroUserError('You do not have permission to use revoke currency command.');\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const revokerName = (await takaro.player.playerControllerGetOne(revoker.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(receiver.gameServerId, receiver.playerId, {\n currency: args.amount,\n });\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `${args.amount} ${currencyName} were revoked by ${revokerName}`,\n opts: {\n recipient: {\n gameId: receiver.gameId,\n },\n },\n });\n await Promise.all([\n revoker.pm(`You successfully revoked ${args.amount} ${currencyName} of ${receiverName}'s balance`),\n messageToReceiver,\n ]);\n return;\n}\nawait main();\n//# sourceMappingURL=revokeCurrency.js.map",
453
+ "function": "import { takaro, data } from '@takaro/helpers';\nasync function main() {\n const { pog: revoker, arguments: args, gameServerId } = data;\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 currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const revokerName = (await takaro.player.playerControllerGetOne(revoker.playerId)).data.data.name;\n const receiverName = (await takaro.player.playerControllerGetOne(receiver.playerId)).data.data.name;\n await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(receiver.gameServerId, receiver.playerId, {\n currency: args.amount,\n });\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `${args.amount} ${currencyName} were revoked by ${revokerName}`,\n opts: {\n recipient: {\n gameId: receiver.gameId,\n },\n },\n });\n await Promise.all([\n revoker.pm(`You successfully revoked ${args.amount} ${currencyName} of ${receiverName}'s balance`),\n messageToReceiver,\n ]);\n return;\n}\nawait main();\n//# sourceMappingURL=revokeCurrency.js.map",
388
454
  "name": "revokeCurrency",
389
455
  "trigger": "revokecurrency",
390
456
  "helpText": "Revokes money from a player. The money disappears.",
457
+ "requiredPermissions": [
458
+ "ECONOMY_UTILS_MANAGE_CURRENCY"
459
+ ],
391
460
  "arguments": [
392
461
  {
393
462
  "name": "receiver",
@@ -406,7 +475,7 @@
406
475
  ]
407
476
  },
408
477
  {
409
- "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { gameServerId, pog: sender, module: mod } = data;\n // try to find a variable with key \"confirmTransfer\"\n const variables = (await takaro.variable.variableControllerSearch({\n filters: {\n key: 'confirmTransfer',\n gameServerId,\n moduleId: mod.moduleId,\n playerId: sender.playerId,\n },\n })).data.data;\n if (variables.length === 0) {\n throw new TakaroUserError('You have no pending transfer.');\n }\n // Remove the variable before potentially executing the transaction.\n await takaro.variable.variableControllerDelete(variables[0].id);\n const pendingTransfer = JSON.parse(variables[0].value);\n await takaro.playerOnGameserver.playerOnGameServerControllerTransactBetweenPlayers(sender.gameServerId, sender.id, pendingTransfer.receiver.id, {\n currency: pendingTransfer.amount,\n });\n const receiverName = (await takaro.player.playerControllerGetOne(pendingTransfer.receiver.playerId)).data.data.name;\n const senderName = (await takaro.player.playerControllerGetOne(sender.playerId)).data.data.name;\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const messageToSender = sender.pm(`You successfully transferred ${pendingTransfer.amount} ${currencyName} to ${receiverName}`);\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `You received ${pendingTransfer.amount} ${currencyName} from ${senderName}`,\n opts: {\n recipient: {\n gameId: pendingTransfer.receiver.gameId,\n },\n },\n });\n await Promise.all([messageToSender, messageToReceiver]);\n return;\n}\nawait main();\n//# sourceMappingURL=confirmTransfer.js.map",
478
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { gameServerId, pog: sender, module: mod } = data;\n // try to find a variable with key \"confirmTransfer\"\n const variables = (await takaro.variable.variableControllerSearch({\n filters: {\n key: ['confirmTransfer'],\n gameServerId: [gameServerId],\n moduleId: [mod.moduleId],\n playerId: [sender.playerId],\n },\n })).data.data;\n if (variables.length === 0) {\n throw new TakaroUserError('You have no pending transfer.');\n }\n // Remove the variable before potentially executing the transaction.\n await takaro.variable.variableControllerDelete(variables[0].id);\n const pendingTransfer = JSON.parse(variables[0].value);\n await takaro.playerOnGameserver.playerOnGameServerControllerTransactBetweenPlayers(sender.gameServerId, sender.id, pendingTransfer.receiver.id, {\n currency: pendingTransfer.amount,\n });\n const receiverName = (await takaro.player.playerControllerGetOne(pendingTransfer.receiver.playerId)).data.data.name;\n const senderName = (await takaro.player.playerControllerGetOne(sender.playerId)).data.data.name;\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n const messageToSender = sender.pm(`You successfully transferred ${pendingTransfer.amount} ${currencyName} to ${receiverName}`);\n const messageToReceiver = takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n message: `You received ${pendingTransfer.amount} ${currencyName} from ${senderName}`,\n opts: {\n recipient: {\n gameId: pendingTransfer.receiver.gameId,\n },\n },\n });\n await Promise.all([messageToSender, messageToReceiver]);\n return;\n}\nawait main();\n//# sourceMappingURL=confirmTransfer.js.map",
410
479
  "name": "confirmTransfer",
411
480
  "trigger": "confirmtransfer",
412
481
  "helpText": "Confirms a pending transfer.",
@@ -484,9 +553,13 @@
484
553
  },
485
554
  {
486
555
  "name": "lottery",
556
+ "author": "Takaro",
557
+ "supportedGames": [
558
+ "all"
559
+ ],
487
560
  "versions": [
488
561
  {
489
- "tag": "0.0.1",
562
+ "tag": "0.0.2",
490
563
  "description": "Players can buy tickets for a lottery, and the winner is chosen at random.",
491
564
  "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"profitMargin\":{\"type\":\"number\",\"maximum\":1,\"minimum\":0,\"description\":\"The profit margin the server takes from the lottery.\",\"default\":0.1}},\"required\":[],\"additionalProperties\":false}",
492
565
  "permissions": [
@@ -512,10 +585,13 @@
512
585
  ],
513
586
  "commands": [
514
587
  {
515
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n const varKey = 'lottery_tickets_bought';\n if (!checkPermission(pog, 'LOTTERY_BUY')) {\n throw new TakaroUserError('You do not have permission to buy lottery tickets.');\n }\n if (args.amount < 1) {\n throw new TakaroUserError('You must buy at least 1 ticket.');\n }\n const tickets = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId: [gameServerId],\n key: [varKey],\n moduleId: [mod.moduleId],\n playerId: [pog.playerId],\n },\n })).data.data;\n // Player already has some tickets bought\n if (tickets.length > 0) {\n const ticketsBought = tickets[0];\n const ticketsBoughtAmount = parseInt(JSON.parse(ticketsBought.value).amount, 10);\n await takaro.variable.variableControllerUpdate(ticketsBought.id, {\n key: varKey,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n gameServerId,\n value: JSON.stringify({ amount: ticketsBoughtAmount + args.amount }),\n });\n }\n // Player has no tickets bought\n else {\n await takaro.variable.variableControllerCreate({\n key: varKey,\n value: JSON.stringify({\n amount: args.amount,\n }),\n gameServerId,\n moduleId: mod.moduleId,\n playerId: pog.playerId,\n });\n }\n const ticketPrice = args.amount * mod.systemConfig.commands.buyTicket.cost;\n // The price of the first ticket is deducted by the command execution itself.\n if (args.amount > 1) {\n await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(gameServerId, pog.playerId, {\n currency: ticketPrice - 1,\n });\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n await pog.pm(`You have successfully bought ${args.amount} tickets for ${ticketPrice} ${currencyName}. Good luck!`);\n}\nawait main();\n//# sourceMappingURL=buyTicket.js.map",
588
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog, gameServerId, arguments: args, module: mod } = data;\n const varKey = 'lottery_tickets_bought';\n if (args.amount < 1) {\n throw new TakaroUserError('You must buy at least 1 ticket.');\n }\n const tickets = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId: [gameServerId],\n key: [varKey],\n moduleId: [mod.moduleId],\n playerId: [pog.playerId],\n },\n })).data.data;\n // Player already has some tickets bought\n if (tickets.length > 0) {\n const ticketsBought = tickets[0];\n const ticketsBoughtAmount = parseInt(JSON.parse(ticketsBought.value).amount, 10);\n await takaro.variable.variableControllerUpdate(ticketsBought.id, {\n key: varKey,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n gameServerId,\n value: JSON.stringify({ amount: ticketsBoughtAmount + args.amount }),\n });\n }\n // Player has no tickets bought\n else {\n await takaro.variable.variableControllerCreate({\n key: varKey,\n value: JSON.stringify({\n amount: args.amount,\n }),\n gameServerId,\n moduleId: mod.moduleId,\n playerId: pog.playerId,\n });\n }\n const ticketPrice = args.amount * mod.systemConfig.commands.buyTicket.cost;\n // The price of the first ticket is deducted by the command execution itself.\n if (args.amount > 1) {\n await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(gameServerId, pog.playerId, {\n currency: ticketPrice - 1,\n });\n }\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n await pog.pm(`You have successfully bought ${args.amount} tickets for ${ticketPrice} ${currencyName}. Good luck!`);\n}\nawait main();\n//# sourceMappingURL=buyTicket.js.map",
516
589
  "name": "buyTicket",
517
590
  "trigger": "buyTicket",
518
591
  "helpText": "Buy a lottery ticket.",
592
+ "requiredPermissions": [
593
+ "LOTTERY_BUY"
594
+ ],
519
595
  "arguments": [
520
596
  {
521
597
  "name": "amount",
@@ -527,10 +603,13 @@
527
603
  ]
528
604
  },
529
605
  {
530
- "function": "import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';\nasync function main() {\n const { pog, gameServerId, module: mod } = data;\n const varKey = 'lottery_tickets_bought';\n if (!checkPermission(pog, 'LOTTERY_VIEW_TICKETS')) {\n throw new TakaroUserError('You do not have permission to view lottery tickets.');\n }\n const tickets = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId,\n key: varKey,\n moduleId: mod.id,\n playerId: pog.playerId,\n },\n })).data.data;\n let ticketsBought = 0;\n if (tickets.length === 1) {\n ticketsBought = parseInt(JSON.parse(tickets[0].value).amount, 10);\n }\n await pog.pm(`You have bought ${ticketsBought} tickets.`);\n}\nawait main();\n//# sourceMappingURL=viewTickets.js.map",
606
+ "function": "import { takaro, data } from '@takaro/helpers';\nasync function main() {\n const { pog, gameServerId, module: mod } = data;\n const varKey = 'lottery_tickets_bought';\n const tickets = (await takaro.variable.variableControllerSearch({\n filters: {\n gameServerId: [gameServerId],\n key: [varKey],\n moduleId: [mod.moduleId],\n playerId: [pog.playerId],\n },\n })).data.data;\n let ticketsBought = 0;\n if (tickets.length === 1) {\n ticketsBought = parseInt(JSON.parse(tickets[0].value).amount, 10);\n }\n await pog.pm(`You have bought ${ticketsBought} tickets.`);\n}\nawait main();\n//# sourceMappingURL=viewTickets.js.map",
531
607
  "name": "viewTickets",
532
608
  "trigger": "viewTickets",
533
609
  "helpText": "View your lottery tickets.",
610
+ "requiredPermissions": [
611
+ "LOTTERY_VIEW_TICKETS"
612
+ ],
534
613
  "arguments": []
535
614
  },
536
615
  {
@@ -546,6 +625,10 @@
546
625
  },
547
626
  {
548
627
  "name": "geoBlock",
628
+ "author": "Takaro",
629
+ "supportedGames": [
630
+ "all"
631
+ ],
549
632
  "versions": [
550
633
  {
551
634
  "tag": "0.0.1",
@@ -572,6 +655,10 @@
572
655
  },
573
656
  {
574
657
  "name": "timedShutdown",
658
+ "author": "Takaro",
659
+ "supportedGames": [
660
+ "all"
661
+ ],
575
662
  "versions": [
576
663
  {
577
664
  "tag": "0.0.1",
@@ -594,10 +681,14 @@
594
681
  },
595
682
  {
596
683
  "name": "dailyRewards",
684
+ "author": "Takaro",
685
+ "supportedGames": [
686
+ "all"
687
+ ],
597
688
  "versions": [
598
689
  {
599
690
  "description": "Provides daily login rewards with streak tracking",
600
- "tag": "0.0.1",
691
+ "tag": "0.0.2",
601
692
  "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"baseReward\":{\"type\":\"number\",\"title\":\"Base Reward\",\"description\":\"Base amount of currency given for daily rewards. This is multiplied by streak level.\",\"default\":100,\"minimum\":1},\"maxStreak\":{\"type\":\"number\",\"title\":\"Maximum Streak\",\"description\":\"Maximum streak level a player can reach\",\"default\":365,\"minimum\":1},\"milestoneRewards\":{\"type\":\"array\",\"title\":\"Milestone Rewards\",\"description\":\"Additional rewards for reaching certain streak milestones\",\"items\":{\"type\":\"object\",\"properties\":{\"days\":{\"type\":\"number\",\"description\":\"Days needed to reach milestone\",\"minimum\":1},\"reward\":{\"type\":\"number\",\"description\":\"Bonus reward amount\"},\"message\":{\"type\":\"string\",\"description\":\"Message to show when milestone is reached\"}}},\"default\":[{\"days\":7,\"reward\":1000,\"message\":\"You did it! 7 days in a row!\"},{\"days\":30,\"reward\":5000,\"message\":\"A whole month! You're on fire!\"},{\"days\":90,\"reward\":20000,\"message\":\"90 days! You're unstoppable!\"},{\"days\":180,\"reward\":50000,\"message\":\"Half a year! You're a legend!\"},{\"days\":365,\"reward\":150000,\"message\":\"365 days! You're a true champion!\"}]}},\"required\":[\"baseReward\",\"maxStreak\",\"milestoneRewards\"],\"additionalProperties\":false}",
602
693
  "functions": [
603
694
  {
@@ -621,10 +712,13 @@
621
712
  ],
622
713
  "commands": [
623
714
  {
624
- "function": "import { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\nimport { DAILY_KEY, STREAK_KEY, getMultiplier } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod } = data;\n if (!checkPermission(pog, 'DAILY_CLAIM')) {\n throw new TakaroUserError('You do not have permission to claim daily rewards.');\n }\n // Get last claim time\n const lastClaimRes = await takaro.variable.variableControllerSearch({\n filters: {\n key: [DAILY_KEY],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n const now = new Date();\n let streak = 1;\n if (lastClaimRes.data.data.length > 0) {\n const lastClaim = new Date(JSON.parse(lastClaimRes.data.data[0].value));\n const hoursSinceLastClaim = (now - lastClaim) / (1000 * 60 * 60);\n // Check if 24 hours have passed\n if (hoursSinceLastClaim < 24) {\n const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000);\n throw new TakaroUserError(`You can claim your next reward at ${nextClaimTime.toLocaleString()}`);\n }\n // Get current streak\n const streakRes = await takaro.variable.variableControllerSearch({\n filters: {\n key: [STREAK_KEY],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (streakRes.data.data.length > 0) {\n // If claimed within 48 hours, increment streak\n if (hoursSinceLastClaim < 48) {\n streak = Math.min(JSON.parse(streakRes.data.data[0].value) + 1, mod.userConfig.maxStreak);\n await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {\n value: JSON.stringify(streak),\n });\n }\n else {\n // Reset streak if more than 48 hours\n await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {\n value: JSON.stringify(1),\n });\n }\n }\n else {\n // Create new streak record\n await takaro.variable.variableControllerCreate({\n key: STREAK_KEY,\n value: JSON.stringify(1),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n }\n // Update last claim time\n await takaro.variable.variableControllerUpdate(lastClaimRes.data.data[0].id, {\n value: JSON.stringify(now),\n });\n }\n else {\n // First time claim\n await takaro.variable.variableControllerCreate({\n key: DAILY_KEY,\n value: JSON.stringify(now),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n await takaro.variable.variableControllerCreate({\n key: STREAK_KEY,\n value: JSON.stringify(1),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n }\n const multiplier = await getMultiplier(pog);\n const baseReward = mod.userConfig.baseReward * streak * multiplier;\n let bonusReward = 0;\n let milestoneMessage = '';\n // Check for milestones\n for (const milestone of mod.userConfig.milestoneRewards) {\n if (streak === milestone.days) {\n bonusReward = milestone.reward;\n milestoneMessage = `\\n${milestone.message}`;\n break;\n }\n }\n // Award total rewards\n const totalReward = baseReward + bonusReward;\n await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, pog.playerId, {\n currency: totalReward,\n });\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n await pog.pm(`Daily reward claimed! You received ${totalReward} ${currencyName}\\n` +\n `Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x bonus!)` : ''}` +\n milestoneMessage);\n}\nawait main();\n//# sourceMappingURL=daily.js.map",
715
+ "function": "import { takaro, data, TakaroUserError } from '@takaro/helpers';\nimport { DAILY_KEY, STREAK_KEY, getMultiplier } from './utils.js';\nasync function main() {\n const { pog, gameServerId, module: mod } = data;\n // Get last claim time\n const lastClaimRes = await takaro.variable.variableControllerSearch({\n filters: {\n key: [DAILY_KEY],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n const now = new Date();\n let streak = 1;\n if (lastClaimRes.data.data.length > 0) {\n const lastClaim = new Date(JSON.parse(lastClaimRes.data.data[0].value));\n const hoursSinceLastClaim = (now - lastClaim) / (1000 * 60 * 60);\n // Check if 24 hours have passed\n if (hoursSinceLastClaim < 24) {\n const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000);\n throw new TakaroUserError(`You can claim your next reward at ${nextClaimTime.toLocaleString()}`);\n }\n // Get current streak\n const streakRes = await takaro.variable.variableControllerSearch({\n filters: {\n key: [STREAK_KEY],\n gameServerId: [gameServerId],\n playerId: [pog.playerId],\n moduleId: [mod.moduleId],\n },\n });\n if (streakRes.data.data.length > 0) {\n // If claimed within 48 hours, increment streak\n if (hoursSinceLastClaim < 48) {\n streak = Math.min(JSON.parse(streakRes.data.data[0].value) + 1, mod.userConfig.maxStreak);\n await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {\n value: JSON.stringify(streak),\n });\n }\n else {\n // Reset streak if more than 48 hours\n await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {\n value: JSON.stringify(1),\n });\n }\n }\n else {\n // Create new streak record\n await takaro.variable.variableControllerCreate({\n key: STREAK_KEY,\n value: JSON.stringify(1),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n }\n // Update last claim time\n await takaro.variable.variableControllerUpdate(lastClaimRes.data.data[0].id, {\n value: JSON.stringify(now),\n });\n }\n else {\n // First time claim\n await takaro.variable.variableControllerCreate({\n key: DAILY_KEY,\n value: JSON.stringify(now),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n await takaro.variable.variableControllerCreate({\n key: STREAK_KEY,\n value: JSON.stringify(1),\n gameServerId,\n playerId: pog.playerId,\n moduleId: mod.moduleId,\n });\n }\n const multiplier = await getMultiplier(pog);\n const baseReward = mod.userConfig.baseReward * streak * multiplier;\n let bonusReward = 0;\n let milestoneMessage = '';\n // Check for milestones\n for (const milestone of mod.userConfig.milestoneRewards) {\n if (streak === milestone.days) {\n bonusReward = milestone.reward;\n milestoneMessage = `\\n${milestone.message}`;\n break;\n }\n }\n // Award total rewards\n const totalReward = baseReward + bonusReward;\n await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, pog.playerId, {\n currency: totalReward,\n });\n const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;\n await pog.pm(`Daily reward claimed! You received ${totalReward} ${currencyName}\\n` +\n `Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x bonus!)` : ''}` +\n milestoneMessage);\n}\nawait main();\n//# sourceMappingURL=daily.js.map",
625
716
  "name": "daily",
626
717
  "trigger": "daily",
627
718
  "helpText": "Claim your daily reward",
719
+ "requiredPermissions": [
720
+ "DAILY_CLAIM"
721
+ ],
628
722
  "arguments": []
629
723
  },
630
724
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takaro/modules",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Built-in modules for Takaro",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",
@@ -41,6 +41,10 @@ export class ICommand extends TakaroDTO<ICommand> {
41
41
  @Type(() => ICommandArgument)
42
42
  @IsOptional()
43
43
  arguments: ICommandArgument[];
44
+ @IsArray()
45
+ @IsString({ each: true })
46
+ @IsOptional()
47
+ requiredPermissions?: string[];
44
48
  }
45
49
 
46
50
  export class IHook extends TakaroDTO<IHook> {
@@ -130,6 +134,13 @@ export class ModuleTransferDTO<T> extends TakaroDTO<T> {
130
134
  @IsString()
131
135
  @IsOptional()
132
136
  takaroVersion = process.env.TAKARO_VERSION;
137
+ @IsString()
138
+ @IsOptional()
139
+ public author?: string;
140
+ @IsArray()
141
+ @IsString({ each: true })
142
+ @IsOptional()
143
+ public supportedGames?: string[];
133
144
 
134
145
  @ValidateNested({ each: true })
135
146
  @Type(() => ModuleTransferVersionDTO)
@@ -478,8 +478,12 @@ const tests = [
478
478
  });
479
479
 
480
480
  const messages = (await events).sort(chatMessageSorter).map((e) => e.data.meta.msg as string);
481
- expect(messages[0]).to.be.eq('You do not have permission to use grant currency command.');
482
- expect(messages[1]).to.be.eq('You do not have permission to use revoke currency command.');
481
+ expect(messages[0]).to.be.eq(
482
+ "⚠️ You need the 'Economy Utils Manage Currency' permission to use this command. Please contact an admin if you need access.",
483
+ );
484
+ expect(messages[1]).to.be.eq(
485
+ "⚠️ You need the 'Economy Utils Manage Currency' permission to use this command. Please contact an admin if you need access.",
486
+ );
483
487
  },
484
488
  }),
485
489
  ];