@takaro/modules 0.0.1

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 (227) hide show
  1. package/README.md +3 -0
  2. package/dist/BuiltinModule.d.ts +49 -0
  3. package/dist/BuiltinModule.js +194 -0
  4. package/dist/BuiltinModule.js.map +1 -0
  5. package/dist/dto/base.d.ts +6 -0
  6. package/dist/dto/base.js +28 -0
  7. package/dist/dto/base.js.map +1 -0
  8. package/dist/dto/discordEvents.d.ts +31 -0
  9. package/dist/dto/discordEvents.js +92 -0
  10. package/dist/dto/discordEvents.js.map +1 -0
  11. package/dist/dto/gameEvents.d.ts +84 -0
  12. package/dist/dto/gameEvents.js +190 -0
  13. package/dist/dto/gameEvents.js.map +1 -0
  14. package/dist/dto/index.d.ts +37 -0
  15. package/dist/dto/index.js +18 -0
  16. package/dist/dto/index.js.map +1 -0
  17. package/dist/dto/takaroEvents.d.ts +150 -0
  18. package/dist/dto/takaroEvents.js +422 -0
  19. package/dist/dto/takaroEvents.js.map +1 -0
  20. package/dist/main.d.ts +4 -0
  21. package/dist/main.js +31 -0
  22. package/dist/main.js.map +1 -0
  23. package/dist/modules/chatBridge/hooks/DiscordToGame.d.ts +1 -0
  24. package/dist/modules/chatBridge/hooks/DiscordToGame.js +18 -0
  25. package/dist/modules/chatBridge/hooks/DiscordToGame.js.map +1 -0
  26. package/dist/modules/chatBridge/hooks/GameToDiscord.d.ts +1 -0
  27. package/dist/modules/chatBridge/hooks/GameToDiscord.js +14 -0
  28. package/dist/modules/chatBridge/hooks/GameToDiscord.js.map +1 -0
  29. package/dist/modules/chatBridge/hooks/PlayerConnected.d.ts +1 -0
  30. package/dist/modules/chatBridge/hooks/PlayerConnected.js +9 -0
  31. package/dist/modules/chatBridge/hooks/PlayerConnected.js.map +1 -0
  32. package/dist/modules/chatBridge/hooks/PlayerDisconnected.d.ts +1 -0
  33. package/dist/modules/chatBridge/hooks/PlayerDisconnected.js +9 -0
  34. package/dist/modules/chatBridge/hooks/PlayerDisconnected.js.map +1 -0
  35. package/dist/modules/chatBridge/index.d.ts +4 -0
  36. package/dist/modules/chatBridge/index.js +54 -0
  37. package/dist/modules/chatBridge/index.js.map +1 -0
  38. package/dist/modules/economyUtils/commands/balance.d.ts +1 -0
  39. package/dist/modules/economyUtils/commands/balance.js +7 -0
  40. package/dist/modules/economyUtils/commands/balance.js.map +1 -0
  41. package/dist/modules/economyUtils/commands/confirmTransfer.d.ts +1 -0
  42. package/dist/modules/economyUtils/commands/confirmTransfer.js +38 -0
  43. package/dist/modules/economyUtils/commands/confirmTransfer.js.map +1 -0
  44. package/dist/modules/economyUtils/commands/grantCurrency.d.ts +1 -0
  45. package/dist/modules/economyUtils/commands/grantCurrency.js +31 -0
  46. package/dist/modules/economyUtils/commands/grantCurrency.js.map +1 -0
  47. package/dist/modules/economyUtils/commands/revokeCurrency.d.ts +1 -0
  48. package/dist/modules/economyUtils/commands/revokeCurrency.js +31 -0
  49. package/dist/modules/economyUtils/commands/revokeCurrency.js.map +1 -0
  50. package/dist/modules/economyUtils/commands/topCurrency.d.ts +1 -0
  51. package/dist/modules/economyUtils/commands/topCurrency.js +22 -0
  52. package/dist/modules/economyUtils/commands/topCurrency.js.map +1 -0
  53. package/dist/modules/economyUtils/commands/transfer.d.ts +1 -0
  54. package/dist/modules/economyUtils/commands/transfer.js +55 -0
  55. package/dist/modules/economyUtils/commands/transfer.js.map +1 -0
  56. package/dist/modules/economyUtils/index.d.ts +4 -0
  57. package/dist/modules/economyUtils/index.js +117 -0
  58. package/dist/modules/economyUtils/index.js.map +1 -0
  59. package/dist/modules/geoBlock/hooks/IPDetected.d.ts +1 -0
  60. package/dist/modules/geoBlock/hooks/IPDetected.js +50 -0
  61. package/dist/modules/geoBlock/hooks/IPDetected.js.map +1 -0
  62. package/dist/modules/geoBlock/index.d.ts +8 -0
  63. package/dist/modules/geoBlock/index.js +321 -0
  64. package/dist/modules/geoBlock/index.js.map +1 -0
  65. package/dist/modules/gimme/commands/gimme.d.ts +1 -0
  66. package/dist/modules/gimme/commands/gimme.js +23 -0
  67. package/dist/modules/gimme/commands/gimme.js.map +1 -0
  68. package/dist/modules/gimme/index.d.ts +4 -0
  69. package/dist/modules/gimme/index.js +43 -0
  70. package/dist/modules/gimme/index.js.map +1 -0
  71. package/dist/modules/highPingKicker/cronJobs/Ping check.d.ts +1 -0
  72. package/dist/modules/highPingKicker/cronJobs/Ping check.js +54 -0
  73. package/dist/modules/highPingKicker/cronJobs/Ping check.js.map +1 -0
  74. package/dist/modules/highPingKicker/index.d.ts +4 -0
  75. package/dist/modules/highPingKicker/index.js +34 -0
  76. package/dist/modules/highPingKicker/index.js.map +1 -0
  77. package/dist/modules/lottery/commands/buyTicket.d.ts +1 -0
  78. package/dist/modules/lottery/commands/buyTicket.js +54 -0
  79. package/dist/modules/lottery/commands/buyTicket.js.map +1 -0
  80. package/dist/modules/lottery/commands/nextDraw.d.ts +1 -0
  81. package/dist/modules/lottery/commands/nextDraw.js +34 -0
  82. package/dist/modules/lottery/commands/nextDraw.js.map +1 -0
  83. package/dist/modules/lottery/commands/viewTickets.d.ts +1 -0
  84. package/dist/modules/lottery/commands/viewTickets.js +23 -0
  85. package/dist/modules/lottery/commands/viewTickets.js.map +1 -0
  86. package/dist/modules/lottery/cronJobs/drawLottery.d.ts +1 -0
  87. package/dist/modules/lottery/cronJobs/drawLottery.js +96 -0
  88. package/dist/modules/lottery/cronJobs/drawLottery.js.map +1 -0
  89. package/dist/modules/lottery/index.d.ts +4 -0
  90. package/dist/modules/lottery/index.js +73 -0
  91. package/dist/modules/lottery/index.js.map +1 -0
  92. package/dist/modules/playerOnboarding/commands/starterkit.d.ts +1 -0
  93. package/dist/modules/playerOnboarding/commands/starterkit.js +34 -0
  94. package/dist/modules/playerOnboarding/commands/starterkit.js.map +1 -0
  95. package/dist/modules/playerOnboarding/hooks/playerConnected.d.ts +1 -0
  96. package/dist/modules/playerOnboarding/hooks/playerConnected.js +11 -0
  97. package/dist/modules/playerOnboarding/hooks/playerConnected.js.map +1 -0
  98. package/dist/modules/playerOnboarding/index.d.ts +4 -0
  99. package/dist/modules/playerOnboarding/index.js +51 -0
  100. package/dist/modules/playerOnboarding/index.js.map +1 -0
  101. package/dist/modules/serverMessages/cronJobs/Automated message.d.ts +1 -0
  102. package/dist/modules/serverMessages/cronJobs/Automated message.js +9 -0
  103. package/dist/modules/serverMessages/cronJobs/Automated message.js.map +1 -0
  104. package/dist/modules/serverMessages/index.d.ts +4 -0
  105. package/dist/modules/serverMessages/index.js +35 -0
  106. package/dist/modules/serverMessages/index.js.map +1 -0
  107. package/dist/modules/teleports/commands/deletetp.d.ts +1 -0
  108. package/dist/modules/teleports/commands/deletetp.js +20 -0
  109. package/dist/modules/teleports/commands/deletetp.js.map +1 -0
  110. package/dist/modules/teleports/commands/deletewaypoint.d.ts +1 -0
  111. package/dist/modules/teleports/commands/deletewaypoint.js +54 -0
  112. package/dist/modules/teleports/commands/deletewaypoint.js.map +1 -0
  113. package/dist/modules/teleports/commands/listwaypoints.d.ts +1 -0
  114. package/dist/modules/teleports/commands/listwaypoints.js +36 -0
  115. package/dist/modules/teleports/commands/listwaypoints.js.map +1 -0
  116. package/dist/modules/teleports/commands/setprivate.d.ts +1 -0
  117. package/dist/modules/teleports/commands/setprivate.js +31 -0
  118. package/dist/modules/teleports/commands/setprivate.js.map +1 -0
  119. package/dist/modules/teleports/commands/setpublic.d.ts +1 -0
  120. package/dist/modules/teleports/commands/setpublic.js +55 -0
  121. package/dist/modules/teleports/commands/setpublic.js.map +1 -0
  122. package/dist/modules/teleports/commands/settp.d.ts +1 -0
  123. package/dist/modules/teleports/commands/settp.js +42 -0
  124. package/dist/modules/teleports/commands/settp.js.map +1 -0
  125. package/dist/modules/teleports/commands/setwaypoint.d.ts +1 -0
  126. package/dist/modules/teleports/commands/setwaypoint.js +88 -0
  127. package/dist/modules/teleports/commands/setwaypoint.js.map +1 -0
  128. package/dist/modules/teleports/commands/teleport.d.ts +1 -0
  129. package/dist/modules/teleports/commands/teleport.js +74 -0
  130. package/dist/modules/teleports/commands/teleport.js.map +1 -0
  131. package/dist/modules/teleports/commands/teleportwaypoint.d.ts +1 -0
  132. package/dist/modules/teleports/commands/teleportwaypoint.js +50 -0
  133. package/dist/modules/teleports/commands/teleportwaypoint.js.map +1 -0
  134. package/dist/modules/teleports/commands/tplist.d.ts +1 -0
  135. package/dist/modules/teleports/commands/tplist.js +45 -0
  136. package/dist/modules/teleports/commands/tplist.js.map +1 -0
  137. package/dist/modules/teleports/functions/utils.d.ts +2 -0
  138. package/dist/modules/teleports/functions/utils.js +18 -0
  139. package/dist/modules/teleports/functions/utils.js.map +1 -0
  140. package/dist/modules/teleports/index.d.ts +4 -0
  141. package/dist/modules/teleports/index.js +184 -0
  142. package/dist/modules/teleports/index.js.map +1 -0
  143. package/dist/modules/utils/commands/help.d.ts +1 -0
  144. package/dist/modules/utils/commands/help.js +29 -0
  145. package/dist/modules/utils/commands/help.js.map +1 -0
  146. package/dist/modules/utils/commands/ping.d.ts +1 -0
  147. package/dist/modules/utils/commands/ping.js +6 -0
  148. package/dist/modules/utils/commands/ping.js.map +1 -0
  149. package/dist/modules/utils/index.d.ts +4 -0
  150. package/dist/modules/utils/index.js +35 -0
  151. package/dist/modules/utils/index.js.map +1 -0
  152. package/dist/modules.json +478 -0
  153. package/package.json +26 -0
  154. package/scripts/buildBuiltinJson.ts +14 -0
  155. package/src/BuiltinModule.ts +125 -0
  156. package/src/__tests__/aliases.integration.test.ts +54 -0
  157. package/src/__tests__/builtinmodule.unit.test.ts +13 -0
  158. package/src/__tests__/commandArgs.integration.test.ts +285 -0
  159. package/src/__tests__/economyUtils.integration.test.ts +488 -0
  160. package/src/__tests__/geoblock.integration.test.ts +380 -0
  161. package/src/__tests__/gimme.integration.test.ts +97 -0
  162. package/src/__tests__/help.integration.test.ts +133 -0
  163. package/src/__tests__/lottery.integration.test.ts +332 -0
  164. package/src/__tests__/modulePermission.integration.test.ts +192 -0
  165. package/src/__tests__/onboarding.integration.test.ts +123 -0
  166. package/src/__tests__/ping.integration.test.ts +36 -0
  167. package/src/__tests__/roleExpiry.integration.test.ts +74 -0
  168. package/src/__tests__/serverMessages.integration.test.ts +104 -0
  169. package/src/__tests__/systemConfigCost.integration.test.ts +196 -0
  170. package/src/__tests__/teleports/listtp.integration.test.ts +115 -0
  171. package/src/__tests__/teleports/publicteleports.integration.test.ts +350 -0
  172. package/src/__tests__/teleports/teleport.integration.test.ts +109 -0
  173. package/src/__tests__/teleports/tpManagement.integration.test.ts +175 -0
  174. package/src/__tests__/teleports/waypoints.integration.test.ts +613 -0
  175. package/src/dto/base.ts +13 -0
  176. package/src/dto/discordEvents.ts +69 -0
  177. package/src/dto/gameEvents.ts +154 -0
  178. package/src/dto/index.ts +25 -0
  179. package/src/dto/takaroEvents.ts +290 -0
  180. package/src/main.ts +36 -0
  181. package/src/modules/.eslintrc +5 -0
  182. package/src/modules/chatBridge/hooks/DiscordToGame.js +18 -0
  183. package/src/modules/chatBridge/hooks/GameToDiscord.js +18 -0
  184. package/src/modules/chatBridge/hooks/PlayerConnected.js +11 -0
  185. package/src/modules/chatBridge/hooks/PlayerDisconnected.js +11 -0
  186. package/src/modules/chatBridge/index.ts +59 -0
  187. package/src/modules/economyUtils/commands/balance.js +8 -0
  188. package/src/modules/economyUtils/commands/confirmTransfer.js +55 -0
  189. package/src/modules/economyUtils/commands/grantCurrency.js +38 -0
  190. package/src/modules/economyUtils/commands/revokeCurrency.js +38 -0
  191. package/src/modules/economyUtils/commands/topCurrency.js +29 -0
  192. package/src/modules/economyUtils/commands/transfer.js +73 -0
  193. package/src/modules/economyUtils/index.ts +125 -0
  194. package/src/modules/geoBlock/hooks/IPDetected.js +52 -0
  195. package/src/modules/geoBlock/index.ts +331 -0
  196. package/src/modules/gimme/commands/gimme.js +28 -0
  197. package/src/modules/gimme/index.ts +49 -0
  198. package/src/modules/highPingKicker/cronJobs/Ping check.js +66 -0
  199. package/src/modules/highPingKicker/index.ts +39 -0
  200. package/src/modules/lottery/commands/buyTicket.js +68 -0
  201. package/src/modules/lottery/commands/nextDraw.js +45 -0
  202. package/src/modules/lottery/commands/viewTickets.js +32 -0
  203. package/src/modules/lottery/cronJobs/drawLottery.js +124 -0
  204. package/src/modules/lottery/index.ts +80 -0
  205. package/src/modules/playerOnboarding/commands/starterkit.js +47 -0
  206. package/src/modules/playerOnboarding/hooks/playerConnected.js +14 -0
  207. package/src/modules/playerOnboarding/index.ts +58 -0
  208. package/src/modules/serverMessages/cronJobs/Automated message.js +12 -0
  209. package/src/modules/serverMessages/index.ts +40 -0
  210. package/src/modules/teleports/commands/deletetp.js +25 -0
  211. package/src/modules/teleports/commands/deletewaypoint.js +77 -0
  212. package/src/modules/teleports/commands/listwaypoints.js +55 -0
  213. package/src/modules/teleports/commands/setprivate.js +39 -0
  214. package/src/modules/teleports/commands/setpublic.js +71 -0
  215. package/src/modules/teleports/commands/settp.js +54 -0
  216. package/src/modules/teleports/commands/setwaypoint.js +112 -0
  217. package/src/modules/teleports/commands/teleport.js +93 -0
  218. package/src/modules/teleports/commands/teleportwaypoint.js +72 -0
  219. package/src/modules/teleports/commands/tplist.js +61 -0
  220. package/src/modules/teleports/functions/utils.js +20 -0
  221. package/src/modules/teleports/index.ts +193 -0
  222. package/src/modules/utils/commands/help.js +38 -0
  223. package/src/modules/utils/commands/ping.js +7 -0
  224. package/src/modules/utils/index.ts +40 -0
  225. package/tsconfig.build.json +10 -0
  226. package/tsconfig.json +9 -0
  227. package/typedoc.json +3 -0
@@ -0,0 +1,380 @@
1
+ import { IntegrationTest, expect } from '@takaro/test';
2
+ import { IModuleTestsSetupData, modulesTestSetup } from '@takaro/test';
3
+ import { HookEvents } from '../dto/index.js';
4
+ import { TakaroEventPlayerNewIpDetected } from '@takaro/modules';
5
+ import { faker } from '@faker-js/faker';
6
+
7
+ const group = 'Geo Block';
8
+
9
+ const customSetup = async function (this: IntegrationTest<IModuleTestsSetupData>): Promise<IModuleTestsSetupData> {
10
+ const setupData = await modulesTestSetup.bind(this)();
11
+
12
+ await Promise.all(
13
+ setupData.players.map(async (player) => {
14
+ await this.client.player.playerControllerRemoveRole(player.id, setupData.role.id);
15
+ })
16
+ );
17
+
18
+ return setupData;
19
+ };
20
+
21
+ const tests = [
22
+ new IntegrationTest<IModuleTestsSetupData>({
23
+ group,
24
+ snapshot: false,
25
+ setup: customSetup,
26
+ name: 'DENY MODE: Blocked country detected -> player gets kicked based on configuration',
27
+ test: async function () {
28
+ await this.client.gameserver.gameServerControllerInstallModule(
29
+ this.setupData.gameserver.id,
30
+ this.setupData.geoBlockModule.id,
31
+ {
32
+ userConfig: JSON.stringify({
33
+ mode: 'deny',
34
+ countries: ['RU'],
35
+ ban: false,
36
+ }),
37
+ }
38
+ );
39
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.PLAYER_DISCONNECTED);
40
+ await this.client.hook.hookControllerTrigger({
41
+ gameServerId: this.setupData.gameserver.id,
42
+ playerId: this.setupData.players[0].id,
43
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
44
+ eventMeta: new TakaroEventPlayerNewIpDetected({
45
+ city: 'nowhere',
46
+ country: 'RU',
47
+ latitude: '0',
48
+ longitude: '0',
49
+ ip: faker.internet.ip(),
50
+ }),
51
+ });
52
+
53
+ expect((await events).length).to.be.eq(1);
54
+ expect((await events)[0].data.msg).to.match(/Kicked Your IP address is banned/);
55
+ expect((await events)[0].data.player.name).to.be.eq(this.setupData.players[0].name);
56
+ },
57
+ }),
58
+ new IntegrationTest<IModuleTestsSetupData>({
59
+ group,
60
+ snapshot: false,
61
+ setup: customSetup,
62
+ name: 'DENY MODE: Non-blocked country detected -> no action taken',
63
+ test: async function () {
64
+ await this.client.gameserver.gameServerControllerInstallModule(
65
+ this.setupData.gameserver.id,
66
+ this.setupData.geoBlockModule.id,
67
+ {
68
+ userConfig: JSON.stringify({
69
+ mode: 'deny',
70
+ countries: ['RU'],
71
+ ban: false,
72
+ }),
73
+ }
74
+ );
75
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.HOOK_EXECUTED);
76
+
77
+ await this.client.hook.hookControllerTrigger({
78
+ gameServerId: this.setupData.gameserver.id,
79
+ playerId: this.setupData.players[0].id,
80
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
81
+ eventMeta: new TakaroEventPlayerNewIpDetected({
82
+ city: 'nowhere',
83
+ country: 'BE',
84
+ latitude: '0',
85
+ longitude: '0',
86
+ ip: faker.internet.ip(),
87
+ }),
88
+ });
89
+
90
+ expect((await events).length).to.be.eq(1);
91
+ const containsAllowedCountryMessage = (await events)[0].data.meta.result.logs.some((log: any) => {
92
+ return log.msg.includes('Allowed country detected, no action');
93
+ });
94
+ expect(containsAllowedCountryMessage).to.be.eq(true, 'Decision message not found');
95
+ },
96
+ }),
97
+ new IntegrationTest<IModuleTestsSetupData>({
98
+ group,
99
+ snapshot: false,
100
+ setup: customSetup,
101
+ name: 'ALLOW MODE: Allowed country detected -> no action taken',
102
+ test: async function () {
103
+ await this.client.gameserver.gameServerControllerInstallModule(
104
+ this.setupData.gameserver.id,
105
+ this.setupData.geoBlockModule.id,
106
+ {
107
+ userConfig: JSON.stringify({
108
+ mode: 'allow',
109
+ countries: ['RU'],
110
+ ban: false,
111
+ }),
112
+ }
113
+ );
114
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.HOOK_EXECUTED);
115
+
116
+ await this.client.hook.hookControllerTrigger({
117
+ gameServerId: this.setupData.gameserver.id,
118
+ playerId: this.setupData.players[0].id,
119
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
120
+ eventMeta: new TakaroEventPlayerNewIpDetected({
121
+ city: 'nowhere',
122
+ country: 'RU',
123
+ latitude: '0',
124
+ longitude: '0',
125
+ ip: faker.internet.ip(),
126
+ }),
127
+ });
128
+
129
+ expect((await events).length).to.be.eq(1);
130
+ const containsAllowedCountryMessage = (await events)[0].data.meta.result.logs.some((log: any) => {
131
+ return log.msg.includes('Allowed country detected, no action');
132
+ });
133
+ expect(containsAllowedCountryMessage).to.be.eq(true, 'Decision message not found');
134
+ },
135
+ }),
136
+ new IntegrationTest<IModuleTestsSetupData>({
137
+ group,
138
+ snapshot: false,
139
+ setup: customSetup,
140
+ name: 'ALLOW MODE: Non-Allowed country detected -> player gets kicked/banned based on configuration',
141
+ test: async function () {
142
+ await this.client.gameserver.gameServerControllerInstallModule(
143
+ this.setupData.gameserver.id,
144
+ this.setupData.geoBlockModule.id,
145
+ {
146
+ userConfig: JSON.stringify({
147
+ mode: 'allow',
148
+ countries: ['RU'],
149
+ ban: false,
150
+ }),
151
+ }
152
+ );
153
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.PLAYER_DISCONNECTED);
154
+
155
+ await this.client.hook.hookControllerTrigger({
156
+ gameServerId: this.setupData.gameserver.id,
157
+ playerId: this.setupData.players[0].id,
158
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
159
+ eventMeta: new TakaroEventPlayerNewIpDetected({
160
+ city: 'nowhere',
161
+ country: 'BE',
162
+ latitude: '0',
163
+ longitude: '0',
164
+ ip: faker.internet.ip(),
165
+ }),
166
+ });
167
+
168
+ expect((await events).length).to.be.eq(1);
169
+ expect((await events)[0].data.msg).to.match(/Kicked Your IP address is banned/);
170
+ expect((await events)[0].data.player.name).to.be.eq(this.setupData.players[0].name);
171
+ },
172
+ }),
173
+ new IntegrationTest<IModuleTestsSetupData>({
174
+ group,
175
+ snapshot: false,
176
+ setup: customSetup,
177
+ name: 'BAN CONFIGURATION: Ban enabled -> player gets banned instead of kicked',
178
+ test: async function () {
179
+ await this.client.gameserver.gameServerControllerInstallModule(
180
+ this.setupData.gameserver.id,
181
+ this.setupData.geoBlockModule.id,
182
+ {
183
+ userConfig: JSON.stringify({
184
+ mode: 'allow',
185
+ countries: ['RU'],
186
+ ban: true,
187
+ }),
188
+ }
189
+ );
190
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.PLAYER_DISCONNECTED);
191
+
192
+ await this.client.hook.hookControllerTrigger({
193
+ gameServerId: this.setupData.gameserver.id,
194
+ playerId: this.setupData.players[0].id,
195
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
196
+ eventMeta: new TakaroEventPlayerNewIpDetected({
197
+ city: 'nowhere',
198
+ country: 'BE',
199
+ latitude: '0',
200
+ longitude: '0',
201
+ ip: faker.internet.ip(),
202
+ }),
203
+ });
204
+
205
+ expect((await events).length).to.be.eq(1);
206
+ expect((await events)[0].data.msg).to.match(/Banned Your IP address is banned/);
207
+ expect((await events)[0].data.player.name).to.be.eq(this.setupData.players[0].name);
208
+ },
209
+ }),
210
+ new IntegrationTest<IModuleTestsSetupData>({
211
+ group,
212
+ snapshot: false,
213
+ setup: customSetup,
214
+ name: 'MESSAGE CONFIGURATION: Custom message displayed to player on kick/ban',
215
+ test: async function () {
216
+ await this.client.gameserver.gameServerControllerInstallModule(
217
+ this.setupData.gameserver.id,
218
+ this.setupData.geoBlockModule.id,
219
+ {
220
+ userConfig: JSON.stringify({
221
+ mode: 'allow',
222
+ countries: ['RU'],
223
+ ban: true,
224
+ message: 'Custom message',
225
+ }),
226
+ }
227
+ );
228
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.PLAYER_DISCONNECTED);
229
+
230
+ await this.client.hook.hookControllerTrigger({
231
+ gameServerId: this.setupData.gameserver.id,
232
+ playerId: this.setupData.players[0].id,
233
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
234
+ eventMeta: new TakaroEventPlayerNewIpDetected({
235
+ city: 'nowhere',
236
+ country: 'BE',
237
+ latitude: '0',
238
+ longitude: '0',
239
+ ip: faker.internet.ip(),
240
+ }),
241
+ });
242
+
243
+ expect((await events).length).to.be.eq(1);
244
+ expect((await events)[0].data.msg).to.match(/Banned Custom message/);
245
+ expect((await events)[0].data.player.name).to.be.eq(this.setupData.players[0].name);
246
+ },
247
+ }),
248
+ new IntegrationTest<IModuleTestsSetupData>({
249
+ group,
250
+ snapshot: false,
251
+ setup: customSetup,
252
+ name: 'MULTIPLE COUNTRIES: Handling multiple countries in the whitelist or blacklist',
253
+ test: async function () {
254
+ await this.client.gameserver.gameServerControllerInstallModule(
255
+ this.setupData.gameserver.id,
256
+ this.setupData.geoBlockModule.id,
257
+ {
258
+ userConfig: JSON.stringify({
259
+ mode: 'deny',
260
+ countries: ['RU', 'BE'],
261
+ ban: true,
262
+ message: 'Custom message',
263
+ }),
264
+ }
265
+ );
266
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.PLAYER_DISCONNECTED);
267
+
268
+ await this.client.hook.hookControllerTrigger({
269
+ gameServerId: this.setupData.gameserver.id,
270
+ playerId: this.setupData.players[0].id,
271
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
272
+ eventMeta: new TakaroEventPlayerNewIpDetected({
273
+ city: 'nowhere',
274
+ country: 'BE',
275
+ latitude: '0',
276
+ longitude: '0',
277
+ ip: faker.internet.ip(),
278
+ }),
279
+ });
280
+
281
+ expect((await events).length).to.be.eq(1);
282
+ expect((await events)[0].data.msg).to.match(/Banned Custom message/);
283
+ expect((await events)[0].data.player.name).to.be.eq(this.setupData.players[0].name);
284
+ },
285
+ }),
286
+ new IntegrationTest<IModuleTestsSetupData>({
287
+ group,
288
+ snapshot: false,
289
+ setup: customSetup,
290
+ name: 'IMMUNITY PERMISSION: Player with GEOBLOCK_IMMUNITY permission is neither kicked nor banned',
291
+ test: async function () {
292
+ await this.client.gameserver.gameServerControllerInstallModule(
293
+ this.setupData.gameserver.id,
294
+ this.setupData.geoBlockModule.id,
295
+ {
296
+ userConfig: JSON.stringify({
297
+ mode: 'deny',
298
+ countries: ['RU'],
299
+ ban: true,
300
+ message: 'Custom message',
301
+ }),
302
+ }
303
+ );
304
+ const permissions = await this.client.permissionCodesToInputs(['GEOBLOCK_IMMUNITY']);
305
+ const roleRes = await this.client.role.roleControllerCreate({
306
+ name: 'Immune to geoblock',
307
+ permissions,
308
+ });
309
+
310
+ await this.client.player.playerControllerAssignRole(this.setupData.players[0].id, roleRes.data.data.id);
311
+
312
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.HOOK_EXECUTED);
313
+
314
+ await this.client.hook.hookControllerTrigger({
315
+ gameServerId: this.setupData.gameserver.id,
316
+ playerId: this.setupData.players[0].id,
317
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
318
+ eventMeta: new TakaroEventPlayerNewIpDetected({
319
+ city: 'nowhere',
320
+ country: 'RU',
321
+ latitude: '0',
322
+ longitude: '0',
323
+ ip: faker.internet.ip(),
324
+ }),
325
+ });
326
+
327
+ expect((await events).length).to.be.eq(1);
328
+ const containsAllowedCountryMessage = (await events)[0].data.meta.result.logs.some((log: any) => {
329
+ return log.msg.includes('Player has immunity, no action');
330
+ });
331
+ expect(containsAllowedCountryMessage).to.be.eq(true, 'Decision message not found');
332
+ },
333
+ }),
334
+ new IntegrationTest<IModuleTestsSetupData>({
335
+ group,
336
+ snapshot: false,
337
+ setup: customSetup,
338
+ name: 'NO COUNTRIES CONFIGURED: No action taken if countries array is empty',
339
+ test: async function () {
340
+ await this.client.gameserver.gameServerControllerInstallModule(
341
+ this.setupData.gameserver.id,
342
+ this.setupData.geoBlockModule.id,
343
+ {
344
+ userConfig: JSON.stringify({
345
+ mode: 'deny',
346
+ countries: [],
347
+ ban: true,
348
+ message: 'Custom message',
349
+ }),
350
+ }
351
+ );
352
+ const events = this.setupData.eventAwaiter.waitForEvents(HookEvents.HOOK_EXECUTED);
353
+
354
+ await this.client.hook.hookControllerTrigger({
355
+ gameServerId: this.setupData.gameserver.id,
356
+ playerId: this.setupData.players[0].id,
357
+ eventType: HookEvents.PLAYER_NEW_IP_DETECTED,
358
+ eventMeta: new TakaroEventPlayerNewIpDetected({
359
+ city: 'nowhere',
360
+ country: 'BE',
361
+ latitude: '0',
362
+ longitude: '0',
363
+ ip: faker.internet.ip(),
364
+ }),
365
+ });
366
+
367
+ expect((await events).length).to.be.eq(1);
368
+ const containsAllowedCountryMessage = (await events)[0].data.meta.result.logs.some((log: any) => {
369
+ return log.msg.includes('Allowed country detected, no action');
370
+ });
371
+ expect(containsAllowedCountryMessage).to.be.eq(true, 'Decision message not found');
372
+ },
373
+ }),
374
+ ];
375
+
376
+ describe(group, function () {
377
+ tests.forEach((test) => {
378
+ test.run();
379
+ });
380
+ });
@@ -0,0 +1,97 @@
1
+ import { IntegrationTest, expect } from '@takaro/test';
2
+ import { IModuleTestsSetupData, modulesTestSetup } from '@takaro/test';
3
+ import { GameEvents } from '../dto/index.js';
4
+
5
+ const group = 'gimme suite';
6
+
7
+ const tests = [
8
+ new IntegrationTest<IModuleTestsSetupData>({
9
+ group,
10
+ snapshot: false,
11
+ setup: modulesTestSetup,
12
+ name: 'Can give an item to a player',
13
+ test: async function () {
14
+ await this.client.gameserver.gameServerControllerInstallModule(
15
+ this.setupData.gameserver.id,
16
+ this.setupData.gimmeModule.id,
17
+ {
18
+ userConfig: JSON.stringify({
19
+ items: ['apple', 'banana', 'orange'],
20
+ commands: [],
21
+ }),
22
+ }
23
+ );
24
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE);
25
+
26
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
27
+ msg: '/gimme',
28
+ playerId: this.setupData.players[0].id,
29
+ });
30
+
31
+ expect((await events).length).to.be.eq(1);
32
+ expect((await events)[0].data.msg).to.match(/You received (apple|banana|orange)/);
33
+ },
34
+ }),
35
+ new IntegrationTest<IModuleTestsSetupData>({
36
+ group,
37
+ snapshot: false,
38
+ setup: modulesTestSetup,
39
+ name: 'Can execute command',
40
+ test: async function () {
41
+ await this.client.gameserver.gameServerControllerInstallModule(
42
+ this.setupData.gameserver.id,
43
+ this.setupData.gimmeModule.id,
44
+ {
45
+ userConfig: JSON.stringify({
46
+ items: [],
47
+ commands: ['say hello from test'],
48
+ }),
49
+ }
50
+ );
51
+
52
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE);
53
+
54
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
55
+ msg: '/gimme',
56
+ playerId: this.setupData.players[0].id,
57
+ });
58
+
59
+ expect((await events).length).to.be.eq(1);
60
+ expect((await events)[0].data.msg).to.eq('hello from test');
61
+ },
62
+ }),
63
+ new IntegrationTest<IModuleTestsSetupData>({
64
+ group,
65
+ snapshot: false,
66
+ setup: modulesTestSetup,
67
+ name: 'When no items or commands configured, displays an error',
68
+ test: async function () {
69
+ await this.client.gameserver.gameServerControllerInstallModule(
70
+ this.setupData.gameserver.id,
71
+ this.setupData.gimmeModule.id,
72
+ {
73
+ userConfig: JSON.stringify({
74
+ items: [],
75
+ commands: [],
76
+ }),
77
+ }
78
+ );
79
+
80
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE);
81
+
82
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
83
+ msg: '/gimme',
84
+ playerId: this.setupData.players[0].id,
85
+ });
86
+
87
+ expect((await events).length).to.be.eq(1);
88
+ expect((await events)[0].data.msg).to.match(/No items or commands configured/);
89
+ },
90
+ }),
91
+ ];
92
+
93
+ describe(group, function () {
94
+ tests.forEach((test) => {
95
+ test.run();
96
+ });
97
+ });
@@ -0,0 +1,133 @@
1
+ import { IntegrationTest, expect } from '@takaro/test';
2
+ import { IModuleTestsSetupData, modulesTestSetup, chatMessageSorter } from '@takaro/test';
3
+ import { GameEvents } from '../dto/gameEvents.js';
4
+
5
+ const group = 'Help command';
6
+
7
+ const tests = [
8
+ new IntegrationTest<IModuleTestsSetupData>({
9
+ group,
10
+ snapshot: false,
11
+ setup: modulesTestSetup,
12
+ name: 'Help command responds with a list of installed commands',
13
+ test: async function () {
14
+ await this.client.gameserver.gameServerControllerInstallModule(
15
+ this.setupData.gameserver.id,
16
+ this.setupData.utilsModule.id
17
+ );
18
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 3);
19
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
20
+ msg: '/help',
21
+ playerId: this.setupData.players[0].id,
22
+ });
23
+
24
+ expect((await events).length).to.be.eq(3);
25
+ const sortedEvents = (await events).sort(chatMessageSorter);
26
+
27
+ expect(sortedEvents[0].data.msg).to.be.eq('Available commands:');
28
+ expect(sortedEvents[1].data.msg).to.be.eq(
29
+ 'help: The text you are reading right now, displays information about commands.'
30
+ );
31
+ expect(sortedEvents[2].data.msg).to.be.eq('ping: Replies with pong, useful for testing if the connection works.');
32
+ },
33
+ }),
34
+ new IntegrationTest<IModuleTestsSetupData>({
35
+ group,
36
+ snapshot: false,
37
+ setup: modulesTestSetup,
38
+ name: 'Help command responds with a list of installed commands, picking up commands from multiple modules',
39
+ test: async function () {
40
+ await this.client.gameserver.gameServerControllerInstallModule(
41
+ this.setupData.gameserver.id,
42
+ this.setupData.utilsModule.id
43
+ );
44
+ await this.client.gameserver.gameServerControllerInstallModule(
45
+ this.setupData.gameserver.id,
46
+ this.setupData.teleportsModule.id
47
+ );
48
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 13);
49
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
50
+ msg: '/help',
51
+ playerId: this.setupData.players[0].id,
52
+ });
53
+
54
+ const sortedEvents = (await events).sort(chatMessageSorter);
55
+
56
+ expect(sortedEvents[0].data.msg).to.be.eq('Available commands:');
57
+ expect(sortedEvents[1].data.msg).to.be.eq('deletetp: Deletes a location.');
58
+ expect(sortedEvents[2].data.msg).to.be.eq('deletewaypoint: Deletes a waypoint.');
59
+ expect(sortedEvents[3].data.msg).to.be.eq(
60
+ 'help: The text you are reading right now, displays information about commands.'
61
+ );
62
+ expect(sortedEvents[4].data.msg).to.be.eq('listwaypoints: Lists all waypoints.');
63
+ expect(sortedEvents[5].data.msg).to.be.eq('ping: Replies with pong, useful for testing if the connection works.');
64
+ expect(sortedEvents[6].data.msg).to.be.eq(
65
+ 'setprivate: Sets a teleport to be private, only the teleport owner can teleport to it.'
66
+ );
67
+ expect(sortedEvents[7].data.msg).to.be.eq(
68
+ 'setpublic: Sets a teleport to be public, allowing other players to teleport to it.'
69
+ );
70
+ expect(sortedEvents[8].data.msg).to.be.eq('settp: Sets a location to teleport to.');
71
+ expect(sortedEvents[9].data.msg).to.be.eq('setwaypoint: Creates a new waypoint.');
72
+ expect(sortedEvents[10].data.msg).to.be.eq('teleport: Teleports to one of your set locations.');
73
+ expect(sortedEvents[11].data.msg).to.be.eq(
74
+ 'teleportwaypoint: Placeholder command, this will not be used directly. The module will install aliases for this command corresponding to the waypoint '
75
+ );
76
+ expect(sortedEvents[12].data.msg).to.be.eq('tplist: Lists all your set locations.');
77
+ },
78
+ }),
79
+ new IntegrationTest<IModuleTestsSetupData>({
80
+ group,
81
+ snapshot: false,
82
+ setup: modulesTestSetup,
83
+ name: 'Help command responds with detailed info about a specific command',
84
+ test: async function () {
85
+ await this.client.gameserver.gameServerControllerInstallModule(
86
+ this.setupData.gameserver.id,
87
+ this.setupData.utilsModule.id
88
+ );
89
+
90
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 1);
91
+
92
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
93
+ msg: '/help ping',
94
+ playerId: this.setupData.players[0].id,
95
+ });
96
+
97
+ expect((await events).length).to.be.eq(1);
98
+ const sortedEvents = (await events).sort(chatMessageSorter);
99
+
100
+ expect(sortedEvents[0].data.msg).to.be.eq('ping: Replies with pong, useful for testing if the connection works.');
101
+ },
102
+ }),
103
+ new IntegrationTest<IModuleTestsSetupData>({
104
+ group,
105
+ snapshot: false,
106
+ setup: modulesTestSetup,
107
+ name: 'Help command responds with unknown command message if command does not exist',
108
+ test: async function () {
109
+ await this.client.gameserver.gameServerControllerInstallModule(
110
+ this.setupData.gameserver.id,
111
+ this.setupData.utilsModule.id
112
+ );
113
+
114
+ const events = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 1);
115
+
116
+ await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
117
+ msg: '/help foobar',
118
+ playerId: this.setupData.players[0].id,
119
+ });
120
+
121
+ expect((await events).length).to.be.eq(1);
122
+ expect((await events)[0].data.msg).to.be.eq(
123
+ 'Unknown command "foobar", use this command without arguments to see all available commands.'
124
+ );
125
+ },
126
+ }),
127
+ ];
128
+
129
+ describe(group, function () {
130
+ tests.forEach((test) => {
131
+ test.run();
132
+ });
133
+ });